diff --git a/code/Exporter.cpp b/code/Exporter.cpp index b83a540b9..76bda9fdf 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -83,6 +83,7 @@ void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportPrope void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*); +void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*); void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*); @@ -115,6 +116,8 @@ Exporter::ExportFormatEntry gExporters[] = #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj, aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */), + Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl, + aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */), #endif #ifndef ASSIMP_BUILD_NO_STL_EXPORTER diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index 3da002080..3f9fabdc4 100644 --- a/code/ObjExporter.cpp +++ b/code/ObjExporter.cpp @@ -83,12 +83,34 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene } } +// ------------------------------------------------------------------------------------------------ +// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp +void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) { + // invoke the exporter + ObjExporter exporter(pFile, pScene, true); + + if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) { + throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile)); + } + + // we're still here - export successfully completed. Write both the main OBJ file and the material script + { + std::unique_ptr outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); + } + outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); + } + + +} + } // end of namespace Assimp static const std::string MaterialExt = ".mtl"; // ------------------------------------------------------------------------------------------------ -ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene) +ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl) : filename(_filename) , pScene(pScene) , vp() @@ -108,8 +130,9 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene) mOutputMat.imbue(l); mOutputMat.precision(16); - WriteGeometryFile(); - WriteMaterialFile(); + WriteGeometryFile(noMtl); + if (!noMtl) + WriteMaterialFile(); } // ------------------------------------------------------------------------------------------------ @@ -236,9 +259,10 @@ void ObjExporter::WriteMaterialFile() } // ------------------------------------------------------------------------------------------------ -void ObjExporter::WriteGeometryFile() { +void ObjExporter::WriteGeometryFile(bool noMtl) { WriteHeader(mOutput); - mOutput << "mtllib " << GetMaterialLibName() << endl << endl; + if (!noMtl) + mOutput << "mtllib " << GetMaterialLibName() << endl << endl; // collect mesh geometry aiMatrix4x4 mBase; @@ -284,7 +308,8 @@ void ObjExporter::WriteGeometryFile() { if (!m.name.empty()) { mOutput << "g " << m.name << endl; } - mOutput << "usemtl " << m.matname << endl; + if (!noMtl) + mOutput << "usemtl " << m.matname << endl; for(const Face& f : m.faces) { mOutput << f.kind << ' '; diff --git a/code/ObjExporter.h b/code/ObjExporter.h index fb60402d7..391f8416d 100644 --- a/code/ObjExporter.h +++ b/code/ObjExporter.h @@ -62,7 +62,7 @@ namespace Assimp { class ObjExporter { public: /// Constructor for a specific scene to export - ObjExporter(const char* filename, const aiScene* pScene); + ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false); ~ObjExporter(); std::string GetMaterialLibName(); std::string GetMaterialLibFileName(); @@ -97,7 +97,7 @@ private: void WriteHeader(std::ostringstream& out); void WriteMaterialFile(); - void WriteGeometryFile(); + void WriteGeometryFile(bool noMtl=false); std::string GetMaterialName(unsigned int index); void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat); void AddNode(const aiNode* nd, const aiMatrix4x4& mParent); diff --git a/test/unit/utObjImportExport.cpp b/test/unit/utObjImportExport.cpp index 3b08df80f..5783c049e 100644 --- a/test/unit/utObjImportExport.cpp +++ b/test/unit/utObjImportExport.cpp @@ -205,6 +205,7 @@ protected: const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", 0 ); EXPECT_NE( nullptr, scene ); EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "obj", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_test.obj" ) ); + EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "objnomtl", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_nomtl_test.obj" ) ); return true; }