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 << "" << XmlTag::model << ">\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" ) );
+}