Better triangulation of quad into two triangles.
This commit is contained in:
parent
c72bfe6f63
commit
14850843c6
|
@ -458,12 +458,10 @@ namespace vcg
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
// Go to next line when needed
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
if (k == tokens.size()) // if EOL
|
|
||||||
{
|
{
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
if (tokens.size() == 0) // if EOF
|
if (tokens.size() == 0) return InvalidFile; // if EOF
|
||||||
return InvalidFile;
|
|
||||||
k = 0;
|
k = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,38 +475,58 @@ namespace vcg
|
||||||
unsigned int trigs = vert_per_face-3; // number of extra faces to add
|
unsigned int trigs = vert_per_face-3; // number of extra faces to add
|
||||||
nFaces += trigs;
|
nFaces += trigs;
|
||||||
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
||||||
int *vertIndices = new int[vert_per_face];
|
std::vector<int> vertIndices(vert_per_face);
|
||||||
|
|
||||||
for (int j=0; j < vert_per_face; j++)
|
for (int j=0; j < vert_per_face; j++)
|
||||||
{
|
{
|
||||||
// Go to next line when needed
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
if (k == tokens.size()) // if EOL
|
|
||||||
{
|
{
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
if (tokens.size() == 0) // if EOF
|
if (tokens.size() == 0) return InvalidFile; // if EOF
|
||||||
return InvalidFile;
|
|
||||||
k = 0;
|
k = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertIndices[j] = atoi(tokens[k].c_str());
|
vertIndices[j] = atoi(tokens[k].c_str());
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
if(vert_per_face==4)
|
||||||
|
{ // To well triangulate the quad:
|
||||||
|
// if the quad is flat and convex we use the shortest diag ,
|
||||||
|
// else we should use the diag that makes the smallest
|
||||||
|
|
||||||
|
const CoordType &P0=mesh.vert[vertIndices[0]].cP();
|
||||||
|
const CoordType &P1=mesh.vert[vertIndices[1]].cP();
|
||||||
|
const CoordType &P2=mesh.vert[vertIndices[2]].cP();
|
||||||
|
const CoordType &P3=mesh.vert[vertIndices[3]].cP();
|
||||||
|
|
||||||
|
CoordType N00 = Normal(P0,P1,P2);
|
||||||
|
CoordType N01 = Normal(P0,P2,P3);
|
||||||
|
CoordType N10 = Normal(P1,P2,P3);
|
||||||
|
CoordType N11 = Normal(P1,P3,P0);
|
||||||
|
|
||||||
|
ScalarType Angle0Rad=Angle(N00,N01);
|
||||||
|
ScalarType Angle1Rad=Angle(N10,N11);
|
||||||
|
|
||||||
|
// QualityRadii is inradius/circumradius; bad when close to zero.
|
||||||
|
// swap diagonal if the worst triangle improve.
|
||||||
|
bool qualityImprove = std::min(QualityRadii(P0,P1,P2),QualityRadii(P0,P2,P3)) < std::min(QualityRadii(P1,P2,P3),QualityRadii(P1,P3,P0));
|
||||||
|
bool swapCauseFlip = (Angle1Rad > M_PI/2.0) && (Angle0Rad <M_PI/2.0);
|
||||||
|
if(qualityImprove && ! swapCauseFlip)
|
||||||
|
std::rotate(vertIndices.begin(), vertIndices.begin()+1, vertIndices.end());
|
||||||
|
|
||||||
|
}
|
||||||
|
// standard fan triangulation (we hope the polygon is convex...)
|
||||||
for (int j=0; j<=vert_per_face-3; j++)
|
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(0) = &(mesh.vert[ vertIndices[0 ] ]);
|
||||||
mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
|
mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
|
||||||
mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
|
mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
|
||||||
if (tri::HasPerFaceFlags(mesh)) {
|
if (tri::HasPerFaceFlags(mesh)) {
|
||||||
// tag internal polygnal edges as "faux"
|
// tag internal polygonal edges as "faux"
|
||||||
if (j>0) mesh.face[f+j].SetF(0);
|
if (j>0) mesh.face[f+j].SetF(0);
|
||||||
if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
|
if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
|
||||||
loadmask |= Mask::IOM_BITPOLYGONAL;
|
loadmask |= Mask::IOM_BITPOLYGONAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f+=trigs;
|
f+=trigs;
|
||||||
delete [] vertIndices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: It is assumed that colored face takes exactly one text line
|
// NOTE: It is assumed that colored face takes exactly one text line
|
||||||
|
|
Loading…
Reference in New Issue