|
@@ -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;
|
|
|
|
|
|
};
|