Doodle3D-Slicer/src/sliceActions/detectOpenClosed.js
casperlamboo 846ddcd97a Better detection of open closed shapes
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
2017-05-26 17:11:38 +02:00

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