calculate face normals in slice process

This commit is contained in:
casperlamboo 2018-02-12 11:41:51 +01:00
parent ca886afa25
commit caf5e655da
3 changed files with 87 additions and 42 deletions

View File

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

View File

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

View File

@ -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',