Expose geometry types in snake case

Generated with the assistance of an AI coding tool.
This commit is contained in:
Thomas Krijnen
2026-08-09 04:44:18 +02:00
parent fbfa51c451
commit be3c2ee770
49 changed files with 300 additions and 287 deletions
+77 -72
View File
@@ -19,28 +19,10 @@
%rename("buffer") stream_or_filename;
// Keep the established Python API names while the underlying C++ types use
// snake_case.
%rename("BRep") ifcopenshell::geom::brep;
%rename("BRepElement") ifcopenshell::geom::brep_element;
%rename("ConversionResult") ifcopenshell::geom::conversion_result;
%rename("ConversionResultShape") ifcopenshell::geom::conversion_result_shape;
%rename("Element") ifcopenshell::geom::element;
%rename("GeometrySerializer") ifcopenshell::geom::geometry_serializer;
%rename("Iterator") ifcopenshell::geom::iterator;
%rename("OpaqueNumber") ifcopenshell::geom::opaque_number;
%rename("Representation") ifcopenshell::geom::representation;
%rename("Serialization") ifcopenshell::geom::serialization;
%rename("SerializedElement") ifcopenshell::geom::serialized_element;
%rename("Settings") ifcopenshell::geom::settings;
%rename("Transformation") ifcopenshell::geom::transformation;
%rename("Triangulation") ifcopenshell::geom::triangulation;
%rename("TriangulationElement") ifcopenshell::geom::triangulation_element;
%rename("WriteOnlyGeometrySerializer") ifcopenshell::geom::write_only_geometry_serializer;
%ignore stream_or_filename::stream;
%ignore ifcopenshell::geom::conversion_result::shape;
%ignore boost::hash_value;
%ignore ifcopenshell::geom::brep_element::geometry_pointer;
%ignore ifcopenshell::geom::native_element::geometry_pointer;
%ignore ifcopenshell::geom::triangulation_element::geometry_pointer;
// This is only used for RGB colours, hence the size of 3
@@ -85,48 +67,26 @@
$1 = &temp;
}
// Using RTTI return a more specialized type of Element
// Note that these elements are not to be owned by SWIG/Python as they will be freed automatically upon the next iteration
// except for the ifcopenshell::geom::element instances which are returned by Iterator::getObject() calls
// Use RTTI to return the most specialized element proxy. The ownership flag is
// supplied by the wrapped function, so iterator copies can transfer ownership
// while borrowed serializer results remain non-owning.
%typemap(out) ifcopenshell::geom::element* {
ifcopenshell::geom::serialized_element* serialized_elem = dynamic_cast<ifcopenshell::geom::serialized_element*>($1);
ifcopenshell::geom::triangulation_element* triangulation_elem = dynamic_cast<ifcopenshell::geom::triangulation_element*>($1);
ifcopenshell::geom::brep_element* brep_elem = dynamic_cast<ifcopenshell::geom::brep_element*>($1);
ifcopenshell::geom::native_element* brep_elem = dynamic_cast<ifcopenshell::geom::native_element*>($1);
if (triangulation_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_ifcopenshell__geom__triangulation_element, 0);
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_ifcopenshell__geom__triangulation_element, $owner);
} else if (serialized_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_ifcopenshell__geom__serialized_element, 0);
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_ifcopenshell__geom__serialized_element, $owner);
} else if (brep_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(brep_elem), SWIGTYPE_p_ifcopenshell__geom__brep_element, 0);
$result = SWIG_NewPointerObj(SWIG_as_voidptr(brep_elem), SWIGTYPE_p_ifcopenshell__geom__native_element, $owner);
} else {
$result = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_ifcopenshell__geom__element, SWIG_POINTER_OWN);
$result = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_ifcopenshell__geom__element, $owner);
}
}
// Iterator results are copies owned by the caller. Release the unique pointer
// into the most specific Python proxy and transfer deletion to Python.
%typemap(out) std::unique_ptr<ifcopenshell::geom::element> {
ifcopenshell::geom::element* elem = $1.release();
ifcopenshell::geom::serialized_element* serialized_elem = dynamic_cast<ifcopenshell::geom::serialized_element*>(elem);
ifcopenshell::geom::triangulation_element* triangulation_elem = dynamic_cast<ifcopenshell::geom::triangulation_element*>(elem);
ifcopenshell::geom::brep_element* brep_elem = dynamic_cast<ifcopenshell::geom::brep_element*>(elem);
if (triangulation_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_ifcopenshell__geom__triangulation_element, SWIG_POINTER_OWN);
} else if (serialized_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_ifcopenshell__geom__serialized_element, SWIG_POINTER_OWN);
} else if (brep_elem) {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(brep_elem), SWIGTYPE_p_ifcopenshell__geom__brep_element, SWIG_POINTER_OWN);
} else {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(elem), SWIGTYPE_p_ifcopenshell__geom__element, SWIG_POINTER_OWN);
}
}
%typemap(out) std::unique_ptr<ifcopenshell::geom::brep_element> {
$result = SWIG_NewPointerObj(SWIG_as_voidptr($1.release()), SWIGTYPE_p_ifcopenshell__geom__brep_element, SWIG_POINTER_OWN);
}
%newobject ifcopenshell::geom::brep::item;
%newobject ifcopenshell::geom::brep::as_compound;
%newobject ifcopenshell::geom::native::item;
%newobject ifcopenshell::geom::native::as_compound;
%newobject ifcopenshell::geom::conversion_result_shape::halfspaces;
%newobject ifcopenshell::geom::conversion_result_shape::box;
@@ -307,6 +267,19 @@ namespace {
%include "../ifcgeom/ifc_geom_api.h"
%include "../ifcgeom/conversion_result.h"
%extend ifcopenshell::geom::conversion_result {
ifcopenshell::geom::conversion_result_shape* _shape() const {
return $self->shape().get();
}
%pythoncode %{
def shape(self):
result = self._shape()
result._parent = self
return result
%}
}
// The implementation tuple is intentionally opaque to Python. Letting SWIG
// emit a type token for all setting descriptors exceeds MSVC's token limit.
%ignore ifcopenshell::geom::settings_container;
@@ -327,11 +300,43 @@ namespace {
GEOMETRY_WITH_BACKREF(ifcopenshell::geom::triangulation_element)
GEOMETRY_WITH_BACKREF(ifcopenshell::geom::serialized_element)
GEOMETRY_WITH_BACKREF(ifcopenshell::geom::brep_element)
GEOMETRY_WITH_BACKREF(ifcopenshell::geom::native_element)
%include "../ifcgeom/element.h"
%include "../ifcgeom/representation.h"
%ignore ifcopenshell::geom::iterator::get;
%ignore ifcopenshell::geom::iterator::get_native;
%ignore ifcopenshell::geom::iterator::get_object;
%newobject ifcopenshell::geom::iterator::_get;
%newobject ifcopenshell::geom::iterator::_get_native;
%newobject ifcopenshell::geom::iterator::_get_object;
%include "../ifcgeom/iterator.h"
%extend ifcopenshell::geom::iterator {
ifcopenshell::geom::element* _get() {
return $self->get().release();
}
ifcopenshell::geom::native_element* _get_native() {
return $self->get_native().release();
}
ifcopenshell::geom::element* _get_object(int id) {
return $self->get_object(id).release();
}
%pythoncode %{
def get(self):
return self._get()
def get_native(self):
return self._get_native()
def get_object(self, id):
return self._get_object(id)
%}
}
%include "../ifcgeom/geometry_serializer.h"
%include "../ifcgeom/taxonomy.h"
%include "../ifcgeom/function_item_evaluator.h"
@@ -339,7 +344,7 @@ GEOMETRY_WITH_BACKREF(ifcopenshell::geom::brep_element)
%{
#include "../serializers/geometry_serializer_plugin.h"
class python_plugin_geometry_serializer : public geometry_serializer {
class python_plugin_geometry_serializer : public ifcopenshell::geom::geometry_serializer {
public:
python_plugin_geometry_serializer(
const std::string& extension,
@@ -347,7 +352,7 @@ public:
const std::string& output_temp_filename,
ifcopenshell::geom::settings& settings
)
: geometry_serializer(settings)
: ifcopenshell::geom::geometry_serializer(settings)
{
ifcopenshell::serializers::geometry_serializer_context context{
output_filename,
@@ -364,7 +369,7 @@ public:
const stream_or_filename& output_temp_filename,
ifcopenshell::geom::settings& settings
)
: geometry_serializer(settings)
: ifcopenshell::geom::geometry_serializer(settings)
{
const auto output_filename_string = output_filename.filename().value_or("");
const auto output_temp_filename_string = output_temp_filename.filename().value_or(output_filename_string);
@@ -420,7 +425,7 @@ public:
serializer_->write(element);
}
void write(const ifcopenshell::geom::brep_element* element) override {
void write(const ifcopenshell::geom::native_element* element) override {
serializer_->write(element);
}
@@ -432,7 +437,7 @@ public:
ifcopenshell::file& file,
const std::string& guid,
const std::string& representation_id,
read_type rt = READ_BREP
ifcopenshell::geom::geometry_serializer::read_type rt = ifcopenshell::geom::geometry_serializer::READ_BREP
) override {
return serializer_->read(file, guid, representation_id, rt);
}
@@ -442,11 +447,11 @@ public:
}
private:
std::shared_ptr<geometry_serializer> serializer_;
std::shared_ptr<ifcopenshell::geom::geometry_serializer> serializer_;
};
%}
%extend geometry_serializer {
%extend ifcopenshell::geom::geometry_serializer {
bool ready() {
return $self->ready();
}
@@ -676,13 +681,13 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
PyObject* operator()(ifcopenshell::geom::element* elem) const {
ifcopenshell::geom::serialized_element* serialized_elem = dynamic_cast<ifcopenshell::geom::serialized_element*>(elem);
ifcopenshell::geom::triangulation_element* triangulation_elem = dynamic_cast<ifcopenshell::geom::triangulation_element*>(elem);
ifcopenshell::geom::brep_element* brep_elem = dynamic_cast<ifcopenshell::geom::brep_element*>(elem);
ifcopenshell::geom::native_element* brep_elem = dynamic_cast<ifcopenshell::geom::native_element*>(elem);
if (triangulation_elem) {
return SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_ifcopenshell__geom__triangulation_element, SWIG_POINTER_OWN);
} else if (serialized_elem) {
return SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_ifcopenshell__geom__serialized_element, SWIG_POINTER_OWN);
} else if (brep_elem) {
return SWIG_NewPointerObj(SWIG_as_voidptr(brep_elem), SWIGTYPE_p_ifcopenshell__geom__brep_element, SWIG_POINTER_OWN);
return SWIG_NewPointerObj(SWIG_as_voidptr(brep_elem), SWIGTYPE_p_ifcopenshell__geom__native_element, SWIG_POINTER_OWN);
} else {
return SWIG_Py_Void();
}
@@ -690,13 +695,13 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
PyObject* operator()(ifcopenshell::geom::representation* representation) const {
ifcopenshell::geom::serialization* serialized_representation = dynamic_cast<ifcopenshell::geom::serialization*>(representation);
ifcopenshell::geom::triangulation* triangulated_representation = dynamic_cast<ifcopenshell::geom::triangulation*>(representation);
ifcopenshell::geom::brep* brep_representation = dynamic_cast<ifcopenshell::geom::brep*>(representation);
ifcopenshell::geom::native* brep_representation = dynamic_cast<ifcopenshell::geom::native*>(representation);
if (serialized_representation) {
return SWIG_NewPointerObj(SWIG_as_voidptr(serialized_representation), SWIGTYPE_p_ifcopenshell__geom__Representation__serialization, SWIG_POINTER_OWN);
return SWIG_NewPointerObj(SWIG_as_voidptr(serialized_representation), SWIGTYPE_p_ifcopenshell__geom__serialization, SWIG_POINTER_OWN);
} else if (triangulated_representation) {
return SWIG_NewPointerObj(SWIG_as_voidptr(triangulated_representation), SWIGTYPE_p_ifcopenshell__geom__Representation__triangulation, SWIG_POINTER_OWN);
return SWIG_NewPointerObj(SWIG_as_voidptr(triangulated_representation), SWIGTYPE_p_ifcopenshell__geom__triangulation, SWIG_POINTER_OWN);
} else if (brep_representation) {
return SWIG_NewPointerObj(SWIG_as_voidptr(brep_representation), SWIGTYPE_p_ifcopenshell__geom__Representation__brep, SWIG_POINTER_OWN);
return SWIG_NewPointerObj(SWIG_as_voidptr(brep_representation), SWIGTYPE_p_ifcopenshell__geom__native, SWIG_POINTER_OWN);
} else {
return SWIG_Py_Void();
}
@@ -722,7 +727,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
// I couldn't get the vector<string> typemap to be applied when %extending Iterator constructor.
// anyway it does not matter as SWIG generates C code without actual constructors
%inline %{
geometry_serializer* create_geometry_serializer(
ifcopenshell::geom::geometry_serializer* create_geometry_serializer(
const std::string& extension,
const std::string& output_filename,
const std::string& output_temp_filename,
@@ -736,7 +741,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
);
}
geometry_serializer* create_geometry_serializer(
ifcopenshell::geom::geometry_serializer* create_geometry_serializer(
const std::string& extension,
const stream_or_filename& output_filename,
const stream_or_filename& output_temp_filename,
@@ -918,7 +923,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
%extend ifcopenshell::geom::serialized_element {
};
%extend ifcopenshell::geom::brep_element {
%extend ifcopenshell::geom::native_element {
double calc_volume_() const {
double v;
if ($self->geometry().calculate_volume(v)) {
@@ -983,7 +988,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
return oss.str();
}
static std::variant<ifcopenshell::geom::element*, ifcopenshell::geom::representation*, ifcopenshell::geom::transformation*> helper_fn_create_shape(logger& logger, const std::string& geometry_library, ifcopenshell::geom::settings& settings, const express::base& instance, const express::base& representation = express::base()) {
static std::variant<ifcopenshell::geom::element*, ifcopenshell::geom::representation*, ifcopenshell::geom::transformation*> helper_fn_create_shape(ifcopenshell::logger& logger, const std::string& geometry_library, ifcopenshell::geom::settings& settings, const express::base& instance, const express::base& representation = express::base()) {
ifcopenshell::file* file = instance.file();
ifcopenshell::geom::converter kernel(ifcopenshell::geom::kernels::construct(file, geometry_library, settings), file, settings, logger);
@@ -997,7 +1002,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
throw ifcopenshell::exception("No suitable IfcRepresentation found");
}
ifcopenshell::geom::brep_element* brep = kernel.create_brep_for_representation_and_product(selected_representation, instance);
ifcopenshell::geom::native_element* brep = kernel.create_brep_for_representation_and_product(selected_representation, instance);
if (!brep) {
std::ostringstream oss_repr, oss_product;
selected_representation.to_string(oss_repr);
@@ -1045,7 +1050,7 @@ struct shape_rtti : public boost::static_visitor<PyObject*>
throw ifcopenshell::exception("Failed to process shape. Instance: " + oss.str());
}
ifcopenshell::geom::brep brep(kernel.settings(), instance.declaration().name(), to_locale_invariant_string(instance.id()), shapes);
ifcopenshell::geom::native brep(kernel.settings(), instance.declaration().name(), to_locale_invariant_string(instance.id()), shapes);
try {
if (settings.get<ifcopenshell::geom::settings::IteratorOutput>().get() == ifcopenshell::geom::settings::SERIALIZED) {
return new ifcopenshell::geom::serialization(brep);
+11 -11
View File
@@ -1186,9 +1186,9 @@ from .entity_instance import entity_instance_mixin
PyObject* convert_cpp_attribute_to_python(const express::base& instance, size_t attribute_index, bool recursive, bool include_identifier) {
return instance.get_attribute_value(attribute_index).apply_visitor([recursive, include_identifier](const auto& v){
using u = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<u, enumeration_reference>) {
if constexpr (std::is_same_v<u, ifcopenshell::enumeration_reference>) {
return pythonize(std::string(v.value()));
} else if constexpr (std::is_same_v<u, derived>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::derived>) {
if (feature_use_attribute_value_derived) {
return SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
} else {
@@ -1228,7 +1228,7 @@ from .entity_instance import entity_instance_mixin
} else {
return pythonize_vector(v);
}
} else if constexpr (std::is_same_v<u, empty_aggregate> || std::is_same_v<u, empty_aggregate_of_aggregate> || std::is_same_v<u, blank>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::empty_aggregate> || std::is_same_v<u, ifcopenshell::empty_aggregate_of_aggregate> || std::is_same_v<u, ifcopenshell::blank>) {
Py_INCREF(Py_None);
return static_cast<PyObject*>(Py_None);
} else if constexpr (is_std_vector_v<u>) {
@@ -1289,16 +1289,16 @@ from .entity_instance import entity_instance_mixin
if constexpr (is_std_vector_v<u>) {
return pythonize_vector(t);
} else if constexpr (std::is_same_v<u, enumeration_reference>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::enumeration_reference>) {
return pythonize(std::string(t.value()));
} else if constexpr (std::is_same_v<u, derived>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::derived>) {
if (feature_use_attribute_value_derived) {
return SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
} else {
Py_INCREF(Py_None);
return static_cast<PyObject*>(Py_None);
}
} else if constexpr (std::is_same_v<u, empty_aggregate> || std::is_same_v<u, empty_aggregate_of_aggregate> || std::is_same_v<u, blank>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::empty_aggregate> || std::is_same_v<u, ifcopenshell::empty_aggregate_of_aggregate> || std::is_same_v<u, ifcopenshell::blank>) {
Py_INCREF(Py_None);
return static_cast<PyObject*>(Py_None);
} else {
@@ -1385,16 +1385,16 @@ from .entity_instance import entity_instance_mixin
} else {
if constexpr (is_std_vector_v<value_type>) {
attribute_val_py = pythonize_vector(t);
} else if constexpr (std::is_same_v<value_type, enumeration_reference>) {
} else if constexpr (std::is_same_v<value_type, ifcopenshell::enumeration_reference>) {
attribute_val_py = pythonize(std::string(t.value()));
} else if constexpr (std::is_same_v<value_type, derived>) {
} else if constexpr (std::is_same_v<value_type, ifcopenshell::derived>) {
if (feature_use_attribute_value_derived) {
attribute_val_py = SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
} else {
Py_INCREF(Py_None);
attribute_val_py = static_cast<PyObject*>(Py_None);
}
} else if constexpr (std::is_same_v<value_type, empty_aggregate> || std::is_same_v<value_type, empty_aggregate_of_aggregate> || std::is_same_v<value_type, blank>) {
} else if constexpr (std::is_same_v<value_type, ifcopenshell::empty_aggregate> || std::is_same_v<value_type, ifcopenshell::empty_aggregate_of_aggregate> || std::is_same_v<value_type, ifcopenshell::blank>) {
Py_INCREF(Py_None);
attribute_val_py = static_cast<PyObject*>(Py_None);
} else {
@@ -1483,14 +1483,14 @@ from .entity_instance import entity_instance_mixin
}
}
%extend logger {
%extend ifcopenshell::logger {
%pythoncode %{
def __iter__(self):
return iter(self.log_messages())
%}
}
%extend log_message {
%extend ifcopenshell::log_message {
std::string severity_string() const {
static const char* const severity_strings[] = {"PERF", "DEBUG", "NOTICE", "WARNING", "ERROR"};
return severity_strings[(int)$self->severity];
+8
View File
@@ -53,6 +53,7 @@
%include "std_string.i"
%include "exception.i"
%include "std_shared_ptr.i"
%include "std_unique_ptr.i"
%{
#include <array>
@@ -257,6 +258,13 @@
// @todo abstract into plug-in interface
#include "../serializers/rocks_db_serializer.h"
using ifcopenshell::attribute_value;
using ifcopenshell::blank;
using ifcopenshell::derived;
using ifcopenshell::empty_aggregate;
using ifcopenshell::empty_aggregate_of_aggregate;
using ifcopenshell::enumeration_reference;
%}
// Create docstrings for generated python code.
+1 -1
View File
@@ -267,7 +267,7 @@
PyObject* pythonize(const ifcopenshell::inverse_attribute* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_ifcopenshell__inverse_attribute, 0); }
PyObject* pythonize(const ifcopenshell::entity* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_ifcopenshell__entity, 0); }
PyObject* pythonize(const ifcopenshell::declaration* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), declaration_type_to_swig(t), 0); }
PyObject* pythonize(const log_message& t) { return SWIG_NewPointerObj(SWIG_as_voidptr(&t), SWIGTYPE_p_log_message, 0); }
PyObject* pythonize(const ifcopenshell::log_message& t) { return SWIG_NewPointerObj(SWIG_as_voidptr(&t), SWIGTYPE_p_ifcopenshell__log_message, 0); }
// @nb ownership
PyObject* pythonize(const ifcopenshell::geom::conversion_result_shape* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_ifcopenshell__geom__conversion_result_shape, SWIG_POINTER_OWN); }
// PyObject* pythonize(const ifcopenshell::geom::conversion_result_shape* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_ifcopenshell__geom__conversion_result_shape, 0); }
+4 -4
View File
@@ -36,16 +36,16 @@
using u = std::decay_t<decltype(v)>;
if constexpr (is_std_vector_v<u>) {
return pythonize_vector(v);
} else if constexpr (std::is_same_v<u, enumeration_reference>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::enumeration_reference>) {
return pythonize(std::string(v.value()));
} else if constexpr (std::is_same_v<u, derived>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::derived>) {
if (feature_use_attribute_value_derived) {
return SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
} else {
Py_INCREF(Py_None);
return static_cast<PyObject*>(Py_None);
}
} else if constexpr (std::is_same_v<u, empty_aggregate> || std::is_same_v<u, empty_aggregate_of_aggregate> || std::is_same_v<u, blank>) {
} else if constexpr (std::is_same_v<u, ifcopenshell::empty_aggregate> || std::is_same_v<u, ifcopenshell::empty_aggregate_of_aggregate> || std::is_same_v<u, ifcopenshell::blank>) {
Py_INCREF(Py_None);
return static_cast<PyObject*>(Py_None);
} else {
@@ -92,7 +92,7 @@ CREATE_VECTOR_TYPEMAP_OUT(ifcopenshell::inverse_attribute const *)
CREATE_VECTOR_TYPEMAP_OUT(ifcopenshell::entity const *)
CREATE_VECTOR_TYPEMAP_OUT(ifcopenshell::declaration const *)
CREATE_VECTOR_TYPEMAP_OUT(ifcopenshell::geom::conversion_result_shape *)
CREATE_VECTOR_TYPEMAP_OUT(log_message)
CREATE_VECTOR_TYPEMAP_OUT(ifcopenshell::log_message)
%typemap(out) ifcopenshell::geom::settings::value_variant_t {
pythonizing_visitor vis;