From da0d3836666f154782a6b9b841d64086bf5b2991 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 9 Oct 2024 13:14:49 +0200 Subject: [PATCH] Distinction between general exception / not supported / not implemented #5484 --- src/ifcgeom/AbstractKernel.cpp | 38 +++++++----- src/ifcgeom/AbstractKernel.h | 77 +++++++++++++++---------- src/ifcgeom/kernels/cgal/CgalKernel.cpp | 4 +- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/ifcgeom/AbstractKernel.cpp b/src/ifcgeom/AbstractKernel.cpp index f785114420..94fa531221 100644 --- a/src/ifcgeom/AbstractKernel.cpp +++ b/src/ifcgeom/AbstractKernel.cpp @@ -22,26 +22,32 @@ using namespace ifcopenshell::geometry; bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::ptr item, IfcGeom::ConversionResults& results) { - // std::stringstream ss; - // item->print(ss); - // auto sss = ss.str(); - // std::wcout << sss.c_str() << std::endl; - - try { - return dispatch_conversion<0>::dispatch(this, item->kind(), item, results); - } catch (std::exception& e) { - std::string prev_exception = std::string(e.what()); + auto with_exception_handling = [&](auto fn) { try { - return dispatch_with_upgrade<0>::dispatch(this, item, results); + return fn(); } catch (std::exception& e) { - Logger::Error(prev_exception + " Conversion for upgraded element failed with: " + std::string(e.what()), item->instance); + Logger::Error(e, item->instance); return false; } catch (...) { + // @todo we can't log OCCT exceptions here, can we do some reraising to solve this? return false; } - } catch (...) { - // @todo we can't log OCCT exceptions here, can we do some reraising to solve this? - return false; + }; + auto without_exception_handling = [](auto fn) { + return fn(); + }; + auto process_with_upgrade = [&]() { + try { + return dispatch_conversion<0>::dispatch(this, item->kind(), item, results); + } catch (const not_implemented_error&) { + return dispatch_with_upgrade<0>::dispatch(this, item, results); + } + }; + + if (propagate_exceptions) { + return without_exception_handling(process_with_upgrade); + } else { + return with_exception_handling(process_with_upgrade); } } @@ -203,6 +209,10 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels } } + for (auto it = kernels.begin(); it != kernels.end(); ++it) { + (**it).propagate_exceptions = it == kernels.begin(); + } + if (!kernels.empty()) { return new HybridKernel(geometry_library, file, conv_settings, kernels); } diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index 13a6a0441f..460a2f0c53 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -15,14 +15,31 @@ inline static bool ALMOST_THE_SAME(const T& a, const T& b, double tolerance = AL return fabs(a - b) < tolerance; } -namespace ifcopenshell { namespace geometry { namespace kernels { +namespace ifcopenshell { + + class IFC_GEOM_API not_implemented_error : public std::exception { + public: + const char* what() const noexcept override { + return "Not implemented."; + } + }; + + class IFC_GEOM_API not_supported_error : public std::exception { + public: + const char* what() const noexcept override { + return "Not supported."; + } + }; + + namespace geometry { namespace kernels { class IFC_GEOM_API AbstractKernel { protected: std::string geometry_library_; Settings settings_; - public: + bool propagate_exceptions = false; + AbstractKernel(const std::string& geometry_library, const Settings& settings) : geometry_library_(geometry_library) , settings_(settings) {} @@ -33,31 +50,31 @@ namespace ifcopenshell { namespace geometry { namespace kernels { return geometry_library_; } - virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::direction3::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::line::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::circle::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::ellipse::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::bspline_curve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::edge::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::loop::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::node::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::colour::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::plane::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::offset_curve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::revolve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::bspline_surface::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::cylinder::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::sphere::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::torus::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::sweep_along_curve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::loft::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::direction3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::line::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::circle::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::ellipse::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::bspline_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::edge::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::loop::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::node::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::colour::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::plane::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::offset_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::revolve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::bspline_surface::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::cylinder::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::sphere::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::torus::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::sweep_along_curve::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } + virtual bool convert_impl(const taxonomy::loft::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); } virtual bool convert_impl(const taxonomy::collection::ptr, IfcGeom::ConversionResults&); virtual bool convert_impl(const taxonomy::piecewise_function::ptr item, IfcGeom::ConversionResults& cs); @@ -66,11 +83,11 @@ namespace ifcopenshell { namespace geometry { namespace kernels { virtual void set_rotation(const std::array &p_rotation); */ - virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw std::runtime_error("Not implemented"); } - virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map&) { throw std::runtime_error("Not implemented"); } + virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw not_implemented_error(); } + virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map&) { throw not_implemented_error(); } virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0; - virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw std::runtime_error("Unification of shapes not implemented in this kernel"); } + virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); } }; AbstractKernel* construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings); diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index 160e47abb3..15201666c7 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -156,13 +156,13 @@ bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) { for (auto& f : l->children) { if (f->basis && f->basis->kind() != taxonomy::PLANE) { Logger::Error("CGAL Kernel: Non-planar faces not supported at the moment"); - return false; + throw not_supported_error(); } for (auto& w : f->children) { for (auto& e : w->children) { if (e->basis && e->basis->kind() == taxonomy::BSPLINE_CURVE) { Logger::Error("CGAL Kernel: B-spline edge curves not supported at the moment"); - return false; + throw not_supported_error(); } } }