mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-22 13:37:58 +01:00
fix intersecties to shapes code
This commit is contained in:
parent
4fc34d0272
commit
0ef85cc918
@ -18,6 +18,8 @@ export const normal = (a) => ({
|
|||||||
x: -a.y,
|
x: -a.y,
|
||||||
y: a.x
|
y: a.x
|
||||||
});
|
});
|
||||||
|
export const equals = (a, b) => a.x === b.x && a.y === b.y;
|
||||||
|
export const almostEquals = (a, b) => Math.abs(a.x - b.x) < 0.001 && Math.abs(a.y - b.y) < 0.001;
|
||||||
export const dot = (a, b) => a.x * b.x + a.y * b.y;
|
export const dot = (a, b) => a.x * b.x + a.y * b.y;
|
||||||
export const length = (v) => Math.sqrt(v.x * v.x + v.y * v.y);
|
export const length = (v) => Math.sqrt(v.x * v.x + v.y * v.y);
|
||||||
export const distanceTo = (a, b) => length(subtract(a, b));
|
export const distanceTo = (a, b) => length(subtract(a, b));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { subtract, normal, normalize, dot, distanceTo, clone } from './helpers/VectorUtils.js';
|
import { subtract, normal, normalize, dot, almostEquals } from './helpers/VectorUtils.js';
|
||||||
|
|
||||||
export default function intersectionsToShapes(intersectionLayers, faces, openObjectIndexes, settings) {
|
export default function intersectionsToShapes(intersectionLayers, faces, openObjectIndexes, settings) {
|
||||||
const layers = [];
|
const layers = [];
|
||||||
@ -86,84 +86,56 @@ export default function intersectionsToShapes(intersectionLayers, faces, openObj
|
|||||||
const shape = shapes[objectIndex].map(lineSegment => lineSegment.map(pointIndex => points[pointIndex]));
|
const shape = shapes[objectIndex].map(lineSegment => lineSegment.map(pointIndex => points[pointIndex]));
|
||||||
const openShape = openObjectIndexes[objectIndex];
|
const openShape = openObjectIndexes[objectIndex];
|
||||||
|
|
||||||
const lines = [shape.pop()];
|
const lines = [];
|
||||||
|
|
||||||
loop: while (shape.length !== 0) {
|
const connectPoints = [];
|
||||||
for (let i = 0; i < lines.length; i ++) {
|
for (let pathIndex = 0; pathIndex < shape.length; pathIndex ++) {
|
||||||
const line = lines[i];
|
const path = shape[pathIndex];
|
||||||
|
|
||||||
const lastPoint = line[line.length - 1];
|
let shapeStartPoint = path[0];
|
||||||
|
for (const point of connectPoints) {
|
||||||
let closestSegmentEnd;
|
if (almostEquals(point.point, shapeStartPoint)) {
|
||||||
let endHit = false;
|
point.start = pathIndex;
|
||||||
const distanceEnd = new WeakMap();
|
shapeStartPoint = null;
|
||||||
for (let i = 0; i < shape.length; i ++) {
|
break;
|
||||||
const lineSegment = shape[i];
|
|
||||||
if (lastPoint === lineSegment[0]) {
|
|
||||||
closestSegmentEnd = lineSegment;
|
|
||||||
endHit = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const distance = distanceTo(lastPoint, lineSegment[0]);
|
|
||||||
distanceEnd.set(lineSegment, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!endHit) {
|
|
||||||
closestSegmentEnd = shape.sort((a, b) => {
|
|
||||||
const distanceA = distanceEnd.get(a);
|
|
||||||
const distanceB = distanceEnd.get(b);
|
|
||||||
if (distanceA === distanceB) return distanceTo(a[0], a[1]) - distanceTo(b[0], b[1]);
|
|
||||||
return distanceA - distanceB;
|
|
||||||
})[0];
|
|
||||||
|
|
||||||
if (distanceTo(closestSegmentEnd[0], lastPoint) < .001) endHit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endHit) {
|
|
||||||
shape.splice(shape.indexOf(closestSegmentEnd), 1);
|
|
||||||
line.splice(line.length, 0, closestSegmentEnd[1]);
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPoint = line[0];
|
|
||||||
|
|
||||||
let closestSegmentStart;
|
|
||||||
let hitStart = false;
|
|
||||||
const distanceStart = new WeakMap();
|
|
||||||
for (let i = 0; i < shape.length; i ++) {
|
|
||||||
const lineSegment = shape[i];
|
|
||||||
if (firstPoint === lineSegment[1]) {
|
|
||||||
closestSegmentStart = lineSegment;
|
|
||||||
hitStart = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const distance = distanceTo(firstPoint, lineSegment[1]);
|
|
||||||
distanceStart.set(lineSegment, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hitStart) {
|
|
||||||
closestSegmentStart = shape.sort((a, b) => {
|
|
||||||
const distanceA = distanceStart.get(a);
|
|
||||||
const distanceB = distanceStart.get(b);
|
|
||||||
if (distanceA === distanceB) return distanceTo(a[0], a[1]) - distanceTo(b[0], b[1]);
|
|
||||||
return distanceA - distanceB;
|
|
||||||
})[0];
|
|
||||||
|
|
||||||
if (distanceTo(closestSegmentStart[1], firstPoint) < .001) hitStart = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hitStart) {
|
|
||||||
shape.splice(shape.indexOf(closestSegmentStart), 1);
|
|
||||||
line.splice(0, 0, closestSegmentStart[0]);
|
|
||||||
continue loop;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lines.push(shape.pop());
|
if (shapeStartPoint) connectPoints.push({ point: shapeStartPoint, start: pathIndex, end: null });
|
||||||
|
|
||||||
|
let shapeEndPoint = path[path.length - 1];
|
||||||
|
for (const point of connectPoints) {
|
||||||
|
if (almostEquals(point.point, shapeEndPoint)) {
|
||||||
|
point.end = pathIndex;
|
||||||
|
shapeEndPoint = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shapeEndPoint) connectPoints.push({ point: shapeEndPoint, start: null, end: pathIndex });
|
||||||
|
}
|
||||||
|
|
||||||
|
while (connectPoints.length !== 0) {
|
||||||
|
let { start, end } = connectPoints.pop();
|
||||||
|
|
||||||
|
const line = [];
|
||||||
|
if (start !== null) line.push(...shape[start]);
|
||||||
|
|
||||||
|
let newPoint;
|
||||||
|
while (end !== null && (newPoint = connectPoints.find(point => point.start === end))) {
|
||||||
|
line.push(...shape[newPoint.start]);
|
||||||
|
connectPoints.splice(connectPoints.indexOf(newPoint), 1);
|
||||||
|
|
||||||
|
if (newPoint.end === start) break;
|
||||||
|
|
||||||
|
end = newPoint.end;
|
||||||
|
start = newPoint.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openShape) {
|
if (openShape) {
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const closed = distanceTo(line[0], line[line.length - 1]) < .001;
|
const closed = almostEquals(line[0], line[line.length - 1]);
|
||||||
if (closed) {
|
if (closed) {
|
||||||
lineShapesClosed.push(line);
|
lineShapesClosed.push(line);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user