Respect merge identical vertices in ObjExporter (#5521)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>pull/5525/head
parent
feb861f17b
commit
39ce0c0456
|
@ -59,9 +59,9 @@ namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
|
// 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
|
// invoke the exporter
|
||||||
ObjExporter exporter(pFile, pScene);
|
ObjExporter exporter(pFile, pScene, false, props);
|
||||||
|
|
||||||
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
||||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
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
|
// 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
|
// invoke the exporter
|
||||||
ObjExporter exporter(pFile, pScene, true);
|
ObjExporter exporter(pFile, pScene, true, props);
|
||||||
|
|
||||||
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
|
||||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
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";
|
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)
|
: filename(_filename)
|
||||||
, pScene(pScene)
|
, pScene(pScene)
|
||||||
, vn()
|
, vn()
|
||||||
|
@ -130,7 +130,10 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMt
|
||||||
mOutputMat.imbue(l);
|
mOutputMat.imbue(l);
|
||||||
mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
|
mOutputMat.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
|
||||||
|
|
||||||
WriteGeometryFile(noMtl);
|
WriteGeometryFile(
|
||||||
|
noMtl,
|
||||||
|
props == nullptr ? true : props->GetPropertyBool("bJoinIdenticalVertices", true)
|
||||||
|
);
|
||||||
if ( !noMtl ) {
|
if ( !noMtl ) {
|
||||||
WriteMaterialFile();
|
WriteMaterialFile();
|
||||||
}
|
}
|
||||||
|
@ -255,14 +258,14 @@ void ObjExporter::WriteMaterialFile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjExporter::WriteGeometryFile(bool noMtl) {
|
void ObjExporter::WriteGeometryFile(bool noMtl, bool merge_identical_vertices) {
|
||||||
WriteHeader(mOutput);
|
WriteHeader(mOutput);
|
||||||
if (!noMtl)
|
if (!noMtl)
|
||||||
mOutput << "mtllib " << GetMaterialLibName() << endl << endl;
|
mOutput << "mtllib " << GetMaterialLibName() << endl << endl;
|
||||||
|
|
||||||
// collect mesh geometry
|
// collect mesh geometry
|
||||||
aiMatrix4x4 mBase;
|
aiMatrix4x4 mBase;
|
||||||
AddNode(pScene->mRootNode, mBase);
|
AddNode(pScene->mRootNode, mBase, merge_identical_vertices);
|
||||||
|
|
||||||
// write vertex positions with colors, if any
|
// write vertex positions with colors, if any
|
||||||
mVpMap.getKeys( vp );
|
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();
|
mMeshes.emplace_back();
|
||||||
MeshInstance& mesh = mMeshes.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) {
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
const unsigned int idx = f.mIndices[a];
|
const unsigned int idx = f.mIndices[a];
|
||||||
|
|
||||||
|
const unsigned int fi = merge_identical_vertices ? 0 : idx;
|
||||||
aiVector3D vert = mat * m->mVertices[idx];
|
aiVector3D vert = mat * m->mVertices[idx];
|
||||||
|
|
||||||
if ( nullptr != m->mColors[ 0 ] ) {
|
if ( nullptr != m->mColors[ 0 ] ) {
|
||||||
aiColor4D col4 = m->mColors[ 0 ][ idx ];
|
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 {
|
} 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) {
|
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;
|
const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
|
||||||
|
|
||||||
aiMesh *cm( nullptr );
|
aiMesh *cm( nullptr );
|
||||||
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
|
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
|
||||||
cm = pScene->mMeshes[nd->mMeshes[i]];
|
cm = pScene->mMeshes[nd->mMeshes[i]];
|
||||||
if (nullptr != cm) {
|
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 {
|
} 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) {
|
for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
|
||||||
AddNode(nd->mChildren[i], mAbs);
|
AddNode(nd->mChildren[i], mAbs, merge_identical_vertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
@ -63,7 +65,7 @@ namespace Assimp {
|
||||||
class ObjExporter {
|
class ObjExporter {
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// 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();
|
~ObjExporter();
|
||||||
std::string GetMaterialLibName();
|
std::string GetMaterialLibName();
|
||||||
std::string GetMaterialLibFileName();
|
std::string GetMaterialLibFileName();
|
||||||
|
@ -97,10 +99,10 @@ private:
|
||||||
|
|
||||||
void WriteHeader(std::ostringstream& out);
|
void WriteHeader(std::ostringstream& out);
|
||||||
void WriteMaterialFile();
|
void WriteMaterialFile();
|
||||||
void WriteGeometryFile(bool noMtl=false);
|
void WriteGeometryFile(bool noMtl=false, bool merge_identical_vertices = false);
|
||||||
std::string GetMaterialName(unsigned int index);
|
std::string GetMaterialName(unsigned int index);
|
||||||
void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
|
void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat, bool merge_identical_vertices);
|
||||||
void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
|
void AddNode(const aiNode* nd, const aiMatrix4x4& mParent, bool merge_identical_vertices);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
@ -109,6 +111,7 @@ private:
|
||||||
struct vertexData {
|
struct vertexData {
|
||||||
aiVector3D vp;
|
aiVector3D vp;
|
||||||
aiColor3D vc; // OBJ does not support 4D color
|
aiColor3D vc; // OBJ does not support 4D color
|
||||||
|
uint32_t index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<aiVector3D> vn, vt;
|
std::vector<aiVector3D> vn, vt;
|
||||||
|
@ -133,7 +136,7 @@ private:
|
||||||
if (a.vc.g > b.vc.g) return false;
|
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 true;
|
||||||
if (a.vc.b > b.vc.b) return false;
|
if (a.vc.b > b.vc.b) return false;
|
||||||
return false;
|
return a.index < b.index;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue