From e06794ef3d3116e76cc0bf1b72fd0209fd2aefce Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sat, 24 Apr 2021 11:05:18 +0200 Subject: [PATCH 1/2] #1153 SVG OBB check --- src/serializers/SvgSerializer.cpp | 16 ++++++++++++++++ src/serializers/SvgSerializer.h | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 9662544c8a..475cbc0423 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -574,6 +574,11 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) { b->second[0] - b->first[0], b->second[1] - b->first[1] ); + +#if OCC_VERSION_HEX >= 0x70300 + view_box_3d_.emplace(); + BRepBndLib::AddOBB(compound_unmirrored, *view_box_3d_, false, false, false); +#endif } std::vector props; @@ -712,6 +717,17 @@ void SvgSerializer::write(const geometry_data& data) { // (When determinant < 0, copy is implied and the input is not mutated.) auto compound_unmirrored = make_transform_global.Shape(); +#if OCC_VERSION_HEX >= 0x70300 + if (view_box_3d_) { + Bnd_OBB obb; + BRepBndLib::AddOBB(compound_unmirrored, obb, false, false, false); + if (view_box_3d_->IsOut(obb)) { + Logger::Notice("Not including element due to viewBox", data.product); + return; + } + } +#endif + if (is_floor_plan_) { BRepBndLib::Add(compound_unmirrored, bnd_); } diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index 270130d996..957bc1aa90 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -33,6 +33,11 @@ #include #include #include +#include + +#if OCC_VERSION_HEX >= 0x70300 +#include +#endif #include #include @@ -141,6 +146,11 @@ protected: boost::optional> size_, offset_2d_; boost::optional space_name_transform_; +#if OCC_VERSION_HEX >= 0x70300 + boost::optional view_box_3d_; +#endif + + bool with_section_heights_from_storey_, print_space_names_, print_space_areas_; storey_height_display_types storey_height_display_; bool draw_door_arcs_, is_floor_plan_; From e801629f865816ebfb29b3b654dca0c2767b114c Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sat, 24 Apr 2021 11:06:13 +0200 Subject: [PATCH 2/2] Add BRepExtrema_DistShapeShape option to tree with extend keyword --- src/ifcgeom/IfcGeomTree.h | 69 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/ifcgeom/IfcGeomTree.h b/src/ifcgeom/IfcGeomTree.h index 8911183b58..049066261b 100644 --- a/src/ifcgeom/IfcGeomTree.h +++ b/src/ifcgeom/IfcGeomTree.h @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace IfcGeom { @@ -38,6 +39,30 @@ namespace IfcGeom { template 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 select(const T& t, bool completely_within = false) const { - std::vector ts = select_box(t); + std::vector select(const T& t, bool completely_within = false, double extend = 0.0) const { + std::vector 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 select(const TopoDS_Shape& s) const { + std::vector 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 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::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& 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 it(settings_, &f); + add_file(it); + } + + void add_file(IfcGeom::Iterator& it) { if (it.initialize()) { do { IfcGeom::BRepElement* elem = (IfcGeom::BRepElement*)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()); } }