mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-07-05 02:10:43 +02:00
when a ‘single walled’, ‘closed’ shape is sliced the shape will appear to be closed by the slicer. This happens because the start and endpoint of the 2d shape are connected. This commits fixes this. In the new approach al parts of the geometry are split up into shapes. Then the 3d shapes are places into two categories (closed and open geometries). Based on weather the 3d geometry is open or closed the 2d shape will be open or closed @mith @peteruithoven
72 lines
1.8 KiB
JavaScript
72 lines
1.8 KiB
JavaScript
export default function detectOpenClosed(geometry) {
|
|
console.log('detecting open and closed lines');
|
|
|
|
const pools = getPools(geometry);
|
|
const openVertices = getOpenVertices(geometry);
|
|
|
|
const openFaces = [];
|
|
for (let i = 0; i < pools.length; i ++) {
|
|
const pool = pools[i];
|
|
|
|
const isOpen = pool.some(face => openVertices[face.a] || openVertices[face.b] || openVertices[face.c]);
|
|
|
|
if (isOpen) openFaces.splice(openFaces.length, 0, ...pool);
|
|
}
|
|
|
|
return geometry.faces.map(face => openFaces.includes(face));
|
|
}
|
|
|
|
function findPool(pools, faceA) {
|
|
for (let i = 0; i < pools.length; i ++) {
|
|
const pool = pools[i];
|
|
|
|
if (pool.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) {
|
|
return pool;
|
|
}
|
|
}
|
|
|
|
const pool = [];
|
|
pools.push(pool);
|
|
return pool;
|
|
}
|
|
|
|
function getPools(geometry) {
|
|
const pools = [];
|
|
|
|
for (let i = 0; i < geometry.faces.length; i ++) {
|
|
const face = geometry.faces[i];
|
|
const pool = findPool(pools, face);
|
|
pool.push(face);
|
|
}
|
|
|
|
for (let i = 0; i < pools.length; i ++) {
|
|
const poolA = pools[i];
|
|
|
|
for (let j = i + 1; j < pools.length; j ++) {
|
|
const poolB = pools[j];
|
|
|
|
for (let k = 0; k < poolA.length; k ++) {
|
|
const faceA = poolA[k];
|
|
if (poolB.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) {
|
|
poolA.splice(poolA.length, 0, ...poolB);
|
|
poolB.splice(0, poolB.length);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return pools.filter(pool => pool.length > 0);
|
|
}
|
|
|
|
function getOpenVertices(geometry) {
|
|
const vertices = Array(geometry.vertices.length).fill(0);
|
|
for (let i = 0; i < geometry.faces.length; i ++) {
|
|
const face = geometry.faces[i];
|
|
vertices[face.a] ++;
|
|
vertices[face.b] ++;
|
|
vertices[face.c] ++;
|
|
}
|
|
|
|
return vertices.map(numFaces => numFaces < 4);
|
|
}
|