From 0f579b80555d591afb933bbe9ca8886ffc3cee22 Mon Sep 17 00:00:00 2001 From: casperlamboo Date: Tue, 18 Jul 2017 10:23:16 +0200 Subject: [PATCH] update detect open closed shapes logic --- .../calculateLayersIntersections.js | 2 + src/sliceActions/createLines.js | 46 ++++++++--------- src/sliceActions/detectOpenClosed.js | 50 ++++++++----------- src/sliceActions/slice.js | 5 +- 4 files changed, 45 insertions(+), 58 deletions(-) diff --git a/src/sliceActions/calculateLayersIntersections.js b/src/sliceActions/calculateLayersIntersections.js index 5187827..707297e 100644 --- a/src/sliceActions/calculateLayersIntersections.js +++ b/src/sliceActions/calculateLayersIntersections.js @@ -13,6 +13,8 @@ export default function calculateLayersIntersections(lines, settings) { for (let lineIndex = 0; lineIndex < lines.length; lineIndex ++) { const line = lines[lineIndex].line; + if (line.isFlat) continue; + 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); diff --git a/src/sliceActions/createLines.js b/src/sliceActions/createLines.js index a45559b..4984ca9 100644 --- a/src/sliceActions/createLines.js +++ b/src/sliceActions/createLines.js @@ -1,6 +1,6 @@ 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; 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]), connects: [], normals: [], - open: false + isFlat }); return index; } -export default function createLines(geometry, settings, openClosed) { +export default function createLines(geometry, settings) { console.log('constructing unique lines from geometry'); const lines = []; @@ -22,34 +22,28 @@ export default function createLines(geometry, settings, openClosed) { for (let i = 0; i < geometry.faces.length; i ++) { const face = geometry.faces[i]; - const open = openClosed[i]; - if (face.normal.y !== 1 && face.normal.y !== -1) { - const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize(); + const lookupA = lineLookup[`${face.b}_${face.a}`]; + const lookupB = lineLookup[`${face.c}_${face.b}`]; + const lookupC = lineLookup[`${face.a}_${face.c}`]; - const lookupA = lineLookup[`${face.b}_${face.a}`]; - const lookupB = lineLookup[`${face.c}_${face.b}`]; - const lookupC = lineLookup[`${face.a}_${face.c}`]; + const isFlat = face.normal.y !== 1 && face.normal.y !== -1; - // only add unique lines - // returns index of said line - const indexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b); - const indexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c); - const indexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a); + // only add unique lines + // returns index of said line + const lineIndexA = typeof lookupA !== 'undefined' ? lookupA : addLine(geometry, lineLookup, lines, face.a, face.b, isFlat); + const lineIndexB = typeof lookupB !== 'undefined' ? lookupB : addLine(geometry, lineLookup, lines, face.b, face.c, isFlat); + const lineIndexC = typeof lookupC !== 'undefined' ? lookupC : addLine(geometry, lineLookup, lines, face.c, face.a, isFlat); - // set connecting lines (based on face) - lines[indexA].connects.push(indexB, indexC); - lines[indexB].connects.push(indexC, indexA); - lines[indexC].connects.push(indexA, indexB); + // set connecting lines (based on face) + lines[lineIndexA].connects.push(lineIndexB, lineIndexC); + lines[lineIndexB].connects.push(lineIndexC, lineIndexA); + lines[lineIndexC].connects.push(lineIndexA, lineIndexB); - lines[indexA].normals.push(normal); - lines[indexB].normals.push(normal); - lines[indexC].normals.push(normal); - - lines[indexA].open = open; - lines[indexB].open = open; - lines[indexC].open = open; - } + const normal = new THREE.Vector2(face.normal.z, face.normal.x).normalize(); + lines[lineIndexA].normals.push(normal); + lines[lineIndexB].normals.push(normal); + lines[lineIndexC].normals.push(normal); } return lines; diff --git a/src/sliceActions/detectOpenClosed.js b/src/sliceActions/detectOpenClosed.js index bcfbad9..228280e 100644 --- a/src/sliceActions/detectOpenClosed.js +++ b/src/sliceActions/detectOpenClosed.js @@ -1,42 +1,45 @@ -export default function detectOpenClosed(geometry) { +export default function detectOpenClosed(lines) { console.log('detecting open and closed lines'); - const pools = getPools(geometry); - const openVertices = getOpenVertices(geometry); + const pools = getPools(lines); + const openLines = lines.map(line => line.connects.length === 2); - 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]); + 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 ++) { 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; } } + // no pool found + // create new pool const pool = []; pools.push(pool); return pool; } -function getPools(geometry) { +function getPools(lines) { 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 lineIndex = 0; lineIndex < lines.length; lineIndex ++) { + const pool = findPool(pools, lines, lineIndex); + pool.push(lineIndex); } for (let i = 0; i < pools.length; i ++) { @@ -46,8 +49,9 @@ function getPools(geometry) { 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)) { + const { connects } = lines[poolA[k]]; + + if (poolB.find(lineIndex => connects.includes(lineIndex))) { poolA.splice(poolA.length, 0, ...poolB); poolB.splice(0, poolB.length); } @@ -57,15 +61,3 @@ function getPools(geometry) { 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); -} diff --git a/src/sliceActions/slice.js b/src/sliceActions/slice.js index 2b3f47f..6fdbdfa 100644 --- a/src/sliceActions/slice.js +++ b/src/sliceActions/slice.js @@ -13,12 +13,11 @@ import applyPrecision from './applyPrecision.js'; import removePrecision from './removePrecision.js'; export default function(geometry, settings) { - geometry.mergeVertices(); geometry.computeFaceNormals(); // get unique lines from geometry; - const openClosed = detectOpenClosed(geometry); - const lines = createLines(geometry, settings, openClosed); + const lines = createLines(geometry, settings); + const openClosed = detectOpenClosed(lines); const { layerIntersectionIndexes,