From 9ba1596e30f4789823ddf6612e387d6e7b8d3f71 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 5 Feb 2024 18:47:08 +1100 Subject: [PATCH] Implement early return bool for intersection tests. --- src/ifcgeom_schema_agnostic/IfcGeomTree.h | 19 +++++++++++++------ .../ifcopenshell/geom/main.py | 6 +++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/ifcgeom_schema_agnostic/IfcGeomTree.h b/src/ifcgeom_schema_agnostic/IfcGeomTree.h index bb2eb6c663..99210f3aaa 100644 --- a/src/ifcgeom_schema_agnostic/IfcGeomTree.h +++ b/src/ifcgeom_schema_agnostic/IfcGeomTree.h @@ -260,9 +260,9 @@ namespace IfcGeom { } bool is_point_in_shape( - gp_Pnt v, - opencascade::handle> bvh, - BRepExtrema_TriangleSet triangle_set, + const gp_Pnt& v, + const opencascade::handle>& bvh, + const BRepExtrema_TriangleSet& triangle_set, // In the case of "touching" rays, let's check again! bool should_check_again = false ) const { @@ -621,7 +621,7 @@ namespace IfcGeom { else return 0.0f; } - bool test_intersection(const T& tA, const T& tB, const TopoDS_Shape& A, const TopoDS_Shape& B, double tolerance) const { + bool test_intersection(const T& tA, const T& tB, const TopoDS_Shape& A, const TopoDS_Shape& B, double tolerance, bool check_all = true) const { // 1. For each vert of A that is inside shape B, find the shortest distance to the closest face // 2. Of those verts, find the innermost vert (i.e. the vert that has the longest distance) @@ -843,6 +843,13 @@ namespace IfcGeom { v_protrusion = current_v_protrusion; v_protrusion_point = {v.X(), v.Y(), v.Z()}; v_surface_point = {point_on_b.X(), point_on_b.Y(), point_on_b.Z()}; + + if ( ! check_all && v_protrusion > tolerance) { + protrusion_distances_.push_back(v_protrusion); + protrusion_points_.push_back(v_protrusion_point); + surface_points_.push_back(v_surface_point); + return true; + } } } } @@ -1400,7 +1407,7 @@ namespace IfcGeom { } } - std::vector clash_intersection(const T& t, double tolerance = 0.002) const { + std::vector clash_intersection(const T& t, double tolerance = 0.002, bool check_all = true) const { protrusion_distances_.clear(); protrusion_points_.clear(); surface_points_.clear(); @@ -1428,7 +1435,7 @@ namespace IfcGeom { i++; std::cout << "Currently doing" << i << std::endl; - if (test_intersection(t, *it, A, B, tolerance)) { + if (test_intersection(t, *it, A, B, tolerance, check_all)) { ts_filtered.push_back(*it); } } diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index 4c3daf17da..64b8801929 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -181,13 +181,13 @@ class tree(ifcopenshell_wrapper.tree): args.append(kwargs.get("extend", -1.0e-5)) return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select_box(*args)] - def clash_intersection(self, value, tolerance=0.002): + def clash_intersection(self, value, tolerance=0.002, check_all=True): def unwrap(value): if isinstance(value, entity_instance): return value.wrapped_data return value - args = [self, unwrap(value), tolerance] + args = [self, unwrap(value), tolerance, check_all] return [entity_instance(e) for e in ifcopenshell_wrapper.tree.clash_intersection(*args)] def clash_collision(self, value, allow_touching=False): @@ -197,7 +197,7 @@ class tree(ifcopenshell_wrapper.tree): return value args = [self, unwrap(value), allow_touching] - return [entity_instance(e) for e in ifcopenshell_wrapper.tree.clash_intersection(*args)] + return [entity_instance(e) for e in ifcopenshell_wrapper.tree.clash_collision(*args)] def clash_clearance(self, value, clearance=0.05): def unwrap(value):