Major rewrite. Now shorter and more robust.
This commit is contained in:
parent
3c322d2206
commit
ffc18db244
|
@ -25,6 +25,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.7 2006/06/21 04:26:26 cignoni
|
||||||
|
added initial test on end of file in the tokenize
|
||||||
|
|
||||||
Revision 1.6 2006/05/21 07:01:04 cignoni
|
Revision 1.6 2006/05/21 07:01:04 cignoni
|
||||||
Added mask clamping to the effective capabilities of the mesh
|
Added mask clamping to the effective capabilities of the mesh
|
||||||
|
|
||||||
|
@ -87,6 +90,7 @@ public:
|
||||||
{
|
{
|
||||||
mask = 0;
|
mask = 0;
|
||||||
cb = 0;
|
cb = 0;
|
||||||
|
numTexCoords=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// It returns a bit mask describing the field preesnt in the ply file
|
/// It returns a bit mask describing the field preesnt in the ply file
|
||||||
|
@ -98,23 +102,33 @@ public:
|
||||||
|
|
||||||
/// number of vertices
|
/// number of vertices
|
||||||
int numVertices;
|
int numVertices;
|
||||||
|
/// number of faces (the number of triangles could be
|
||||||
/// number of triangles
|
/// larger in presence of polygonal faces
|
||||||
int numTriangles;
|
int numFaces;
|
||||||
|
/// number of texture coords indexes
|
||||||
|
int numTexCoords;
|
||||||
|
|
||||||
}; // end class
|
}; // end class
|
||||||
|
|
||||||
|
|
||||||
struct OBJFacet
|
//struct OBJFacet
|
||||||
{
|
//{
|
||||||
CoordType n;
|
// CoordType n;
|
||||||
CoordType t;
|
// CoordType t;
|
||||||
CoordType v[3];
|
// CoordType v[3];
|
||||||
|
//
|
||||||
short attr; // material index
|
// short attr; // material index
|
||||||
|
//};
|
||||||
|
struct ObjIndexedFace
|
||||||
|
{
|
||||||
|
int v[3];
|
||||||
|
int n[3];
|
||||||
|
int t[3];
|
||||||
|
int tInd;
|
||||||
|
Color4b c;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TexCoord
|
struct ObjTexCoord
|
||||||
{
|
{
|
||||||
float u;
|
float u;
|
||||||
float v;
|
float v;
|
||||||
|
@ -217,6 +231,20 @@ static const char* ErrorMsg(int error)
|
||||||
else return obj_error_msg[error];
|
else return obj_error_msg[error];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper functions that checks the range of indexes
|
||||||
|
// putting them in the correct range if less than zero (as in the obj style)
|
||||||
|
|
||||||
|
static bool GoodObjIndex(int &index, const int maxVal)
|
||||||
|
{
|
||||||
|
if (index > maxVal) return false;
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
index += maxVal+1;
|
||||||
|
if (index<0 || index > maxVal) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int Open(OpenMeshType &mesh, const char *filename, int &loadmask, CallBackPos *cb=0)
|
static int Open(OpenMeshType &mesh, const char *filename, int &loadmask, CallBackPos *cb=0)
|
||||||
{
|
{
|
||||||
Info oi;
|
Info oi;
|
||||||
|
@ -250,7 +278,7 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
if (oi.numVertices == 0)
|
if (oi.numVertices == 0)
|
||||||
return E_NO_VERTEX;
|
return E_NO_VERTEX;
|
||||||
|
|
||||||
if (oi.numTriangles == 0)
|
if (oi.numFaces == 0)
|
||||||
return E_NO_FACE;
|
return E_NO_FACE;
|
||||||
|
|
||||||
std::ifstream stream(filename);
|
std::ifstream stream(filename);
|
||||||
|
@ -258,13 +286,16 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
return E_CANTOPEN;
|
return E_CANTOPEN;
|
||||||
|
|
||||||
std::vector<Material> materials; // materials vector
|
std::vector<Material> materials; // materials vector
|
||||||
std::vector<TexCoord> texCoords; // texture coordinates
|
std::vector<ObjTexCoord> texCoords; // texture coordinates
|
||||||
std::vector<CoordType> normals; // vertex normals
|
std::vector<CoordType> normals; // vertex normals
|
||||||
|
std::vector<ObjIndexedFace> indexedFaces;
|
||||||
std::vector< std::string > tokens;
|
std::vector< std::string > tokens;
|
||||||
std::string header;
|
std::string header;
|
||||||
|
|
||||||
short currentMaterialIdx = 0; // index of current material into materials vector
|
short currentMaterialIdx = 0; // index of current material into materials vector
|
||||||
|
Color4b currentColor=Color4b::LightGray; // we declare this outside code block since other
|
||||||
|
// triangles of this face will share the same color
|
||||||
|
|
||||||
Material defaultMaterial; // default material: white
|
Material defaultMaterial; // default material: white
|
||||||
materials.push_back(defaultMaterial);
|
materials.push_back(defaultMaterial);
|
||||||
|
|
||||||
|
@ -273,13 +304,14 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
int numTexCoords = 0; // stores the number of texture coordinates been read till now
|
int numTexCoords = 0; // stores the number of texture coordinates been read till now
|
||||||
int numVNormals = 0; // stores the number of vertex normals been read till now
|
int numVNormals = 0; // stores the number of vertex normals been read till now
|
||||||
|
|
||||||
int numVerticesPlusFaces = oi.numVertices + oi.numTriangles;
|
int numVerticesPlusFaces = oi.numVertices + oi.numFaces;
|
||||||
|
|
||||||
// vertices and faces allocatetion
|
// vertices and faces allocatetion
|
||||||
VertexIterator vi = Allocator<OpenMeshType>::AddVertices(m,oi.numVertices);
|
VertexIterator vi = Allocator<OpenMeshType>::AddVertices(m,oi.numVertices);
|
||||||
FaceIterator fi = Allocator<OpenMeshType>::AddFaces(m,oi.numTriangles);
|
//FaceIterator fi = Allocator<OpenMeshType>::AddFaces(m,oi.numFaces);
|
||||||
|
|
||||||
|
ObjIndexedFace ff;
|
||||||
|
|
||||||
// parsing file
|
|
||||||
while (!stream.eof())
|
while (!stream.eof())
|
||||||
{
|
{
|
||||||
tokens.clear();
|
tokens.clear();
|
||||||
|
@ -303,19 +335,7 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
// assigning vertex color
|
// assigning vertex color
|
||||||
// ----------------------
|
// ----------------------
|
||||||
if( oi.mask & vcg::tri::io::Mask::IOM_VERTCOLOR)
|
if( oi.mask & vcg::tri::io::Mask::IOM_VERTCOLOR)
|
||||||
{
|
(*vi).C() = currentColor;
|
||||||
Material material = materials[currentMaterialIdx];
|
|
||||||
Point3f diffuseColor = material.diffuse;
|
|
||||||
unsigned char r = (unsigned char) (diffuseColor[0] * 255.0);
|
|
||||||
unsigned char g = (unsigned char) (diffuseColor[1] * 255.0);
|
|
||||||
unsigned char b = (unsigned char) (diffuseColor[2] * 255.0);
|
|
||||||
unsigned char alpha = (unsigned char) (material.alpha * 255.0);
|
|
||||||
Color4b vertexColor = Color4b(r, g, b, alpha);
|
|
||||||
(*vi).C()[0] = vertexColor[0];
|
|
||||||
(*vi).C()[1] = vertexColor[1];
|
|
||||||
(*vi).C()[2] = vertexColor[2];
|
|
||||||
(*vi).C()[3] = vertexColor[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
++vi; // move to next vertex iterator
|
++vi; // move to next vertex iterator
|
||||||
|
|
||||||
|
@ -327,7 +347,7 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
{
|
{
|
||||||
if (numTokens < 3) return E_BAD_VERT_TEX_STATEMENT;
|
if (numTokens < 3) return E_BAD_VERT_TEX_STATEMENT;
|
||||||
|
|
||||||
TexCoord t;
|
ObjTexCoord t;
|
||||||
t.u = static_cast<float>(atof(tokens[1].c_str()));
|
t.u = static_cast<float>(atof(tokens[1].c_str()));
|
||||||
t.v = static_cast<float>(atof(tokens[2].c_str()));
|
t.v = static_cast<float>(atof(tokens[2].c_str()));
|
||||||
texCoords.push_back(t);
|
texCoords.push_back(t);
|
||||||
|
@ -350,361 +370,48 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
{
|
{
|
||||||
if (numTokens < 4) return E_LESS_THAN_3VERTINFACE;
|
if (numTokens < 4) return E_LESS_THAN_3VERTINFACE;
|
||||||
|
|
||||||
int v1_index, v2_index, v3_index;
|
std::string vertex;
|
||||||
int vt1_index, vt2_index, vt3_index;
|
std::string texcoord;
|
||||||
int vn1_index, vn2_index, vn3_index;
|
std::string normal;
|
||||||
|
for(int i=0;i<3;++i) // remember index starts from 1 instead of 0
|
||||||
|
SplitToken(tokens[i+1], ff.v[i], ff.n[i], ff.t[i], oi.mask);
|
||||||
|
|
||||||
if (( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) &&
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
||||||
( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string texcoord;
|
|
||||||
std::string normal;
|
|
||||||
|
|
||||||
SplitVVTVNToken(tokens[1], vertex, texcoord, normal);
|
|
||||||
v1_index = atoi(vertex.c_str());
|
|
||||||
vt1_index = atoi(texcoord.c_str());
|
|
||||||
vn1_index = atoi(normal.c_str());
|
|
||||||
|
|
||||||
SplitVVTVNToken(tokens[2], vertex, texcoord, normal);
|
|
||||||
v2_index = atoi(vertex.c_str());
|
|
||||||
vt2_index = atoi(texcoord.c_str());
|
|
||||||
vn2_index = atoi(normal.c_str());
|
|
||||||
|
|
||||||
SplitVVTVNToken(tokens[3], vertex, texcoord, normal);
|
|
||||||
v3_index = atoi(vertex.c_str());
|
|
||||||
vt3_index = atoi(texcoord.c_str());
|
|
||||||
vn3_index = atoi(normal.c_str());
|
|
||||||
}
|
|
||||||
else if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string texcoord;
|
|
||||||
|
|
||||||
SplitVVTToken(tokens[1], vertex, texcoord);
|
|
||||||
v1_index = atoi(vertex.c_str());
|
|
||||||
vt1_index = atoi(texcoord.c_str());
|
|
||||||
|
|
||||||
SplitVVTToken(tokens[2], vertex, texcoord);
|
|
||||||
v2_index = atoi(vertex.c_str());
|
|
||||||
vt2_index = atoi(texcoord.c_str());
|
|
||||||
|
|
||||||
SplitVVTToken(tokens[3], vertex, texcoord);
|
|
||||||
v3_index = atoi(vertex.c_str());
|
|
||||||
vt3_index = atoi(texcoord.c_str());
|
|
||||||
}
|
|
||||||
else if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string normal;
|
|
||||||
|
|
||||||
SplitVVNToken(tokens[1], vertex, normal);
|
|
||||||
v1_index = atoi(vertex.c_str());
|
|
||||||
vn1_index = atoi(normal.c_str());
|
|
||||||
|
|
||||||
SplitVVNToken(tokens[2], vertex, normal);
|
|
||||||
v2_index = atoi(vertex.c_str());
|
|
||||||
vn2_index = atoi(normal.c_str());
|
|
||||||
|
|
||||||
SplitVVNToken(tokens[3], vertex, normal);
|
|
||||||
v3_index = atoi(vertex.c_str());
|
|
||||||
vn3_index = atoi(normal.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v1_index = atoi(tokens[1].c_str());
|
|
||||||
v2_index = atoi(tokens[2].c_str());
|
|
||||||
v3_index = atoi(tokens[3].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
|
||||||
{
|
{
|
||||||
// verifying validity of texture coords indices
|
// verifying validity of texture coords indices
|
||||||
// --------------------------------------------
|
for(int i=0;i<3;i++)
|
||||||
if (vt1_index < 0)
|
if(!GoodObjIndex(ff.t[i],oi.numTexCoords))
|
||||||
{
|
return E_BAD_VERT_TEX_INDEX;
|
||||||
vt1_index += numTexCoords;
|
|
||||||
if (vt1_index < 0) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
}
|
|
||||||
else if (vt1_index > numTexCoords) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
else --vt1_index;
|
|
||||||
|
|
||||||
if (vt2_index < 0)
|
ff.tInd=materials[currentMaterialIdx].textureIdx;
|
||||||
{
|
|
||||||
vt2_index += numTexCoords;
|
|
||||||
if (vt2_index < 0) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
}
|
|
||||||
else if (vt2_index > numTexCoords) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
else --vt2_index;
|
|
||||||
|
|
||||||
if (vt3_index < 0)
|
|
||||||
{
|
|
||||||
vt3_index += numTexCoords;
|
|
||||||
if (vt3_index < 0) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
}
|
|
||||||
else if (vt3_index > numTexCoords) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
else --vt3_index;
|
|
||||||
|
|
||||||
|
|
||||||
// assigning wedge texture coordinates
|
|
||||||
// -----------------------------------
|
|
||||||
Material material = materials[currentMaterialIdx];
|
|
||||||
|
|
||||||
TexCoord t = texCoords[vt1_index];
|
|
||||||
(*fi).WT(0).u() = t.u;
|
|
||||||
(*fi).WT(0).v() = t.v;
|
|
||||||
(*fi).WT(0).n() = material.textureIdx;
|
|
||||||
|
|
||||||
t = texCoords[vt2_index];
|
|
||||||
(*fi).WT(1).u() = t.u;
|
|
||||||
(*fi).WT(1).v() = t.v;
|
|
||||||
(*fi).WT(1).n() = material.textureIdx;
|
|
||||||
|
|
||||||
t = texCoords[vt3_index];
|
|
||||||
(*fi).WT(2).u() = t.u;
|
|
||||||
(*fi).WT(2).v() = t.v;
|
|
||||||
(*fi).WT(2).n() = material.textureIdx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifying validity of vertex indices
|
// verifying validity of vertex indices
|
||||||
// ------------------------------------
|
if ((ff.v[0] == ff.v[1]) || (ff.v[0] == ff.v[2]) || (ff.v[1] == ff.v[2]))
|
||||||
if (v1_index < 0)
|
result = E_VERTICES_WITH_SAME_IDX_IN_FACE;
|
||||||
{
|
|
||||||
v1_index += numVertices;
|
|
||||||
if (v1_index < 0) return E_BAD_VERT_INDEX;
|
|
||||||
}
|
|
||||||
else if (v1_index > numVertices) return E_BAD_VERT_INDEX;
|
|
||||||
else v1_index--; // since index starts from 1 instead of 0
|
|
||||||
|
|
||||||
if (v2_index < 0)
|
for(int i=0;i<3;i++)
|
||||||
{
|
if(!GoodObjIndex(ff.v[i],numVertices))
|
||||||
v2_index += numVertices;
|
return E_BAD_VERT_INDEX;
|
||||||
if (v2_index < 0) return E_BAD_VERT_INDEX;
|
|
||||||
}
|
|
||||||
else if (v2_index > numVertices) return E_BAD_VERT_INDEX;
|
|
||||||
else v2_index--; // since index starts from 1 instead of 0
|
|
||||||
|
|
||||||
if (v3_index < 0)
|
|
||||||
{
|
|
||||||
v3_index += numVertices;
|
|
||||||
if (v3_index < 0) return E_BAD_VERT_INDEX;
|
|
||||||
}
|
|
||||||
else if (v3_index > numVertices) return E_BAD_VERT_INDEX;
|
|
||||||
else v3_index--; // since index starts from 1 instead of 0
|
|
||||||
|
|
||||||
if ((v1_index == v2_index) ||
|
|
||||||
(v1_index == v3_index) ||
|
|
||||||
(v2_index == v3_index))
|
|
||||||
result = E_VERTICES_WITH_SAME_IDX_IN_FACE;
|
|
||||||
|
|
||||||
// assigning face vertices
|
|
||||||
// -----------------------
|
|
||||||
(*fi).V(0) = &(m.vert[ v1_index ]);
|
|
||||||
(*fi).V(1) = &(m.vert[ v2_index ]);
|
|
||||||
(*fi).V(2) = &(m.vert[ v3_index ]);
|
|
||||||
|
|
||||||
// assigning face normal
|
// assigning face normal
|
||||||
// ---------------------
|
// ---------------------
|
||||||
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
||||||
{
|
{
|
||||||
// verifying validity of vertex normal indices
|
// verifying validity of vertex normal indices
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
if (vn1_index < 0)
|
for(int i=0;i<3;i++)
|
||||||
{
|
if(!GoodObjIndex(ff.n[i],numVNormals)) return E_BAD_VERT_NORMAL_INDEX;
|
||||||
vn1_index += numVNormals;
|
|
||||||
if (vn1_index < 0) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
}
|
|
||||||
else if (vn1_index > numVNormals) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
else vn1_index--;
|
|
||||||
|
|
||||||
if (vn2_index < 0)
|
|
||||||
{
|
|
||||||
vn2_index += numVNormals;
|
|
||||||
if (vn2_index < 0) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
}
|
|
||||||
else if (vn2_index > numVNormals) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
else vn2_index--;
|
|
||||||
|
|
||||||
if (vn3_index < 0)
|
|
||||||
{
|
|
||||||
vn3_index += numVNormals;
|
|
||||||
if (vn3_index < 0) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
}
|
|
||||||
else if (vn3_index > numVNormals) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
else vn3_index--;
|
|
||||||
|
|
||||||
|
|
||||||
// face normal is computed as an average of wedge normals
|
|
||||||
CoordType n = (normals[vn1_index] + normals[vn2_index] + normals[vn3_index]);
|
|
||||||
n.Normalize();
|
|
||||||
|
|
||||||
(*fi).N() = n;
|
|
||||||
|
|
||||||
(*fi).WN(0) = normals[vn1_index];
|
|
||||||
(*fi).WN(1) = normals[vn2_index];
|
|
||||||
(*fi).WN(2) = normals[vn3_index];
|
|
||||||
}
|
}
|
||||||
else // computing face normal from position of face vertices
|
|
||||||
face::ComputeNormalizedNormal(*fi);
|
|
||||||
|
|
||||||
// assigning face color
|
// assigning face color
|
||||||
// --------------------
|
// --------------------
|
||||||
Color4b faceColor; // we declare this outside code block since other
|
if( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR)
|
||||||
// triangles of this face will share the same color
|
ff.c = currentColor;
|
||||||
if( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR)
|
|
||||||
{
|
|
||||||
Material material = materials[currentMaterialIdx];
|
|
||||||
Point3f diffuseColor = material.diffuse;
|
|
||||||
unsigned char r = (unsigned char) (diffuseColor[0] * 255.0);
|
|
||||||
unsigned char g = (unsigned char) (diffuseColor[1] * 255.0);
|
|
||||||
unsigned char b = (unsigned char) (diffuseColor[2] * 255.0);
|
|
||||||
unsigned char alpha = (unsigned char) (material.alpha * 255.0);
|
|
||||||
faceColor = Color4b(r, g, b, alpha);
|
|
||||||
(*fi).C()[0] = faceColor[0];
|
|
||||||
(*fi).C()[1] = faceColor[1];
|
|
||||||
(*fi).C()[2] = faceColor[2];
|
|
||||||
(*fi).C()[3] = faceColor[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
++fi;
|
|
||||||
++numTriangles;
|
++numTriangles;
|
||||||
|
indexedFaces.push_back(ff);
|
||||||
int vertexesPerFace = static_cast<int>(tokens.size()-1);
|
/*
|
||||||
int iVertex = 3;
|
|
||||||
while (iVertex < vertexesPerFace) // add other triangles
|
|
||||||
{
|
|
||||||
int v4_index;
|
|
||||||
int vt4_index;
|
|
||||||
int vn4_index;
|
|
||||||
|
|
||||||
if (( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) &&
|
|
||||||
( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL ) )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string texcoord;
|
|
||||||
std::string normal;
|
|
||||||
|
|
||||||
SplitVVTVNToken(tokens[++iVertex], vertex, texcoord, normal);
|
|
||||||
v4_index = atoi(vertex.c_str());
|
|
||||||
vt4_index = atoi(texcoord.c_str());
|
|
||||||
vn4_index = atoi(normal.c_str());
|
|
||||||
}
|
|
||||||
else if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string texcoord;
|
|
||||||
|
|
||||||
SplitVVTToken(tokens[++iVertex], vertex, texcoord);
|
|
||||||
v4_index = atoi(vertex.c_str());
|
|
||||||
vt4_index = atoi(texcoord.c_str());
|
|
||||||
}
|
|
||||||
else if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
|
||||||
{
|
|
||||||
std::string vertex;
|
|
||||||
std::string normal;
|
|
||||||
|
|
||||||
SplitVVNToken(tokens[++iVertex], vertex, normal);
|
|
||||||
v4_index = atoi(vertex.c_str());
|
|
||||||
vn4_index = atoi(normal.c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
v4_index = atoi(tokens[++iVertex].c_str());
|
|
||||||
|
|
||||||
// assigning wedge texture coordinates
|
|
||||||
// -----------------------------------
|
|
||||||
if( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
|
||||||
{
|
|
||||||
// verifying validity of texture coords index
|
|
||||||
// ------------------------------------------
|
|
||||||
if (vt4_index < 0)
|
|
||||||
{
|
|
||||||
vt4_index += numTexCoords;
|
|
||||||
if (vt4_index < 0) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
}
|
|
||||||
else if (vt4_index > numTexCoords) return E_BAD_VERT_TEX_INDEX;
|
|
||||||
else --vt4_index;
|
|
||||||
|
|
||||||
|
|
||||||
Material material = materials[currentMaterialIdx];
|
|
||||||
TexCoord t = texCoords[vt1_index];
|
|
||||||
(*fi).WT(0).u() = t.u;
|
|
||||||
(*fi).WT(0).v() = t.v;
|
|
||||||
(*fi).WT(0).n() = material.textureIdx;
|
|
||||||
|
|
||||||
t = texCoords[vt3_index];
|
|
||||||
(*fi).WT(1).u() = t.u;
|
|
||||||
(*fi).WT(1).v() = t.v;
|
|
||||||
(*fi).WT(1).n() = material.textureIdx;
|
|
||||||
|
|
||||||
t = texCoords[vt4_index];
|
|
||||||
(*fi).WT(2).u() = t.u;
|
|
||||||
(*fi).WT(2).v() = t.v;
|
|
||||||
(*fi).WT(2).n() = material.textureIdx;
|
|
||||||
|
|
||||||
vt3_index = vt4_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifying validity of vertex index
|
|
||||||
// ----------------------------------
|
|
||||||
if (v4_index < 0)
|
|
||||||
{
|
|
||||||
v4_index += numVertices;
|
|
||||||
if (v4_index < 0) return E_BAD_VERT_INDEX;
|
|
||||||
}
|
|
||||||
else if (v4_index > numVertices) return E_BAD_VERT_INDEX;
|
|
||||||
else v4_index--; // since index starts from 1 instead of 0
|
|
||||||
|
|
||||||
if ((v1_index == v4_index) ||
|
|
||||||
(v3_index == v4_index))
|
|
||||||
result = E_VERTICES_WITH_SAME_IDX_IN_FACE;
|
|
||||||
|
|
||||||
// assigning face vertices
|
|
||||||
// -----------------------
|
|
||||||
(*fi).V(0) = &(m.vert[ v1_index ]);
|
|
||||||
(*fi).V(1) = &(m.vert[ v3_index ]);
|
|
||||||
(*fi).V(2) = &(m.vert[ v4_index ]);
|
|
||||||
|
|
||||||
// assigning face normal
|
|
||||||
// ---------------------
|
|
||||||
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
|
||||||
{
|
|
||||||
// verifying validity of vertex normal index
|
|
||||||
// -----------------------------------------
|
|
||||||
if (vn4_index < 0)
|
|
||||||
{
|
|
||||||
vn4_index += numVNormals;
|
|
||||||
if (vn4_index < 0) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
}
|
|
||||||
else if (vn4_index > numVNormals) return E_BAD_VERT_NORMAL_INDEX;
|
|
||||||
else vn4_index--;
|
|
||||||
|
|
||||||
|
|
||||||
// face normal is computed as an average of wedge normals
|
|
||||||
CoordType n = (normals[vn1_index] + normals[vn3_index] + normals[vn4_index]);
|
|
||||||
n.Normalize();
|
|
||||||
|
|
||||||
(*fi).N() = n;
|
|
||||||
|
|
||||||
(*fi).WN(0) = normals[vn1_index];
|
|
||||||
(*fi).WN(1) = normals[vn3_index];
|
|
||||||
(*fi).WN(2) = normals[vn4_index];
|
|
||||||
|
|
||||||
vn3_index = vn4_index;
|
|
||||||
}
|
|
||||||
else // computing face normal from position of face vertices
|
|
||||||
face::ComputeNormalizedNormal(*fi);
|
|
||||||
|
|
||||||
// assigning face color
|
|
||||||
// --------------------
|
|
||||||
if( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR)
|
|
||||||
{
|
|
||||||
(*fi).C()[0] = faceColor[0];
|
|
||||||
(*fi).C()[1] = faceColor[1];
|
|
||||||
(*fi).C()[2] = faceColor[2];
|
|
||||||
(*fi).C()[3] = faceColor[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// A face polygon composed of more than three vertices is triangulated
|
// A face polygon composed of more than three vertices is triangulated
|
||||||
// according to the following schema:
|
// according to the following schema:
|
||||||
// v5
|
// v5
|
||||||
|
@ -722,17 +429,58 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
// This way vertex v1 becomes the common vertex of all newly generated
|
// This way vertex v1 becomes the common vertex of all newly generated
|
||||||
// triangles, and this may lead to the creation of very thin triangles.
|
// triangles, and this may lead to the creation of very thin triangles.
|
||||||
*/
|
*/
|
||||||
++fi;
|
|
||||||
++numTriangles;
|
|
||||||
|
|
||||||
v3_index = v4_index;
|
int vertexesPerFace = static_cast<int>(tokens.size()-1);
|
||||||
|
int iVertex = 3;
|
||||||
|
while (iVertex < vertexesPerFace) // add other triangles
|
||||||
|
{
|
||||||
|
ObjIndexedFace ffNew=ff;
|
||||||
|
int v4_index;
|
||||||
|
int vt4_index;
|
||||||
|
int vn4_index;
|
||||||
|
|
||||||
|
SplitToken(tokens[++iVertex], v4_index, vn4_index, vt4_index, oi.mask);
|
||||||
|
|
||||||
|
// assigning wedge texture coordinates
|
||||||
|
// -----------------------------------
|
||||||
|
if( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD )
|
||||||
|
{
|
||||||
|
// verifying validity of texture coords index
|
||||||
|
// ------------------------------------------
|
||||||
|
if(!GoodObjIndex(v4_index, numVertices))
|
||||||
|
return E_BAD_VERT_INDEX;
|
||||||
|
if(!GoodObjIndex(vn4_index,numVNormals))
|
||||||
|
return E_BAD_VERT_NORMAL_INDEX;
|
||||||
|
if(!GoodObjIndex(vt4_index,oi.numTexCoords))
|
||||||
|
return E_BAD_VERT_TEX_INDEX;
|
||||||
|
|
||||||
|
ffNew.t[1]=ff.t[2];
|
||||||
|
ffNew.t[2]=vt4_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ff.v[0] == v4_index) || (ff.v[2] == v4_index)) result = E_VERTICES_WITH_SAME_IDX_IN_FACE;
|
||||||
|
ffNew.v[1]=ff.v[2];
|
||||||
|
ffNew.v[2]=v4_index;
|
||||||
|
|
||||||
|
// assigning face normal
|
||||||
|
// ---------------------
|
||||||
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
||||||
|
{
|
||||||
|
ffNew.n[1]=ff.n[2];
|
||||||
|
ffNew.n[2]=vn4_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
++numTriangles;
|
||||||
|
indexedFaces.push_back(ffNew);
|
||||||
|
ff.v[2] = v4_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback invocation, abort loading process if the call returns false
|
// callback invocation, abort loading process if the call returns false
|
||||||
if ((cb !=NULL) && (((numTriangles + numVertices)%100)==0) &&
|
if ((cb !=NULL)&& (((numTriangles + numVertices)%100)==0) )
|
||||||
!(*cb)(static_cast<int>(100.0f * static_cast<float>(numTriangles +
|
{
|
||||||
numVertices) / static_cast<float>(numVerticesPlusFaces)), "Face Loading"))
|
if (!(*cb)((100.0f * (numTriangles +numVertices) / numVerticesPlusFaces), "Face Loading"))
|
||||||
return E_ABORTED;
|
return E_ABORTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (header.compare("mtllib")==0) // material library
|
else if (header.compare("mtllib")==0) // material library
|
||||||
{
|
{
|
||||||
|
@ -752,6 +500,13 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
if (currentMaterialName == materialName)
|
if (currentMaterialName == materialName)
|
||||||
{
|
{
|
||||||
currentMaterialIdx = i;
|
currentMaterialIdx = i;
|
||||||
|
Material &material = materials[currentMaterialIdx];
|
||||||
|
Point3f diffuseColor = material.diffuse;
|
||||||
|
unsigned char r = (unsigned char) (diffuseColor[0] * 255.0);
|
||||||
|
unsigned char g = (unsigned char) (diffuseColor[1] * 255.0);
|
||||||
|
unsigned char b = (unsigned char) (diffuseColor[2] * 255.0);
|
||||||
|
unsigned char alpha = (unsigned char) (material.alpha * 255.0);
|
||||||
|
currentColor= Color4b(r, g, b, alpha);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
|
@ -764,9 +519,36 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we simply ignore other situations
|
// we simply ignore other situations
|
||||||
}
|
} // end for each line...
|
||||||
}
|
} // end while stream not eof
|
||||||
|
|
||||||
|
FaceIterator fi = Allocator<OpenMeshType>::AddFaces(m,numTriangles);
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
// Now the final pass to convert indexes into pointers for face to vert/norm/tex references
|
||||||
|
for(int i=0;i<numTriangles;++i)
|
||||||
|
{
|
||||||
|
assert(m.face.size()==m.fn);
|
||||||
|
for(int j=0;j<3;++j)
|
||||||
|
{
|
||||||
|
m.face[i].V(j)=&(m.vert[indexedFaces[i].v[j]]);
|
||||||
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD ) {
|
||||||
|
ObjTexCoord t = texCoords[indexedFaces[i].t[j]];
|
||||||
|
m.face[i].WT(j).u() = t.u;
|
||||||
|
m.face[i].WT(j).v() = t.v;
|
||||||
|
m.face[i].WT(j).n() = indexedFaces[i].tInd;
|
||||||
|
}
|
||||||
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
||||||
|
m.face[i].WN(j)=normals[indexedFaces[i].n[j]];
|
||||||
|
}
|
||||||
|
if ( oi.mask & vcg::tri::io::Mask::IOM_FACECOLOR )
|
||||||
|
m.face[i].C()=indexedFaces[i].c;
|
||||||
|
if ( oi.mask & vcg::tri::io::Mask::IOM_WEDGNORMAL )
|
||||||
|
// face normal is computed as an average of wedge normals
|
||||||
|
m.face[i].N()= m.face[i].WN(0)+m.face[i].WN(1)+m.face[i].WN(2);
|
||||||
|
else // computing face normal from position of face vertices
|
||||||
|
face::ComputeNormalizedNormal(m.face[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} // end of Open
|
} // end of Open
|
||||||
|
|
||||||
|
@ -808,6 +590,26 @@ static int Open( OpenMeshType &m, const char * filename, Info &oi)
|
||||||
while (from<length);
|
while (from<length);
|
||||||
} // end TokenizeNextLine
|
} // end TokenizeNextLine
|
||||||
|
|
||||||
|
inline static const void SplitToken(std::string token, int &vId, int &nId, int &tId, int mask)
|
||||||
|
{
|
||||||
|
std::string vertex;
|
||||||
|
std::string texcoord;
|
||||||
|
std::string normal;
|
||||||
|
if( ( mask & Mask::IOM_WEDGTEXCOORD ) && (mask & Mask::IOM_WEDGNORMAL) ) SplitVVTVNToken(token, vertex, texcoord, normal);
|
||||||
|
if(!( mask & Mask::IOM_WEDGTEXCOORD ) && (mask & Mask::IOM_WEDGNORMAL) ) SplitVVNToken(token, vertex, normal);
|
||||||
|
if( ( mask & Mask::IOM_WEDGTEXCOORD ) &&!(mask & Mask::IOM_WEDGNORMAL) ) SplitVVTToken(token, vertex, texcoord);
|
||||||
|
if(!( mask & Mask::IOM_WEDGTEXCOORD ) &&!(mask & Mask::IOM_WEDGNORMAL) ) SplitVToken(token, vertex);
|
||||||
|
|
||||||
|
vId = atoi(vertex.c_str())-1;
|
||||||
|
if(mask & Mask::IOM_WEDGTEXCOORD) tId = atoi(texcoord.c_str())-1;
|
||||||
|
if(mask & Mask::IOM_WEDGNORMAL)nId= atoi(normal.c_str())-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static const void SplitVToken(std::string token, std::string &vertex)
|
||||||
|
{
|
||||||
|
vertex=token;
|
||||||
|
}
|
||||||
|
|
||||||
inline static const void SplitVVTToken(std::string token, std::string &vertex, std::string &texcoord)
|
inline static const void SplitVVTToken(std::string token, std::string &vertex, std::string &texcoord)
|
||||||
{
|
{
|
||||||
vertex.clear();
|
vertex.clear();
|
||||||
|
@ -917,7 +719,7 @@ static bool LoadMask(const char * filename, int &mask)
|
||||||
* \param filename The name of the file to open
|
* \param filename The name of the file to open
|
||||||
* \param mask A mask which will be filled according to type of data found in the object
|
* \param mask A mask which will be filled according to type of data found in the object
|
||||||
* \param oi A structure which will be filled with infos about the object to be opened
|
* \param oi A structure which will be filled with infos about the object to be opened
|
||||||
*/
|
*/
|
||||||
static bool LoadMask(const char * filename, Info &oi)
|
static bool LoadMask(const char * filename, Info &oi)
|
||||||
{
|
{
|
||||||
std::ifstream stream(filename);
|
std::ifstream stream(filename);
|
||||||
|
@ -963,9 +765,13 @@ static bool LoadMask(const char * filename, int &mask)
|
||||||
++numVertices;
|
++numVertices;
|
||||||
if (bUsingMaterial) bHasPerVertexColor = true;
|
if (bUsingMaterial) bHasPerVertexColor = true;
|
||||||
}
|
}
|
||||||
|
if (header.compare("vt")==0)
|
||||||
|
{
|
||||||
|
++oi.numTexCoords;
|
||||||
|
}
|
||||||
else if (header.compare("f")==0)
|
else if (header.compare("f")==0)
|
||||||
{
|
{
|
||||||
numTriangles += (static_cast<int>(tokens.size()) - 3);
|
numTriangles += (tokens.size() - 3);
|
||||||
std::string remainingText = tokens[1];
|
std::string remainingText = tokens[1];
|
||||||
|
|
||||||
// we base our assumption on the fact that the way vertex data is
|
// we base our assumption on the fact that the way vertex data is
|
||||||
|
@ -1038,7 +844,11 @@ static bool LoadMask(const char * filename, int &mask)
|
||||||
numTriangles += (static_cast<int>(tokens.size()) - 3);
|
numTriangles += (static_cast<int>(tokens.size()) - 3);
|
||||||
if (bUsingMaterial) bHasPerFaceColor = true;
|
if (bUsingMaterial) bHasPerFaceColor = true;
|
||||||
}
|
}
|
||||||
else if (header.compare("usemtl")==0)
|
else if (header.compare("vt")==0)
|
||||||
|
{
|
||||||
|
++oi.numTexCoords;
|
||||||
|
}
|
||||||
|
else if (header.compare("usemtl")==0)
|
||||||
bUsingMaterial = true;
|
bUsingMaterial = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,20 +865,14 @@ static bool LoadMask(const char * filename, int &mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mask = 0;
|
oi.mask = 0;
|
||||||
|
if (bHasPerWedgeTexCoord) oi.mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
|
||||||
if (bHasPerWedgeTexCoord)
|
if (bHasPerWedgeNormal) oi.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
|
||||||
mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
|
if (bHasPerVertexColor) oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
||||||
if (bHasPerWedgeNormal)
|
if (bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
||||||
mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
|
|
||||||
if (bHasPerVertexColor)
|
|
||||||
mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
|
||||||
if (bHasPerFaceColor)
|
|
||||||
mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
|
||||||
|
|
||||||
oi.mask = mask;
|
|
||||||
oi.numVertices = numVertices;
|
oi.numVertices = numVertices;
|
||||||
oi.numTriangles = numTriangles;
|
oi.numFaces = numTriangles;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue