@@ -14,149 +14,191 @@ THREE.STLExporter.prototype = {
1414
1515 constructor : THREE . STLExporter ,
1616
17- parse : ( function ( ) {
17+ parse : function ( scene , options ) {
1818
19- var vector = new THREE . Vector3 ( ) ;
20- var normalMatrixWorld = new THREE . Matrix3 ( ) ;
19+ if ( options === undefined ) options = { } ;
2120
22- return function parse ( scene , options ) {
21+ var binary = options . binary !== undefined ? options . binary : false ;
2322
24- if ( options === undefined ) options = { } ;
23+ //
2524
26- var binary = options . binary !== undefined ? options . binary : false ;
25+ var objects = [ ] ;
26+ var triangles = 0 ;
2727
28- //
28+ scene . traverse ( function ( object ) {
2929
30- var objects = [ ] ;
31- var triangles = 0 ;
30+ if ( object . isMesh ) {
3231
33- scene . traverse ( function ( object ) {
32+ var geometry = object . geometry ;
3433
35- if ( object . isMesh ) {
34+ if ( geometry . isGeometry ) {
3635
37- var geometry = object . geometry ;
36+ geometry = new THREE . BufferGeometry ( ) . fromGeometry ( geometry ) ;
3837
39- if ( geometry . isBufferGeometry ) {
40-
41- geometry = new THREE . Geometry ( ) . fromBufferGeometry ( geometry ) ;
38+ }
4239
43- }
40+ var index = geometry . index ;
41+ var positionAttribute = geometry . getAttribute ( 'position' ) ;
4442
45- if ( geometry . isGeometry ) {
43+ triangles += ( index !== null ) ? ( index . count / 3 ) : ( positionAttribute . count / 3 ) ;
4644
47- triangles += geometry . faces . length ;
45+ objects . push ( {
46+ object3d : object ,
47+ geometry : geometry
48+ } ) ;
4849
49- objects . push ( {
50+ }
5051
51- geometry : geometry ,
52- matrixWorld : object . matrixWorld
52+ } ) ;
5353
54- } ) ;
54+ var output ;
55+ var offset = 80 ; // skip header
5556
56- }
57+ if ( binary === true ) {
5758
58- }
59+ var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4 ;
60+ var arrayBuffer = new ArrayBuffer ( bufferLength ) ;
61+ output = new DataView ( arrayBuffer ) ;
62+ output . setUint32 ( offset , triangles , true ) ; offset += 4 ;
5963
60- } ) ;
64+ } else {
6165
62- if ( binary ) {
66+ output = '' ;
67+ output += 'solid exported\n' ;
6368
64- var offset = 80 ; // skip header
65- var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4 ;
66- var arrayBuffer = new ArrayBuffer ( bufferLength ) ;
67- var output = new DataView ( arrayBuffer ) ;
68- output . setUint32 ( offset , triangles , true ) ; offset += 4 ;
69+ }
6970
70- for ( var i = 0 , il = objects . length ; i < il ; i ++ ) {
71+ var vA = new THREE . Vector3 ( ) ;
72+ var vB = new THREE . Vector3 ( ) ;
73+ var vC = new THREE . Vector3 ( ) ;
74+ var cb = new THREE . Vector3 ( ) ;
75+ var ab = new THREE . Vector3 ( ) ;
76+ var normal = new THREE . Vector3 ( ) ;
7177
72- var object = objects [ i ] ;
78+ for ( var i = 0 , il = objects . length ; i < il ; i ++ ) {
7379
74- var vertices = object . geometry . vertices ;
75- var faces = object . geometry . faces ;
76- var matrixWorld = object . matrixWorld ;
80+ var object = objects [ i ] . object3d ;
81+ var geometry = objects [ i ] . geometry ;
7782
78- normalMatrixWorld . getNormalMatrix ( matrixWorld ) ;
83+ var index = geometry . index ;
84+ var positionAttribute = geometry . getAttribute ( 'position' ) ;
7985
80- for ( var j = 0 , jl = faces . length ; j < jl ; j ++ ) {
86+ if ( index !== null ) {
8187
82- var face = faces [ j ] ;
88+ // indexed geometry
8389
84- vector . copy ( face . normal ) . applyMatrix3 ( normalMatrixWorld ) . normalize ( ) ;
90+ for ( var j = 0 ; j < index . count ; j += 3 ) {
8591
86- output . setFloat32 ( offset , vector . x , true ) ; offset += 4 ; // normal
87- output . setFloat32 ( offset , vector . y , true ) ; offset += 4 ;
88- output . setFloat32 ( offset , vector . z , true ) ; offset += 4 ;
92+ var a = index . getX ( j + 0 ) ;
93+ var b = index . getX ( j + 1 ) ;
94+ var c = index . getX ( j + 2 ) ;
8995
90- var indices = [ face . a , face . b , face . c ] ;
96+ writeFace ( a , b , c , positionAttribute , object ) ;
9197
92- for ( var k = 0 ; k < 3 ; k ++ ) {
98+ }
9399
94- vector . copy ( vertices [ indices [ k ] ] ) . applyMatrix4 ( matrixWorld ) ;
100+ } else {
95101
96- output . setFloat32 ( offset , vector . x , true ) ; offset += 4 ; // vertices
97- output . setFloat32 ( offset , vector . y , true ) ; offset += 4 ;
98- output . setFloat32 ( offset , vector . z , true ) ; offset += 4 ;
102+ // non-indexed geometry
99103
100- }
104+ for ( var j = 0 ; j < positionAttribute . count ; j += 3 ) {
101105
102- output . setUint16 ( offset , 0 , true ) ; offset += 2 ; // attribute byte count
106+ var a = j + 0 ;
107+ var b = j + 1 ;
108+ var c = j + 2 ;
103109
104- }
110+ writeFace ( a , b , c , positionAttribute , object ) ;
105111
106112 }
107113
108- return output ;
114+ }
115+
116+ }
109117
110- } else {
118+ if ( binary === false ) {
111119
112- var output = '' ;
120+ output + = 'endsolid exported\n ' ;
113121
114- output += 'solid exported\n' ;
122+ }
115123
116- for ( var i = 0 , il = objects . length ; i < il ; i ++ ) {
124+ return output ;
117125
118- var object = objects [ i ] ;
126+ function writeFace ( a , b , c , positionAttribute , object ) {
119127
120- var vertices = object . geometry . vertices ;
121- var faces = object . geometry . faces ;
122- var matrixWorld = object . matrixWorld ;
128+ vA . fromBufferAttribute ( positionAttribute , a ) ;
129+ vB . fromBufferAttribute ( positionAttribute , b ) ;
130+ vC . fromBufferAttribute ( positionAttribute , c ) ;
123131
124- normalMatrixWorld . getNormalMatrix ( matrixWorld ) ;
132+ if ( object . isSkinnedMesh === true ) {
125133
126- for ( var j = 0 , jl = faces . length ; j < jl ; j ++ ) {
134+ object . boneTransform ( a , vA ) ;
135+ object . boneTransform ( b , vB ) ;
136+ object . boneTransform ( c , vC ) ;
127137
128- var face = faces [ j ] ;
138+ }
129139
130- vector . copy ( face . normal ) . applyMatrix3 ( normalMatrixWorld ) . normalize ( ) ;
140+ vA . applyMatrix4 ( object . matrixWorld ) ;
141+ vB . applyMatrix4 ( object . matrixWorld ) ;
142+ vC . applyMatrix4 ( object . matrixWorld ) ;
131143
132- output += '\tfacet normal ' + vector . x + ' ' + vector . y + ' ' + vector . z + '\n' ;
133- output += '\t\touter loop\n' ;
144+ writeNormal ( vA , vB , vC ) ;
134145
135- var indices = [ face . a , face . b , face . c ] ;
146+ writeVertex ( vA ) ;
147+ writeVertex ( vB ) ;
148+ writeVertex ( vC ) ;
136149
137- for ( var k = 0 ; k < 3 ; k ++ ) {
150+ if ( binary === true ) {
138151
139- vector . copy ( vertices [ indices [ k ] ] ) . applyMatrix4 ( matrixWorld ) ;
152+ output . setUint16 ( offset , 0 , true ) ; offset += 2 ;
140153
141- output += '\t\t\tvertex ' + vector . x + ' ' + vector . y + ' ' + vector . z + '\n' ;
154+ } else {
142155
143- }
156+ output += '\t\tendloop\n' ;
157+ output += '\tendfacet\n' ;
144158
145- output += '\t\tendloop\n' ;
146- output += '\tendfacet\n' ;
159+ }
147160
148- }
161+ }
149162
150- }
163+ function writeNormal ( vA , vB , vC ) {
164+
165+ cb . subVectors ( vC , vB ) ;
166+ ab . subVectors ( vA , vB ) ;
167+ cb . cross ( ab ) . normalize ( ) ;
151168
152- output += 'endsolid exported\n' ;
169+ normal . copy ( cb ) . normalize ( ) ;
170+
171+ if ( binary === true ) {
172+
173+ output . setFloat32 ( offset , normal . x , true ) ; offset += 4 ;
174+ output . setFloat32 ( offset , normal . y , true ) ; offset += 4 ;
175+ output . setFloat32 ( offset , normal . z , true ) ; offset += 4 ;
176+
177+ } else {
178+
179+ output += '\tfacet normal ' + normal . x + ' ' + normal . y + ' ' + normal . z + '\n' ;
180+ output += '\t\touter loop\n' ;
181+
182+ }
183+
184+ }
185+
186+ function writeVertex ( vertex ) {
187+
188+ if ( binary === true ) {
189+
190+ output . setFloat32 ( offset , vertex . x , true ) ; offset += 4 ;
191+ output . setFloat32 ( offset , vertex . y , true ) ; offset += 4 ;
192+ output . setFloat32 ( offset , vertex . z , true ) ; offset += 4 ;
193+
194+ } else {
153195
154- return output ;
196+ output += '\t\t\tvertex ' + vertex . x + ' ' + vertex . y + ' ' + vertex . z + '\n' ;
155197
156198 }
157199
158- } ;
200+ }
159201
160- } ( ) )
202+ }
161203
162204} ;
0 commit comments