فهرست منبع

Automatically clean shape data passed to ExtrudeGeometry (#30750)

* Automatically clean shape data passed to ExtrudeGeometry

Before triangulating a shape, ExtrudeGeometry now welds any index-adjacent points within a small hardcoded distance threshold of each other. This resolves common triangulation artifacts caused by improperly formatted shape data.

* Code review tweaks

* Update screenshots

---------

Co-authored-by: Garrett Johnson <garrett.kjohnson@gmail.com>
Micah LaSala 9 ماه پیش
والد
کامیت
16dae58588

BIN
examples/screenshots/webgl_custom_attributes_lines.jpg


BIN
examples/screenshots/webgl_modifier_tessellation.jpg


+ 55 - 6
src/geometries/ExtrudeGeometry.js

@@ -162,14 +162,53 @@ class ExtrudeGeometry extends BufferGeometry {
 
 			}
 
+			/**Merges index-adjacent points that are within a threshold distance of each other. Array is modified in-place. Threshold distance is empirical, and scaled based on the magnitude of point coordinates.
+			 * @param {Array<Vector2>} points
+			*/
+			function mergeOverlappingPoints( points ) {
+
+				const THRESHOLD = 1e-10;
+				const THRESHOLD_SQ = THRESHOLD * THRESHOLD;
+				let prevPos = points[ 0 ];
+				for ( let i = 1; i <= points.length; i ++ ) {
+
+					const currentIndex = i % points.length;
+					const currentPos = points[ currentIndex ];
+					const dx = currentPos.x - prevPos.x;
+					const dy = currentPos.y - prevPos.y;
+					const distSq = dx * dx + dy * dy;
+
+					const scalingFactorSqrt = Math.max(
+						Math.abs( currentPos.x ),
+						Math.abs( currentPos.y ),
+						Math.abs( prevPos.x ),
+						Math.abs( prevPos.y )
+					);
+					const thesholdSqScaled = THRESHOLD_SQ * scalingFactorSqrt * scalingFactorSqrt;
+					if ( distSq <= thesholdSqScaled ) {
+
+						points.splice( currentIndex, 1 );
+						i --;
+						continue;
 
-			const faces = ShapeUtils.triangulateShape( vertices, holes );
+					}
+
+					prevPos = currentPos;
+
+				}
+
+			}
+
+			mergeOverlappingPoints( vertices );
+			holes.forEach( mergeOverlappingPoints );
+
+			const numHoles = holes.length;
 
 			/* Vertices */
 
 			const contour = vertices; // vertices has all points but contour has only points of circumference
 
-			for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
+			for ( let h = 0; h < numHoles; h ++ ) {
 
 				const ahole = holes[ h ];
 
@@ -186,7 +225,7 @@ class ExtrudeGeometry extends BufferGeometry {
 
 			}
 
-			const vlen = vertices.length, flen = faces.length;
+			const vlen = vertices.length;
 
 
 			// Find directions for point movement
@@ -333,7 +372,7 @@ class ExtrudeGeometry extends BufferGeometry {
 			const holesMovements = [];
 			let oneHoleMovements, verticesMovements = contourMovements.concat();
 
-			for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
+			for ( let h = 0, hl = numHoles; h < hl; h ++ ) {
 
 				const ahole = holes[ h ];
 
@@ -354,6 +393,8 @@ class ExtrudeGeometry extends BufferGeometry {
 
 			}
 
+			const contractedContourVertices = [];
+			const expandedHoleVertices = [];
 
 			// Loop bevelSegments, 1 for the front, 1 for the back
 
@@ -372,28 +413,36 @@ class ExtrudeGeometry extends BufferGeometry {
 					const vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
 
 					v( vert.x, vert.y, - z );
+					if ( t == 0 ) contractedContourVertices.push( vert );
 
 				}
 
 				// expand holes
 
-				for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
+				for ( let h = 0, hl = numHoles; h < hl; h ++ ) {
 
 					const ahole = holes[ h ];
 					oneHoleMovements = holesMovements[ h ];
-
+					const oneHoleVertices = [];
 					for ( let i = 0, il = ahole.length; i < il; i ++ ) {
 
 						const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
 
 						v( vert.x, vert.y, - z );
+						if ( t == 0 ) oneHoleVertices.push( vert );
 
 					}
 
+					if ( t == 0 ) expandedHoleVertices.push( oneHoleVertices );
+
 				}
 
 			}
 
+			const faces = ShapeUtils.triangulateShape( contractedContourVertices, expandedHoleVertices );
+
+			const flen = faces.length;
+
 			const bs = bevelSize + bevelOffset;
 
 			// Back facing vertices

粤ICP备19079148号