|
@@ -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';
|
|
|
|
|
|
}
|
|
|
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
- }() )
|
|
|
+ }
|
|
|
|
|
|
};
|
|
|
|