diff --git a/src/sliceActions/createLines.js b/src/sliceActions/createLines.js index 2147290..f0deb8a 100644 --- a/src/sliceActions/createLines.js +++ b/src/sliceActions/createLines.js @@ -1,24 +1,5 @@ -import { normalize } from './helpers/vector2.js'; - -function addLine(vertices, lineLookup, lines, a, b, faceIndex) { - let index; - if (typeof lineLookup[`${b}_${a}`] !== 'undefined') { - index = lineLookup[`${b}_${a}`]; - } else { - index = lines.length; - lineLookup[`${a}_${b}`] = index; - - 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 }); - } - lines[index].faces.push(faceIndex); - - return index; -} +import * as vector2 from './helpers/vector2.js'; +import * as vector3 from './helpers/vector3.js'; export default function createLines(geometry, settings) { const faces = []; @@ -26,16 +7,9 @@ export default function createLines(geometry, settings) { const lineLookup = {}; 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]; + const { x: a, y: b, z: c } = getVertex(geometry.faces, i); + const normal = calculateNormal(geometry.vertices, a, b, c); // skip faces that point up or down if (normal.y > .999 || normal.y < -.999) { @@ -47,7 +21,7 @@ export default function createLines(geometry, settings) { 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 flatNormal = vector2.normalize({ x: normal.z, y: normal.x }); const lineIndexes = [indexA, indexB, indexC]; faces.push({ lineIndexes, flatNormal, objectIndex }); @@ -55,3 +29,44 @@ export default function createLines(geometry, settings) { return { lines, faces }; } + +function addLine(vertices, lineLookup, lines, a, b, faceIndex) { + let index; + if (typeof lineLookup[`${b}_${a}`] !== 'undefined') { + index = lineLookup[`${b}_${a}`]; + } else { + index = lines.length; + lineLookup[`${a}_${b}`] = index; + + const start = getVertex(vertices, a); + const end = getVertex(vertices, b); + + const line = { start, end }; + const faces = []; + lines.push({ line, faces }); + } + lines[index].faces.push(faceIndex); + + return index; +} + +function calculateNormal(vertices, a, b, c) { + a = getVertex(vertices, a); + b = getVertex(vertices, b); + c = getVertex(vertices, c); + + const cb = vector3.subtract(c, b); + const ab = vector3.subtract(a, b); + const normal = vector3.normalize(vector3.cross(cb, ab)); + + return normal; +} + +function getVertex(vertices, i) { + const i3 = i * 3; + return { + x: vertices[i3], + y: vertices[i3 + 1], + z: vertices[i3 + 2] + }; +} diff --git a/src/sliceActions/helpers/vector3.js b/src/sliceActions/helpers/vector3.js new file mode 100644 index 0000000..7f227de --- /dev/null +++ b/src/sliceActions/helpers/vector3.js @@ -0,0 +1,38 @@ +export const subtract = (a, b) => ({ + x: a.x - b.x, + y: a.y - b.y, + z: a.z - b.z +}); +export const add = (a, b) => ({ + x: a.x + b.x, + y: a.y + b.y, + z: a.z + b.z +}); +export const scale = (v, factor) => ({ + x: v.x * factor, + y: v.y * factor, + z: v.z * factor, +}); +export const divide = (v, factor) => ({ + x: v.x / factor, + y: v.y / factor, + z: v.z / factor +}); +export const cross = (a, b) => ({ + x: a.y * b.z - a.z * b.y, + y: a.z * b.x - a.x * b.z, + z: a.x * b.y - a.y * b.x +}); +export const equals = (a, b) => a.x === b.x && a.y === b.y && a.z === b.z; +export const almostEquals = (a, b) => Math.abs(a.x - b.x) < 0.001 && Math.abs(a.y - b.y) < 0.001 && Math.abs(a.z - b.z) < 0.001; +export const length = (v) => Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); +export const distanceTo = (a, b) => length(subtract(a, b)); +export const normalize = (v) => { + const l = length(v); + + return { + x: v.x / l, + y: v.y / l, + z: v.z / l + }; +}; diff --git a/src/slicer.js b/src/slicer.js index a44a447..5c28fc8 100644 --- a/src/slicer.js +++ b/src/slicer.js @@ -25,7 +25,6 @@ export function sliceGeometry(settings, geometry, materials, matrix, sync = fals } if (matrix && matrix.isMatrix4) geometry.applyMatrix(matrix); - geometry.computeFaceNormals(); const vertices = geometry.vertices.reduce((array, { x, y, z }, i) => { const i3 = i * 3; @@ -41,13 +40,6 @@ export function sliceGeometry(settings, geometry, materials, matrix, sync = fals 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; @@ -55,7 +47,7 @@ export function sliceGeometry(settings, geometry, materials, matrix, sync = fals if (faces.length === 0) throw new Error('Geometry does not contain any data'); - geometry = { vertices, faces, objectIndexes, faceNormals }; + geometry = { vertices, faces, objectIndexes }; const openObjectIndexes = materials instanceof Array ? materials.map(({ side }) => { switch (side) { @@ -114,8 +106,8 @@ function sliceAsync(settings, geometry, openObjectIndexes, constructLinePreview, } }); - const { vertices, faces, objectIndexes, faceNormals } = geometry; - const buffers = [vertices.buffer, faces.buffer, objectIndexes.buffer, faceNormals.buffer]; + const { vertices, faces, objectIndexes } = geometry; + const buffers = [vertices.buffer, faces.buffer, objectIndexes.buffer]; slicerWorker.postMessage({ message: 'SLICE',