mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +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;
|
TopoDS_Compound compound;
|
||||||
builder.MakeCompound(compound);
|
builder.MakeCompound(compound);
|
||||||
builder.Add(compound, s1);
|
builder.Add(compound, s1);
|
||||||
for (const auto& s2 : second_operand_shapes) {
|
for (auto& p : opening_vector) {
|
||||||
builder.Add(compound, s2);
|
builder.Add(compound, p.second);
|
||||||
}
|
}
|
||||||
shape = compound;
|
shape = compound;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
||||||
#include <BRepCheck.hxx>
|
#include <BRepCheck.hxx>
|
||||||
#include <ShapeAnalysis_Edge.hxx>
|
#include <ShapeAnalysis_Edge.hxx>
|
||||||
|
#include <Bnd_OBB.hxx>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -406,6 +407,30 @@ bool IfcGeom::util::is_extrusion(const gp_Vec & v, const TopoDS_Shape & s, TopoD
|
|||||||
return true;
|
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) {
|
int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape & a, const TopTools_ListOfShape & bs, TopTools_ListOfShape & c) {
|
||||||
TopTools_IndexedMapOfShape a_faces;
|
TopTools_IndexedMapOfShape a_faces;
|
||||||
TopExp::MapShapes(a, TopAbs_FACE, 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_unify = true;
|
||||||
const bool do_subtraction_eliminate_disjoint_bbox = true;
|
const bool do_subtraction_eliminate_disjoint_bbox = true;
|
||||||
const bool do_subtraction_eliminate_touching = 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 do_attempt_2d_boolean = settings.attempt_2d;
|
||||||
const bool debug = settings.debug;
|
const bool debug = settings.debug;
|
||||||
|
|
||||||
@@ -858,6 +884,8 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
|||||||
b = b_input;
|
b = b_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_2d = count(a, TopAbs_FACE) > 0 && count(a, TopAbs_SHELL) == 0;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
BRepAlgoAPI_BooleanOperation* builder;
|
BRepAlgoAPI_BooleanOperation* builder;
|
||||||
TopTools_ListOfShape b_tmp;
|
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");
|
PERF("boolean subtraction: eliminate touching");
|
||||||
|
|
||||||
b_tmp.Clear();
|
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) {
|
} else if (op == BOPAlgo_COMMON) {
|
||||||
builder = new BRepAlgoAPI_Common();
|
builder = new BRepAlgoAPI_Common();
|
||||||
} else if (op == BOPAlgo_FUSE) {
|
} else if (op == BOPAlgo_FUSE) {
|
||||||
@@ -895,6 +934,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (b.Extent() == 0) {
|
if (b.Extent() == 0) {
|
||||||
|
Logger::Warning("No other operands remaining, using first operand");
|
||||||
result = a;
|
result = a;
|
||||||
return true;
|
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_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);
|
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);
|
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