diff --git a/web/app/brep/operations/boolean.js b/web/app/brep/operations/boolean.js index 73f44a29..da4e0f7c 100644 --- a/web/app/brep/operations/boolean.js +++ b/web/app/brep/operations/boolean.js @@ -65,7 +65,9 @@ export function BooleanAlgorithm( shell1, shell2, type ) { const face = faceData.face; const loops = []; const seen = new Set(); - const edges = face.outerLoop.halfEdges.concat(faceData.newEdges); + const edges = []; + for (let e of face.edges) edges.push(e); + faceData.newEdges.forEach(e => edges.push(e)); while (true) { let edge = edges.pop(); if (!edge) { @@ -176,7 +178,7 @@ function loopsToFaces(originFace, loops, out) { } } const nestedLoops = getNestedLoops(originFace, loops); - + //loops.forEach(l => l.halfEdges.forEach(h => __DEBUG__.AddHalfEdge(h))) for (let nestedLoop of nestedLoops) { if (nestedLoop.loop.isCCW(originFace.surface)) { createFaces(nestedLoop); @@ -225,7 +227,7 @@ function initSolveData(shell, facesData) { const solveData = new FaceSolveData(face); facesData.push(solveData); face.__faceSolveData = solveData; - for (let he of face.outerLoop.halfEdges) { + for (let he of face.edges) { EdgeSolveData.clear(he); solveData.vertexToEdge.set(he.vertexA, [he]); } @@ -261,8 +263,8 @@ function intersectFaces(shell1, shell2, inverseCrossEdgeDirection) { const curve = face1.surface.intersect(face2.surface); const nodes = []; - collectNodesOfIntersection(face2, face1.outerLoop, nodes); - collectNodesOfIntersection(face1, face2.outerLoop, nodes); + collectNodesOfIntersectionOfFace(face2, face1, nodes); + collectNodesOfIntersectionOfFace(face1, face2, nodes); const newEdges = []; const direction = face1.surface.normal.cross(face2.surface.normal); @@ -283,6 +285,12 @@ function intersectFaces(shell1, shell2, inverseCrossEdgeDirection) { } } +function collectNodesOfIntersectionOfFace(splittingFace, face, nodes) { + for (let loop of face.loops) { + collectNodesOfIntersection(splittingFace, loop, nodes); + } +} + function collectNodesOfIntersection(face, loop, nodes) { const verticesCases = new Set(); for (let edge of loop.halfEdges) { @@ -449,9 +457,20 @@ function intersectFaceWithEdge(face, edge, result, vertecies) { } function pointBelongsToFace(point, face) { - //TODO: holes case const tr = new Matrix3().setBasis(face.surface.calculateBasis()); - const polygon = face.outerLoop.asPolygon().map(p => tr.apply(p)); + if (pointInsideLoop(point, face.outerLoop, tr)) { + for (let innerLoop of face.innerLoops) { + if (pointInsideLoop(point, innerLoop, tr)) { + return false; + } + } + return true; + } + return false; +} + +function pointInsideLoop(point, loop, tr) { + const polygon = loop.asPolygon().map(p => tr.apply(p)); const point2d = tr.apply(point); return pointInsidePolygon(point2d, polygon); } diff --git a/web/app/brep/topo/face.js b/web/app/brep/topo/face.js index 527b657d..83472879 100644 --- a/web/app/brep/topo/face.js +++ b/web/app/brep/topo/face.js @@ -8,7 +8,8 @@ export class Face extends TopoObject { this.shell = null; this.outerLoop = null; this.innerLoops = []; - this.defineIterable('loops', () => loopsGenerator(this)) + this.defineIterable('loops', () => loopsGenerator(this)); + this.defineIterable('edges', () => halfEdgesGenerator(this)) } } @@ -20,4 +21,11 @@ export function* loopsGenerator(face) { yield innerLoop; } } - \ No newline at end of file + +export function* halfEdgesGenerator(face) { + for (let loop of face.loops) { + for (let halfEdge of loop.halfEdges) { + yield halfEdge; + } + } +} diff --git a/web/app/brep/topo/loop.js b/web/app/brep/topo/loop.js index 17dfb64b..2ed9124a 100644 --- a/web/app/brep/topo/loop.js +++ b/web/app/brep/topo/loop.js @@ -18,7 +18,7 @@ export class Loop extends TopoObject { const lowestLeftIdx = math.findLowestLeftPoint(polygon2d); const n = polygon.length; const nextIdx = ((lowestLeftIdx + 1) % n); - const prevIdx = ((n - lowestLeftIdx - 1) % n); + const prevIdx = ((n + lowestLeftIdx - 1) % n); const o = polygon[lowestLeftIdx]; const first = polygon[nextIdx].minus(o); const last = o.minus(polygon[prevIdx]);