From 95e9cd75fac5d079bbfdae3be881d317c1fa3521 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 6 Dec 2017 21:41:48 +0100 Subject: [PATCH 1/2] 3MF: fix working test for 3MF-export. --- code/D3MFExporter.cpp | 60 +++++++++++++++++++++++++++++++------ code/D3MFExporter.h | 3 ++ code/D3MFImporter.cpp | 1 - code/D3MFOpcPackage.cpp | 8 ++--- include/assimp/IOSystem.hpp | 12 ++++++++ test/unit/utIOSystem.cpp | 3 ++ 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/code/D3MFExporter.cpp b/code/D3MFExporter.cpp index 70c2dd409..4fb13ca7b 100644 --- a/code/D3MFExporter.cpp +++ b/code/D3MFExporter.cpp @@ -63,6 +63,11 @@ void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pSce } D3MF::D3MFExporter myExporter( pFile, pScene ); if ( myExporter.validate() ) { + if ( pIOSystem->Exists( pFile ) ) { + if ( !pIOSystem->DeleteFile( pFile ) ) { + throw DeadlyExportError( "File exists, cannot override : " + std::string( pFile ) ); + } + } bool ok = myExporter.exportArchive(pFile); if ( !ok ) { throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) ); @@ -76,6 +81,9 @@ D3MFExporter::D3MFExporter( const char* pFile, const aiScene* pScene ) : mArchiveName( pFile ) , m_zipArchive( nullptr ) , mScene( pScene ) +, mModelOutput() +, mRelOutput() +, mContentOutput() , mBuildItems() , mRelations() { // empty @@ -107,6 +115,7 @@ bool D3MFExporter::exportArchive( const char *file ) { if ( nullptr == m_zipArchive ) { return false; } + ok |= exportContentTypes(); ok |= export3DModel(); ok |= exportRelations(); @@ -116,16 +125,36 @@ bool D3MFExporter::exportArchive( const char *file ) { return ok; } + +bool D3MFExporter::exportContentTypes() { + mContentOutput.clear(); + + mContentOutput << ""; + mContentOutput << std::endl; + mContentOutput << ""; + mContentOutput << std::endl; + mContentOutput << ""; + mContentOutput << std::endl; + mContentOutput << ""; + mContentOutput << std::endl; + mContentOutput << ""; + mContentOutput << std::endl; + exportContentTyp( XmlTag::CONTENT_TYPES_ARCHIVE ); + + return true; +} + bool D3MFExporter::exportRelations() { mRelOutput.clear(); - mRelOutput << "\n"; - mRelOutput << "\n"; + mRelOutput << ""; + mRelOutput << std::endl; + mRelOutput << ""; for ( size_t i = 0; i < mRelations.size(); ++i ) { - mRelOutput << "target << "\" "; - mRelOutput << "id=\"" << mRelations[i]->id << "\" "; - mRelOutput << "Type=\"" << mRelations[ i ]->type << "/>"; + mRelOutput << "target << "\" "; + mRelOutput << "Id=\"" << mRelations[i]->id << "\" "; + mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />"; mRelOutput << std::endl; } mRelOutput << ""; @@ -157,12 +186,12 @@ bool D3MFExporter::export3DModel() { mModelOutput << "\n"; OpcPackageRelationship *info = new OpcPackageRelationship; - info->id = mArchiveName; - info->target = "rel0"; - info->type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel"; + info->id = "rel0"; + info->target = "/3D/3DModel.model"; + info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; mRelations.push_back( info ); - writeModelToArchive( "3D", "3DModel.model" ); + writeModelToArchive( "/3D", "3DModel.model" ); mModelOutput.flush(); return true; @@ -251,6 +280,19 @@ void D3MFExporter::writeBuild() { mModelOutput << std::endl; } +void D3MFExporter::exportContentTyp( const std::string &filename ) { + if ( nullptr == m_zipArchive ) { + throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." ); + } + const std::string entry = filename; + zip_entry_open( m_zipArchive, entry.c_str() ); + + const std::string &exportTxt( mContentOutput.str() ); + zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() ); + + zip_entry_close( m_zipArchive ); +} + void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) { if ( nullptr == m_zipArchive ) { throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." ); diff --git a/code/D3MFExporter.h b/code/D3MFExporter.h index 8a38eff05..16efabf29 100644 --- a/code/D3MFExporter.h +++ b/code/D3MFExporter.h @@ -69,6 +69,7 @@ public: ~D3MFExporter(); bool validate(); bool exportArchive( const char *file ); + bool exportContentTypes(); bool exportRelations(); bool export3DModel(); @@ -79,6 +80,7 @@ protected: void writeVertex( const aiVector3D &pos ); void writeFaces( aiMesh *mesh ); void writeBuild(); + void exportContentTyp( const std::string &filename ); void writeModelToArchive( const std::string &folder, const std::string &modelName ); void writeRelInfoToFile( const std::string &folder, const std::string &relName ); @@ -88,6 +90,7 @@ private: const aiScene *mScene; std::ostringstream mModelOutput; std::ostringstream mRelOutput; + std::ostringstream mContentOutput; std::vector mBuildItems; std::vector mRelations; }; diff --git a/code/D3MFImporter.cpp b/code/D3MFImporter.cpp index 3d1846d21..fec36cebe 100644 --- a/code/D3MFImporter.cpp +++ b/code/D3MFImporter.cpp @@ -100,7 +100,6 @@ public: scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren](); std::copy(children.begin(), children.end(), scene->mRootNode->mChildren); - } private: diff --git a/code/D3MFOpcPackage.cpp b/code/D3MFOpcPackage.cpp index 1db8cab13..20d4acaf6 100644 --- a/code/D3MFOpcPackage.cpp +++ b/code/D3MFOpcPackage.cpp @@ -416,9 +416,9 @@ public: void ParseChildNode(XmlReader* xmlReader) { OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); - relPtr->id = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_ID.c_str()); - relPtr->type = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TYPE.c_str()); - relPtr->target = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TARGET.c_str()); + relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str()); + relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str()); + relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str()); m_relationShips.push_back(relPtr); } @@ -494,7 +494,7 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) { }); if(itr == reader.m_relationShips.end()) - throw DeadlyImportError("Cannot find" + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE); + throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE); return (*itr)->target; } diff --git a/include/assimp/IOSystem.hpp b/include/assimp/IOSystem.hpp index 4a88c4a31..f4fbb6023 100644 --- a/include/assimp/IOSystem.hpp +++ b/include/assimp/IOSystem.hpp @@ -224,6 +224,8 @@ public: */ virtual bool ChangeDirectory( const std::string &path ); + virtual bool DeleteFile( const std::string &file ); + private: std::vector m_pathStack; }; @@ -342,6 +344,16 @@ bool IOSystem::ChangeDirectory( const std::string &path ) { #endif // _WIN32 } + +// ---------------------------------------------------------------------------- +AI_FORCE_INLINE +bool IOSystem::DeleteFile( const std::string &file ) { + if ( file.empty() ) { + return false; + } + const int retCode( ::remove( file.c_str() ) ); + return ( 0 == retCode ); +} } //!ns Assimp #endif //AI_IOSYSTEM_H_INC diff --git a/test/unit/utIOSystem.cpp b/test/unit/utIOSystem.cpp index f33b22039..5e3e98031 100644 --- a/test/unit/utIOSystem.cpp +++ b/test/unit/utIOSystem.cpp @@ -73,3 +73,6 @@ TEST_F( IOSystemTest, accessDirectoryStackTest ) { EXPECT_EQ( 0U, pImp->StackSize() ); } +TEST_F( IOSystemTest, delFileTest ) { + EXPECT_FALSE( pImp->DeleteFile( "none" ) ); +} From c23c63e82119ecbead5da2cb86e8d5bb3d686aa1 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 6 Dec 2017 22:15:34 +0100 Subject: [PATCH 2/2] fix correct folder naming scheme. --- code/D3MFExporter.cpp | 2 +- code/D3MFOpcPackage.cpp | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/code/D3MFExporter.cpp b/code/D3MFExporter.cpp index 4fb13ca7b..0320dac21 100644 --- a/code/D3MFExporter.cpp +++ b/code/D3MFExporter.cpp @@ -191,7 +191,7 @@ bool D3MFExporter::export3DModel() { info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; mRelations.push_back( info ); - writeModelToArchive( "/3D", "3DModel.model" ); + writeModelToArchive( "3D", "3DModel.model" ); mModelOutput.flush(); return true; diff --git a/code/D3MFOpcPackage.cpp b/code/D3MFOpcPackage.cpp index 20d4acaf6..49143fee7 100644 --- a/code/D3MFOpcPackage.cpp +++ b/code/D3MFOpcPackage.cpp @@ -413,14 +413,22 @@ public: // empty } + bool validateRels( OpcPackageRelationshipPtr &relPtr ) { + if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) { + return false; + } + return true; + } + void ParseChildNode(XmlReader* xmlReader) { OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str()); relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str()); relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str()); - - m_relationShips.push_back(relPtr); + if ( validateRels( relPtr ) ) { + m_relationShips.push_back( relPtr ); + } } std::vector m_relationShips; @@ -450,13 +458,19 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile) std::string rootFile = ReadPackageRootRelationship(fileStream); if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) { rootFile = rootFile.substr( 1 ); + if ( rootFile[ 0 ] == '/' ) { + // deal with zipbug + rootFile = rootFile.substr( 1 ); + } } DefaultLogger::get()->debug(rootFile); mRootStream = mZipArchive->Open(rootFile.c_str()); - - ai_assert(mRootStream != nullptr); + ai_assert( mRootStream != nullptr ); + if ( nullptr == mRootStream ) { + throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile ); + } // const size_t size = zipArchive->FileSize(); // m_Data.resize( size );