void CModelWriter_3MF_Native::addAttachments(_In_ CModel * pModel, _In_ POpcPackageWriter pPackageWriter, _In_ POpcPackagePart pModelPart) { __NMRASSERT(pModel != nullptr); __NMRASSERT(pModelPart.get() != nullptr); __NMRASSERT(pPackageWriter.get() != nullptr); nfUint32 nCount = pModel->getAttachmentCount(); nfUint32 nIndex; if (nCount > 0) { for (nIndex = 0; nIndex < nCount; nIndex++) { PModelAttachment pAttachment = pModel->getModelAttachment(nIndex); PImportStream pStream = pAttachment->getStream(); std::wstring sPath = fnIncludeLeadingPathDelimiter(pAttachment->getPathURI()); std::wstring sRelationShipType = pAttachment->getRelationShipType(); if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); // create Texture Part POpcPackagePart pAttachmentPart = pPackageWriter->addPart(sPath); PExportStream pExportStream = pAttachmentPart->getExportStream(); // Copy data pStream->seekPosition(0, true); pExportStream->copyFrom(pStream.get(), pStream->retrieveSize(), MODELWRITER_NATIVE_BUFFERSIZE); // add relationships pModelPart->addRelationship(generateRelationShipID(), sRelationShipType.c_str(), pAttachmentPart->getURI()); } } }
void CModelWriter_3MF_Native::writePackageToStream(_In_ PExportStream pStream) { if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); if (m_pModel == nullptr) throw CNMRException(NMR_ERROR_NOMODELTOWRITE); // Write Model Stream POpcPackageWriter pPackageWriter = std::make_shared<COpcPackageWriter>(pStream); POpcPackagePart pModelPart = pPackageWriter->addPart(PACKAGE_3D_MODEL_URI); PXmlWriter_Native pXMLWriter = std::make_shared<CXmlWriter_Native>(pModelPart->getExportStream()); writeModelStream(pXMLWriter.get(), m_pModel); // add Root relationships pPackageWriter->addRootRelationship(generateRelationShipID(), PACKAGE_START_PART_RELATIONSHIP_TYPE, pModelPart.get()); // add Textures addTextureParts(m_pModel, pPackageWriter, pModelPart); // add Content Types pPackageWriter->addContentType(PACKAGE_3D_RELS_EXTENSION, PACKAGE_3D_RELS_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_MODEL_EXTENSION, PACKAGE_3D_MODEL_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_TEXTURE_EXTENSION, PACKAGE_TEXTURE_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_PNG_EXTENSION, PACKAGE_PNG_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_JPEG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_JPG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); }
void CModelWriter_3MF_Native::addTextureParts(_In_ CModel * pModel, _In_ POpcPackageWriter pPackageWriter, _In_ POpcPackagePart pModelPart) { __NMRASSERT(pModel != nullptr); __NMRASSERT(pModelPart.get() != nullptr); __NMRASSERT(pPackageWriter.get() != nullptr); nfUint32 nCount = pModel->getTextureStreamCount(); nfUint32 nIndex; if (nCount > 0) { for (nIndex = 0; nIndex < nCount; nIndex++) { PImportStream pStream = pModel->getTextureStream(nIndex); std::wstring sPath = fnIncludeLeadingPathDelimiter (pModel->getTextureStreamPath(nIndex)); if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); // create Texture Part POpcPackagePart pTexturePart = pPackageWriter->addPart(sPath); PExportStream pExportStream = pTexturePart->getExportStream(); // Copy data pStream->seekPosition(0, true); pExportStream->copyFrom(pStream.get(), pStream->retrieveSize(), MODELWRITER_NATIVE_BUFFERSIZE); // add relationships pModelPart->addRelationship(generateRelationShipID(), PACKAGE_TEXTURE_RELATIONSHIP_TYPE, pTexturePart.get()); } } }
void CModelWriter_3MF_Native::writePackageToStream(_In_ PExportStream pStream) { if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); if (m_pModel == nullptr) throw CNMRException(NMR_ERROR_NOMODELTOWRITE); // Write Model Stream POpcPackageWriter pPackageWriter = std::make_shared<COpcPackageWriter>(pStream); POpcPackagePart pModelPart = pPackageWriter->addPart(PACKAGE_3D_MODEL_URI); PXmlWriter_Native pXMLWriter = std::make_shared<CXmlWriter_Native>(pModelPart->getExportStream()); writeModelStream(pXMLWriter.get(), m_pModel); // add Root relationships pPackageWriter->addRootRelationship(generateRelationShipID(), PACKAGE_START_PART_RELATIONSHIP_TYPE, pModelPart.get()); PModelAttachment pPackageThumbnail = m_pModel->getPackageThumbnail(); if (pPackageThumbnail.get() != nullptr) { // create Package Thumbnail Part POpcPackagePart pThumbnailPart = pPackageWriter->addPart(pPackageThumbnail->getPathURI()); PExportStream pExportStream = pThumbnailPart->getExportStream(); // Copy data PImportStream pPackageThumbnailStream = pPackageThumbnail->getStream(); pPackageThumbnailStream->seekPosition(0, true); pExportStream->copyFrom(pPackageThumbnailStream.get(), pPackageThumbnailStream->retrieveSize(), MODELWRITER_NATIVE_BUFFERSIZE); // add root relationship pPackageWriter->addRootRelationship(generateRelationShipID(), pPackageThumbnail->getRelationShipType(), pThumbnailPart.get()); } // add slicestacks that reference other files addSlicerefAttachments(m_pModel); // add Attachments addAttachments(m_pModel, pPackageWriter, pModelPart); // add Content Types pPackageWriter->addContentType(PACKAGE_3D_RELS_EXTENSION, PACKAGE_3D_RELS_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_MODEL_EXTENSION, PACKAGE_3D_MODEL_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_TEXTURE_EXTENSION, PACKAGE_TEXTURE_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_PNG_EXTENSION, PACKAGE_PNG_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_JPEG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); pPackageWriter->addContentType(PACKAGE_3D_JPG_EXTENSION, PACKAGE_JPG_CONTENT_TYPE); std::map<std::wstring, std::wstring> CustomContentTypes = m_pModel->getCustomContentTypes(); std::map<std::wstring, std::wstring>::iterator iContentTypeIterator; for (iContentTypeIterator = CustomContentTypes.begin(); iContentTypeIterator != CustomContentTypes.end(); iContentTypeIterator++) { if (!m_pModel->contentTypeIsDefault(iContentTypeIterator->first)) { pPackageWriter->addContentType(iContentTypeIterator->first, iContentTypeIterator->second); } } }
PImportStream CModelReader_3MF_Native::extract3MFOPCPackage(_In_ PImportStream pPackageStream) { m_pPackageReader = std::make_shared<COpcPackageReader>(pPackageStream); COpcPackageRelationship * pModelRelation = m_pPackageReader->findRootRelation(PACKAGE_START_PART_RELATIONSHIP_TYPE, true); if (pModelRelation == nullptr) throw CNMRException(NMR_ERROR_OPCRELATIONSHIPSETREADFAILED); std::wstring sTargetPartURI = pModelRelation->getTargetPartURI(); POpcPackagePart pModelPart = m_pPackageReader->createPart (sTargetPartURI); if (pModelPart == nullptr) throw CNMRException(NMR_ERROR_OPCCOULDNOTGETMODELSTREAM); extractTexturesFromRelationships(pModelPart.get()); return pModelPart->getImportStream(); }
void CModelReader_3MF_Native::extractTexturesFromRelationships(_In_ COpcPackagePart * pModelPart) { if (pModelPart == nullptr) throw CNMRException(NMR_ERROR_INVALIDPARAM); std::list<POpcPackageRelationship> RelationShips = pModelPart->getRelationShips(); std::list<POpcPackageRelationship>::iterator iIterator; for (iIterator = RelationShips.begin(); iIterator != RelationShips.end(); iIterator++) { std::wstring sType = (*iIterator)->getType(); if (wcscmp(sType.c_str(), PACKAGE_TEXTURE_RELATIONSHIP_TYPE) == 0) { std::wstring sURI = (*iIterator)->getTargetPartURI(); POpcPackagePart pTexturePart = m_pPackageReader->createPart(sURI); PImportStream pTextureStream = pTexturePart->getImportStream(); PImportStream pMemoryStream = pTextureStream->copyToMemory(); addTextureStream(sURI, pMemoryStream); } } }
void COpcPackageWriter::finishPackage() { writeContentTypes(); writeRootRelationships(); auto iIterator = m_Parts.begin(); while (iIterator != m_Parts.end()) { POpcPackagePart pPart = *iIterator; if (pPart->hasRelationships()) { std::wstring sURI = pPart->getURI(); std::wstring sName = fnExtractFileName(sURI); std::wstring sPath = sURI.substr(0, sURI.length() - sName.length()); sPath += L"_rels/"; sPath += sName; sPath += std::wstring(L".")+PACKAGE_3D_RELS_EXTENSION; PExportStream pStream = m_pZIPWriter->createEntry(sPath, fnGetUnixTime()); pPart->writeRelationships(pStream); } iIterator++; } }
POpcPackagePart COpcPackageReader::createPart(_In_ std::wstring sPath) { std::wstring sRealPath = fnRemoveLeadingPathDelimiter (sPath); auto iPartIterator = m_Parts.find(sRealPath); if (iPartIterator != m_Parts.end()) { return iPartIterator->second; } PImportStream pStream = openZIPEntry(sRealPath); if (pStream.get() == nullptr) throw CNMRException(NMR_ERROR_COULDNOTCREATEOPCPART); POpcPackagePart pPart = std::make_shared<COpcPackagePart>(sRealPath, pStream); m_Parts.insert(std::make_pair(sRealPath, pPart)); std::wstring sRelationShipName = fnExtractFileName(sRealPath); std::wstring sRelationShipPath = sRealPath.substr(0, sRealPath.length() - sRelationShipName.length()); sRelationShipPath += L"_rels/"; sRelationShipPath += sRelationShipName; sRelationShipPath += L".rels"; PImportStream pRelStream = openZIPEntry(sRelationShipPath); if (pRelStream.get() != nullptr) { POpcPackageRelationshipReader pReader = std::make_shared<COpcPackageRelationshipReader>(pRelStream); nfUint32 nCount = pReader->getCount(); nfUint32 nIndex; for (nIndex = 0; nIndex < nCount; nIndex++) { POpcPackageRelationship pRelationShip = pReader->getRelationShip(nIndex); pPart->addRelationship(pRelationShip->getID(), pRelationShip->getType(), pRelationShip->getTargetPartURI()); } } return pPart; }