Merge pull request #1618 from assimp/3mf_export_fixes
3MF: fix working test for 3MF-export.pull/1620/head
commit
26cdec5633
|
@ -63,6 +63,11 @@ void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pSce
|
||||||
}
|
}
|
||||||
D3MF::D3MFExporter myExporter( pFile, pScene );
|
D3MF::D3MFExporter myExporter( pFile, pScene );
|
||||||
if ( myExporter.validate() ) {
|
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);
|
bool ok = myExporter.exportArchive(pFile);
|
||||||
if ( !ok ) {
|
if ( !ok ) {
|
||||||
throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
|
throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
|
||||||
|
@ -76,6 +81,9 @@ D3MFExporter::D3MFExporter( const char* pFile, const aiScene* pScene )
|
||||||
: mArchiveName( pFile )
|
: mArchiveName( pFile )
|
||||||
, m_zipArchive( nullptr )
|
, m_zipArchive( nullptr )
|
||||||
, mScene( pScene )
|
, mScene( pScene )
|
||||||
|
, mModelOutput()
|
||||||
|
, mRelOutput()
|
||||||
|
, mContentOutput()
|
||||||
, mBuildItems()
|
, mBuildItems()
|
||||||
, mRelations() {
|
, mRelations() {
|
||||||
// empty
|
// empty
|
||||||
|
@ -107,6 +115,7 @@ bool D3MFExporter::exportArchive( const char *file ) {
|
||||||
if ( nullptr == m_zipArchive ) {
|
if ( nullptr == m_zipArchive ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
ok |= exportContentTypes();
|
||||||
ok |= export3DModel();
|
ok |= export3DModel();
|
||||||
ok |= exportRelations();
|
ok |= exportRelations();
|
||||||
|
|
||||||
|
@ -116,16 +125,36 @@ bool D3MFExporter::exportArchive( const char *file ) {
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool D3MFExporter::exportContentTypes() {
|
||||||
|
mContentOutput.clear();
|
||||||
|
|
||||||
|
mContentOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||||
|
mContentOutput << std::endl;
|
||||||
|
mContentOutput << "<Types xmlns = \"http://schemas.openxmlformats.org/package/2006/content-types\">";
|
||||||
|
mContentOutput << std::endl;
|
||||||
|
mContentOutput << "<Default Extension = \"rels\" ContentType = \"application/vnd.openxmlformats-package.relationships+xml\" />";
|
||||||
|
mContentOutput << std::endl;
|
||||||
|
mContentOutput << "<Default Extension = \"model\" ContentType = \"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\" />";
|
||||||
|
mContentOutput << std::endl;
|
||||||
|
mContentOutput << "</Types>";
|
||||||
|
mContentOutput << std::endl;
|
||||||
|
exportContentTyp( XmlTag::CONTENT_TYPES_ARCHIVE );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool D3MFExporter::exportRelations() {
|
bool D3MFExporter::exportRelations() {
|
||||||
mRelOutput.clear();
|
mRelOutput.clear();
|
||||||
|
|
||||||
mRelOutput << "<?xml version = \"1.0\" encoding = \"UTF-8\"?>\n";
|
mRelOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||||
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n";
|
mRelOutput << std::endl;
|
||||||
|
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||||||
|
|
||||||
for ( size_t i = 0; i < mRelations.size(); ++i ) {
|
for ( size_t i = 0; i < mRelations.size(); ++i ) {
|
||||||
mRelOutput << "<Relationship Target =\"/3D/" << mRelations[ i ]->target << "\" ";
|
mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
|
||||||
mRelOutput << "id=\"" << mRelations[i]->id << "\" ";
|
mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
|
||||||
mRelOutput << "Type=\"" << mRelations[ i ]->type << "/>";
|
mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
|
||||||
mRelOutput << std::endl;
|
mRelOutput << std::endl;
|
||||||
}
|
}
|
||||||
mRelOutput << "</Relationships>";
|
mRelOutput << "</Relationships>";
|
||||||
|
@ -157,9 +186,9 @@ bool D3MFExporter::export3DModel() {
|
||||||
mModelOutput << "</" << XmlTag::model << ">\n";
|
mModelOutput << "</" << XmlTag::model << ">\n";
|
||||||
|
|
||||||
OpcPackageRelationship *info = new OpcPackageRelationship;
|
OpcPackageRelationship *info = new OpcPackageRelationship;
|
||||||
info->id = mArchiveName;
|
info->id = "rel0";
|
||||||
info->target = "rel0";
|
info->target = "/3D/3DModel.model";
|
||||||
info->type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||||
mRelations.push_back( info );
|
mRelations.push_back( info );
|
||||||
|
|
||||||
writeModelToArchive( "3D", "3DModel.model" );
|
writeModelToArchive( "3D", "3DModel.model" );
|
||||||
|
@ -251,6 +280,19 @@ void D3MFExporter::writeBuild() {
|
||||||
mModelOutput << std::endl;
|
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 ) {
|
void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) {
|
||||||
if ( nullptr == m_zipArchive ) {
|
if ( nullptr == m_zipArchive ) {
|
||||||
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
|
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
~D3MFExporter();
|
~D3MFExporter();
|
||||||
bool validate();
|
bool validate();
|
||||||
bool exportArchive( const char *file );
|
bool exportArchive( const char *file );
|
||||||
|
bool exportContentTypes();
|
||||||
bool exportRelations();
|
bool exportRelations();
|
||||||
bool export3DModel();
|
bool export3DModel();
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ protected:
|
||||||
void writeVertex( const aiVector3D &pos );
|
void writeVertex( const aiVector3D &pos );
|
||||||
void writeFaces( aiMesh *mesh );
|
void writeFaces( aiMesh *mesh );
|
||||||
void writeBuild();
|
void writeBuild();
|
||||||
|
void exportContentTyp( const std::string &filename );
|
||||||
void writeModelToArchive( const std::string &folder, const std::string &modelName );
|
void writeModelToArchive( const std::string &folder, const std::string &modelName );
|
||||||
void writeRelInfoToFile( const std::string &folder, const std::string &relName );
|
void writeRelInfoToFile( const std::string &folder, const std::string &relName );
|
||||||
|
|
||||||
|
@ -88,6 +90,7 @@ private:
|
||||||
const aiScene *mScene;
|
const aiScene *mScene;
|
||||||
std::ostringstream mModelOutput;
|
std::ostringstream mModelOutput;
|
||||||
std::ostringstream mRelOutput;
|
std::ostringstream mRelOutput;
|
||||||
|
std::ostringstream mContentOutput;
|
||||||
std::vector<unsigned int> mBuildItems;
|
std::vector<unsigned int> mBuildItems;
|
||||||
std::vector<OpcPackageRelationship*> mRelations;
|
std::vector<OpcPackageRelationship*> mRelations;
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,7 +100,6 @@ public:
|
||||||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||||
|
|
||||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -413,15 +413,23 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
|
||||||
|
if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ParseChildNode(XmlReader* xmlReader) {
|
void ParseChildNode(XmlReader* xmlReader) {
|
||||||
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
||||||
|
|
||||||
relPtr->id = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_ID.c_str());
|
relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
|
||||||
relPtr->type = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
||||||
relPtr->target = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
||||||
|
if ( validateRels( relPtr ) ) {
|
||||||
m_relationShips.push_back( relPtr );
|
m_relationShips.push_back( relPtr );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
||||||
};
|
};
|
||||||
|
@ -450,13 +458,19 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
||||||
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
||||||
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
||||||
rootFile = rootFile.substr( 1 );
|
rootFile = rootFile.substr( 1 );
|
||||||
|
if ( rootFile[ 0 ] == '/' ) {
|
||||||
|
// deal with zipbug
|
||||||
|
rootFile = rootFile.substr( 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->debug(rootFile);
|
DefaultLogger::get()->debug(rootFile);
|
||||||
|
|
||||||
mRootStream = mZipArchive->Open(rootFile.c_str());
|
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();
|
// const size_t size = zipArchive->FileSize();
|
||||||
// m_Data.resize( size );
|
// m_Data.resize( size );
|
||||||
|
|
|
@ -224,6 +224,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool ChangeDirectory( const std::string &path );
|
virtual bool ChangeDirectory( const std::string &path );
|
||||||
|
|
||||||
|
virtual bool DeleteFile( const std::string &file );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> m_pathStack;
|
std::vector<std::string> m_pathStack;
|
||||||
};
|
};
|
||||||
|
@ -342,6 +344,16 @@ bool IOSystem::ChangeDirectory( const std::string &path ) {
|
||||||
#endif // _WIN32
|
#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
|
} //!ns Assimp
|
||||||
|
|
||||||
#endif //AI_IOSYSTEM_H_INC
|
#endif //AI_IOSYSTEM_H_INC
|
||||||
|
|
|
@ -73,3 +73,6 @@ TEST_F( IOSystemTest, accessDirectoryStackTest ) {
|
||||||
EXPECT_EQ( 0U, pImp->StackSize() );
|
EXPECT_EQ( 0U, pImp->StackSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F( IOSystemTest, delFileTest ) {
|
||||||
|
EXPECT_FALSE( pImp->DeleteFile( "none" ) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue