BREP boolean algorithm / case for overlapping surfaces

This commit is contained in:
Val Erastov 2017-01-18 18:18:02 -08:00
parent c516d6548f
commit 4eb43da556

View file

@ -10,6 +10,7 @@ import Vector from '../../math/vector';
import * as math from '../../math/math';
export const TOLERANCE = 1e-8;
export const TOLERANCE_SQ = TOLERANCE * TOLERANCE;
const TYPE = {
UNION: 0,
@ -50,6 +51,8 @@ function invertLoop(loop) {
export function BooleanAlgorithm( shell1, shell2, type ) {
__DEBUG__.Clear();
const facesData = [];
initSolveData(shell1, facesData);
@ -77,7 +80,7 @@ export function BooleanAlgorithm( shell1, shell2, type ) {
}
const loop = new Loop();
while (edge) {
__DEBUG__.AddHalfEdge(edge);
//__DEBUG__.AddHalfEdge(edge);
const isNew = faceData.newEdges.indexOf(edge) != -1;
if (isNew) newLoops.add(loop);
@ -255,8 +258,8 @@ function findMaxTurningLeft(edge, edges) {
function intersectFaces(shell1, shell2, inverseCrossEdgeDirection) {
for (let i = 0; i < shell1.faces.length; i++) {
const face1 = shell1.faces[i];
for (let j = 0; j < shell2.faces.length; j++) {
const face1 = shell1.faces[i];
const face2 = shell2.faces[j];
if (face1.surface.equals(face2.surface, TOLERANCE)) {
@ -289,6 +292,11 @@ function intersectFaces(shell1, shell2, inverseCrossEdgeDirection) {
}
function collectNodesOfIntersectionOfFace(splittingFace, face, nodes) {
//__DEBUG__.Clear();
//for (let l of splittingFace.loops) l.halfEdges.forEach(he => __DEBUG__.AddHalfEdge(he, 0x00ff00));
//for (let l of face.loops) l.halfEdges.forEach(he => __DEBUG__.AddHalfEdge(he, 0x0000ff));
for (let loop of face.loops) {
collectNodesOfIntersection(splittingFace, loop, nodes);
}
@ -297,6 +305,7 @@ function collectNodesOfIntersectionOfFace(splittingFace, face, nodes) {
function collectNodesOfIntersection(face, loop, nodes) {
const verticesCases = new Set();
for (let edge of loop.halfEdges) {
//__DEBUG__.AddHalfEdge(edge);
const edgeSolveData = EdgeSolveData.get(edge);
if (edgeSolveData.skipFace.has(face)) {
continue;
@ -309,6 +318,12 @@ function collectNodesOfIntersection(face, loop, nodes) {
}
intersectFaceWithEdge(face, edge, nodes, verticesCases);
}
for (let he of loop.halfEdges) {
if (verticesCases.has(he.vertexA) && verticesCases.has(he.vertexB)) {
deleteEdge(he.edge);
}
}
}
function split(nodes, result, onCurve, direction) {
@ -431,6 +446,9 @@ function intersectFaceWithEdge(face, edge, result, vertecies) {
const ab = edge.vertexB.point.minus(p0);
const length = ab.length();
const v = ab._multiply(1 / length);
if (math.areEqual(v.dot(face.surface.normal), 0, TOLERANCE_SQ)) {
return; // we not consider edges parallel to the face
}
const edgeLine = new Line(p0, v);
const t = edgeLine.intersectSurface(face.surface);
if (t >= 0 && t <= length) {
@ -439,7 +457,7 @@ function intersectFaceWithEdge(face, edge, result, vertecies) {
//TODO: should check if point on a vertex then exclude two edges of the vertex from further intersection test cuz it would produce three identical Nodes
if (pointBelongsToFace(pointOfIntersection, face)) {
let vertexOfIntersection;
if (math.areVectorsEqual(edge.vertexA.point, pointOfIntersection, TOLERANCE)) { //TODO: TOLERANCE^2 ???
if (math.areVectorsEqual(edge.vertexA.point, pointOfIntersection, TOLERANCE)) {
vertecies.add(edge.vertexA);
vertexOfIntersection = edge.vertexA;
//console.log("point A on surface");
@ -459,6 +477,19 @@ function intersectFaceWithEdge(face, edge, result, vertecies) {
}
}
function deleteEdge(edge) {
if (edge.halfEdge1 != null) {
deleteHalfEdge(edge.halfEdge1);
}
if (edge.halfEdge2 != null) {
deleteHalfEdge(edge.halfEdge2);
}
}
function deleteHalfEdge(he) {
removeFromListInMap(he.loop.face.data[MY].vertexToEdge, he.vertexA, he);
}
function pointBelongsToFace(point, face) {
const tr = face.surface.get2DTransformation();
if (pointInsideLoop(point, face.outerLoop, tr)) {
@ -583,5 +614,15 @@ function addToListInMap(map, key, value) {
list.push(value);
}
function removeFromListInMap(map, key, value) {
let list = map.get(key);
if (list) {
const idx = list.indexOf(value);
if (idx != -1) {
list.splice(idx, 1);
}
}
}
const MY = '__BOOLEAN_ALGORITHM_DATA__';
let xxx = 0;