Corrected triangulation bug in off file.
This commit is contained in:
parent
c72396e6f7
commit
45b736926a
|
@ -369,81 +369,103 @@ namespace vcg
|
||||||
unsigned int f0=0;
|
unsigned int f0=0;
|
||||||
|
|
||||||
|
|
||||||
// Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals
|
// Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals
|
||||||
std::vector<VertexPointer> qtmp;
|
std::vector<VertexPointer> qtmp;
|
||||||
BitQuad<MESH_TYPE>::QuadTriangulate(qtmp);
|
BitQuad<MESH_TYPE>::QuadTriangulate(qtmp);
|
||||||
|
|
||||||
for (unsigned int f=0; f < nFaces; f++)
|
for (unsigned int f=0; f < nFaces; f++)
|
||||||
{
|
{
|
||||||
f0 = f;
|
f0 = f;
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
return InvalidFile;
|
return InvalidFile;
|
||||||
|
|
||||||
if(cb && (f%1000)==0)
|
if(cb && (f%1000)==0)
|
||||||
cb(50+f*50/nFaces,"Face Loading");
|
cb(50+f*50/nFaces,"Face Loading");
|
||||||
|
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
int vert_per_face = atoi(tokens[0].c_str());
|
int vert_per_face = atoi(tokens[0].c_str());
|
||||||
if(vert_per_face < 3)
|
if(vert_per_face < 3)
|
||||||
return ErrorDegenerateFace;
|
return ErrorDegenerateFace;
|
||||||
k = 1;
|
k = 1;
|
||||||
if (vert_per_face == 3)
|
if (vert_per_face == 3)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
{
|
{
|
||||||
if (k == tokens.size()) // if EOL // Go to next line when needed
|
TokenizeNextLine(stream, tokens);
|
||||||
{
|
if (tokens.size() == 0) return InvalidFile; // if EOF
|
||||||
TokenizeNextLine(stream, tokens);
|
k = 0;
|
||||||
if (tokens.size() == 0) return InvalidFile; // if EOF
|
}
|
||||||
k = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.face[f].V(j) = &(mesh.vert[ atoi(tokens[k].c_str()) ]);
|
mesh.face[f].V(j) = &(mesh.vert[ atoi(tokens[k].c_str()) ]);
|
||||||
k++;
|
k++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The face must be triangulated
|
||||||
|
unsigned int trigs = vert_per_face-3; // number of extra faces to add
|
||||||
|
nFaces += trigs;
|
||||||
|
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
||||||
|
std::vector<int> vertIndices(vert_per_face);
|
||||||
|
std::vector<vcg::Point3f > polygonVect(vert_per_face); // vec of polygon loops used for the triangulation of polygonal face
|
||||||
|
for (int j=0; j < vert_per_face; j++)
|
||||||
{
|
{
|
||||||
// The face must be triangulate
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
unsigned int trigs = vert_per_face-3; // number of extra faces to add
|
{
|
||||||
nFaces += trigs;
|
TokenizeNextLine(stream, tokens);
|
||||||
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
if (tokens.size() == 0) return InvalidFile; // if EOF
|
||||||
std::vector<int> vertIndices(vert_per_face);
|
k = 0;
|
||||||
for (int j=0; j < vert_per_face; j++)
|
}
|
||||||
{
|
vertIndices[j] = atoi(tokens[k].c_str());
|
||||||
if (k == tokens.size()) // if EOL // Go to next line when needed
|
polygonVect[j] = mesh.vert[ vertIndices[j] ].P();
|
||||||
{
|
k++;
|
||||||
TokenizeNextLine(stream, tokens);
|
|
||||||
if (tokens.size() == 0) return InvalidFile; // if EOF
|
|
||||||
k = 0;
|
|
||||||
}
|
|
||||||
vertIndices[j] = atoi(tokens[k].c_str());
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
if(vert_per_face==4)
|
|
||||||
{ // To well triangulate use the bitquad support function that reorders vertex for a simple fan
|
|
||||||
std::vector<VertexPointer> q(4);
|
|
||||||
for(int qqi=0;qqi<4;++qqi)
|
|
||||||
q[qqi]=& mesh.vert[vertIndices[qqi]];
|
|
||||||
BitQuad<MESH_TYPE>::QuadTriangulate(q);
|
|
||||||
for(int qqi=0;qqi<4;++qqi)
|
|
||||||
vertIndices[qqi] = q[qqi]- & mesh.vert[0];
|
|
||||||
}
|
|
||||||
// standard fan triangulation (we hope the polygon is convex...)
|
|
||||||
for (int j=0; j<=vert_per_face-3; j++)
|
|
||||||
{
|
|
||||||
mesh.face[f+j].V(0) = &(mesh.vert[ vertIndices[0 ] ]);
|
|
||||||
mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
|
|
||||||
mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
|
|
||||||
if (tri::HasPerFaceFlags(mesh)) {
|
|
||||||
// tag internal polygonal edges as "faux"
|
|
||||||
if (j>0) mesh.face[f+j].SetF(0);
|
|
||||||
if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
|
|
||||||
loadmask |= Mask::IOM_BITPOLYGONAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f+=trigs;
|
|
||||||
}
|
}
|
||||||
|
if(vert_per_face==4)
|
||||||
|
{ // To well triangulate use the bitquad support function that reorders vertex for a simple fan
|
||||||
|
std::vector<VertexPointer> q(4);
|
||||||
|
for(int qqi=0;qqi<4;++qqi)
|
||||||
|
q[qqi]=& mesh.vert[vertIndices[qqi]];
|
||||||
|
BitQuad<MESH_TYPE>::QuadTriangulate(q);
|
||||||
|
for(int qqi=0;qqi<4;++qqi)
|
||||||
|
vertIndices[qqi] = q[qqi]- & mesh.vert[0];
|
||||||
|
// build a two face fan
|
||||||
|
for (int j=0; j<2; j++)
|
||||||
|
{
|
||||||
|
mesh.face[f+j].V(0) = &(mesh.vert[ vertIndices[0 ] ]);
|
||||||
|
mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
|
||||||
|
mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
|
||||||
|
if (tri::HasPerFaceFlags(mesh)) {
|
||||||
|
// tag internal polygonal edges as "faux"
|
||||||
|
if (j>0) mesh.face[f+j].SetF(0);
|
||||||
|
if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
|
||||||
|
loadmask |= Mask::IOM_BITPOLYGONAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // standard fan triangulation (we hope the polygon is convex...)
|
||||||
|
{
|
||||||
|
std::vector<int> indexTriangulatedVect;
|
||||||
|
// TessellatePlanarPolygon3(polygonVect,indexTriangulatedVect);
|
||||||
|
std::vector< std::vector<Point3f> > loopVect;
|
||||||
|
loopVect.push_back(polygonVect);
|
||||||
|
#ifdef __gl_h_
|
||||||
|
//qDebug("OK: using opengl tessellation for a polygon of %i vertices",vertexesPerFace);
|
||||||
|
vcg::glu_tesselator::tesselate<vcg::Point3f>(loopVect, indexTriangulatedVect);
|
||||||
|
#else
|
||||||
|
//qDebug("Warning: using fan tessellation for a polygon of %i vertices",vertexesPerFace);
|
||||||
|
InternalFanTessellator(loopVect, indexTriangulatedVect);
|
||||||
|
#endif
|
||||||
|
for (int j=0; j<indexTriangulatedVect.size(); j+=3)
|
||||||
|
{
|
||||||
|
mesh.face[f+j/3].V(0) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+0] ] ]);
|
||||||
|
mesh.face[f+j/3].V(1) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+1] ] ]);
|
||||||
|
mesh.face[f+j/3].V(2) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+2] ] ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f+=trigs;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: It is assumed that colored face takes exactly one text line
|
// NOTE: It is assumed that colored face takes exactly one text line
|
||||||
// (otherwise it is impossible to parse color information since
|
// (otherwise it is impossible to parse color information since
|
||||||
|
@ -540,7 +562,7 @@ namespace vcg
|
||||||
std::string line;
|
std::string line;
|
||||||
do
|
do
|
||||||
std::getline(stream, line, '\n');
|
std::getline(stream, line, '\n');
|
||||||
while (line[0] == '#' || line.length()==0);
|
while (line[0] == '#' || line.length()==0 || line[0]=='\r');
|
||||||
|
|
||||||
size_t from = 0;
|
size_t from = 0;
|
||||||
size_t to = 0;
|
size_t to = 0;
|
||||||
|
|
Loading…
Reference in New Issue