mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
#3141 eliminate_narrow_operands()
This commit is contained in:
@@ -209,8 +209,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
TopoDS_Compound compound;
|
||||
builder.MakeCompound(compound);
|
||||
builder.Add(compound, s1);
|
||||
for (const auto& s2 : second_operand_shapes) {
|
||||
builder.Add(compound, s2);
|
||||
for (auto& p : opening_vector) {
|
||||
builder.Add(compound, p.second);
|
||||
}
|
||||
shape = compound;
|
||||
return true;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
||||
#include <BRepCheck.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <Bnd_OBB.hxx>
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
@@ -406,6 +407,30 @@ bool IfcGeom::util::is_extrusion(const gp_Vec & v, const TopoDS_Shape & s, TopoD
|
||||
return true;
|
||||
}
|
||||
|
||||
int IfcGeom::util::eliminate_narrow_operands(double prec, const TopTools_ListOfShape& bs, TopTools_ListOfShape & c) {
|
||||
int N = 0;
|
||||
TopTools_ListIteratorOfListOfShape it(bs);
|
||||
for (; it.More(); it.Next()) {
|
||||
|
||||
Bnd_OBB box;
|
||||
BRepBndLib::AddOBB(it.Value(), box, false, false, false);
|
||||
|
||||
auto min_dimension = box.XHSize() < box.YHSize() ? box.XHSize() : box.YHSize();
|
||||
min_dimension = min_dimension < box.ZHSize() ? min_dimension : box.ZHSize();
|
||||
|
||||
bool is_narrow = min_dimension < prec;
|
||||
|
||||
Logger::Notice("Min OBB dimension of operand = " + std::to_string(min_dimension));
|
||||
|
||||
if (!is_narrow) {
|
||||
c.Append(it.Value());
|
||||
} else {
|
||||
++N;
|
||||
}
|
||||
}
|
||||
return N;
|
||||
}
|
||||
|
||||
int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape & a, const TopTools_ListOfShape & bs, TopTools_ListOfShape & c) {
|
||||
TopTools_IndexedMapOfShape a_faces;
|
||||
TopExp::MapShapes(a, TopAbs_FACE, a_faces);
|
||||
@@ -806,6 +831,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
const bool do_unify = true;
|
||||
const bool do_subtraction_eliminate_disjoint_bbox = true;
|
||||
const bool do_subtraction_eliminate_touching = true;
|
||||
const bool do_eliminate_narrow_obb = true;
|
||||
const bool do_attempt_2d_boolean = settings.attempt_2d;
|
||||
const bool debug = settings.debug;
|
||||
|
||||
@@ -858,6 +884,8 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
b = b_input;
|
||||
}
|
||||
|
||||
bool is_2d = count(a, TopAbs_FACE) > 0 && count(a, TopAbs_SHELL) == 0;
|
||||
|
||||
bool success = false;
|
||||
BRepAlgoAPI_BooleanOperation* builder;
|
||||
TopTools_ListOfShape b_tmp;
|
||||
@@ -875,7 +903,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
}
|
||||
}
|
||||
|
||||
if (do_subtraction_eliminate_touching) {
|
||||
if (!is_2d && do_subtraction_eliminate_touching) {
|
||||
PERF("boolean subtraction: eliminate touching");
|
||||
|
||||
b_tmp.Clear();
|
||||
@@ -886,6 +914,17 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_2d && do_eliminate_narrow_obb) {
|
||||
PERF("boolean subtraction: eliminate narrow");
|
||||
|
||||
b_tmp.Clear();
|
||||
auto N = eliminate_narrow_operands(fuzziness, b, b_tmp);
|
||||
if (N) {
|
||||
Logger::Notice("Eliminated " + std::to_string(N) + " narrow operands");
|
||||
std::swap(b, b_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (op == BOPAlgo_COMMON) {
|
||||
builder = new BRepAlgoAPI_Common();
|
||||
} else if (op == BOPAlgo_FUSE) {
|
||||
@@ -895,6 +934,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
}
|
||||
|
||||
if (b.Extent() == 0) {
|
||||
Logger::Warning("No other operands remaining, using first operand");
|
||||
result = a;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ namespace IfcGeom {
|
||||
|
||||
int eliminate_touching_operands(double prec, const TopoDS_Shape& a, const TopTools_ListOfShape& bs, TopTools_ListOfShape& c);
|
||||
|
||||
int eliminate_narrow_operands(double prec, const TopTools_ListOfShape& bs, TopTools_ListOfShape & c);
|
||||
|
||||
TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
|
||||
|
||||
bool boolean_subtraction_2d_using_builder(const TopoDS_Shape& a_input, const TopTools_ListOfShape& b_input, TopoDS_Shape& result, double eps);
|
||||
|
||||
Reference in New Issue
Block a user