zincjs 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +27 -22
  2. package/build/zinc.js +2 -2
  3. package/build/zinc.js.map +1 -1
  4. package/package.json +4 -1
  5. package/src/controls.js +1332 -1241
  6. package/src/geometryCSG.js +111 -115
  7. package/src/glyphsetCSG.js +51 -55
  8. package/src/loaders/GLTFToZincJSLoader.js +31 -33
  9. package/src/loaders/JSONLoader.js +339 -449
  10. package/src/loaders/OBJLoader.js +654 -851
  11. package/src/loaders/STLLoader.js +271 -329
  12. package/src/loaders/niftiReader.js +90 -59
  13. package/src/loaders/primitivesLoader.js +55 -52
  14. package/src/minimap.js +63 -43
  15. package/src/primitives/geometry.js +40 -44
  16. package/src/primitives/glyph.js +16 -19
  17. package/src/primitives/glyphset.js +229 -185
  18. package/src/primitives/label.js +29 -31
  19. package/src/primitives/lines.js +20 -20
  20. package/src/primitives/lines2.js +33 -39
  21. package/src/primitives/lod.js +43 -43
  22. package/src/primitives/marker.js +31 -32
  23. package/src/primitives/markerCluster.js +32 -35
  24. package/src/primitives/pointset.js +86 -83
  25. package/src/primitives/texturePrimitive.js +9 -10
  26. package/src/primitives/textureSlides.js +84 -97
  27. package/src/primitives/textureVolume.js +46 -49
  28. package/src/primitives/tubeLines.js +108 -108
  29. package/src/primitives/zincObject.js +176 -184
  30. package/src/region.js +145 -155
  31. package/src/renderRequests.js +3 -3
  32. package/src/renderer.js +635 -620
  33. package/src/scene.js +479 -419
  34. package/src/sceneExporter.js +22 -17
  35. package/src/sceneLoader.js +542 -296
  36. package/src/shaders/rgbVolumeRender.js +11 -18
  37. package/src/shaders/textureArray.js +5 -12
  38. package/src/shaders/textureSlide.js +10 -17
  39. package/src/shaders/volumeRender.js +11 -18
  40. package/src/shaders/volumeRender_old.js +11 -18
  41. package/src/shaders/volumeTexture.js +7 -14
  42. package/src/textSprite.js +23 -19
  43. package/src/texture/texture.js +14 -15
  44. package/src/texture/textureArray.js +14 -16
  45. package/src/three/InstancedPoints.js +2 -9
  46. package/src/three/Loader.js +334 -315
  47. package/src/three/line/Line.js +165 -215
  48. package/src/three/line/LineSegments.js +40 -55
  49. package/src/three/line/LineSegments2.js +322 -366
  50. package/src/three/line/LineSegmentsGeometry.js +239 -280
  51. package/src/three-js-csg.js +260 -252
  52. package/src/tsl/glyphRenderMaterial.js +12 -3
  53. package/src/tsl/glyphTransform.js +51 -29
  54. package/src/tsl/textureSlides.js +23 -24
  55. package/src/utilities.js +309 -371
  56. package/src/videoHandler.js +76 -83
  57. package/src/workers/geometryCSG.worker.js +33 -36
  58. package/src/workers/geometryCSGInternal.js +39 -44
  59. package/src/zinc.js +4 -7
  60. package/vite.config.js +7 -7
@@ -1,11 +1,11 @@
1
1
  import {
2
- BufferAttribute,
3
- BufferGeometry,
4
- FileLoader,
5
- Float32BufferAttribute,
6
- Loader,
7
- LoaderUtils,
8
- Vector3
2
+ BufferAttribute,
3
+ BufferGeometry,
4
+ FileLoader,
5
+ Float32BufferAttribute,
6
+ Loader,
7
+ LoaderUtils,
8
+ Vector3,
9
9
  } from 'three/webgpu';
10
10
 
11
11
  /**
@@ -59,341 +59,283 @@ import {
59
59
  * const mesh = new THREE.Mesh(geometry, materials);
60
60
  */
