diff --git a/src/sliceActions/createLines.js b/src/sliceActions/createLines.js index 0c8cf20..7dcb51b 100644 --- a/src/sliceActions/createLines.js +++ b/src/sliceActions/createLines.js @@ -1,6 +1,6 @@ import { normalize } from './helpers/vector2D.js'; -function addLine(geometry, lineLookup, lines, a, b, faceIndex) { +function addLine(vertices, lineLookup, lines, a, b, faceIndex) { let index; if (typeof lineLookup[`${b}_${a}`] !== 'undefined') { index = lineLookup[`${b}_${a}`]; @@ -8,7 +8,10 @@ function addLine(geometry, lineLookup, lines, a, b, faceIndex) { index = lines.length; lineLookup[`${a}_${b}`] = index; - const line = { start: geometry.vertices[a], end: geometry.vertices[b] }; + const start = { x: vertices[a * 3], y: vertices[a * 3 + 1], z: vertices[a * 3 + 2] }; + const end = { x: vertices[b * 3], y: vertices[b * 3 + 1], z: vertices[b * 3 + 2] }; + + const line = { start, end }; const faces = []; lines.push({ line, faces }); } @@ -22,8 +25,17 @@ export default function createLines(geometry, settings) { const lines = []; const lineLookup = {}; - for (let i = 0; i < geometry.faces.length; i ++) { - const { normal, materialIndex: objectIndex, a, b, c } = geometry.faces[i]; + for (let i = 0; i < geometry.objectIndexes.length; i ++) { + const i3 = i * 3; + const objectIndex = geometry.objectIndexes[i]; + const normal = { + x: geometry.faceNormals[i3], + y: geometry.faceNormals[i3 + 1], + z: geometry.faceNormals[i3 + 2] + }; + const a = geometry.faces[i3]; + const b = geometry.faces[i3 + 1]; + const c = geometry.faces[i3 + 2]; // skip faces that point up or down if (normal.y > .999 || normal.y < -.999) { @@ -31,9 +43,9 @@ export default function createLines(geometry, settings) { continue; } - const indexA = addLine(geometry, lineLookup, lines, a, b, i); - const indexB = addLine(geometry, lineLookup, lines, b, c, i); - const indexC = addLine(geometry, lineLookup, lines, c, a, i); + const indexA = addLine(geometry.vertices, lineLookup, lines, a, b, i); + const indexB = addLine(geometry.vertices, lineLookup, lines, b, c, i); + const indexC = addLine(geometry.vertices, lineLookup, lines, c, a, i); const flatNormal = normalize({ x: normal.z, y: normal.x }); const lineIndexes = [indexA, indexB, indexC]; diff --git a/src/sliceActions/slice.js b/src/sliceActions/slice.js index 8a36539..516864b 100644 --- a/src/sliceActions/slice.js +++ b/src/sliceActions/slice.js @@ -65,8 +65,9 @@ export default function(settings, geometry, openObjectIndexes, constructLinePrev updateProgress('Finished'); // if (constructLinePreview) gcode.linePreview = createGcodeGeometry(gcode.gcode); - // gcode.gcode = gcodeToString(gcode.gcode); - // return gcode; + + gcode.gcode = gcodeToString(gcode.gcode); + return gcode; } const PRECISION_INVERSE = 1 / PRECISION; diff --git a/src/slicer.js b/src/slicer.js index 7ee9723..79590cb 100644 --- a/src/slicer.js +++ b/src/slicer.js @@ -23,13 +23,38 @@ export function sliceGeometry(settings, geometry, materials, matrix, sync = fals throw new Error('Geometry is not an instance of BufferGeometry or Geometry'); } - if (geometry.faces.length === 0) { - throw new Error('Geometry does not contain any data'); - } + if (matrix && matrix.isMatrix4) geometry.applyMatrix(matrix); + geometry.computeFaceNormals(); - if (matrix && matrix.isMatrix4) { - geometry.applyMatrix(matrix); - } + const vertices = geometry.vertices.reduce((array, { x, y, z }, i) => { + const i3 = i * 3; + array[i3] = x; + array[i3 + 1] = y; + array[i3 + 2] = z; + return array; + }, new Float32Array(geometry.vertices.length * 3)); + const faces = geometry.faces.reduce((array, { a, b, c }, i) => { + const i3 = i * 3; + array[i3] = a; + array[i3 + 1] = b; + array[i3 + 2] = c; + return array; + }, new Uint32Array(geometry.faces.length * 3)); + const faceNormals = geometry.faces.reduce((array, { normal: { x, y, z } }, i) => { + const i3 = i * 3; + array[i3] = x; + array[i3 + 1] = y; + array[i3 + 2] = z; + return array; + }, new Float32Array(geometry.faces.length * 3)); + const objectIndexes = geometry.faces.reduce((array, { materialIndex }, i) => { + array[i] = materialIndex; + return array; + }, new Uint8Array(geometry.faces.length)); + + if (faces.length === 0) throw new Error('Geometry does not contain any data'); + + geometry = { vertices, faces, objectIndexes, faceNormals }; const openObjectIndexes = materials instanceof Array ? materials.map(({ side }) => { switch (side) { @@ -95,11 +120,12 @@ function sliceAsync(settings, geometry, openObjectIndexes, constructLinePreview, } }); - // send geometry and settings to worker to start the slicing progress - geometry = geometry.toJSON(); + const { vertices, faces, objectIndexes, faceNormals } = geometry; + const buffers = [vertices.buffer, faces.buffer, objectIndexes.buffer, faceNormals.buffer]; + slicerWorker.postMessage({ message: 'SLICE', data: { settings, geometry, openObjectIndexes, constructLinePreview } - }); + }, buffers); }); } diff --git a/src/slicer.worker.js b/src/slicer.worker.js index c43f88a..4ebcb50 100644 --- a/src/slicer.worker.js +++ b/src/slicer.worker.js @@ -1,6 +1,5 @@ import 'core-js'; // polyfills import slice from './sliceActions/slice.js'; -import * as THREE from 'three'; const onProgress = progress => { self.postMessage({ @@ -9,14 +8,11 @@ const onProgress = progress => { }); } -const loader = new THREE.JSONLoader(); - self.addEventListener('message', (event) => { const { message, data } = event.data; switch (message) { case 'SLICE': { - const { settings, geometry: JSONGeometry, constructLinePreview, openObjectIndexes } = data; - const { geometry } = loader.parse(JSONGeometry.data); + const { settings, geometry, constructLinePreview, openObjectIndexes } = data; const gcode = slice(settings, geometry, openObjectIndexes, constructLinePreview, onProgress);