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
pull/1/head
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];

View File

@ -1469,7 +1469,8 @@ A sample report looks like this (some unrelated log messages omitted, grouped en
@verbatim
Debug, T5488: START `total`
Info, T5488: Found a matching importer for this file format
Debug, T5488: START `import`
Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey`
Debug, T5488: END `import`, dt= 3.516 s
@ -1478,43 +1479,51 @@ Debug, T5488: END `import`, dt= 3.516 s
Debug, T5488: START `preprocess`
Debug, T5488: END `preprocess`, dt= 0.001 s
Info, T5488: Entering post processing pipeline
Debug, T5488: START `postprocess`
Debug, T5488: RemoveRedundantMatsProcess begin
Debug, T5488: RemoveRedundantMatsProcess finished
Debug, T5488: END `postprocess`, dt= 0.001 s
Debug, T5488: START `postprocess`
Debug, T5488: TriangulateProcess begin
Info, T5488: TriangulateProcess finished. All polygons have been triangulated.
Debug, T5488: END `postprocess`, dt= 3.415 s
Debug, T5488: START `postprocess`
Debug, T5488: SortByPTypeProcess begin
Info, T5488: Points: 0, Lines: 0, Triangles: 1, Polygons: 0 (Meshes, X = removed)
Debug, T5488: SortByPTypeProcess finished
Debug, T5488: SortByPTypeProcess finished
Debug, T5488: START `postprocess`
Debug, T5488: JoinVerticesProcess begin
Debug, T5488: Mesh 0 (unnamed) | Verts in: 503808 out: 126345 | ~74.922
Info, T5488: JoinVerticesProcess finished | Verts in: 503808 out: 126345 | ~74.9
Debug, T5488: END `postprocess`, dt= 2.052 s
Debug, T5488: END `postprocess`, dt= 2.052 s
Debug, T5488: START `postprocess`
Debug, T5488: FlipWindingOrderProcess begin
Debug, T5488: FlipWindingOrderProcess finished
Debug, T5488: END `postprocess`, dt= 0.006 s
Debug, T5488: START `postprocess`
Debug, T5488: LimitBoneWeightsProcess begin
Debug, T5488: LimitBoneWeightsProcess end
Debug, T5488: END `postprocess`, dt= 0.001 s
Debug, T5488: START `postprocess`
Debug, T5488: ImproveCacheLocalityProcess begin
Debug, T5488: Mesh 0 | ACMR in: 0.851622 out: 0.718139 | ~15.7
Info, T5488: Cache relevant are 1 meshes (251904 faces). Average output ACMR is 0.718139
Debug, T5488: ImproveCacheLocalityProcess finished.
Debug, T5488: END `postprocess`, dt= 1.903 s
Info, T5488: Leaving post processing pipeline
Debug, T5488: END `total`, dt= 11.269 s
@endverbatim