| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 | import {	Vector3} from '../../../build/three.module.js';/** * 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;				if ( geometry.isBufferGeometry !== true ) {					throw new Error( 'THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.' );				}				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 };
 |