Last active
February 4, 2017 23:12
-
-
Save filharvey/d98bd2b20cd0a2c4403fab0a132000c5 to your computer and use it in GitHub Desktop.
Exports a THREE.js scene mesh to STL, making it suitable for 3d printing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Based on https://github.com/mrdoob/three.js/blob/a72347515fa34e892f7a9bfa66a34fdc0df55954/examples/js/exporters/STLExporter.js | |
* extended from https://gist.github.com/kjlubick/fb6ba9c51df63ba0951f | |
* Tested on r68 and r70 | |
* @author kjlubick / https://github.com/kjlubick | |
* @author kovacsv / http://kovacsv.hu/ | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
THREE.STLExporter = function () {}; | |
THREE.STLExporter.prototype = { | |
constructor: THREE.STLExporter, | |
parse: ( function () { | |
var vector = new THREE.Vector3(); | |
var normalMatrixWorld = new THREE.Matrix3(); | |
return function ( scene ) { | |
var output = ''; | |
output += 'solid exported\n'; | |
scene.traverse( function ( object ) { | |
if ( object instanceof THREE.Mesh ) { | |
var geometry = object.geometry; | |
var skeleton = object.skeleton; | |
var matrixWorld = object.matrixWorld; | |
var mesh = object; | |
if (geometry instanceof THREE.BufferGeometry) | |
{ | |
geometry = new THREE.Geometry().fromBufferGeometry( geometry ); | |
} | |
if ( geometry instanceof THREE.Geometry ) { | |
var vertices = geometry.vertices; | |
var faces = geometry.faces; | |
normalMatrixWorld.getNormalMatrix( matrixWorld ); | |
for ( var i = 0, l = faces.length; i < l; i ++ ) { | |
var face = faces[ i ]; | |
vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize(); | |
output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n'; | |
output += '\t\touter loop\n'; | |
var indices = [ face.a, face.b, face.c ]; | |
for ( var j = 0; j < 3; j ++ ) { | |
var vertexIndex = indices[ j ]; | |
if (geometry.skinIndices.length == 0) { | |
vector.copy( vertices[ vertexIndex ] ).applyMatrix4( matrixWorld ); | |
output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n'; | |
} else { | |
vector.copy( vertices[ vertexIndex ] ); //.applyMatrix4( matrixWorld ); | |
// see https://github.com/mrdoob/three.js/issues/3187 | |
boneIndices = []; | |
boneIndices[0] = geometry.skinIndices[vertexIndex].x; | |
boneIndices[1] = geometry.skinIndices[vertexIndex].y; | |
boneIndices[2] = geometry.skinIndices[vertexIndex].z; | |
boneIndices[3] = geometry.skinIndices[vertexIndex].w; | |
weights = []; | |
weights[0] = geometry.skinWeights[vertexIndex].x; | |
weights[1] = geometry.skinWeights[vertexIndex].y; | |
weights[2] = geometry.skinWeights[vertexIndex].z; | |
weights[3] = geometry.skinWeights[vertexIndex].w; | |
inverses = []; | |
inverses[0] = skeleton.boneInverses[ boneIndices[0] ]; | |
inverses[1] = skeleton.boneInverses[ boneIndices[1] ]; | |
inverses[2] = skeleton.boneInverses[ boneIndices[2] ]; | |
inverses[3] = skeleton.boneInverses[ boneIndices[3] ]; | |
skinMatrices = []; | |
skinMatrices[0] = skeleton.bones[ boneIndices[0] ].matrixWorld; | |
skinMatrices[1] = skeleton.bones[ boneIndices[1] ].matrixWorld; | |
skinMatrices[2] = skeleton.bones[ boneIndices[2] ].matrixWorld; | |
skinMatrices[3] = skeleton.bones[ boneIndices[3] ].matrixWorld; | |
var finalVector = new THREE.Vector4(); | |
for(var k = 0; k<4; k++) { | |
var tempVector = new THREE.Vector4(vector.x, vector.y, vector.z); | |
tempVector.multiplyScalar(weights[k]); | |
//the inverse takes the vector into local bone space | |
tempVector.applyMatrix4(inverses[k]) | |
//which is then transformed to the appropriate world space | |
.applyMatrix4(skinMatrices[k]); | |
finalVector.add(tempVector); | |
} | |
output += '\t\t\tvertex ' + finalVector.x + ' ' + finalVector.y + ' ' + finalVector.z + '\n'; | |
} | |
} | |
output += '\t\tendloop\n'; | |
output += '\tendfacet\n'; | |
} | |
} | |
} | |
} ); | |
output += 'endsolid exported\n'; | |
return output; | |
}; | |
}() ) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment