Ver Fonte

Support colors in binary STLs

Eugene Rymski há 11 anos atrás
pai
commit
739b1844e6

+ 66 - 4
examples/js/loaders/STLLoader.js

@@ -8,7 +8,7 @@
  * Supports both binary and ASCII encoded files, with automatic detection of type.
  *
  * Limitations:
- * 	Binary decoding ignores header. There doesn't seem to be much of a use for it.
+ * 	Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
  * 	There is perhaps some question as to how valid it is to always assume little-endian-ness.
  * 	ASCII decoding assumes file is UTF-8. Seems to work for the examples...
  *
@@ -21,6 +21,14 @@
  *
  * 	} );
  * 	loader.load( './models/stl/slotted_disk.stl' );
+ *
+ * For binary STLs geometry might contain colors for vertices. To use it:
+ *  ... // use the same code to load STL as above
+ *  var geometry = event.content;
+ *  if (geometry.hasColors) {
+ *    material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
+ *  } else { .... }
+ * var mesh = new THREE.Mesh( geometry, material );
  */
 
 
@@ -103,6 +111,28 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 
 	var reader = new DataView( data );
 	var faces = reader.getUint32( 80, true );
+
+	var r, g, b, hasColors = false, colors;
+	var defaultR, defaultG, defaultB, alpha;
+
+	// process STL header
+	// check for default color in header ("COLOR=rgba" sequence).
+	for (var index = 0; index < 80 - 10; index++) {
+
+		if ((reader.getUint32(index, false) == 0x434F4C4F /*COLO*/) &&
+			(reader.getUint8(index + 4) == 0x52 /*'R'*/) &&
+			(reader.getUint8(index + 5) == 0x3D /*'='*/)) {
+
+				hasColors = true;
+				colors = new Float32Array( faces * 3 * 3);
+
+				defaultR = reader.getUint8(index + 6) / 255;
+				defaultG = reader.getUint8(index + 7) / 255;
+				defaultB = reader.getUint8(index + 8) / 255;
+				alpha = reader.getUint8(index + 9) / 255;
+			}
+		}
+
 	var dataOffset = 84;
 	var faceLength = 12 * 4 + 2;
 
@@ -116,6 +146,26 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 	for ( var face = 0; face < faces; face ++ ) {
 
 		var start = dataOffset + face * faceLength;
+		var normalX = reader.getFloat32(start, true);
+		var normalY = reader.getFloat32(start + 4, true);
+		var normalZ = reader.getFloat32(start + 8, true);
+
+		if (hasColors) {
+
+			var packedColor = reader.getUint16(start + 48, true);
+
+			if ((packedColor & 0x8000) === 0) { // facet has its own unique color
+
+				r = (packedColor & 0x1F) / 31;
+				g = ((packedColor >> 5) & 0x1F) / 31;
+				b = ((packedColor >> 10) & 0x1F) / 31;
+			} else {
+
+				r = defaultR;
+				g = defaultG;
+				b = defaultB;
+			}
+		}
 
 		for ( var i = 1; i <= 3; i ++ ) {
 
@@ -125,9 +175,15 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 			vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true );
 			vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-			normals[ offset     ] = reader.getFloat32( start    , true );
-			normals[ offset + 1 ] = reader.getFloat32( start + 4, true );
-			normals[ offset + 2 ] = reader.getFloat32( start + 8, true );
+			normals[ offset     ] = normalX;
+			normals[ offset + 1 ] = normalY;
+			normals[ offset + 2 ] = normalZ;
+
+			if (hasColors) {
+				colors[ offset     ] = r;
+				colors[ offset + 1 ] = g;
+				colors[ offset + 2 ] = b;
+			}
 
 			offset += 3;
 
@@ -138,6 +194,12 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 	geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
 	geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 
+	if (hasColors) {
+		geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
+		geometry.hasColors = true;
+		geometry.alpha = alpha;
+	}
+
 	return geometry;
 
 };

BIN
examples/models/stl/binary/colored.stl


+ 25 - 0
examples/webgl_loader_stl.html

@@ -146,6 +146,31 @@
 				} );
 				loader.load( './models/stl/binary/pr2_head_tilt.stl' );
 
+				// Colored binary STL
+				var loaderColored = new THREE.STLLoader();
+				loaderColored.addEventListener( 'load', function ( event ) {
+
+					var geometry = event.content;
+
+					var meshMaterial = material;
+					if (geometry.hasColors) {
+						meshMaterial = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
+					}
+
+					var mesh = new THREE.Mesh( geometry, meshMaterial );
+
+					mesh.position.set( 0.5, 0.2, 0 );
+					mesh.rotation.set( - Math.PI / 2, Math.PI / 2, 0 );
+					mesh.scale.set( 0.3, 0.3, 0.3 );
+
+					mesh.castShadow = true;
+					mesh.receiveShadow = true;
+
+					scene.add( mesh );
+
+				} );
+				loaderColored.load( './models/stl/binary/colored.stl' );
+
 
 				// Lights