From 22f830b053f87960af1b8e786a8915e05987c4ba Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 24 Mar 2024 16:45:31 +0100 Subject: [PATCH] #4130 setOnlyValid() option that skips and logs invalid topology --- src/ifcgeom_schema_agnostic/base_utils.cpp | 42 ++++++++++++++++++++++ src/ifcgeom_schema_agnostic/base_utils.h | 2 ++ src/serializers/SvgSerializer.cpp | 4 +++ src/serializers/SvgSerializer.h | 9 +++++ 4 files changed, 57 insertions(+) diff --git a/src/ifcgeom_schema_agnostic/base_utils.cpp b/src/ifcgeom_schema_agnostic/base_utils.cpp index e9eff396d4..daf3712c7a 100644 --- a/src/ifcgeom_schema_agnostic/base_utils.cpp +++ b/src/ifcgeom_schema_agnostic/base_utils.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include @@ -739,3 +741,43 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis return valid_shell; } + +bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) { + BRepCheck_Analyzer ana(s); + if (ana.IsValid()) { + return true; + } + + std::stringstream str; + bool any_emitted = false; + + std::function dump; + dump = [&ana, &str, &dump, &any_emitted](const TopoDS_Shape& s) { + if (!ana.Result(s).IsNull()) { + BRepCheck_ListIteratorOfListOfStatus itl; + itl.Initialize(ana.Result(s)->Status()); + for (; itl.More(); itl.Next()) { + if (itl.Value() != BRepCheck_NoError) { + if (any_emitted) { + str << ", "; + } + BRepCheck::Print(itl.Value(), str); + str.seekp(str.tellp() - (std::streamoff)1); + str << " on "; + TopAbs::Print(s.ShapeType(), str); + BRepTools::Dump(s, str); + any_emitted = true; + } + } + } + for (TopoDS_Iterator it(s); it.More(); it.Next()) { + dump(it.Value()); + } + }; + + dump(s); + + Logger::Warning(str.str()); + + return false; +} \ No newline at end of file diff --git a/src/ifcgeom_schema_agnostic/base_utils.h b/src/ifcgeom_schema_agnostic/base_utils.h index a5d59e5887..f00d399a56 100644 --- a/src/ifcgeom_schema_agnostic/base_utils.h +++ b/src/ifcgeom_schema_agnostic/base_utils.h @@ -70,6 +70,8 @@ namespace IfcGeom { TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&); TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&); + + bool validate_shape(const TopoDS_Shape&); } } diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index cef46ee05c..36b3cdb1d5 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -729,6 +729,10 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) { compound_local = comp2; } + if (only_valid_ && !IfcGeom::util::validate_shape(compound_local)) { + return; + } + geometry_data data{ compound_local, dash_arrays, trsf, brep_obj->product(), storey, elev, brep_obj->name(), nameElement(storey, brep_obj) }; if (auto_section_ || auto_elevation_ || section_ref_ || elevation_ref_ || elevation_ref_guid_ || deferred_section_data_) { diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index 9aeff1e0e6..b5e8e7c98e 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -550,6 +550,7 @@ protected: bool unify_inputs_; bool mirror_y_; bool mirror_x_; + bool only_valid_; int profile_threshold_; @@ -717,6 +718,14 @@ public: return unify_inputs_; } + void setOnlyValid(bool b) { + only_valid_ = b; + } + + bool getOnlyValid(bool b) const { + return only_valid_; + } + void setScale(double s) { scale_ = s; } void setDrawingCenter(double x, double y) { center_x_ = x; center_y_ = y;