123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- import { Vector3 } from 'three';
- /**
- * Usage:
- * const exporter = new STLExporter();
- *
- * // second argument is a list of options
- * const data = exporter.parse( mesh, { binary: true } );
- *
- */
- class STLExporter {
- parse( scene, options = {} ) {
- const binary = options.binary !== undefined ? options.binary : false;
- //
- const objects = [];
- let triangles = 0;
- scene.traverse( function ( object ) {
- if ( object.isMesh ) {
- const geometry = object.geometry;
- const index = geometry.index;
- const positionAttribute = geometry.getAttribute( 'position' );
- triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
- objects.push( {
- object3d: object,
- geometry: geometry
- } );
- }
- } );
- let output;
- let offset = 80; // skip header
- if ( binary === true ) {
- const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
- const arrayBuffer = new ArrayBuffer( bufferLength );
- output = new DataView( arrayBuffer );
- output.setUint32( offset, triangles, true ); offset += 4;
- } else {
- output = '';
- output += 'solid exported\n';
- }
- const vA = new Vector3();
- const vB = new Vector3();
- const vC = new Vector3();
- const cb = new Vector3();
- const ab = new Vector3();
- const normal = new Vector3();
- for ( let i = 0, il = objects.length; i < il; i ++ ) {
- const object = objects[ i ].object3d;
- const geometry = objects[ i ].geometry;
- const index = geometry.index;
- const positionAttribute = geometry.getAttribute( 'position' );
- if ( index !== null ) {
- // indexed geometry
- for ( let j = 0; j < index.count; j += 3 ) {
- const a = index.getX( j + 0 );
- const b = index.getX( j + 1 );
- const c = index.getX( j + 2 );
- writeFace( a, b, c, positionAttribute, object );
- }
- } else {
- // non-indexed geometry
- for ( let j = 0; j < positionAttribute.count; j += 3 ) {
- const a = j + 0;
- const b = j + 1;
- const c = j + 2;
- writeFace( a, b, c, positionAttribute, object );
- }
- }
- }
- if ( binary === false ) {
- output += 'endsolid exported\n';
- }
- return output;
- function writeFace( a, b, c, positionAttribute, object ) {
- vA.fromBufferAttribute( positionAttribute, a );
- vB.fromBufferAttribute( positionAttribute, b );
- vC.fromBufferAttribute( positionAttribute, c );
- if ( object.isSkinnedMesh === true ) {
- object.boneTransform( a, vA );
- object.boneTransform( b, vB );
- object.boneTransform( c, vC );
- }
- vA.applyMatrix4( object.matrixWorld );
- vB.applyMatrix4( object.matrixWorld );
- vC.applyMatrix4( object.matrixWorld );
- writeNormal( vA, vB, vC );
- writeVertex( vA );
- writeVertex( vB );
- writeVertex( vC );
- if ( binary === true ) {
- output.setUint16( offset, 0, true ); offset += 2;
- } else {
- output += '\t\tendloop\n';
- output += '\tendfacet\n';
- }
- }
- function writeNormal( vA, vB, vC ) {
- cb.subVectors( vC, vB );
- ab.subVectors( vA, vB );
- cb.cross( ab ).normalize();
- 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 {
- output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
- }
- }
- }
- }
- export { STLExporter };
|