mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-22 05:37:55 +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';
|
import * as vector2 from './helpers/vector2.js';
|
||||||
|
import * as vector3 from './helpers/vector3.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function createLines(geometry, settings) {
|
export default function createLines(geometry, settings) {
|
||||||
const faces = [];
|
const faces = [];
|
||||||
@ -26,16 +7,9 @@ export default function createLines(geometry, settings) {
|
|||||||
const lineLookup = {};
|
const lineLookup = {};
|
||||||
|
|
||||||
for (let i = 0; i < geometry.objectIndexes.length; i ++) {
|
for (let i = 0; i < geometry.objectIndexes.length; i ++) {
|
||||||
const i3 = i * 3;
|
|
||||||
const objectIndex = geometry.objectIndexes[i];
|
const objectIndex = geometry.objectIndexes[i];
|
||||||
const normal = {
|
const { x: a, y: b, z: c } = getVertex(geometry.faces, i);
|
||||||
x: geometry.faceNormals[i3],
|
const normal = calculateNormal(geometry.vertices, a, b, c);
|
||||||
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
|
// skip faces that point up or down
|
||||||
if (normal.y > .999 || normal.y < -.999) {
|
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 indexB = addLine(geometry.vertices, lineLookup, lines, b, c, i);
|
||||||
const indexC = addLine(geometry.vertices, lineLookup, lines, c, a, 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];
|
const lineIndexes = [indexA, indexB, indexC];
|
||||||
|
|
||||||
faces.push({ lineIndexes, flatNormal, objectIndex });
|
faces.push({ lineIndexes, flatNormal, objectIndex });
|
||||||
@ -55,3 +29,44 @@ export default function createLines(geometry, settings) {
|
|||||||
|
|
||||||
return { lines, faces };
|
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);
|
if (matrix && matrix.isMatrix4) geometry.applyMatrix(matrix);
|
||||||
geometry.computeFaceNormals();
|
|
||||||
|
|
||||||
const vertices = geometry.vertices.reduce((array, { x, y, z }, i) => {
|
const vertices = geometry.vertices.reduce((array, { x, y, z }, i) => {
|
||||||
const i3 = i * 3;
|
const i3 = i * 3;
|
||||||
@ -41,13 +40,6 @@ export function sliceGeometry(settings, geometry, materials, matrix, sync = fals
|
|||||||
array[i3 + 2] = c;
|
array[i3 + 2] = c;
|
||||||
return array;
|
return array;
|
||||||
}, new Uint32Array(geometry.faces.length * 3));
|
}, 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) => {
|
const objectIndexes = geometry.faces.reduce((array, { materialIndex }, i) => {
|
||||||
array[i] = materialIndex;
|
array[i] = materialIndex;
|
||||||
return array;
|
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');
|
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 }) => {
|
const openObjectIndexes = materials instanceof Array ? materials.map(({ side }) => {
|
||||||
switch (side) {
|
switch (side) {
|
||||||
@ -114,8 +106,8 @@ function sliceAsync(settings, geometry, openObjectIndexes, constructLinePreview,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { vertices, faces, objectIndexes, faceNormals } = geometry;
|
const { vertices, faces, objectIndexes } = geometry;
|
||||||
const buffers = [vertices.buffer, faces.buffer, objectIndexes.buffer, faceNormals.buffer];
|
const buffers = [vertices.buffer, faces.buffer, objectIndexes.buffer];
|
||||||
|
|
||||||
slicerWorker.postMessage({
|
slicerWorker.postMessage({
|
||||||
message: 'SLICE',
|
message: 'SLICE',
|
||||||
|
Loading…
Reference in New Issue
Block a user