2
0
Эх сурвалжийг харах

Merge pull request #6449 from dubejf/patch-1

Resize coordinates array in EdgesGeometry
Ricardo Cabello 10 жил өмнө
parent
commit
afc4f5908d

+ 8 - 12
src/extras/geometries/EdgesGeometry.js

@@ -33,7 +33,6 @@ THREE.EdgesGeometry = function ( geometry, thresholdAngle ) {
 
 	var vertices = geometry2.vertices;
 	var faces = geometry2.faces;
-	var numEdges = 0;
 
 	for ( var i = 0, l = faces.length; i < l; i ++ ) {
 
@@ -50,7 +49,6 @@ THREE.EdgesGeometry = function ( geometry, thresholdAngle ) {
 			if ( hash[ key ] === undefined ) {
 
 				hash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };
-				numEdges ++;
 
 			} else {
 
@@ -62,9 +60,7 @@ THREE.EdgesGeometry = function ( geometry, thresholdAngle ) {
 
 	}
 
-	var coords = new Float32Array( numEdges * 2 * 3 );
-
-	var index = 0;
+	var coords = [];
 
 	for ( var key in hash ) {
 
@@ -73,20 +69,20 @@ THREE.EdgesGeometry = function ( geometry, thresholdAngle ) {
 		if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {
 
 			var vertex = vertices[ h.vert1 ];
-			coords[ index ++ ] = vertex.x;
-			coords[ index ++ ] = vertex.y;
-			coords[ index ++ ] = vertex.z;
+			coords.push( vertex.x );
+			coords.push( vertex.y );
+			coords.push( vertex.z );
 
 			vertex = vertices[ h.vert2 ];
-			coords[ index ++ ] = vertex.x;
-			coords[ index ++ ] = vertex.y;
-			coords[ index ++ ] = vertex.z;
+			coords.push( vertex.x );
+			coords.push( vertex.y );
+			coords.push( vertex.z );
 
 		}
 
 	}
 
-	this.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( coords ), 3 ) );
 
 };
 

+ 273 - 0
test/unit/geometry/EdgesGeometry.js

@@ -0,0 +1,273 @@
+module( "EdgesGeometry" );
+
+var DEBUG = false;
+
+var vertList = [
+	new THREE.Vector3(0, 0, 0), 
+	new THREE.Vector3(1, 0, 0),
+	new THREE.Vector3(1, 1, 0),
+	new THREE.Vector3(0, 1, 0),
+	new THREE.Vector3(1, 1, 1),
+];
+
+test( "singularity", function() {
+	
+	testEdges( vertList, [1, 1, 1], 0 );
+	
+});
+
+test( "needle", function() {
+	
+	testEdges( vertList, [0, 0, 1], 0 );
+	
+});
+
+test( "single triangle", function() {
+	
+	testEdges( vertList, [0, 1, 2], 3 );
+	
+});
+
+test( "two isolated triangles", function() {
+	
+	var vertList = [
+		new THREE.Vector3(0, 0, 0), 
+		new THREE.Vector3(1, 0, 0),
+		new THREE.Vector3(1, 1, 0),
+		new THREE.Vector3(0, 0, 1), 
+		new THREE.Vector3(1, 0, 1),
+		new THREE.Vector3(1, 1, 1),
+	];
+	
+	testEdges( vertList, [0, 1, 2, 3, 4, 5], 6 );
+	
+});
+
+test( "two flat triangles", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 2, 3], 4 );
+	
+});
+
+test( "two flat triangles, inverted", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 3, 2], 5 );
+	
+});
+
+test( "two non-coplanar triangles", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 4, 2], 5 );
+	
+});
+
+test( "three triangles, coplanar first", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 2, 3, 0, 4, 2], 7 );
+	
+});
+
+test( "three triangles, coplanar last", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 4, 2, 0, 2, 3], 6 ); // Should be 7
+	
+});
+
+test( "tetrahedron", function() {
+	
+	testEdges( vertList, [0, 1, 2, 0, 1, 4, 0, 4, 2, 1, 2, 4], 6 );
+	
+});
+
+
+
+//
+// HELPERS
+//
+
+function testEdges ( vertList, idxList, numAfter ) {
+	
+	var geoms = createGeometries ( vertList, idxList );
+
+	for ( var i = 0 ; i < geoms.length ; i ++ ) {
+	
+		var geom = geoms[i];
+		console.log(geom);
+		var numBefore = idxList.length;
+		equal( countEdges (geom), numBefore, "Edges before!" );
+	
+		var egeom = new THREE.EdgesGeometry ( geom );;
+	
+		equal( countEdges (egeom), numAfter, "Edges after!" );
+		output( geom, egeom );
+		
+	}
+	
+}
+
+function createGeometries ( vertList, idxList ) {
+	
+	var geomIB = createIndexedBufferGeometry ( vertList, idxList );
+	var geom = new THREE.Geometry().fromBufferGeometry( geomIB );
+	var geomB = new THREE.BufferGeometry().fromGeometry( geom );
+	var geomDC = addDrawCalls( geomIB.clone() );
+	return [ geom, geomB, geomIB, geomDC ];
+	
+}
+
+function createIndexedBufferGeometry ( vertList, idxList ) {
+	
+	var geom = new THREE.BufferGeometry();
+	
+	var indexTable = [];	
+	var numTris = idxList.length / 3;
+	var numVerts = 0;
+
+	var indices = new Uint32Array( numTris * 3 );
+	var vertices = new Float32Array( vertList.length * 3 );
+	
+	for ( var i = 0; i < numTris; i ++ ) {
+
+		for ( var j = 0; j < 3; j ++ ) {
+			
+			var idx = idxList[ 3 * i + j ];
+			if ( indexTable[ idx ] === undefined ) {
+				
+				var v = vertList[ idx ];
+				vertices[ 3 * numVerts ] = v.x;
+				vertices[ 3 * numVerts + 1 ] = v.y;
+				vertices[ 3 * numVerts + 2 ] = v.z;
+				
+				indexTable[ idx ] = numVerts;
+				
+				numVerts ++;
+				
+			}
+			
+			indices[ 3 * i + j ] = indexTable[ idx ] ;
+			
+		}
+		
+	}
+	
+	vertices = vertices.subarray( 0, 3 * numVerts );
+	
+	geom.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+	geom.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+		
+	geom.computeFaceNormals();
+	
+	return geom;
+	
+}
+
+function addDrawCalls ( geometry ) {
+	
+	var numTris = geometry.getAttribute( 'index' ).length / 3;
+	
+	var offset = 0;
+	for ( var i = 0 ; i < numTris; i ++ ) {
+
+		var start = i * 3;
+		var count = 3;
+	
+		geometry.addDrawCall ( start, count, offset );
+	
+	}
+	
+	return geometry;
+	
+}
+
+function countEdges ( geom ) {
+	
+	if ( geom instanceof THREE.EdgesGeometry ) {
+		
+		return geom.getAttribute( 'position' ).length / ( 3 * 2 );
+		
+	}
+	
+	if ( geom.faces !== undefined ) {
+		
+		return geom.faces.length * 3;
+		
+	}
+		
+	var indices = geom.getAttribute( 'index' );
+	if ( indices !== undefined ) {
+		
+		return indices.length;
+		 
+	}
+		
+	return geom.getAttribute( 'position' ).length / 3;
+	
+}
+
+//
+// DEBUGGING
+//
+
+var renderer;
+var camera;
+var scene = new THREE.Scene();
+var xoffset = 0;
+
+function output ( geom, egeom ) {
+	
+	if ( DEBUG !== true ) return;
+	
+	if ( !renderer ) initDebug();
+	
+	var mesh = new THREE.Mesh( geom, undefined );
+	var edges = new THREE.Line( egeom, new THREE.LineBasicMaterial( { color: 'black' }), THREE.LinePieces );
+
+	mesh.position.setX( xoffset );
+	edges.position.setX( xoffset ++ );
+	scene.add(mesh);
+	scene.add(edges);
+	
+	if (scene.children.length % 8 === 0) {
+		xoffset += 2;
+	}
+	
+}
+
+function initDebug () {
+
+	renderer = new THREE.WebGLRenderer({
+
+		antialias: true
+		
+	});
+	
+	var width = 600;
+	var height = 480;
+	
+	renderer.setSize(width, height);
+	renderer.setClearColor( 0xCCCCCC );
+
+	camera = new THREE.PerspectiveCamera(45, width / height, 1, 100);
+	camera.position.x = 30;
+	camera.position.z = 40;
+	camera.lookAt(new THREE.Vector3(30, 0, 0));
+	
+	document.body.appendChild(renderer.domElement);
+
+	var controls = new THREE.OrbitControls( camera, renderer.domElement );
+	controls.target = new THREE.Vector3(30, 0, 0);
+	
+	animate();
+
+	function animate() {
+
+		requestAnimationFrame( animate );
+
+		controls.update();
+		
+		renderer.render( scene, camera );
+
+	}
+	
+}
+

+ 5 - 0
test/unit/unittests_three.html

@@ -32,5 +32,10 @@
   <script src="math/Matrix3.js"></script>
   <script src="math/Matrix4.js"></script>
   <script src="math/Frustum.js"></script>
+  
+  <script src="geometry/EdgesGeometry.js"></script>
+   
+  <!-- for debug output -->
+  <script src="../../examples/js/controls/OrbitControls.js"></script>
 </body>
 </html>