update detect open closed shapes logic

This commit is contained in:
casperlamboo 2017-07-18 10:23:16 +02:00
parent b92a35a0c1
commit 0f579b8055
4 changed files with 45 additions and 58 deletions

View File

@ -13,6 +13,8 @@ export default function calculateLayersIntersections(lines, settings) {
for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) { for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) {
const line = lines[lineIndex].line; const line = lines[lineIndex].line;
if (line.isFlat) continue;
const min = Math.ceil(Math.min(line.start.y, line.end.y) / layerHeight); const min = Math.ceil(Math.min(line.start.y, line.end.y) / layerHeight);
const max = Math.floor(Math.max(line.start.y, line.end.y) / layerHeight); const max = Math.floor(Math.max(line.start.y, line.end.y) / layerHeight);

View File

@ -1,6 +1,6 @@
import * as THREE from 'three.js'; import * as THREE from 'three.js';
function addLine(geometry, lineLookup, lines, a, b) { function addLine(geometry, lineLookup, lines, a, b, isFlat) {
const index = lines.length; const index = lines.length;
lineLookup[`${a}_${b}`] = index; lineLookup[`${a}_${b}`] = index;
@ -8,13 +8,13 @@ function addLine(geometry, lineLookup, lines, a, b) {
line: new THREE.Line3(geometry.vertices[a], geometry.vertices[b]), line: new THREE.Line3(geometry.vertices[a], geometry.vertices[b]),
connects: [], connects: [],
normals: [], normals: [],
open: false isFlat
}); });
return index; return index;
} }
export default function createLines(geometry, settings, openClosed) { export default function createLines(geometry, settings) {
console.log('constructing unique lines from geometry'); console.log('constructing unique lines from geometry');
const lines = []; const lines = [];
@ -22,34 +22,28 @@ export default function createLines(geometry, settings, openClosed) {
for (let i = 0; i < geometry.faces.length; i ++) { for (let i = 0; i < geometry.faces.length; i ++) {
const face = geometry.faces[i]; const face = geometry.faces[i];
const open = openClosed[i];
if (face.normal.y !== 1 && face.normal.y !== -1) { const lookupA = lineLookup[`${face.b}_${face.a}`];
const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize(); const lookupB = lineLookup[`${face.c}_${face.b}`];
const lookupC = lineLookup[`${face.a}_${face.c}`];
const lookupA = lineLookup[`${face.b}_${face.a}`]; const isFlat = face.normal.y !== 1 && face.normal.y !== -1;
const lookupB = lineLookup[`${face.c}_${face.b}`];
const lookupC = lineLookup[`${face.a}_${face.c}`];
// only add unique lines // only add unique lines
// returns index of said line // returns index of said line
const indexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b); const lineIndexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b, isFlat);
const indexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c); const lineIndexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c, isFlat);
const indexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a); const lineIndexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a, isFlat);
// set connecting lines (based on face) // set connecting lines (based on face)
lines[indexA].connects.push(indexB, indexC); lines[lineIndexA].connects.push(lineIndexB, lineIndexC);
lines[indexB].connects.push(indexC, indexA); lines[lineIndexB].connects.push(lineIndexC, lineIndexA);
lines[indexC].connects.push(indexA, indexB); lines[lineIndexC].connects.push(lineIndexA, lineIndexB);
lines[indexA].normals.push(normal); const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize();
lines[indexB].normals.push(normal); lines[lineIndexA].normals.push(normal);
lines[indexC].normals.push(normal); lines[lineIndexB].normals.push(normal);
lines[lineIndexC].normals.push(normal);
lines[indexA].open = open;
lines[indexB].open = open;
lines[indexC].open = open;
}
} }
return lines; return lines;

View File

@ -1,42 +1,45 @@
export default function detectOpenClosed(geometry) { export default function detectOpenClosed(lines) {
console.log('detecting open and closed lines'); console.log('detecting open and closed lines');
const pools = getPools(geometry); const pools = getPools(lines);
const openVertices = getOpenVertices(geometry); const openLines = lines.map(line => line.connects.length === 2);
const openFaces = [];
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
const pool = pools[i]; const pool = pools[i];
const isOpen = pool.some(face => openVertices[face.a] || openVertices[face.b] || openVertices[face.c]); const isOpen = pool.some(lineIndex => openLines[lineIndex]);
if (isOpen) openFaces.splice(openFaces.length, 0, ...pool); for (let j = 0; j < pool.length; j ++) {
const lineIndex = pool[j];
const line = lines[lineIndex];
line.open = isOpen;
}
} }
return geometry.faces.map(face => openFaces.includes(face));
} }
function findPool(pools, faceA) { function findPool(pools, lines, lineIndex) {
const { connects } = lines[lineIndex];
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
const pool = pools[i]; const pool = pools[i];
if (pool.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) { if (pool.find(lineIndex => connects.includes(lineIndex))) {
return pool; return pool;
} }
} }
// no pool found
// create new pool
const pool = []; const pool = [];
pools.push(pool); pools.push(pool);
return pool; return pool;
} }
function getPools(geometry) { function getPools(lines) {
const pools = []; const pools = [];
for (let i = 0; i < geometry.faces.length; i ++) { for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) {
const face = geometry.faces[i]; const pool = findPool(pools, lines, lineIndex);
const pool = findPool(pools, face); pool.push(lineIndex);
pool.push(face);
} }
for (let i = 0; i < pools.length; i ++) { for (let i = 0; i < pools.length; i ++) {
@ -46,8 +49,9 @@ function getPools(geometry) {
const poolB = pools[j]; const poolB = pools[j];
for (let k = 0; k < poolA.length; k ++) { for (let k = 0; k < poolA.length; k ++) {
const faceA = poolA[k]; const { connects } = lines[poolA[k]];
if (poolB.find(faceB => faceA.a === faceB.a || faceA.a === faceB.b || faceA.a === faceB.c)) {
if (poolB.find(lineIndex => connects.includes(lineIndex))) {
poolA.splice(poolA.length, 0, ...poolB); poolA.splice(poolA.length, 0, ...poolB);
poolB.splice(0, poolB.length); poolB.splice(0, poolB.length);
} }
@ -57,15 +61,3 @@ function getPools(geometry) {
return pools.filter(pool => pool.length > 0); 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);
}

View File

@ -13,12 +13,11 @@ import applyPrecision from './applyPrecision.js';
import removePrecision from './removePrecision.js'; import removePrecision from './removePrecision.js';
export default function(geometry, settings) { export default function(geometry, settings) {
geometry.mergeVertices();
geometry.computeFaceNormals(); geometry.computeFaceNormals();
// get unique lines from geometry; // get unique lines from geometry;
const openClosed = detectOpenClosed(geometry); const lines = createLines(geometry, settings);
const lines = createLines(geometry, settings, openClosed); const openClosed = detectOpenClosed(lines);
const { const {
layerIntersectionIndexes, layerIntersectionIndexes,