Skip ear cutting algorithm for quadrilaterals, makes triangulation MUCH, MUCH faster (100x) for models composed of quadrilaterals (i.e. Blender, Terragen).

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@773 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2010-07-09 16:44:13 +00:00
parent aae8637666
commit 9c1306a95a
2 changed files with 44 additions and 16 deletions

View File

@@ -205,19 +205,33 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
}
#endif
// if it's a simple primitive, just copy it
// if it's a simple point,line or triangle: just copy it
if( face.mNumIndices <= 3)
{
aiFace& nface = *curOut++;
nface.mNumIndices = face.mNumIndices;
nface.mIndices = face.mIndices;
}
// quadrilaterals can't have ears. trifanning will always work
else if ( face.mNumIndices == 4) {
aiFace& nface = *curOut++;
nface.mNumIndices = 3;
nface.mIndices = face.mIndices;
aiFace& sface = *curOut++;
sface.mNumIndices = 3;
sface.mIndices = new unsigned int[3];
sface.mIndices[0] = face.mIndices[0];
sface.mIndices[1] = face.mIndices[2];
sface.mIndices[2] = face.mIndices[3];
}
else
{
// A polygon with more than 3 vertices can be either concave or convex.
// Usually everything we're getting is convex and we could easily
// triangulate by trifanning. However, LightWave is probably the only
// modeller making extensive use of highly concave monster polygons ...
// modeller to make extensive use of highly concave monster polygons ...
// so we need to apply the full 'ear cutting' algorithm.
// RERQUIREMENT: polygon is expected to be simple and *nearly* planar.
@@ -226,8 +240,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// Collect all vertices of of the polygon.
aiVector3D* verts = pMesh->mVertices;
for (tmp = 0; tmp < max; ++tmp)
for (tmp = 0; tmp < max; ++tmp) {
temp_verts[tmp] = verts[idx[tmp]];
}
// Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
aiVector3D n;
@@ -278,16 +293,18 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// break after we looped two times without a positive match
for (next=ear+1;done[(next>max-1?next=0:next)];++next);
if (next < ear) {
if (++num_found == 2)
if (++num_found == 2) {
break;
}
}
const aiVector2D* pnt1 = (const aiVector2D*)&temp_verts[ear],
*pnt0 = (const aiVector2D*)&temp_verts[prev],
*pnt2 = (const aiVector2D*)&temp_verts[next];
// Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
if (OnLeftSideOfLine (*pnt0,*pnt2,*pnt1))
if (OnLeftSideOfLine (*pnt0,*pnt2,*pnt1)) {
continue;
}
// and no other point may be contained in this triangle
for ( tmp = 0; tmp < max; ++tmp) {
@@ -304,8 +321,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
break;
}
if (tmp != max)
if (tmp != max) {
continue;
}
// this vertex is an ear
break;
@@ -339,8 +357,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
aiFace& nface = *curOut++;
nface.mNumIndices = 3;
if (!nface.mIndices)
if (!nface.mIndices) {
nface.mIndices = new unsigned int[3];
}
// setup indices for the new triangle ...
nface.mIndices[0] = idx[prev];