From fa3c57b01660ae6a39dd1467607c8bee98f230da Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 19 Mar 2025 11:42:43 +0100 Subject: [PATCH] Implement readable setting type retrieval --- src/ifcgeom/ConversionSettings.h | 89 ++++++++++++++++++++++++++++++-- src/ifcwrap/IfcGeomWrapper.i | 6 +++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index d509cc27fc..a82be36b05 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -422,6 +422,68 @@ namespace ifcopenshell { static constexpr bool defaultvalue = false; }; } + + namespace impl { + template + struct readable_name { + static constexpr const char* name = "Unknown Type"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "bool"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "int"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "double"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "std::string"; + }; + + template <> + struct readable_name> { + static constexpr const char* name = "std::set"; + }; + + template <> + struct readable_name> { + static constexpr const char* name = "std::set"; + }; + + template <> + struct readable_name> { + static constexpr const char* name = "std::vector"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "IteratorOutputOptions"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "FunctionStepMethod"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "OutputDimensionalityTypes"; + }; + + template <> + struct readable_name { + static constexpr const char* name = "TriangulationMethod"; + }; + } template class IFC_GEOM_API SettingsContainer { @@ -450,17 +512,34 @@ namespace ifcopenshell { } } + template + std::string get_type_(const std::string& name) const { + if (std::tuple_element_t::name == name) { + return impl::readable_name::base_type>::name; + } + if constexpr (Index + 1 < std::tuple_size_v) { + return get_type_(name); + } else { + throw std::runtime_error("Setting not available"); + } + } + template void set_option_(const std::string& name, const value_variant_t& val) { if (std::tuple_element_t::name == name) { if constexpr (std::is_enum_v::base_type>) { - if (val.which() == 1) { - auto val_as_enum = (typename std::tuple_element_t::base_type) boost::get(val); + if (auto* val_ptr = boost::get(&val)) { + auto val_as_enum = (typename std::tuple_element_t::base_type) *val_ptr; std::get(settings).value = val_as_enum; return; } } - std::get(settings).value = boost::get::base_type>(val); + try { + std::get(settings).value = boost::get::base_type>(val); + } catch (const boost::bad_get&) { + std::string ty = impl::readable_name::base_type>::name; + throw std::runtime_error("Expected a value of type <" + ty + "> for setting '" + name + "'"); + } } else if constexpr (Index + 1 < std::tuple_size_v) { set_option_(name, val); } else { @@ -505,6 +584,10 @@ namespace ifcopenshell { set_option_<0>(name, val); } + std::string get_type(const std::string& name) { + return get_type_<0>(name); + } + std::vector setting_names() const { std::vector r; get_setting_names_<0>(r); diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index c0dd62c04f..35168dc969 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -394,6 +394,9 @@ assign_matrix_access(revolve); std::vector setting_names() { return $self->setting_names(); } + std::string get_type(const std::string& name) { + return $self->get_type(name); + } } %extend ifcopenshell::geometry::SerializerSettings { @@ -418,6 +421,9 @@ assign_matrix_access(revolve); std::vector setting_names() { return $self->setting_names(); } + std::string get_type(const std::string& name) { + return $self->get_type(name); + } } #ifdef IFOPSH_WITH_OPENCASCADE