mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Add BRepExtrema_DistShapeShape option to tree with extend keyword
This commit is contained in:
+44
-25
@@ -30,6 +30,7 @@
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepAlgoAPI_Common.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
|
||||
namespace IfcGeom {
|
||||
@@ -38,6 +39,30 @@ namespace IfcGeom {
|
||||
template <typename T>
|
||||
class tree {
|
||||
|
||||
bool test(const TopoDS_Shape& A, const TopoDS_Shape& B, bool completely_within, double extend) const {
|
||||
if (extend > 0.) {
|
||||
BRepExtrema_DistShapeShape dss(A, B);
|
||||
if (dss.Perform() && dss.NbSolution() >= 1) {
|
||||
return dss.Value() <= extend;
|
||||
}
|
||||
} else if (completely_within) {
|
||||
BRepAlgoAPI_Cut cut(B, A);
|
||||
if (cut.IsDone()) {
|
||||
if (IfcGeom::Kernel::count(cut.Shape(), TopAbs_SHELL) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BRepAlgoAPI_Common common(A, B);
|
||||
if (common.IsDone()) {
|
||||
if (IfcGeom::Kernel::count(common.Shape(), TopAbs_SHELL) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void add(const T& t, const Bnd_Box& b) {
|
||||
@@ -104,8 +129,8 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<T> select(const T& t, bool completely_within = false) const {
|
||||
std::vector<T> ts = select_box(t);
|
||||
std::vector<T> select(const T& t, bool completely_within = false, double extend = 0.0) const {
|
||||
std::vector<T> ts = select_box(t, completely_within, extend);
|
||||
if (ts.empty()) {
|
||||
return ts;
|
||||
}
|
||||
@@ -126,29 +151,18 @@ namespace IfcGeom {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (completely_within) {
|
||||
BRepAlgoAPI_Cut cut(B, A);
|
||||
if (cut.IsDone()) {
|
||||
if (IfcGeom::Kernel::count(cut.Shape(), TopAbs_SHELL) == 0) {
|
||||
ts_filtered.push_back(*it);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BRepAlgoAPI_Common common(A, B);
|
||||
if (common.IsDone()) {
|
||||
if (IfcGeom::Kernel::count(common.Shape(), TopAbs_SHELL) > 0) {
|
||||
ts_filtered.push_back(*it);
|
||||
}
|
||||
}
|
||||
if (test(A, B, completely_within, extend)) {
|
||||
ts_filtered.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return ts_filtered;
|
||||
}
|
||||
|
||||
std::vector<T> select(const TopoDS_Shape& s) const {
|
||||
std::vector<T> select(const TopoDS_Shape& s, bool completely_within = false, double extend = -1.e-5) const {
|
||||
Bnd_Box bb;
|
||||
BRepBndLib::AddClose(s, bb);
|
||||
bb.SetGap(bb.GetGap() + extend);
|
||||
|
||||
std::vector<T> ts;
|
||||
|
||||
@@ -156,7 +170,7 @@ namespace IfcGeom {
|
||||
return ts;
|
||||
}
|
||||
|
||||
ts = select_box(bb);
|
||||
ts = select_box(bb, completely_within);
|
||||
|
||||
if (ts.empty()) {
|
||||
return ts;
|
||||
@@ -168,16 +182,13 @@ namespace IfcGeom {
|
||||
typename std::vector<T>::const_iterator it = ts.begin();
|
||||
for (it = ts.begin(); it != ts.end(); ++it) {
|
||||
const TopoDS_Shape& B = shapes_.find(*it)->second;
|
||||
|
||||
|
||||
if (IfcGeom::Kernel::count(B, TopAbs_SHELL) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BRepAlgoAPI_Common common(s, B);
|
||||
if (common.IsDone()) {
|
||||
if (IfcGeom::Kernel::count(common.Shape(), TopAbs_SHELL) > 0) {
|
||||
ts_filtered.push_back(*it);
|
||||
}
|
||||
if (test(s, B, completely_within, extend)) {
|
||||
ts_filtered.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +269,10 @@ namespace IfcGeom {
|
||||
add_file(f, settings);
|
||||
}
|
||||
|
||||
tree(IfcGeom::Iterator<double>& it) {
|
||||
add_file(it);
|
||||
}
|
||||
|
||||
void add_file(IfcParse::IfcFile& f, const IfcGeom::IteratorSettings& settings) {
|
||||
IfcGeom::IteratorSettings settings_ = settings;
|
||||
settings_.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
|
||||
@@ -266,10 +281,14 @@ namespace IfcGeom {
|
||||
|
||||
IfcGeom::Iterator<double> it(settings_, &f);
|
||||
|
||||
add_file(it);
|
||||
}
|
||||
|
||||
void add_file(IfcGeom::Iterator<double>& it) {
|
||||
if (it.initialize()) {
|
||||
do {
|
||||
IfcGeom::BRepElement<double>* elem = (IfcGeom::BRepElement<double>*)it.get();
|
||||
add((IfcUtil::IfcBaseEntity*)f.instance_by_id(elem->id()), elem->geometry().as_compound());
|
||||
add((IfcUtil::IfcBaseEntity*)it.file()->instance_by_id(elem->id()), elem->geometry().as_compound());
|
||||
} while (it.next());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user