remove duplicate vectors when export obj format
parent
e8a23ccec9
commit
8f34c24ae0
|
@ -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
|
// 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"));
|
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);
|
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"));
|
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);
|
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);
|
AddNode(pScene->mRootNode,mBase);
|
||||||
|
|
||||||
// write vertex positions
|
// write vertex positions
|
||||||
|
vpMap.getVectors(vp);
|
||||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vp) {
|
BOOST_FOREACH(const aiVector3D& v, vp) {
|
||||||
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -206,6 +201,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write uv coordinates
|
// write uv coordinates
|
||||||
|
vtMap.getVectors(vt);
|
||||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vt) {
|
BOOST_FOREACH(const aiVector3D& v, vt) {
|
||||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -213,6 +209,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write vertex normals
|
// write vertex normals
|
||||||
|
vnMap.getVectors(vn);
|
||||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vn) {
|
BOOST_FOREACH(const aiVector3D& v, vn) {
|
||||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
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)
|
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.matname = GetMaterialName(m->mMaterialIndex);
|
||||||
|
|
||||||
mesh.faces.resize(m->mNumFaces);
|
mesh.faces.resize(m->mNumFaces);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
const aiFace& f = m->mFaces[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) {
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
const unsigned int idx = f.mIndices[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,
|
aiVector3D vert = mat * m->mVertices[idx];
|
||||||
// in which case we should instead reference the previous occurrence.
|
face.indices[a].vp = vpMap.getIndex(vert);
|
||||||
ai_assert(m->mVertices);
|
|
||||||
vp.push_back( mat * m->mVertices[idx] );
|
|
||||||
face.indices[a].vp = vp.size();
|
|
||||||
|
|
||||||
if (m->mNormals) {
|
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]) {
|
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,21 @@ private:
|
||||||
const aiScene* const pScene;
|
const aiScene* const pScene;
|
||||||
|
|
||||||
std::vector<aiVector3D> vp, vn, vt;
|
std::vector<aiVector3D> vp, vn, vt;
|
||||||
|
|
||||||
|
class vecIndexMap
|
||||||
|
{
|
||||||
|
int mNextIndex;
|
||||||
|
std::map<aiVector3D, int> vecMap;
|
||||||
|
public:
|
||||||
|
|
||||||
|
vecIndexMap():mNextIndex(1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int getIndex(const aiVector3D& vec);
|
||||||
|
void getVectors( std::vector<aiVector3D>& vecs );
|
||||||
|
};
|
||||||
|
|
||||||
|
vecIndexMap vpMap, vnMap, vtMap;
|
||||||
std::vector<MeshInstance> meshes;
|
std::vector<MeshInstance> meshes;
|
||||||
|
|
||||||
// this endl() doesn't flush() the stream
|
// this endl() doesn't flush() the stream
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
// comparison
|
// comparison
|
||||||
bool operator== (const aiVector3t& other) const;
|
bool operator== (const aiVector3t& other) const;
|
||||||
bool operator!= (const aiVector3t& other) const;
|
bool operator!= (const aiVector3t& other) const;
|
||||||
|
bool operator< (const aiVector3t& other) const;
|
||||||
|
|
||||||
template <typename TOther>
|
template <typename TOther>
|
||||||
operator aiVector3t<TOther> () const;
|
operator aiVector3t<TOther> () const;
|
||||||
|
|
|
@ -149,6 +149,16 @@ AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& oth
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename TReal>
|
template <typename TReal>
|
||||||
|
AI_FORCE_INLINE bool aiVector3t<TReal>::operator< (const aiVector3t<TReal>& other) const {
|
||||||
|
if(x < other.x) return true;
|
||||||
|
if(x > other.x) return false;
|
||||||
|
if(y < other.y) return true;
|
||||||
|
if(y > other.y) return false;
|
||||||
|
if(z < other.z) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
template <typename TReal>
|
||||||
AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
|
AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
|
||||||
return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
|
return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue