Merge pull request #1618 from assimp/3mf_export_fixes

3MF: fix working test for 3MF-export.
pull/1620/head
Kim Kulling 2017-12-07 00:48:26 +01:00 committed by GitHub
commit 26cdec5633
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 17 deletions

View File

@ -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 << "<?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() {
mRelOutput.clear();
mRelOutput << "<?xml version = \"1.0\" encoding = \"UTF-8\"?>\n";
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n";
mRelOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
mRelOutput << std::endl;
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
for ( size_t i = 0; i < mRelations.size(); ++i ) {
mRelOutput << "<Relationship Target =\"/3D/" << mRelations[ i ]->target << "\" ";
mRelOutput << "id=\"" << mRelations[i]->id << "\" ";
mRelOutput << "Type=\"" << mRelations[ i ]->type << "/>";
mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
mRelOutput << std::endl;
}
mRelOutput << "</Relationships>";
@ -157,9 +186,9 @@ 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" );
@ -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." );

View File

@ -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<unsigned int> mBuildItems;
std::vector<OpcPackageRelationship*> mRelations;
};

View File

@ -100,7 +100,6 @@ public:
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
}
private:

View File

@ -413,15 +413,23 @@ 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->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());
if ( validateRels( relPtr ) ) {
m_relationShips.push_back( relPtr );
}
}
std::vector<OpcPackageRelationshipPtr> 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 );
if ( nullptr == mRootStream ) {
throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile );
}
// const size_t size = zipArchive->FileSize();
// m_Data.resize( size );

View File

@ -224,6 +224,8 @@ public:
*/
virtual bool ChangeDirectory( const std::string &path );
virtual bool DeleteFile( const std::string &file );
private:
std::vector<std::string> 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

View File

@ -73,3 +73,6 @@ TEST_F( IOSystemTest, accessDirectoryStackTest ) {
EXPECT_EQ( 0U, pImp->StackSize() );
}
TEST_F( IOSystemTest, delFileTest ) {
EXPECT_FALSE( pImp->DeleteFile( "none" ) );
}