From 7add275d404aca0811cfc4483c260b7cb361febb Mon Sep 17 00:00:00 2001 From: QuimMoya Date: Mon, 28 Oct 2024 11:12:05 +0100 Subject: [PATCH] Added method to deal with huge numbers of triangles --- .../boolean-utils/shared-position.h | 67 ++++++++++++++++++- src/cpp/geometry/operations/geometryutils.h | 5 -- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/cpp/geometry/operations/boolean-utils/shared-position.h b/src/cpp/geometry/operations/boolean-utils/shared-position.h index 6302e832..a41ccacf 100644 --- a/src/cpp/geometry/operations/boolean-utils/shared-position.h +++ b/src/cpp/geometry/operations/boolean-utils/shared-position.h @@ -510,6 +510,7 @@ namespace fuzzybools std::vector triangles; std::map, size_t> segmentCounts; std::vector irrelevantFaces; + std::vector irrelevantFaces_toTest; std::map>> planeSegments; std::map, size_t>> planeSegmentCounts; @@ -868,8 +869,8 @@ namespace fuzzybools auto boxA = A.GetAABB(); auto boxB = B.GetAABB(); - AddGeometry(A, boxB, true); - AddGeometry(B, boxA, false); + AddGeometry(A, B, boxB, true); + AddGeometry(B, A, boxA, false); _linkedA = &A; _linkedB = &B; @@ -877,7 +878,7 @@ namespace fuzzybools //============================================================================================ - void AddGeometry(const Geometry& geom, const AABB& relevantBounds, bool isA) + void AddGeometry(const Geometry& geom, const Geometry& secondGeom, const AABB& relevantBounds, bool isA) { Geometry relevant; @@ -901,6 +902,40 @@ namespace fuzzybools continue; } + // Arbitrary limit. If an element has more than 1000 faces only those that touch a face of the other solid will pass + // This limit allows terrains and other models containing too many planes to optimize the number of planes that are computed + // This method is only applied to huge models because it has some unexpected drawbacks + + if(geom.numFaces > 1000) + { + bool contact = false; + + for (size_t j = 0; j < secondGeom.numFaces; j++) + { + auto faceBox2 = secondGeom.GetFaceBox(j); + + if (faceBox.intersects(faceBox2)) + { + contact = true; + break; + } + } + + if(!contact) + { + if (isA) + { + A.irrelevantFaces_toTest.push_back(i); + } + else + { + B.irrelevantFaces_toTest.push_back(i); + } + + continue; + } + } + if (isA) { #ifdef CSG_DEBUG_OUTPUT @@ -1743,6 +1778,32 @@ namespace fuzzybools sp.TriangulatePlane(geom, plane); } + // re-add irrelevant faces that should be tested + for (auto& faceIndex : sp.A.irrelevantFaces_toTest) + { + const Face& f = sp._linkedA->GetFace(faceIndex); + + auto a = sp._linkedA->GetPoint(f.i0); + auto b = sp._linkedA->GetPoint(f.i1); + auto c = sp._linkedA->GetPoint(f.i2); + + geom.AddFace(a, b, c); + } + + if (UNION) + { + for (auto& faceIndex : sp.B.irrelevantFaces_toTest) + { + const Face& f = sp._linkedB->GetFace(faceIndex); + + auto a = sp._linkedB->GetPoint(f.i0); + auto b = sp._linkedB->GetPoint(f.i1); + auto c = sp._linkedB->GetPoint(f.i2); + + geom.AddFace(a, b, c); + } + } + geom.data = geom.numFaces; // re-add irrelevant faces diff --git a/src/cpp/geometry/operations/geometryutils.h b/src/cpp/geometry/operations/geometryutils.h index 3da1025b..c8c78eed 100644 --- a/src/cpp/geometry/operations/geometryutils.h +++ b/src/cpp/geometry/operations/geometryutils.h @@ -657,11 +657,6 @@ namespace webifc::geometry spdlog::error("[TriangulateBounds() Expected outer bound first! {}", expressID); } - if(bounds[0].curve.points.size() == 189) - { - bounds[0] = bounds[0]; - } - glm::dvec3 v1, v2, v3; if (!GetBasisFromCoplanarPoints(bounds[0].curve.points, v1, v2, v3)) {