|
@@ -28,6 +28,31 @@
|
|
|
* material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
|
|
|
* } else { .... }
|
|
|
* var mesh = new THREE.Mesh( geometry, material );
|
|
|
+ *
|
|
|
+ * For ASCII STLs containing multiple solids, each solid is assigned to a different group.
|
|
|
+ * Groups can be used to assign a different color by defining an array of materials with the same length of
|
|
|
+ * geometry.groups and passing it to the Mesh constructor:
|
|
|
+ *
|
|
|
+ * var mesh = new THREE.Mesh( geometry, material );
|
|
|
+ *
|
|
|
+ * For example:
|
|
|
+ *
|
|
|
+ * var materials = [];
|
|
|
+ * var nGeometryGroups = geometry.groups.length;
|
|
|
+ *
|
|
|
+ * var colorMap = ...; // Some logic to index colors.
|
|
|
+ *
|
|
|
+ * for (var i = 0; i < nGeometryGroups; i++) {
|
|
|
+ *
|
|
|
+ * var material = new THREE.MeshStandardMaterial({
|
|
|
+ * color: colorMap[i],
|
|
|
+ * wireframe: false
|
|
|
+ * });
|
|
|
+ *
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * materials.push(material);
|
|
|
+ * var mesh = new THREE.Mesh(geometry, materials);
|
|
|
*/
|
|
|
|
|
|
|
|
@@ -107,7 +132,7 @@ THREE.STLLoader.prototype = {
|
|
|
|
|
|
// If "solid" text is matched to the current offset, declare it to be an ASCII STL.
|
|
|
|
|
|
- if ( matchDataViewAt ( solid, reader, off ) ) return false;
|
|
|
+ if ( matchDataViewAt( solid, reader, off ) ) return false;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -201,7 +226,7 @@ THREE.STLLoader.prototype = {
|
|
|
|
|
|
var vertexstart = start + i * 12;
|
|
|
var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
|
|
|
-
|
|
|
+
|
|
|
vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
|
|
|
vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
|
|
|
vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
|
|
@@ -240,6 +265,7 @@ THREE.STLLoader.prototype = {
|
|
|
function parseASCII( data ) {
|
|
|
|
|
|
var geometry = new THREE.BufferGeometry();
|
|
|
+ var patternSolid = /solid([\s\S]*?)endsolid/g;
|
|
|
var patternFace = /facet([\s\S]*?)endfacet/g;
|
|
|
var faceCounter = 0;
|
|
|
|
|
@@ -254,53 +280,80 @@ THREE.STLLoader.prototype = {
|
|
|
|
|
|
var result;
|
|
|
|
|
|
- while ( ( result = patternFace.exec( data ) ) !== null ) {
|
|
|
+ var groupVertexes = [];
|
|
|
+ var groupCount = 0;
|
|
|
+ var startVertex = 0;
|
|
|
+ var endVertex = 0;
|
|
|
|
|
|
- var vertexCountPerFace = 0;
|
|
|
- var normalCountPerFace = 0;
|
|
|
+ while ( ( result = patternSolid.exec( data ) ) !== null ) {
|
|
|
|
|
|
- var text = result[ 0 ];
|
|
|
+ startVertex = endVertex;
|
|
|
|
|
|
- while ( ( result = patternNormal.exec( text ) ) !== null ) {
|
|
|
+ var solid = result[ 0 ];
|
|
|
|
|
|
- normal.x = parseFloat( result[ 1 ] );
|
|
|
- normal.y = parseFloat( result[ 2 ] );
|
|
|
- normal.z = parseFloat( result[ 3 ] );
|
|
|
- normalCountPerFace ++;
|
|
|
+ while ( ( result = patternFace.exec( solid ) ) !== null ) {
|
|
|
|
|
|
- }
|
|
|
+ var vertexCountPerFace = 0;
|
|
|
+ var normalCountPerFace = 0;
|
|
|
|
|
|
- while ( ( result = patternVertex.exec( text ) ) !== null ) {
|
|
|
+ var text = result[ 0 ];
|
|
|
|
|
|
- vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) );
|
|
|
- normals.push( normal.x, normal.y, normal.z );
|
|
|
- vertexCountPerFace ++;
|
|
|
+ while ( ( result = patternNormal.exec( text ) ) !== null ) {
|
|
|
|
|
|
- }
|
|
|
+ normal.x = parseFloat( result[ 1 ] );
|
|
|
+ normal.y = parseFloat( result[ 2 ] );
|
|
|
+ normal.z = parseFloat( result[ 3 ] );
|
|
|
+ normalCountPerFace ++;
|
|
|
|
|
|
- // every face have to own ONE valid normal
|
|
|
+ }
|
|
|
|
|
|
- if ( normalCountPerFace !== 1 ) {
|
|
|
+ while ( ( result = patternVertex.exec( text ) ) !== null ) {
|
|
|
|
|
|
- console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter );
|
|
|
+ vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) );
|
|
|
+ normals.push( normal.x, normal.y, normal.z );
|
|
|
+ vertexCountPerFace ++;
|
|
|
+ endVertex ++;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- // each face have to own THREE valid vertices
|
|
|
+ // every face have to own ONE valid normal
|
|
|
|
|
|
- if ( vertexCountPerFace !== 3 ) {
|
|
|
+ if ( normalCountPerFace !== 1 ) {
|
|
|
|
|
|
- console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter );
|
|
|
+ console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // each face have to own THREE valid vertices
|
|
|
+
|
|
|
+ if ( vertexCountPerFace !== 3 ) {
|
|
|
+
|
|
|
+ console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ faceCounter ++;
|
|
|
|
|
|
}
|
|
|
|
|
|
- faceCounter ++;
|
|
|
+ groupVertexes.push( { startVertex: startVertex, endVertex: endVertex } );
|
|
|
+ groupCount ++;
|
|
|
|
|
|
}
|
|
|
|
|
|
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
|
|
|
geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
|
|
|
|
|
|
+ if ( groupCount > 0 ) {
|
|
|
+
|
|
|
+ for ( var i = 0; i < groupVertexes.length; i ++ ) {
|
|
|
+
|
|
|
+ geometry.addGroup( groupVertexes[ i ].startVertex, groupVertexes[ i ].endVertex, i );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
return geometry;
|
|
|
|
|
|
}
|
|
@@ -327,6 +380,7 @@ THREE.STLLoader.prototype = {
|
|
|
array_buffer[ i ] = buffer.charCodeAt( i ) & 0xff; // implicitly assumes little-endian
|
|
|
|
|
|
}
|
|
|
+
|
|
|
return array_buffer.buffer || array_buffer;
|
|
|
|
|
|
} else {
|