Browse Source

Support for export to binary STL.

Binary STL shaves file size down quite a bit, for example a recent random file went from 2.2mb to 714kb. For more savings, ZIP on the binary STL shaves an addition 1/3, which takes the same file down to 270k. Use ZIP.js, JSZip or another option to handle this last step.
Michael Deal 11 years ago
parent
commit
e1d0713bfd
1 changed files with 61 additions and 25 deletions
  1. 61 25
      examples/js/exporters/STLExporter.js

+ 61 - 25
examples/js/exporters/STLExporter.js

@@ -1,6 +1,7 @@
 /**
  * @author kovacsv / http://kovacsv.hu/
  * @author mrdoob / http://mrdoob.com/
+ * @author mudcube / http://mudcu.be/
  */
  
 THREE.STLExporter = function () {};
@@ -14,57 +15,92 @@ THREE.STLExporter.prototype = {
 		var vector = new THREE.Vector3();
 		var normalMatrixWorld = new THREE.Matrix3();
 
-		return function ( scene ) {
+		return function ( scene, encodeBinary ) {
 
-			var output = '';
+			if ( encodeBinary ) {
+				var triangles = 0;
+				scene.traverse( function ( object ) {
+					if ( !(object instanceof THREE.Mesh) ) return;
+					triangles += object.geometry.faces.length;
+				});
 
-			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;
+			} else {
+				var output = 'solid exported\n';
+			}
 
 			scene.traverse( function ( object ) {
 
-				if ( object instanceof THREE.Mesh ) {
+				if ( !(object instanceof THREE.Mesh) ) return;
+				if ( !(object.geometry instanceof THREE.Geometry )) return;
 
-					var geometry = object.geometry;
-					var matrixWorld = object.matrixWorld;
+				var geometry = object.geometry;
+				var matrixWorld = object.matrixWorld;
 
-					if ( geometry instanceof THREE.Geometry ) {
+				var vertices = geometry.vertices;
+				var faces = geometry.faces;
 
-						var vertices = geometry.vertices;
-						var faces = geometry.faces;
+				normalMatrixWorld.getNormalMatrix( matrixWorld );
 
-						normalMatrixWorld.getNormalMatrix( matrixWorld );
+				for ( var i = 0, l = faces.length; i < l; i ++ ) {
 
-						for ( var i = 0, l = faces.length; i < l; i ++ ) {
+					var face = faces[ i ];
 
-							var face = faces[ i ];
+					vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
 
-							vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+					if ( encodeBinary ) {
 
-							output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
-							output += '\t\touter loop\n';
+						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 indices = [ face.a, face.b, face.c ];
+					} else {
 
-							for ( var j = 0; j < 3; j ++ ) {
+						output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+						output += '\t\touter loop\n';
 
-								vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+					}
 
-								output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+					var indices = [ face.a, face.b, face.c ];
 
-							}
+					for ( var j = 0; j < 3; j ++ ) {
 
-							output += '\t\tendloop\n';
-							output += '\tendfacet\n';
+						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
 
-						}
+						if ( encodeBinary ) {
+
+							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;
 
+						} else {
+
+							output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+
+						}
 					}
 
+					if ( encodeBinary ) {
+
+						output.setUint16(offset, 0, true); offset += 2; // attribute byte count					
+
+					} else {
+
+						output += '\t\tendloop\n';
+						output += '\tendfacet\n';
+
+					}
 				}
 
 			} );
-
-			output += 'endsolid exported\n';
+			
+			if ( !encodeBinary ) {
+				output += 'endsolid exported\n';
+			}
 
 			return output;