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 #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) if( face.mNumIndices <= 3)
{ {
aiFace& nface = *curOut++; aiFace& nface = *curOut++;
nface.mNumIndices = face.mNumIndices; nface.mNumIndices = face.mNumIndices;
nface.mIndices = face.mIndices; 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 else
{ {
// A polygon with more than 3 vertices can be either concave or convex. // A polygon with more than 3 vertices can be either concave or convex.
// Usually everything we're getting is convex and we could easily // Usually everything we're getting is convex and we could easily
// triangulate by trifanning. However, LightWave is probably the only // 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. // so we need to apply the full 'ear cutting' algorithm.
// RERQUIREMENT: polygon is expected to be simple and *nearly* planar. // 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. // Collect all vertices of of the polygon.
aiVector3D* verts = pMesh->mVertices; aiVector3D* verts = pMesh->mVertices;
for (tmp = 0; tmp < max; ++tmp) for (tmp = 0; tmp < max; ++tmp) {
temp_verts[tmp] = verts[idx[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 // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
aiVector3D n; aiVector3D n;
@ -278,16 +293,18 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// break after we looped two times without a positive match // break after we looped two times without a positive match
for (next=ear+1;done[(next>max-1?next=0:next)];++next); for (next=ear+1;done[(next>max-1?next=0:next)];++next);
if (next < ear) { if (next < ear) {
if (++num_found == 2) if (++num_found == 2) {
break; break;
}
} }
const aiVector2D* pnt1 = (const aiVector2D*)&temp_verts[ear], const aiVector2D* pnt1 = (const aiVector2D*)&temp_verts[ear],
*pnt0 = (const aiVector2D*)&temp_verts[prev], *pnt0 = (const aiVector2D*)&temp_verts[prev],
*pnt2 = (const aiVector2D*)&temp_verts[next]; *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. // 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; continue;
}
// and no other point may be contained in this triangle // and no other point may be contained in this triangle
for ( tmp = 0; tmp < max; ++tmp) { for ( tmp = 0; tmp < max; ++tmp) {
@ -304,8 +321,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
break; break;
} }
if (tmp != max) if (tmp != max) {
continue; continue;
}
// this vertex is an ear // this vertex is an ear
break; break;
@ -339,8 +357,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
aiFace& nface = *curOut++; aiFace& nface = *curOut++;
nface.mNumIndices = 3; nface.mNumIndices = 3;
if (!nface.mIndices) if (!nface.mIndices) {
nface.mIndices = new unsigned int[3]; nface.mIndices = new unsigned int[3];
}
// setup indices for the new triangle ... // setup indices for the new triangle ...
nface.mIndices[0] = idx[prev]; 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 @verbatim
Debug, T5488: START `total` Debug, T5488: START `total`
Info, T5488: Found a matching importer for this file format Info, T5488: Found a matching importer for this file format
Debug, T5488: START `import` Debug, T5488: START `import`
Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey` Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey`
Debug, T5488: END `import`, dt= 3.516 s 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: START `preprocess`
Debug, T5488: END `preprocess`, dt= 0.001 s Debug, T5488: END `preprocess`, dt= 0.001 s
Info, T5488: Entering post processing pipeline Info, T5488: Entering post processing pipeline
Debug, T5488: START `postprocess` Debug, T5488: START `postprocess`
Debug, T5488: RemoveRedundantMatsProcess begin Debug, T5488: RemoveRedundantMatsProcess begin
Debug, T5488: RemoveRedundantMatsProcess finished Debug, T5488: RemoveRedundantMatsProcess finished
Debug, T5488: END `postprocess`, dt= 0.001 s Debug, T5488: END `postprocess`, dt= 0.001 s
Debug, T5488: START `postprocess` Debug, T5488: START `postprocess`
Debug, T5488: TriangulateProcess begin Debug, T5488: TriangulateProcess begin
Info, T5488: TriangulateProcess finished. All polygons have been triangulated. Info, T5488: TriangulateProcess finished. All polygons have been triangulated.
Debug, T5488: END `postprocess`, dt= 3.415 s Debug, T5488: END `postprocess`, dt= 3.415 s
Debug, T5488: START `postprocess` Debug, T5488: START `postprocess`
Debug, T5488: SortByPTypeProcess begin Debug, T5488: SortByPTypeProcess begin
Info, T5488: Points: 0, Lines: 0, Triangles: 1, Polygons: 0 (Meshes, X = removed) 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: START `postprocess`
Debug, T5488: JoinVerticesProcess begin Debug, T5488: JoinVerticesProcess begin
Debug, T5488: Mesh 0 (unnamed) | Verts in: 503808 out: 126345 | ~74.922 Debug, T5488: Mesh 0 (unnamed) | Verts in: 503808 out: 126345 | ~74.922
Info, T5488: JoinVerticesProcess finished | Verts in: 503808 out: 126345 | ~74.9 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: START `postprocess`
Debug, T5488: FlipWindingOrderProcess begin Debug, T5488: FlipWindingOrderProcess begin
Debug, T5488: FlipWindingOrderProcess finished Debug, T5488: FlipWindingOrderProcess finished
Debug, T5488: END `postprocess`, dt= 0.006 s Debug, T5488: END `postprocess`, dt= 0.006 s
Debug, T5488: START `postprocess` Debug, T5488: START `postprocess`
Debug, T5488: LimitBoneWeightsProcess begin Debug, T5488: LimitBoneWeightsProcess begin
Debug, T5488: LimitBoneWeightsProcess end Debug, T5488: LimitBoneWeightsProcess end
Debug, T5488: END `postprocess`, dt= 0.001 s Debug, T5488: END `postprocess`, dt= 0.001 s
Debug, T5488: START `postprocess` Debug, T5488: START `postprocess`
Debug, T5488: ImproveCacheLocalityProcess begin Debug, T5488: ImproveCacheLocalityProcess begin
Debug, T5488: Mesh 0 | ACMR in: 0.851622 out: 0.718139 | ~15.7 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 Info, T5488: Cache relevant are 1 meshes (251904 faces). Average output ACMR is 0.718139
Debug, T5488: ImproveCacheLocalityProcess finished. Debug, T5488: ImproveCacheLocalityProcess finished.
Debug, T5488: END `postprocess`, dt= 1.903 s Debug, T5488: END `postprocess`, dt= 1.903 s
Info, T5488: Leaving post processing pipeline Info, T5488: Leaving post processing pipeline
Debug, T5488: END `total`, dt= 11.269 s Debug, T5488: END `total`, dt= 11.269 s
@endverbatim @endverbatim