File : API\core\io\zmIOTypes.h Namespace : core::io
#define Z3D_ID_DECLARATION 0x4C434544 //"DECL" #define Z3D_ID_DATA 0x41544144 //"DATA" #define Z3D_ID_THUMBNAIL 0x424D4854 //"THMB" #define Z3D_ID_FILEINFO 0x4F464E49 //"INFO" #define Z3D_ID_SUBSTREAM 0x54534253 //"SBST" #define Z3D_ID_END_OF_FILE 0x46444E45 //"ENDF" // ZModeler v2.x file signature: //#define Z3D_FILE_SIGNATURE 0x53324D5A //ZM2S
Chunk identifiers for .z3d files. These are the only chunk identifiers used, while the rest of data is encapsulated in "DATA" chunks. Each chunk starts with chunk header:
//header: { DWORD m_dwType; //chunk ID (one of Z3D_ID_* values) DWORD m_dwID; //chunk unique ID (inside .z3d file) DWORD m_dwVersion; //chunk version (any format you like) DWORD m_dwSize; //size of data, followed by this header };
And followed by chunk-specific data. For example, Z3D_ID_THUMBNAIL is followed by pure JPEG image data (size is m_dwSize bytes) which represents thumbnail image.
.z3d files can contain substreams in it. The most common case is a core::io::CZIPStream substream block which encapuslates all file data into it's own single ZIPped block. Substream is limited with chunk data size and long dataLength written right after a class name is an uncompressed data size.
// // code fragment; chunkInfo is a chunk header as shown above; // if (chunkInfo.m_dwType == Z3D_ID_SUBSTREAM) //substream chunk found; { ZPtr<core::io::IStream> pSubst; long nDataLen = 0, nCLen = 0; ZString strClass; pInStream->read(&nCLen, 4); //length of classname string strClass.length(nCLen); pInStream->read((LPSTR)strClass, nCLen); pInStream->read(&nDataLen, 4); //dataLength for substreamed class //create substream on supplied stream: if (ZRESULT_OK != createSharedClass(strClass, IID_(core::io::IStream), (void**)&pSubst)) ::ShowMessageDirect(core::MT_ERROR, _T("Failed to create substream \"%s\"."), (LPCTSTR)strClass); else if (ZRESULT_OK != pSubst->subStream(pInStream, chunkInfo.m_dwSize-4-nCLen-4) || ZRESULT_OK != pSubst->setLength(nDataLen)) ::ShowMessageDirect(core::MT_ERROR, _T("Failed to substream.")); else { seqSubStreaming.add(pInStream);//backup previouse stream; pInStream = pSubst; //set substream as current continue;//and read from substream } } //end code fragment; //