baker.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. const { slices, pushAll } = require('./array')
  2. const {toStl, rotate} = require('./stl')
  3. const THREE = require('./three')
  4. const transformedSkinVertex = require('./transformed-skin-vertex')
  5. THREE.Baker = function() {};
  6. THREE.Baker.prototype = {
  7. constructor: THREE.Baker,
  8. parse: (function() {
  9. var vector = new THREE.Vec3();
  10. var normalMatrixWorld = new THREE.Matrix3();
  11. return function parse(scene, options) {
  12. if (options === undefined) options = {};
  13. var binary = options.binary !== undefined ? options.binary : false;
  14. //
  15. var objects = [];
  16. var triangles = [];
  17. const _triangles = triangles
  18. scene.traverse(function(object) {
  19. if (object.isMesh) {
  20. if (object.pose && object.skeleton && typeof(object.skeleton.pose) == 'function') {
  21. console.log('Posing object', object)
  22. //object.pose();
  23. }
  24. if (object.geometry && object.geometry.attributes) {
  25. object.geometry.attributes._geometry = object.geometry
  26. object.geometry.attributes._object = object
  27. console.log(object.geometry.attributes)
  28. }
  29. var og = object.geometry;
  30. var geometry = object.geometry;
  31. /* FROM */
  32. let positions, triangles, skinIndices, skinWeights
  33. if (geometry instanceof THREE.BufferGeometry) {
  34. var a, b, c;
  35. var index = geometry.index;
  36. var attributes = geometry.attributes;
  37. // Figure out where each triangle is supposed to be, globally.
  38. positions = slices(attributes.position.array, 3).map(([x, y, z]) => new THREE.Vec3(x, y, z));
  39. triangles = index
  40. ? slices(Array.from(index.array).map(i => positions[i]), 3)
  41. : slices(positions, 3)
  42. if (attributes.skinIndex) {
  43. skinIndices = slices(Array.from(attributes.skinIndex.array), 4)
  44. skinWeights = slices(attributes.skinWeight.array, 4)
  45. }
  46. } else if (geometry instanceof THREE.Geometry) {
  47. console.log('GEOMETRY')
  48. positions = geometry.vertices.map(v => v.clone())
  49. triangles = geometry.faces.map(({a, b, c}) => [
  50. positions[a],
  51. positions[b],
  52. positions[c]
  53. ])
  54. if (object.geometry.skinIndices) {
  55. skinIndices = object.geometry.skinIndices.map(({x, y, z, w}) => [x, y, z, w])
  56. skinWeights = object.geometry.skinWeights.map(({x, y, z, w}) => [x, y, z, w])
  57. }
  58. {
  59. /*
  60. var fvA, fvB, fvC;
  61. //var isFaceMaterial = material instanceof THREE.MultiMaterial;
  62. //var materials = isFaceMaterial === true ? material.materials : null;
  63. var vertices = geometry.vertices;
  64. var faces = geometry.faces;
  65. var faceVertexUvs = geometry.faceVertexUvs[0];
  66. if (faceVertexUvs.length > 0) uvs = faceVertexUvs;
  67. for (var f = 0, fl = faces.length; f < fl; f++) {
  68. var face = faces[f];
  69. //var faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;
  70. //if ( faceMaterial === undefined ) continue;
  71. fvA = vertices[face.a];
  72. fvB = vertices[face.b];
  73. fvC = vertices[face.c];
  74. / *
  75. if ( faceMaterial.morphTargets === true ) {
  76. var morphTargets = geometry.morphTargets;
  77. var morphInfluences = this.morphTargetInfluences;
  78. vA.set( 0, 0, 0 );
  79. vB.set( 0, 0, 0 );
  80. vC.set( 0, 0, 0 );
  81. for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
  82. var influence = morphInfluences[ t ];
  83. if ( influence === 0 ) continue;
  84. var targets = morphTargets[ t ].vertices;
  85. vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );
  86. vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );
  87. vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );
  88. }
  89. vA.add( fvA );
  90. vB.add( fvB );
  91. vC.add( fvC );
  92. fvA = vA;
  93. fvB = vB;
  94. fvC = vC;
  95. }
  96. * /
  97. // if (this.boneTransform) {
  98. // console.log('YES')
  99. // fvA = this.boneTransform(fvA, face.a);
  100. // fvB = this.boneTransform(fvB, face.b);
  101. // fvC = this.boneTransform(fvC, face.c);
  102. // }
  103. }
  104. */
  105. }
  106. } else {
  107. console.log(geometry && geometry.constructor.name || 'Non-Geo')
  108. }
  109. let o = object
  110. // positions.forEach((p, i) => {
  111. // p.applyMatrix4(object.matrixWorld)
  112. // })
  113. if (skinIndices) {
  114. // const skinIndices = object.geometry.skinIndices.map(({x, y, z, w}) => [x, y, z, w])
  115. // const skinWeights = object.geometry.skinWeights.map(({x, y, z, w}) => [x, y, z, w])
  116. const bones = object.skeleton.bones
  117. positions.forEach((p, index) => {
  118. var skinIndex = skinIndices[index]
  119. var skinWeight = skinWeights[index]
  120. const skinVertex = p.clone().applyMatrix4(object.bindMatrix)
  121. //var skinVertex = positions[index].applyMatrix4(object.bindMatrix)
  122. //(new THREE.Vector3 ()).fromAttribute (skin.geometry.getAttribute ('position'), index).applyMatrix4 (skin.bindMatrix);
  123. var result = new THREE.Vector3 ()
  124. var temp = new THREE.Vector3 ()
  125. var tempMatrix = new THREE.Matrix4 ()
  126. var properties = ['x', 'y', 'z', 'w'];
  127. for (var i = 0; i < 4; i++) {
  128. var boneIndex = skinIndex[i];
  129. if (boneIndex >= 0) {
  130. tempMatrix.multiplyMatrices (object.skeleton.bones[boneIndex].matrixWorld, object.skeleton.boneInverses[boneIndex]);
  131. //result.add (temp.copy (skinVertex).multiplyScalar (skinWeights[properties[i]]).applyMatrix4 (tempMatrix));
  132. //result.add (temp.copy (skinVertex).applyMatrix4 (tempMatrix).multiplyScalar (skinWeight[i]));
  133. result.add(skinVertex.clone().applyMatrix4(tempMatrix).multiplyScalar(skinWeight[i]))
  134. }
  135. }
  136. result.applyMatrix4(object.bindMatrixInverse)
  137. p.copy(result)
  138. //return result.applyMatrix4 (skin.bindMatrixInverse);
  139. // const skinIndex = skinIndices[i]
  140. // const skinWeight = skinWeights[i]
  141. // skinIndex.forEach((s, j) => {
  142. // //https://stackoverflow.com/questions/31620194/how-to-calculate-transformed-skin-vertices
  143. // //result.add (temp.copy (skinVertex).applyMatrix4 (tempMatrix).multiplyScalar (skinWeights[properties[i]]));
  144. // const w = skinWeight[j]
  145. // const bone = bones[s]
  146. // if (bone) {
  147. // p.add(p.clone().applyMatrix4(bone.matrixWorld).multiplyScalar(w))
  148. // }
  149. // })
  150. })
  151. }
  152. // attributes.position is a flattened Array<Array<Vector3>>.
  153. // attributes.skinIndex is a flattened Array<Array(4)<Int>>. Each is an ordinal to a bone.
  154. // attributes.skinWeight is a flattened Array<Array(4)<Float>>. Each is a 0.0 - 1.0 weight for a bone.
  155. // if (attributes.skinIndex) {
  156. // const skinIndex = attributes.skinIndex
  157. // const skinWeight = attributes.skinWeight
  158. // const bones = object.skeleton.bones
  159. // const bonesPerPosition = slices(Array.from(skinIndex.array).map(i => bones[i]), 4)
  160. // const weightsPerPosition = slices(skinWeight.array, 4)
  161. // positions.forEach((p, i) => {
  162. // const bones = bonesPerPosition[i]
  163. // const weights = weightsPerPosition[i]
  164. // bones.forEach((bone, b) => {
  165. // const weight = weights[b]
  166. // if (weight !== 0) {
  167. // const matrix = bone.matrix.clone().multiply(object.matrixWorld)
  168. // //matrix.multiplyScalar(weight)
  169. // p.applyMatrix4(matrix)
  170. // }
  171. // })
  172. // })
  173. // }
  174. pushAll(_triangles, triangles)
  175. /* END FROM*/
  176. }
  177. });
  178. console.log('Triangles', triangles)
  179. const stl = toStl(rotate(triangles))
  180. window.save = (filename) => console.save(stl, filename || 'export.stl')
  181. console.log('save([filename]) to save')
  182. };
  183. }())
  184. };