Przeglądaj źródła

Merge pull request #20494 from Mugen87/dev51

STLExporter: Use BufferGeometry, supported skeletons.
Mr.doob 4 lat temu
rodzic
commit
77240ec9dc
2 zmienionych plików z 245 dodań i 162 usunięć
  1. 122 80
      examples/js/exporters/STLExporter.js
  2. 123 82
      examples/jsm/exporters/STLExporter.js

+ 122 - 80
examples/js/exporters/STLExporter.js

@@ -14,149 +14,191 @@ THREE.STLExporter.prototype = {
 
 	constructor: THREE.STLExporter,
 
-	parse: ( function () {
+	parse: function ( scene, options ) {
 
-		var vector = new THREE.Vector3();
-		var normalMatrixWorld = new THREE.Matrix3();
+		if ( options === undefined ) options = {};
 
-		return function parse( scene, options ) {
+		var binary = options.binary !== undefined ? options.binary : false;
 
-			if ( options === undefined ) options = {};
+		//
 
-			var binary = options.binary !== undefined ? options.binary : false;
+		var objects = [];
+		var triangles = 0;
 
-			//
+		scene.traverse( function ( object ) {
 
-			var objects = [];
-			var triangles = 0;
+			if ( object.isMesh ) {
 
-			scene.traverse( function ( object ) {
+				var geometry = object.geometry;
 
-				if ( object.isMesh ) {
+				if ( geometry.isGeometry ) {
 
-					var geometry = object.geometry;
+					geometry = new THREE.BufferGeometry().fromGeometry( geometry );
 
-					if ( geometry.isBufferGeometry ) {
-
-						geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+				}
 
-					}
+				var index = geometry.index;
+				var positionAttribute = geometry.getAttribute( 'position' );
 
-					if ( geometry.isGeometry ) {
+				triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
 
-						triangles += geometry.faces.length;
+				objects.push( {
+					object3d: object,
+					geometry: geometry
+				} );
 
-						objects.push( {
+			}
 
-							geometry: geometry,
-							matrixWorld: object.matrixWorld
+		} );
 
-						} );
+		var output;
+		var offset = 80; // skip header
 
-					}
+		if ( binary === true ) {
 
-				}
+			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
+			var arrayBuffer = new ArrayBuffer( bufferLength );
+			output = new DataView( arrayBuffer );
+			output.setUint32( offset, triangles, true ); offset += 4;
 
-			} );
+		} else {
 
-			if ( binary ) {
+			output = '';
+			output += 'solid exported\n';
 
-				var offset = 80; // skip header
-				var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-				var arrayBuffer = new ArrayBuffer( bufferLength );
-				var output = new DataView( arrayBuffer );
-				output.setUint32( offset, triangles, true ); offset += 4;
+		}
 
-				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+		var vA = new THREE.Vector3();
+		var vB = new THREE.Vector3();
+		var vC = new THREE.Vector3();
+		var cb = new THREE.Vector3();
+		var ab = new THREE.Vector3();
+		var normal = new THREE.Vector3();
 
-					var object = objects[ i ];
+		for ( var i = 0, il = objects.length; i < il; i ++ ) {
 
-					var vertices = object.geometry.vertices;
-					var faces = object.geometry.faces;
-					var matrixWorld = object.matrixWorld;
+			var object = objects[ i ].object3d;
+			var geometry = objects[ i ].geometry;
 
-					normalMatrixWorld.getNormalMatrix( matrixWorld );
+			var index = geometry.index;
+			var positionAttribute = geometry.getAttribute( 'position' );
 
-					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+			if ( index !== null ) {
 
-						var face = faces[ j ];
+				// indexed geometry
 
-						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+				for ( var j = 0; j < index.count; j += 3 ) {
 
-						output.setFloat32( offset, vector.x, true ); offset += 4; // normal
-						output.setFloat32( offset, vector.y, true ); offset += 4;
-						output.setFloat32( offset, vector.z, true ); offset += 4;
+					var a = index.getX( j + 0 );
+					var b = index.getX( j + 1 );
+					var c = index.getX( j + 2 );
 
-						var indices = [ face.a, face.b, face.c ];
+					writeFace( a, b, c, positionAttribute, object );
 
-						for ( var k = 0; k < 3; k ++ ) {
+				}
 
-							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+			} else {
 
-							output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
-							output.setFloat32( offset, vector.y, true ); offset += 4;
-							output.setFloat32( offset, vector.z, true ); offset += 4;
+				// non-indexed geometry
 
-						}
+				for ( var j = 0; j < positionAttribute.count; j += 3 ) {
 
-						output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
+					var a = j + 0;
+					var b = j + 1;
+					var c = j + 2;
 
-					}
+					writeFace( a, b, c, positionAttribute, object );
 
 				}
 
-				return output;
+			}
+
+		}
 
-			} else {
+		if ( binary === false ) {
 
-				var output = '';
+			output += 'endsolid exported\n';
 
-				output += 'solid exported\n';
+		}
 
-				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+		return output;
 
-					var object = objects[ i ];
+		function writeFace( a, b, c, positionAttribute, object ) {
 
-					var vertices = object.geometry.vertices;
-					var faces = object.geometry.faces;
-					var matrixWorld = object.matrixWorld;
+			vA.fromBufferAttribute( positionAttribute, a );
+			vB.fromBufferAttribute( positionAttribute, b );
+			vC.fromBufferAttribute( positionAttribute, c );
 
-					normalMatrixWorld.getNormalMatrix( matrixWorld );
+			if ( object.isSkinnedMesh === true ) {
 
-					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+				object.boneTransform( a, vA );
+				object.boneTransform( b, vB );
+				object.boneTransform( c, vC );
 
-						var face = faces[ j ];
+			}
 
-						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+			vA.applyMatrix4( object.matrixWorld );
+			vB.applyMatrix4( object.matrixWorld );
+			vC.applyMatrix4( object.matrixWorld );
 
-						output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
-						output += '\t\touter loop\n';
+			writeNormal( vA, vB, vC );
 
-						var indices = [ face.a, face.b, face.c ];
+			writeVertex( vA );
+			writeVertex( vB );
+			writeVertex( vC );
 
-						for ( var k = 0; k < 3; k ++ ) {
+			if ( binary === true ) {
 
-							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+				output.setUint16( offset, 0, true ); offset += 2;
 
-							output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+			} else {
 
-						}
+				output += '\t\tendloop\n';
+				output += '\tendfacet\n';
 
-						output += '\t\tendloop\n';
-						output += '\tendfacet\n';
+			}
 
-					}
+		}
 
-				}
+		function writeNormal( vA, vB, vC ) {
+
+			cb.subVectors( vC, vB );
+			ab.subVectors( vA, vB );
+			cb.cross( ab ).normalize();
 
-				output += 'endsolid exported\n';
+			normal.copy( cb ).normalize();
+
+			if ( binary === true ) {
+
+				output.setFloat32( offset, normal.x, true ); offset += 4;
+				output.setFloat32( offset, normal.y, true ); offset += 4;
+				output.setFloat32( offset, normal.z, true ); offset += 4;
+
+			} else {
+
+				output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
+				output += '\t\touter loop\n';
+
+			}
+
+		}
+
+		function writeVertex( vertex ) {
+
+			if ( binary === true ) {
+
+				output.setFloat32( offset, vertex.x, true ); offset += 4;
+				output.setFloat32( offset, vertex.y, true ); offset += 4;
+				output.setFloat32( offset, vertex.z, true ); offset += 4;
+
+			} else {
 
-				return output;
+				output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 
 			}
 
-		};
+		}
 
-	}() )
+	}
 
 };

+ 123 - 82
examples/jsm/exporters/STLExporter.js

@@ -1,6 +1,5 @@
 import {
-	Geometry,
-	Matrix3,
+	BufferGeometry,
 	Vector3
 } from "../../../build/three.module.js";
 /**
@@ -18,150 +17,192 @@ STLExporter.prototype = {
 
 	constructor: STLExporter,
 
-	parse: ( function () {
+	parse: function ( scene, options ) {
 
-		var vector = new Vector3();
-		var normalMatrixWorld = new Matrix3();
+		if ( options === undefined ) options = {};
 
-		return function parse( scene, options ) {
+		var binary = options.binary !== undefined ? options.binary : false;
 
-			if ( options === undefined ) options = {};
+		//
 
-			var binary = options.binary !== undefined ? options.binary : false;
+		var objects = [];
+		var triangles = 0;
 
-			//
+		scene.traverse( function ( object ) {
 
-			var objects = [];
-			var triangles = 0;
+			if ( object.isMesh ) {
 
-			scene.traverse( function ( object ) {
+				var geometry = object.geometry;
 
-				if ( object.isMesh ) {
+				if ( geometry.isGeometry ) {
 
-					var geometry = object.geometry;
+					geometry = new BufferGeometry().fromGeometry( geometry );
 
-					if ( geometry.isBufferGeometry ) {
-
-						geometry = new Geometry().fromBufferGeometry( geometry );
+				}
 
-					}
+				var index = geometry.index;
+				var positionAttribute = geometry.getAttribute( 'position' );
 
-					if ( geometry.isGeometry ) {
+				triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
 
-						triangles += geometry.faces.length;
+				objects.push( {
+					object3d: object,
+					geometry: geometry
+				} );
 
-						objects.push( {
+			}
 
-							geometry: geometry,
-							matrixWorld: object.matrixWorld
+		} );
 
-						} );
+		var output;
+		var offset = 80; // skip header
 
-					}
+		if ( binary === true ) {
 
-				}
+			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
+			var arrayBuffer = new ArrayBuffer( bufferLength );
+			output = new DataView( arrayBuffer );
+			output.setUint32( offset, triangles, true ); offset += 4;
 
-			} );
+		} else {
 
-			if ( binary ) {
+			output = '';
+			output += 'solid exported\n';
 
-				var offset = 80; // skip header
-				var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-				var arrayBuffer = new ArrayBuffer( bufferLength );
-				var output = new DataView( arrayBuffer );
-				output.setUint32( offset, triangles, true ); offset += 4;
+		}
 
-				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+		var vA = new Vector3();
+		var vB = new Vector3();
+		var vC = new Vector3();
+		var cb = new Vector3();
+		var ab = new Vector3();
+		var normal = new Vector3();
 
-					var object = objects[ i ];
+		for ( var i = 0, il = objects.length; i < il; i ++ ) {
 
-					var vertices = object.geometry.vertices;
-					var faces = object.geometry.faces;
-					var matrixWorld = object.matrixWorld;
+			var object = objects[ i ].object3d;
+			var geometry = objects[ i ].geometry;
 
-					normalMatrixWorld.getNormalMatrix( matrixWorld );
+			var index = geometry.index;
+			var positionAttribute = geometry.getAttribute( 'position' );
 
-					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+			if ( index !== null ) {
 
-						var face = faces[ j ];
+				// indexed geometry
 
-						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+				for ( var j = 0; j < index.count; j += 3 ) {
 
-						output.setFloat32( offset, vector.x, true ); offset += 4; // normal
-						output.setFloat32( offset, vector.y, true ); offset += 4;
-						output.setFloat32( offset, vector.z, true ); offset += 4;
+					var a = index.getX( j + 0 );
+					var b = index.getX( j + 1 );
+					var c = index.getX( j + 2 );
 
-						var indices = [ face.a, face.b, face.c ];
+					writeFace( a, b, c, positionAttribute, object );
 
-						for ( var k = 0; k < 3; k ++ ) {
+				}
 
-							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+			} else {
 
-							output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
-							output.setFloat32( offset, vector.y, true ); offset += 4;
-							output.setFloat32( offset, vector.z, true ); offset += 4;
+				// non-indexed geometry
 
-						}
+				for ( var j = 0; j < positionAttribute.count; j += 3 ) {
 
-						output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
+					var a = j + 0;
+					var b = j + 1;
+					var c = j + 2;
 
-					}
+					writeFace( a, b, c, positionAttribute, object );
 
 				}
 
-				return output;
+			}
+
+		}
 
-			} else {
+		if ( binary === false ) {
 
-				var output = '';
+			output += 'endsolid exported\n';
 
-				output += 'solid exported\n';
+		}
 
-				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+		return output;
 
-					var object = objects[ i ];
+		function writeFace( a, b, c, positionAttribute, object ) {
 
-					var vertices = object.geometry.vertices;
-					var faces = object.geometry.faces;
-					var matrixWorld = object.matrixWorld;
+			vA.fromBufferAttribute( positionAttribute, a );
+			vB.fromBufferAttribute( positionAttribute, b );
+			vC.fromBufferAttribute( positionAttribute, c );
 
-					normalMatrixWorld.getNormalMatrix( matrixWorld );
+			if ( object.isSkinnedMesh === true ) {
 
-					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+				object.boneTransform( a, vA );
+				object.boneTransform( b, vB );
+				object.boneTransform( c, vC );
 
-						var face = faces[ j ];
+			}
 
-						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+			vA.applyMatrix4( object.matrixWorld );
+			vB.applyMatrix4( object.matrixWorld );
+			vC.applyMatrix4( object.matrixWorld );
 
-						output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
-						output += '\t\touter loop\n';
+			writeNormal( vA, vB, vC );
 
-						var indices = [ face.a, face.b, face.c ];
+			writeVertex( vA );
+			writeVertex( vB );
+			writeVertex( vC );
 
-						for ( var k = 0; k < 3; k ++ ) {
+			if ( binary === true ) {
 
-							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+				output.setUint16( offset, 0, true ); offset += 2;
 
-							output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+			} else {
 
-						}
+				output += '\t\tendloop\n';
+				output += '\tendfacet\n';
 
-						output += '\t\tendloop\n';
-						output += '\tendfacet\n';
+			}
 
-					}
+		}
 
-				}
+		function writeNormal( vA, vB, vC ) {
+
+			cb.subVectors( vC, vB );
+			ab.subVectors( vA, vB );
+			cb.cross( ab ).normalize();
 
-				output += 'endsolid exported\n';
+			normal.copy( cb ).normalize();
+
+			if ( binary === true ) {
+
+				output.setFloat32( offset, normal.x, true ); offset += 4;
+				output.setFloat32( offset, normal.y, true ); offset += 4;
+				output.setFloat32( offset, normal.z, true ); offset += 4;
+
+			} else {
+
+				output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
+				output += '\t\touter loop\n';
+
+			}
+
+		}
+
+		function writeVertex( vertex ) {
+
+			if ( binary === true ) {
+
+				output.setFloat32( offset, vertex.x, true ); offset += 4;
+				output.setFloat32( offset, vertex.y, true ); offset += 4;
+				output.setFloat32( offset, vertex.z, true ); offset += 4;
+
+			} else {
 
-				return output;
+				output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 
 			}
 
-		};
+		}
 
-	}() )
+	}
 
 };