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 );
|
||||
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." );
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -100,7 +100,6 @@ public:
|
|||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||
|
||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -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->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());
|
||||
|
||||
m_relationShips.push_back(relPtr);
|
||||
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);
|
||||
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 );
|
||||
|
@ -494,7 +508,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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -73,3 +73,6 @@ TEST_F( IOSystemTest, accessDirectoryStackTest ) {
|
|||
EXPECT_EQ( 0U, pImp->StackSize() );
|
||||
}
|
||||
|
||||
TEST_F( IOSystemTest, delFileTest ) {
|
||||
EXPECT_FALSE( pImp->DeleteFile( "none" ) );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue