mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-12-22 19:13:50 +01:00
calculate face normals in slice process
This commit is contained in:
parent
ca886afa25
commit
caf5e655da
@ -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]
|
||||
};
|
||||
}
|
||||
|
38
src/sliceActions/helpers/vector3.js
Normal file
38
src/sliceActions/helpers/vector3.js
Normal 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
|
||||
};
|
||||
};
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user