From 396e7bcdb4fceba28874c0b87849cdade93be837 Mon Sep 17 00:00:00 2001 From: HiMemX <99434376+HiMemX@users.noreply.github.com> Date: Wed, 7 Sep 2022 23:09:50 +0200 Subject: [PATCH 1/3] -Obj vertex fix --- ObjExporter.cpp | 412 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 ObjExporter.cpp diff --git a/ObjExporter.cpp b/ObjExporter.cpp new file mode 100644 index 000000000..a5d8325fc --- /dev/null +++ b/ObjExporter.cpp @@ -0,0 +1,412 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2020, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER + +#include "ObjExporter.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Assimp; + +namespace Assimp { + +// ------------------------------------------------------------------------------------------------ +// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp +void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) { + // invoke the exporter + ObjExporter exporter(pFile, pScene); + + 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 == nullptr) { + throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); + } + outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); + } + { + std::unique_ptr outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt")); + if (outfile == nullptr) { + throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName())); + } + outfile->Write( exporter.mOutputMat.str().c_str(), static_cast(exporter.mOutputMat.tellp()),1); + } +} + +// ------------------------------------------------------------------------------------------------ +// 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* ) { + // 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 == nullptr) { + 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, bool noMtl) +: filename(_filename) +, pScene(pScene) +, vn() +, vt() +, vp() +, useVc(false) +, mVnMap() +, mVtMap() +, mVpMap() +, mMeshes() +, endl("\n") { + // make sure that all formatting happens using the standard, C locale and not the user's current locale + const std::locale& l = std::locale("C"); + mOutput.imbue(l); + mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION); + mOutputMat.imbue(l); + mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION); + + WriteGeometryFile(noMtl); + if ( !noMtl ) { + WriteMaterialFile(); + } +} + +// ------------------------------------------------------------------------------------------------ +ObjExporter::~ObjExporter() = default; + +// ------------------------------------------------------------------------------------------------ +std::string ObjExporter::GetMaterialLibName() { + // within the Obj file, we use just the relative file name with the path stripped + const std::string& s = GetMaterialLibFileName(); + std::string::size_type il = s.find_last_of("/\\"); + if (il != std::string::npos) { + return s.substr(il + 1); + } + + return s; +} + +// ------------------------------------------------------------------------------------------------ +std::string ObjExporter::GetMaterialLibFileName() { + // Remove existing .obj file extension so that the final material file name will be fileName.mtl and not fileName.obj.mtl + size_t lastdot = filename.find_last_of('.'); + if ( lastdot != std::string::npos ) { + return filename.substr( 0, lastdot ) + MaterialExt; + } + + return filename + MaterialExt; +} + +// ------------------------------------------------------------------------------------------------ +void ObjExporter::WriteHeader(std::ostringstream& out) { + out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl; + out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' + << aiGetVersionRevision() << ")" << endl << endl; +} + +// ------------------------------------------------------------------------------------------------ +std::string ObjExporter::GetMaterialName(unsigned int index) { + const aiMaterial* const mat = pScene->mMaterials[index]; + if ( nullptr == mat ) { + static const std::string EmptyStr; + return EmptyStr; + } + + aiString s; + if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) { + return std::string(s.data,s.length); + } + + char number[ sizeof(unsigned int) * 3 + 1 ]; + ASSIMP_itoa10(number,index); + return "$Material_" + std::string(number); +} + +// ------------------------------------------------------------------------------------------------ +void ObjExporter::WriteMaterialFile() { + WriteHeader(mOutputMat); + + for(unsigned int i = 0; i < pScene->mNumMaterials; ++i) { + const aiMaterial* const mat = pScene->mMaterials[i]; + + int illum = 1; + mOutputMat << "newmtl " << GetMaterialName(i) << endl; + + aiColor4D c; + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) { + mOutputMat << "Kd " << c.r << " " << c.g << " " << c.b << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) { + mOutputMat << "Ka " << c.r << " " << c.g << " " << c.b << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) { + mOutputMat << "Ks " << c.r << " " << c.g << " " << c.b << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_EMISSIVE,c)) { + mOutputMat << "Ke " << c.r << " " << c.g << " " << c.b << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_TRANSPARENT,c)) { + mOutputMat << "Tf " << c.r << " " << c.g << " " << c.b << endl; + } + + ai_real o; + if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) { + mOutputMat << "d " << o << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_REFRACTI,o)) { + mOutputMat << "Ni " << o << endl; + } + + if(AI_SUCCESS == mat->Get(AI_MATKEY_SHININESS,o) && o) { + mOutputMat << "Ns " << o << endl; + illum = 2; + } + + mOutputMat << "illum " << illum << endl; + + aiString s; + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) { + mOutputMat << "map_Kd " << s.data << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) { + mOutputMat << "map_Ka " << s.data << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) { + mOutputMat << "map_Ks " << s.data << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) { + mOutputMat << "map_Ns " << s.data << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) { + mOutputMat << "map_d " << s.data << endl; + } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) { + // implementations seem to vary here, so write both variants + mOutputMat << "bump " << s.data << endl; + mOutputMat << "map_bump " << s.data << endl; + } + + mOutputMat << endl; + } +} + +void ObjExporter::WriteGeometryFile(bool noMtl) { + WriteHeader(mOutput); + if (!noMtl) + mOutput << "mtllib " << GetMaterialLibName() << endl << endl; + + // collect mesh geometry + aiMatrix4x4 mBase; + AddNode(pScene->mRootNode, mBase); + + // write vertex positions with colors, if any + mVpMap.getKeys( vp ); + if ( !useVc ) { + mOutput << "# " << vp.size() << " vertex positions" << endl; + for ( const vertexData& v : vp ) { + mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl; + } + } else { + mOutput << "# " << vp.size() << " vertex positions and colors" << endl; + for ( const vertexData& v : vp ) { + mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl; + } + } + mOutput << endl; + + // write uv coordinates + mVtMap.getKeys(vt); + mOutput << "# " << vt.size() << " UV coordinates" << endl; + for(const aiVector3D& v : vt) { + mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl; + } + mOutput << endl; + + // write vertex normals + mVnMap.getKeys(vn); + mOutput << "# " << vn.size() << " vertex normals" << endl; + for(const aiVector3D& v : vn) { + mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl; + } + mOutput << endl; + + // now write all mesh instances + for(const MeshInstance& m : mMeshes) { + mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl; + if (!m.name.empty()) { + mOutput << "g " << m.name << endl; + } + if ( !noMtl ) { + mOutput << "usemtl " << m.matname << endl; + } + + for(const Face& f : m.faces) { + mOutput << f.kind << ' '; + for(const FaceVertex& fv : f.indices) { + mOutput << ' ' << fv.vp; + + if (f.kind != 'p') { + if (fv.vt || f.kind == 'f') { + mOutput << '/'; + } + if (fv.vt) { + mOutput << fv.vt; + } + if (f.kind == 'f' && fv.vn) { + mOutput << '/' << fv.vn; + } + } + } + + mOutput << endl; + } + mOutput << endl; + } +} + +// ------------------------------------------------------------------------------------------------ +void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) { + mMeshes.emplace_back(); + MeshInstance& mesh = mMeshes.back(); + + if ( nullptr != m->mColors[ 0 ] ) { + useVc = true; + } + + mesh.name = std::string( name.data, name.length ); + mesh.matname = GetMaterialName(m->mMaterialIndex); + + mesh.faces.resize(m->mNumFaces); + + for(unsigned int i = 0; i < m->mNumFaces; ++i) { + const aiFace& f = m->mFaces[i]; + + Face& face = mesh.faces[i]; + switch (f.mNumIndices) { + case 1: + face.kind = 'p'; + break; + case 2: + face.kind = 'l'; + break; + default: + face.kind = 'f'; + } + face.indices.resize(f.mNumIndices); + + for(unsigned int a = 0; a < f.mNumIndices; ++a) { + const unsigned int idx = f.mIndices[a]; + + aiVector3D vert = mat * m->mVertices[idx]; + + if ( nullptr != m->mColors[ 0 ] ) { + aiColor4D col4 = m->mColors[ 0 ][ idx ]; + face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(col4.r, col4.g, col4.b)}); + } else { + face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0)}); + } + + if (m->mNormals) { + aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx]; + face.indices[a].vn = mVnMap.getIndex(norm); + } else { + face.indices[a].vn = 0; + } + + if ( m->mTextureCoords[ 0 ] ) { + face.indices[a].vt = mVtMap.getIndex(m->mTextureCoords[0][idx]); + } else { + face.indices[a].vt = 0; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent) { + const aiMatrix4x4& mAbs = mParent * nd->mTransformation; + + aiMesh *cm( nullptr ); + for(unsigned int i = 0; i < nd->mNumMeshes; ++i) { + cm = pScene->mMeshes[nd->mMeshes[i]]; + if (nullptr != cm) { + AddMesh(cm->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs); + } else { + AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs); + } + } + + for(unsigned int i = 0; i < nd->mNumChildren; ++i) { + AddNode(nd->mChildren[i], mAbs); + } +} + +// ------------------------------------------------------------------------------------------------ + +#endif // ASSIMP_BUILD_NO_OBJ_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT From 7872297ab7ac29ae1d310f2d680c9beb1d342d78 Mon Sep 17 00:00:00 2001 From: HiMemX <99434376+HiMemX@users.noreply.github.com> Date: Wed, 7 Sep 2022 23:10:06 +0200 Subject: [PATCH 2/3] Delete ObjExporter.cpp --- ObjExporter.cpp | 412 ------------------------------------------------ 1 file changed, 412 deletions(-) delete mode 100644 ObjExporter.cpp diff --git a/ObjExporter.cpp b/ObjExporter.cpp deleted file mode 100644 index a5d8325fc..000000000 --- a/ObjExporter.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, assimp team - - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#ifndef ASSIMP_BUILD_NO_EXPORT -#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER - -#include "ObjExporter.h" -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Assimp; - -namespace Assimp { - -// ------------------------------------------------------------------------------------------------ -// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp -void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) { - // invoke the exporter - ObjExporter exporter(pFile, pScene); - - 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 == nullptr) { - throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); - } - outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); - } - { - std::unique_ptr outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt")); - if (outfile == nullptr) { - throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName())); - } - outfile->Write( exporter.mOutputMat.str().c_str(), static_cast(exporter.mOutputMat.tellp()),1); - } -} - -// ------------------------------------------------------------------------------------------------ -// 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* ) { - // 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 == nullptr) { - 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, bool noMtl) -: filename(_filename) -, pScene(pScene) -, vn() -, vt() -, vp() -, useVc(false) -, mVnMap() -, mVtMap() -, mVpMap() -, mMeshes() -, endl("\n") { - // make sure that all formatting happens using the standard, C locale and not the user's current locale - const std::locale& l = std::locale("C"); - mOutput.imbue(l); - mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION); - mOutputMat.imbue(l); - mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION); - - WriteGeometryFile(noMtl); - if ( !noMtl ) { - WriteMaterialFile(); - } -} - -// ------------------------------------------------------------------------------------------------ -ObjExporter::~ObjExporter() = default; - -// ------------------------------------------------------------------------------------------------ -std::string ObjExporter::GetMaterialLibName() { - // within the Obj file, we use just the relative file name with the path stripped - const std::string& s = GetMaterialLibFileName(); - std::string::size_type il = s.find_last_of("/\\"); - if (il != std::string::npos) { - return s.substr(il + 1); - } - - return s; -} - -// ------------------------------------------------------------------------------------------------ -std::string ObjExporter::GetMaterialLibFileName() { - // Remove existing .obj file extension so that the final material file name will be fileName.mtl and not fileName.obj.mtl - size_t lastdot = filename.find_last_of('.'); - if ( lastdot != std::string::npos ) { - return filename.substr( 0, lastdot ) + MaterialExt; - } - - return filename + MaterialExt; -} - -// ------------------------------------------------------------------------------------------------ -void ObjExporter::WriteHeader(std::ostringstream& out) { - out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl; - out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' - << aiGetVersionRevision() << ")" << endl << endl; -} - -// ------------------------------------------------------------------------------------------------ -std::string ObjExporter::GetMaterialName(unsigned int index) { - const aiMaterial* const mat = pScene->mMaterials[index]; - if ( nullptr == mat ) { - static const std::string EmptyStr; - return EmptyStr; - } - - aiString s; - if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) { - return std::string(s.data,s.length); - } - - char number[ sizeof(unsigned int) * 3 + 1 ]; - ASSIMP_itoa10(number,index); - return "$Material_" + std::string(number); -} - -// ------------------------------------------------------------------------------------------------ -void ObjExporter::WriteMaterialFile() { - WriteHeader(mOutputMat); - - for(unsigned int i = 0; i < pScene->mNumMaterials; ++i) { - const aiMaterial* const mat = pScene->mMaterials[i]; - - int illum = 1; - mOutputMat << "newmtl " << GetMaterialName(i) << endl; - - aiColor4D c; - if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) { - mOutputMat << "Kd " << c.r << " " << c.g << " " << c.b << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) { - mOutputMat << "Ka " << c.r << " " << c.g << " " << c.b << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) { - mOutputMat << "Ks " << c.r << " " << c.g << " " << c.b << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_EMISSIVE,c)) { - mOutputMat << "Ke " << c.r << " " << c.g << " " << c.b << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_TRANSPARENT,c)) { - mOutputMat << "Tf " << c.r << " " << c.g << " " << c.b << endl; - } - - ai_real o; - if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) { - mOutputMat << "d " << o << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_REFRACTI,o)) { - mOutputMat << "Ni " << o << endl; - } - - if(AI_SUCCESS == mat->Get(AI_MATKEY_SHININESS,o) && o) { - mOutputMat << "Ns " << o << endl; - illum = 2; - } - - mOutputMat << "illum " << illum << endl; - - aiString s; - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) { - mOutputMat << "map_Kd " << s.data << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) { - mOutputMat << "map_Ka " << s.data << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) { - mOutputMat << "map_Ks " << s.data << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) { - mOutputMat << "map_Ns " << s.data << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) { - mOutputMat << "map_d " << s.data << endl; - } - if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) { - // implementations seem to vary here, so write both variants - mOutputMat << "bump " << s.data << endl; - mOutputMat << "map_bump " << s.data << endl; - } - - mOutputMat << endl; - } -} - -void ObjExporter::WriteGeometryFile(bool noMtl) { - WriteHeader(mOutput); - if (!noMtl) - mOutput << "mtllib " << GetMaterialLibName() << endl << endl; - - // collect mesh geometry - aiMatrix4x4 mBase; - AddNode(pScene->mRootNode, mBase); - - // write vertex positions with colors, if any - mVpMap.getKeys( vp ); - if ( !useVc ) { - mOutput << "# " << vp.size() << " vertex positions" << endl; - for ( const vertexData& v : vp ) { - mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl; - } - } else { - mOutput << "# " << vp.size() << " vertex positions and colors" << endl; - for ( const vertexData& v : vp ) { - mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl; - } - } - mOutput << endl; - - // write uv coordinates - mVtMap.getKeys(vt); - mOutput << "# " << vt.size() << " UV coordinates" << endl; - for(const aiVector3D& v : vt) { - mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl; - } - mOutput << endl; - - // write vertex normals - mVnMap.getKeys(vn); - mOutput << "# " << vn.size() << " vertex normals" << endl; - for(const aiVector3D& v : vn) { - mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl; - } - mOutput << endl; - - // now write all mesh instances - for(const MeshInstance& m : mMeshes) { - mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl; - if (!m.name.empty()) { - mOutput << "g " << m.name << endl; - } - if ( !noMtl ) { - mOutput << "usemtl " << m.matname << endl; - } - - for(const Face& f : m.faces) { - mOutput << f.kind << ' '; - for(const FaceVertex& fv : f.indices) { - mOutput << ' ' << fv.vp; - - if (f.kind != 'p') { - if (fv.vt || f.kind == 'f') { - mOutput << '/'; - } - if (fv.vt) { - mOutput << fv.vt; - } - if (f.kind == 'f' && fv.vn) { - mOutput << '/' << fv.vn; - } - } - } - - mOutput << endl; - } - mOutput << endl; - } -} - -// ------------------------------------------------------------------------------------------------ -void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) { - mMeshes.emplace_back(); - MeshInstance& mesh = mMeshes.back(); - - if ( nullptr != m->mColors[ 0 ] ) { - useVc = true; - } - - mesh.name = std::string( name.data, name.length ); - mesh.matname = GetMaterialName(m->mMaterialIndex); - - mesh.faces.resize(m->mNumFaces); - - for(unsigned int i = 0; i < m->mNumFaces; ++i) { - const aiFace& f = m->mFaces[i]; - - Face& face = mesh.faces[i]; - switch (f.mNumIndices) { - case 1: - face.kind = 'p'; - break; - case 2: - face.kind = 'l'; - break; - default: - face.kind = 'f'; - } - face.indices.resize(f.mNumIndices); - - for(unsigned int a = 0; a < f.mNumIndices; ++a) { - const unsigned int idx = f.mIndices[a]; - - aiVector3D vert = mat * m->mVertices[idx]; - - if ( nullptr != m->mColors[ 0 ] ) { - aiColor4D col4 = m->mColors[ 0 ][ idx ]; - face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(col4.r, col4.g, col4.b)}); - } else { - face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0)}); - } - - if (m->mNormals) { - aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx]; - face.indices[a].vn = mVnMap.getIndex(norm); - } else { - face.indices[a].vn = 0; - } - - if ( m->mTextureCoords[ 0 ] ) { - face.indices[a].vt = mVtMap.getIndex(m->mTextureCoords[0][idx]); - } else { - face.indices[a].vt = 0; - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent) { - const aiMatrix4x4& mAbs = mParent * nd->mTransformation; - - aiMesh *cm( nullptr ); - for(unsigned int i = 0; i < nd->mNumMeshes; ++i) { - cm = pScene->mMeshes[nd->mMeshes[i]]; - if (nullptr != cm) { - AddMesh(cm->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs); - } else { - AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs); - } - } - - for(unsigned int i = 0; i < nd->mNumChildren; ++i) { - AddNode(nd->mChildren[i], mAbs); - } -} - -// ------------------------------------------------------------------------------------------------ - -#endif // ASSIMP_BUILD_NO_OBJ_EXPORTER -#endif // ASSIMP_BUILD_NO_EXPORT From 4c9d270a5ead2f5a25d7c701d8a793c2defc62e9 Mon Sep 17 00:00:00 2001 From: HiMemX <99434376+HiMemX@users.noreply.github.com> Date: Wed, 7 Sep 2022 23:10:31 +0200 Subject: [PATCH 3/3] -Vertex export fix --- code/AssetLib/Obj/ObjExporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/Obj/ObjExporter.cpp b/code/AssetLib/Obj/ObjExporter.cpp index 189164769..a5d8325fc 100644 --- a/code/AssetLib/Obj/ObjExporter.cpp +++ b/code/AssetLib/Obj/ObjExporter.cpp @@ -269,12 +269,12 @@ void ObjExporter::WriteGeometryFile(bool noMtl) { if ( !useVc ) { mOutput << "# " << vp.size() << " vertex positions" << endl; for ( const vertexData& v : vp ) { - mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl; + mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl; } } else { mOutput << "# " << vp.size() << " vertex positions and colors" << endl; for ( const vertexData& v : vp ) { - mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl; + mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl; } } mOutput << endl;