Implement early return bool for intersection tests.

This commit is contained in:
Dion Moult
2024-02-05 18:47:08 +11:00
parent 930020bf05
commit 9ba1596e30
2 changed files with 16 additions and 9 deletions
+13 -6
View File
@@ -260,9 +260,9 @@ namespace IfcGeom {
} }
bool is_point_in_shape( bool is_point_in_shape(
gp_Pnt v, const gp_Pnt& v,
opencascade::handle<BVH_Tree<double, 3, BVH_BinaryTree>> bvh, const opencascade::handle<BVH_Tree<double, 3, BVH_BinaryTree>>& bvh,
BRepExtrema_TriangleSet triangle_set, const BRepExtrema_TriangleSet& triangle_set,
// In the case of "touching" rays, let's check again! // In the case of "touching" rays, let's check again!
bool should_check_again = false bool should_check_again = false
) const { ) const {
@@ -621,7 +621,7 @@ namespace IfcGeom {
else return 0.0f; 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 // 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) // 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 = current_v_protrusion;
v_protrusion_point = {v.X(), v.Y(), v.Z()}; v_protrusion_point = {v.X(), v.Y(), v.Z()};
v_surface_point = {point_on_b.X(), point_on_b.Y(), point_on_b.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<T> clash_intersection(const T& t, double tolerance = 0.002) const { std::vector<T> clash_intersection(const T& t, double tolerance = 0.002, bool check_all = true) const {
protrusion_distances_.clear(); protrusion_distances_.clear();
protrusion_points_.clear(); protrusion_points_.clear();
surface_points_.clear(); surface_points_.clear();
@@ -1428,7 +1435,7 @@ namespace IfcGeom {
i++; i++;
std::cout << "Currently doing" << i << std::endl; 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); ts_filtered.push_back(*it);
} }
} }
@@ -181,13 +181,13 @@ class tree(ifcopenshell_wrapper.tree):
args.append(kwargs.get("extend", -1.0e-5)) args.append(kwargs.get("extend", -1.0e-5))
return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select_box(*args)] 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): def unwrap(value):
if isinstance(value, entity_instance): if isinstance(value, entity_instance):
return value.wrapped_data return value.wrapped_data
return value 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)] return [entity_instance(e) for e in ifcopenshell_wrapper.tree.clash_intersection(*args)]
def clash_collision(self, value, allow_touching=False): def clash_collision(self, value, allow_touching=False):
@@ -197,7 +197,7 @@ class tree(ifcopenshell_wrapper.tree):
return value return value
args = [self, unwrap(value), allow_touching] 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 clash_clearance(self, value, clearance=0.05):
def unwrap(value): def unwrap(value):