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" ) ); +}