61
61
 
62
-
63
62
  class STLLoader extends Loader {
63
+ constructor(manager) {
64
+ super(manager);
65
+ }
66
+
67
+ load(url, onLoad, onProgress, onError) {
68
+ const scope = this;
69
+
70
+ const loader = new FileLoader(this.manager);
71
+ loader.setPath(this.path);
72
+ loader.setResponseType('arraybuffer');
73
+ loader.setRequestHeader(this.requestHeader);
74
+ loader.setWithCredentials(this.withCredentials);
75
+
76
+ loader.load(
77
+ url,
78
+ function (text) {
79
+ try {
80
+ onLoad(scope.parse(text));
81
+ } catch (e) {
82
+ if (onError) {
83
+ onError(e);
84
+ } else {
85
+ console.error(e);
86
+ }
87
+
88
+ scope.manager.itemError(url);
89
+ }
90
+ },
91
+ onProgress,
92
+ onError,
93
+ );
94
+ }
95
+
96
+ parse(data) {
97
+ function isBinary(data) {
98
+ const reader = new DataView(data);
99
+ const face_size = (32 / 8) * 3 + (32 / 8) * 3 * 3 + 16 / 8;
100
+ const n_faces = reader.getUint32(80, true);
101
+ const expect = 80 + 32 / 8 + n_faces * face_size;
102
+
103
+ if (expect === reader.byteLength) {
104
+ return true;
105
+ }
106
+
107
+ // An ASCII STL data must begin with 'solid ' as the first six bytes.
108
+ // However, ASCII STLs lacking the SPACE after the 'd' are known to be
109
+ // plentiful. So, check the first 5 bytes for 'solid'.
110
+
111
+ // Several encodings, such as UTF-8, precede the text with up to 5 bytes:
112
+ // https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
113
+ // Search for "solid" to start anywhere after those prefixes.
114
+
115
+ // US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd'
116
+
117
+ const solid = [115, 111, 108, 105, 100];
118
+
119
+ for (let off = 0; off < 5; off++) {
120
+ // If "solid" text is matched to the current offset, declare it to be an ASCII STL.
121
+
122
+ if (matchDataViewAt(solid, reader, off)) return false;
123
+ }
124
+
125
+ // Couldn't find "solid" text at the beginning; it is binary STL.
126
+
127
+ return true;
128
+ }
129
+
130
+ function matchDataViewAt(query, reader, offset) {
131
+ // Check if each byte in query matches the corresponding byte from the current offset
132
+
133
+ for (let i = 0, il = query.length; i < il; i++) {
134
+ if (query[i] !== reader.getUint8(offset + i, false)) return false;
135
+ }
136
+
137
+ return true;
138
+ }
139
+
140
+ function parseBinary(data) {
141
+ const reader = new DataView(data);
142
+ const faces = reader.getUint32(80, true);
143
+
144
+ let r,
145
+ g,
146
+ b,
147
+ hasColors = false,
148
+ colors;
149
+ let defaultR, defaultG, defaultB, alpha;
150
+
151
+ // process STL header
152
+ // check for default color in header ("COLOR=rgba" sequence).
153
+
154
+ for (let index = 0; index < 80 - 10; index++) {
155
+ if (
156
+ reader.getUint32(index, false) == 0x434f4c4f /*COLO*/ &&
157
+ reader.getUint8(index + 4) == 0x52 /*'R'*/ &&
158
+ reader.getUint8(index + 5) == 0x3d /*'='*/
159
+ ) {
160
+ hasColors = true;
161
+ colors = new Float32Array(faces * 3 * 3);
162
+
163
+ defaultR = reader.getUint8(index + 6) / 255;
164
+ defaultG = reader.getUint8(index + 7) / 255;
165
+ defaultB = reader.getUint8(index + 8) / 255;
166
+ alpha = reader.getUint8(index + 9) / 255;
167
+ }
168
+ }
169
+
170
+ const dataOffset = 84;
171
+ const faceLength = 12 * 4 + 2;
172
+
173
+ const geometry = new BufferGeometry();
174
+
175
+ const vertices = new Float32Array(faces * 3 * 3);
176
+ const normals = new Float32Array(faces * 3 * 3);
177
+
178
+ for (let face = 0; face < faces; face++) {
179
+ const start = dataOffset + face * faceLength;
180
+ const normalX = reader.getFloat32(start, true);
181
+ const normalY = reader.getFloat32(start + 4, true);
182
+ const normalZ = reader.getFloat32(start + 8, true);
183
+
184
+ if (hasColors) {
185
+ const packedColor = reader.getUint16(start + 48, true);
186
+
187
+ if ((packedColor & 0x8000) === 0) {
188
+ // facet has its own unique color
189
+
190
+ r = (packedColor & 0x1f) / 31;
191
+ g = ((packedColor >> 5) & 0x1f) / 31;
192
+ b = ((packedColor >> 10) & 0x1f) / 31;
193
+ } else {
194
+ r = defaultR;
195
+ g = defaultG;
196
+ b = defaultB;
197
+ }
198
+ }
199
+
200
+ for (let i = 1; i <= 3; i++) {
201
+ const vertexstart = start + i * 12;
202
+ const componentIdx = face * 3 * 3 + (i - 1) * 3;
203
+
204
+ vertices[componentIdx] = reader.getFloat32(vertexstart, true);
205
+ vertices[componentIdx + 1] = reader.getFloat32(vertexstart + 4, true);
206
+ vertices[componentIdx + 2] = reader.getFloat32(vertexstart + 8, true);
207
+
208
+ normals[componentIdx] = normalX;
209
+ normals[componentIdx + 1] = normalY;
210
+ normals[componentIdx + 2] = normalZ;
64
211
 
65
- constructor( manager ) {
66
-
67
- super( manager );
68
-
69
- }
70
-
71
- load( url, onLoad, onProgress, onError ) {
72
-
73
- const scope = this;
74
-
75
- const loader = new FileLoader( this.manager );
76
- loader.setPath( this.path );
77
- loader.setResponseType( 'arraybuffer' );
78
- loader.setRequestHeader( this.requestHeader );
79
- loader.setWithCredentials( this.withCredentials );
80
-
81
- loader.load( url, function ( text ) {
82
-
83
- try {
84
-
85
- onLoad( scope.parse( text ) );
86
-
87
- } catch ( e ) {
88
-
89
- if ( onError ) {
90
-
91
- onError( e );
92
-
93
- } else {
94
-
95
- console.error( e );
96
-
97
- }
98
-
99
- scope.manager.itemError( url );
100
-
101
- }
102
-
103
- }, onProgress, onError );
104
-
105
- }
106
-
107
- parse( data ) {
108
-
109
- function isBinary( data ) {
110
-
111
- const reader = new DataView( data );
112
- const face_size = ( 32 / 8 * 3 ) + ( ( 32 / 8 * 3 ) * 3 ) + ( 16 / 8 );
113
- const n_faces = reader.getUint32( 80, true );
114
- const expect = 80 + ( 32 / 8 ) + ( n_faces * face_size );
115
-
116
- if ( expect === reader.byteLength ) {
117
-
118
- return true;
119
-
120
- }
121
-
122
- // An ASCII STL data must begin with 'solid ' as the first six bytes.
123
- // However, ASCII STLs lacking the SPACE after the 'd' are known to be
124
- // plentiful. So, check the first 5 bytes for 'solid'.
125
-
126
- // Several encodings, such as UTF-8, precede the text with up to 5 bytes:
127
- // https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
128
- // Search for "solid" to start anywhere after those prefixes.
129
-
130
- // US-ASCII ordinal values for 's', 'o', 'l', 'i', 'd'
131
-
132
- const solid = [ 115, 111, 108, 105, 100 ];
133
-
134
- for ( let off = 0; off < 5; off ++ ) {
135
-
136
- // If "solid" text is matched to the current offset, declare it to be an ASCII STL.
137
-
138
- if ( matchDataViewAt( solid, reader, off ) ) return false;
139
-
140
- }
141
-
142
- // Couldn't find "solid" text at the beginning; it is binary STL.
143
-
144
- return true;
145
-
146
- }
147
-
148
- function matchDataViewAt( query, reader, offset ) {
149
-
150
- // Check if each byte in query matches the corresponding byte from the current offset
151
-
152
- for ( let i = 0, il = query.length; i < il; i ++ ) {
153
-
154
- if ( query[ i ] !== reader.getUint8( offset + i, false ) ) return false;
155
-
156
- }
157
-
158
- return true;
159
-
160
- }
161
-
162
- function parseBinary( data ) {
163
-
164
- const reader = new DataView( data );
165
- const faces = reader.getUint32( 80, true );
166
-
167
- let r, g, b, hasColors = false, colors;
168
- let defaultR, defaultG, defaultB, alpha;
169
-
170
- // process STL header
171
- // check for default color in header ("COLOR=rgba" sequence).
172
-
173
- for ( let index = 0; index < 80 - 10; index ++ ) {
174
-
175
- if ( ( reader.getUint32( index, false ) == 0x434F4C4F /*COLO*/ ) &&
176
- ( reader.getUint8( index + 4 ) == 0x52 /*'R'*/ ) &&
177
- ( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
178
-
179
- hasColors = true;
180
- colors = new Float32Array( faces * 3 * 3 );
181
-
182
- defaultR = reader.getUint8( index + 6 ) / 255;
183
- defaultG = reader.getUint8( index + 7 ) / 255;
184
- defaultB = reader.getUint8( index + 8 ) / 255;
185
- alpha = reader.getUint8( index + 9 ) / 255;
186
-
187
- }
188
-
189
- }
190
-
191
- const dataOffset = 84;
192
- const faceLength = 12 * 4 + 2;
193
-
194
- const geometry = new BufferGeometry();
195
-
196
- const vertices = new Float32Array( faces * 3 * 3 );
197
- const normals = new Float32Array( faces * 3 * 3 );
198
-
199
- for ( let face = 0; face < faces; face ++ ) {
200
-
201
- const start = dataOffset + face * faceLength;
202
- const normalX = reader.getFloat32( start, true );
203
- const normalY = reader.getFloat32( start + 4, true );
204
- const normalZ = reader.getFloat32( start + 8, true );
205
-
206
- if ( hasColors ) {
207
-
208
- const packedColor = reader.getUint16( start + 48, true );
209
-
210
- if ( ( packedColor & 0x8000 ) === 0 ) {
211
-
212
- // facet has its own unique color
213
-
214
- r = ( packedColor & 0x1F ) / 31;
215
- g = ( ( packedColor >> 5 ) & 0x1F ) / 31;
216
- b = ( ( packedColor >> 10 ) & 0x1F ) / 31;
217
-
218
- } else {
219
-
220
- r = defaultR;
221
- g = defaultG;
222
- b = defaultB;
223
-
224
- }
225
-
226
- }
227
-
228
- for ( let i = 1; i <= 3; i ++ ) {
229
-
230
- const vertexstart = start + i * 12;
231
- const componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
232
-
233
- vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
234
- vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
235
- vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
236
-
237
- normals[ componentIdx ] = normalX;
238
- normals[ componentIdx + 1 ] = normalY;
239
- normals[ componentIdx + 2 ] = normalZ;
240
-
241
- if ( hasColors ) {
242
-
243
- colors[ componentIdx ] = r;
244
- colors[ componentIdx + 1 ] = g;
245
- colors[ componentIdx + 2 ] = b;
246
-
247
- }
248
-
249
- }
250
-
251
- }
252
-
253
- geometry.setAttribute( 'position', new BufferAttribute( vertices, 3 ) );
254
- geometry.setAttribute( 'normal', new BufferAttribute( normals, 3 ) );
255
-
256
- if ( hasColors ) {
257
-
258
- geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );
259
- geometry.hasColors = true;
260
- geometry.alpha = alpha;
261
-
262
- }
263
-
264
- return geometry;
265
-
266
- }
267
-
268
- function parseASCII( data ) {
269
-
270
- const geometry = new BufferGeometry();
271
- const patternSolid = /solid([\s\S]*?)endsolid/g;
272
- const patternFace = /facet([\s\S]*?)endfacet/g;
273
- let faceCounter = 0;
274
-
275
- const patternFloat = /[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source;
276
- const patternVertex = new RegExp( 'vertex' + patternFloat + patternFloat + patternFloat, 'g' );
277
- const patternNormal = new RegExp( 'normal' + patternFloat + patternFloat + patternFloat, 'g' );
278
-
279
- const vertices = [];
280
- const normals = [];
281
-
282
- const normal = new Vector3();
283
-
284
- let result;
285
-
286
- let groupCount = 0;
287
- let startVertex = 0;
288
- let endVertex = 0;
289
-
290
- while ( ( result = patternSolid.exec( data ) ) !== null ) {
291
-
292
- startVertex = endVertex;
293
-
294
- const solid = result[ 0 ];
295
-
296
- while ( ( result = patternFace.exec( solid ) ) !== null ) {
297
-
298
- let vertexCountPerFace = 0;
299
- let normalCountPerFace = 0;
300
-
301
- const text = result[ 0 ];
302
-
303
- while ( ( result = patternNormal.exec( text ) ) !== null ) {
304
-
305
- normal.x = parseFloat( result[ 1 ] );
306
- normal.y = parseFloat( result[ 2 ] );
307
- normal.z = parseFloat( result[ 3 ] );
308
- normalCountPerFace ++;
309
-
310
- }
311
-
312
- while ( ( result = patternVertex.exec( text ) ) !== null ) {
313
-
314
- vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) );
315
- normals.push( normal.x, normal.y, normal.z );
316
- vertexCountPerFace ++;
317
- endVertex ++;
318
-
319
- }
320
-
321
- // every face have to own ONE valid normal
322
-
323
- if ( normalCountPerFace !== 1 ) {
324
-
325
- console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter );
326
-
327
- }
328
-
329
- // each face have to own THREE valid vertices
330
-
331
- if ( vertexCountPerFace !== 3 ) {
332
-
333
- console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter );
334
-
335
- }
336
-
337
- faceCounter ++;
338
-
339
- }
340
-
341
- const start = startVertex;
342
- const count = endVertex - startVertex;
343
-
344
- geometry.addGroup( start, count, groupCount );
345
- groupCount ++;
346
-
347
- }
348
-
349
- geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
350
- geometry.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
351
-
352
- return geometry;
353
-
354
- }
355
-
356
- function ensureString( buffer ) {
357
-
358
- if ( typeof buffer !== 'string' ) {
359
-
360
- return LoaderUtils.decodeText( new Uint8Array( buffer ) );
361
-
362
- }
363
-
364
- return buffer;
365
-
366
- }
367
-
368
- function ensureBinary( buffer ) {
369
-
370
- if ( typeof buffer === 'string' ) {
371
-
372
- const array_buffer = new Uint8Array( buffer.length );
373
- for ( let i = 0; i < buffer.length; i ++ ) {
374
-
375
- array_buffer[ i ] = buffer.charCodeAt( i ) & 0xff; // implicitly assumes little-endian
212
+ if (hasColors) {
213
+ colors[componentIdx] = r;
214
+ colors[componentIdx + 1] = g;
215
+ colors[componentIdx + 2] = b;
216
+ }
217
+ }
218
+ }
219
+
220
+ geometry.setAttribute('position', new BufferAttribute(vertices, 3));
221
+ geometry.setAttribute('normal', new BufferAttribute(normals, 3));
222
+
223
+ if (hasColors) {
224
+ geometry.setAttribute('color', new BufferAttribute(colors, 3));
225
+ geometry.hasColors = true;
226
+ geometry.alpha = alpha;
227
+ }
228
+
229
+ return geometry;
230
+ }
231
+
232
+ function parseASCII(data) {
233
+ const geometry = new BufferGeometry();
234
+ const patternSolid = /solid([\s\S]*?)endsolid/g;
235
+ const patternFace = /facet([\s\S]*?)endfacet/g;
236
+ let faceCounter = 0;
237
+
238
+ const patternFloat = /[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source;
239
+ const patternVertex = new RegExp('vertex' + patternFloat + patternFloat + patternFloat, 'g');
240
+ const patternNormal = new RegExp('normal' + patternFloat + patternFloat + patternFloat, 'g');
241
+
242
+ const vertices = [];
243
+ const normals = [];
244
+
245
+ const normal = new Vector3();
246
+
247
+ let result;
248
+
249
+ let groupCount = 0;
250
+ let startVertex = 0;
251
+ let endVertex = 0;
252
+
253
+ while ((result = patternSolid.exec(data)) !== null) {
254
+ startVertex = endVertex;
255
+
256
+ const solid = result[0];
257
+
258
+ while ((result = patternFace.exec(solid)) !== null) {
259
+ let vertexCountPerFace = 0;
260
+ let normalCountPerFace = 0;
261
+
262
+ const text = result[0];
263
+
264
+ while ((result = patternNormal.exec(text)) !== null) {
265
+ normal.x = parseFloat(result[1]);
266
+ normal.y = parseFloat(result[2]);
267
+ normal.z = parseFloat(result[3]);
268
+ normalCountPerFace++;
269
+ }
270
+
271
+ while ((result = patternVertex.exec(text)) !== null) {
272
+ vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));
273
+ normals.push(normal.x, normal.y, normal.z);
274
+ vertexCountPerFace++;
275
+ endVertex++;
276
+ }
277
+
278
+ // every face have to own ONE valid normal
279
+
280
+ if (normalCountPerFace !== 1) {
281
+ console.error(
282
+ "THREE.STLLoader: Something isn't right with the normal of face number " +
283
+ faceCounter,
284
+ );
285
+ }
286
+
287
+ // each face have to own THREE valid vertices
288
+
289
+ if (vertexCountPerFace !== 3) {
290
+ console.error(
291
+ "THREE.STLLoader: Something isn't right with the vertices of face number " +
292
+ faceCounter,
293
+ );
294
+ }
295
+
296
+ faceCounter++;
297
+ }
376
298
 
377
- }
299
+ const start = startVertex;
300
+ const count = endVertex - startVertex;
378
301
 
379
- return array_buffer.buffer || array_buffer;
302
+ geometry.addGroup(start, count, groupCount);
303
+ groupCount++;
304
+ }
380
305
 
381
- } else {
306
+ geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
307
+ geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3));
382
308
 
