remove duplicate vectors when export obj format

This commit is contained in:
Marshall Hahn
2013-09-30 14:07:53 -04:00
parent e8a23ccec9
commit 8f34c24ae0
4 changed files with 65 additions and 15 deletions

View File

@@ -59,16 +59,10 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write both the main OBJ file and the material script
{
boost::scoped_ptr<IOStream> 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<size_t>(exporter.mOutput.tellp()),1);
}
{
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
if(outfile == NULL) {
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
}
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
}
}
@@ -199,6 +193,7 @@ void ObjExporter :: WriteGeometryFile()
AddNode(pScene->mRootNode,mBase);
// write vertex positions
vpMap.getVectors(vp);
mOutput << "# " << vp.size() << " vertex positions" << endl;
BOOST_FOREACH(const aiVector3D& v, vp) {
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
@@ -206,6 +201,7 @@ void ObjExporter :: WriteGeometryFile()
mOutput << endl;
// write uv coordinates
vtMap.getVectors(vt);
mOutput << "# " << vt.size() << " UV coordinates" << endl;
BOOST_FOREACH(const aiVector3D& v, vt) {
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
@@ -213,6 +209,7 @@ void ObjExporter :: WriteGeometryFile()
mOutput << endl;
// write vertex normals
vnMap.getVectors(vn);
mOutput << "# " << vn.size() << " vertex normals" << endl;
BOOST_FOREACH(const aiVector3D& v, vn) {
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
@@ -252,6 +249,31 @@ void ObjExporter :: WriteGeometryFile()
}
}
int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec)
{
std::map<aiVector3D, int>::iterator vertIt = vecMap.find(vec);
if(vertIt != vecMap.end()){// vertex already exists, so reference it
return vertIt->second;
}
vecMap[vec] = mNextIndex;
int ret = mNextIndex;
mNextIndex++;
return ret;
}
void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs )
{
vecs.resize(vecMap.size());
for(std::map<aiVector3D, int>::iterator it = vecMap.begin(); it != vecMap.end(); it++){
vecs[it->second-1] = it->first;
}
}
// ------------------------------------------------------------------------------------------------
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
{
@@ -262,6 +284,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
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];
@@ -281,21 +304,22 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
const unsigned int idx = f.mIndices[a];
// XXX need a way to check if this is an unique vertex or if we had it already,
// in which case we should instead reference the previous occurrence.
ai_assert(m->mVertices);
vp.push_back( mat * m->mVertices[idx] );
face.indices[a].vp = vp.size();
aiVector3D vert = mat * m->mVertices[idx];
face.indices[a].vp = vpMap.getIndex(vert);
if (m->mNormals) {
vn.push_back( m->mNormals[idx] );
face.indices[a].vn = vnMap.getIndex(m->mNormals[idx]);
}
else{
face.indices[a].vn = 0;
}
face.indices[a].vn = vn.size();
if (m->mTextureCoords[0]) {
vt.push_back( m->mTextureCoords[0][idx] );
face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]);
}
else{
face.indices[a].vt = 0;
}
face.indices[a].vt = vt.size();
}
}
}