summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Knodt <julianknodt@gmail.com>2024-04-02 09:31:19 -0700
committerGitHub <noreply@github.com>2024-04-02 18:31:19 +0200
commit39ce0c0456b2cb4453dd69edd7d76274795e7287 (patch)
tree11b714a21f989ac735f63c8da10aa8275ae60136
parentfeb861f17bf937fd42e0591b3347b95009033eec (diff)
Respect merge identical vertices in ObjExporter (#5521)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
-rw-r--r--code/AssetLib/Obj/ObjExporter.cpp34
-rw-r--r--code/AssetLib/Obj/ObjExporter.h13
2 files changed, 27 insertions, 20 deletions
diff --git a/code/AssetLib/Obj/ObjExporter.cpp b/code/AssetLib/Obj/ObjExporter.cpp
index a5d8325fc..7c5c051f3 100644
--- a/code/AssetLib/Obj/ObjExporter.cpp
+++ b/code/AssetLib/Obj/ObjExporter.cpp
@@ -59,9 +59,9 @@ 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*/) {
+void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* props) {
// invoke the exporter
- ObjExporter exporter(pFile, pScene);
+ ObjExporter exporter(pFile, pScene, false, props);
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
@@ -86,9 +86,9 @@ 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* ) {
+void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* props) {
// invoke the exporter
- ObjExporter exporter(pFile, pScene, true);
+ ObjExporter exporter(pFile, pScene, true, props);
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
@@ -111,7 +111,7 @@ void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* p
static const std::string MaterialExt = ".mtl";
// ------------------------------------------------------------------------------------------------
-ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl)
+ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl, const ExportProperties* props)
: filename(_filename)
, pScene(pScene)
, vn()
@@ -130,7 +130,10 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMt
mOutputMat.imbue(l);
mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
- WriteGeometryFile(noMtl);
+ WriteGeometryFile(
+ noMtl,
+ props == nullptr ? true : props->GetPropertyBool("bJoinIdenticalVertices", true)
+ );
if ( !noMtl ) {
WriteMaterialFile();
}
@@ -255,14 +258,14 @@ void ObjExporter::WriteMaterialFile() {
}
}
-void ObjExporter::WriteGeometryFile(bool noMtl) {
+void ObjExporter::WriteGeometryFile(bool noMtl, bool merge_identical_vertices) {
WriteHeader(mOutput);
if (!noMtl)
mOutput << "mtllib " << GetMaterialLibName() << endl << endl;
// collect mesh geometry
aiMatrix4x4 mBase;
- AddNode(pScene->mRootNode, mBase);
+ AddNode(pScene->mRootNode, mBase, merge_identical_vertices);
// write vertex positions with colors, if any
mVpMap.getKeys( vp );
@@ -330,7 +333,7 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
}
// ------------------------------------------------------------------------------------------------
-void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
+void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat, bool merge_identical_vertices) {
mMeshes.emplace_back();
MeshInstance& mesh = mMeshes.back();
@@ -362,13 +365,14 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
const unsigned int idx = f.mIndices[a];
+ const unsigned int fi = merge_identical_vertices ? 0 : idx;
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)});
+ face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(col4.r, col4.g, col4.b), fi});
} else {
- face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0)});
+ face.indices[a].vp = mVpMap.getIndex({vert, aiColor3D(0,0,0), fi});
}
if (m->mNormals) {
@@ -388,21 +392,21 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
}
// ------------------------------------------------------------------------------------------------
-void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent) {
+void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices) {
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);
+ AddMesh(cm->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs, merge_identical_vertices);
} else {
- AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs);
+ AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs, merge_identical_vertices);
}
}
for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
- AddNode(nd->mChildren[i], mAbs);
+ AddNode(nd->mChildren[i], mAbs, merge_identical_vertices);
}
}
diff --git a/code/AssetLib/Obj/ObjExporter.h b/code/AssetLib/Obj/ObjExporter.h
index a64f38f74..4c92aa16f 100644
--- a/code/AssetLib/Obj/ObjExporter.h
+++ b/code/AssetLib/Obj/ObjExporter.h
@@ -51,6 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <map>
+#include <assimp/Exporter.hpp>
+
struct aiScene;
struct aiNode;
struct aiMesh;
@@ -63,7 +65,7 @@ namespace Assimp {
class ObjExporter {
public:
/// Constructor for a specific scene to export
- ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false);
+ ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false, const ExportProperties* props = nullptr);
~ObjExporter();
std::string GetMaterialLibName();
std::string GetMaterialLibFileName();
@@ -97,10 +99,10 @@ private:
void WriteHeader(std::ostringstream& out);
void WriteMaterialFile();
- void WriteGeometryFile(bool noMtl=false);
+ void WriteGeometryFile(bool noMtl=false, bool merge_identical_vertices = 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);
+ void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat, bool merge_identical_vertices);
+ void AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices);
private:
std::string filename;
@@ -109,6 +111,7 @@ private:
struct vertexData {
aiVector3D vp;
aiColor3D vc; // OBJ does not support 4D color
+ uint32_t index = 0;
};
std::vector<aiVector3D> vn, vt;
@@ -133,7 +136,7 @@ private:
if (a.vc.g > b.vc.g) return false;
if (a.vc.b < b.vc.b) return true;
if (a.vc.b > b.vc.b) return false;
- return false;
+ return a.index < b.index;
}
};