383
- return buffer;
309
+ return geometry;
310
+ }
384
311
 
385
- }
312
+ function ensureString(buffer) {
313
+ if (typeof buffer !== 'string') {
314
+ return LoaderUtils.decodeText(new Uint8Array(buffer));
315
+ }
386
316
 
387
- }
317
+ return buffer;
318
+ }
388
319
 
389
- // start
320
+ function ensureBinary(buffer) {
321
+ if (typeof buffer === 'string') {
322
+ const array_buffer = new Uint8Array(buffer.length);
323
+ for (let i = 0; i < buffer.length; i++) {
324
+ array_buffer[i] = buffer.charCodeAt(i) & 0xff; // implicitly assumes little-endian
325
+ }
390
326
 
391
- const binData = ensureBinary( data );
327
+ return array_buffer.buffer || array_buffer;
328
+ } else {
329
+ return buffer;
330
+ }
331
+ }
392
332
 
393
- return isBinary( binData ) ? parseBinary( binData ) : parseASCII( ensureString( data ) );
333
+ // start
394
334
 
395
- }
335
+ const binData = ensureBinary(data);
396
336
 
337
+ return isBinary(binData) ? parseBinary(binData) : parseASCII(ensureString(data));
338
+ }
397
339
  }
398
340
 
399
341
  export { STLLoader };