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-9d2fd5bffc1fpull/1/head
parent
aae8637666
commit
9c1306a95a
|
@ -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];
|
||||||
|
|
27
doc/dox.h
27
doc/dox.h
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue