瀏覽代碼

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
aramis_acg 15 年之前
父節點
當前提交
9c1306a95a
共有 2 個文件被更改,包括 44 次插入16 次删除
  1. 26 7
      code/TriangulateProcess.cpp
  2. 18 9
      doc/dox.h

+ 26 - 7
code/TriangulateProcess.cpp

@@ -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];

+ 18 - 9
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