@@ -117,6 +117,7 @@ std::pair<char const*, size_t> vector_to_buffer(const T& t) {
117117 // @this is really annoying, but apparently inheritance
118118 // is lost in swig in the shared_ptr type hiearchy
119119 using namespace ifcopenshell ::geometry::taxonomy;
120+ if (!$1 ) $1 = try_upcast<boolean_result>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__boolean_result_t);
120121 if (!$1 ) $1 = try_upcast<bspline_curve>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_curve_t);
121122 if (!$1 ) $1 = try_upcast<bspline_surface>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_surface_t);
122123 if (!$1 ) $1 = try_upcast<circle>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__circle_t);
@@ -154,6 +155,41 @@ std::string taxonomy_item_repr(ifcopenshell::geometry::taxonomy::item::ptr i) {
154155}
155156%}
156157
158+ %{
159+
160+
161+ namespace {
162+ // Helper function to create a Python tuple from an Eigen matrix/vector
163+ template <typename T>
164+ PyObject* eigen_to_python_tuple (const Eigen::MatrixBase<T>& mat) {
165+ constexpr auto rows = T::RowsAtCompileTime;
166+ constexpr auto cols = T::ColsAtCompileTime;
167+
168+ if constexpr (rows == 1 || cols == 1 ) {
169+ // Eigen::Vector (1D array)
170+ PyObject* tuple = PyTuple_New (rows * cols);
171+ for (int i = 0 ; i < mat.size (); ++i) {
172+ PyTuple_SetItem (tuple, i, PyFloat_FromDouble (mat (i)));
173+ }
174+ return tuple;
175+ } else {
176+ // Eigen::Matrix (2D array)
177+ PyObject* tuple = PyTuple_New (rows);
178+ for (int i = 0 ; i < rows; ++i) {
179+ PyObject* row = PyTuple_New (cols);
180+ for (int j = 0 ; j < cols; ++j) {
181+ PyTuple_SetItem (row, j, PyFloat_FromDouble (mat (i, j)));
182+ }
183+ PyTuple_SetItem (tuple, i, row);
184+ }
185+ return tuple;
186+ }
187+ }
188+ }
189+
190+ %}
191+
192+ %shared_ptr(ifcopenshell::geometry::taxonomy::boolean_result);
157193%shared_ptr(ifcopenshell::geometry::taxonomy::item);
158194%shared_ptr(ifcopenshell::geometry::taxonomy::implicit_item);
159195%shared_ptr(ifcopenshell::geometry::taxonomy::piecewise_function);
@@ -223,46 +259,85 @@ std::string taxonomy_item_repr(ifcopenshell::geometry::taxonomy::item::ptr i) {
223259 }
224260}
225261
226- %extend ifcopenshell::geometry::taxonomy::point3 {
227- PyObject* coords_ () const {
228- auto result = PyTuple_New (3 );
229- for (int i = 0 ; i < 3 ; ++i) {
230- PyTuple_SET_ITEM (result, i, PyFloat_FromDouble ($self->ccomponents ().data ()[i]));
231- }
232- return result;
262+
263+ %define assign_component_acccess (item_name)
264+
265+ %extend ifcopenshell::geometry::taxonomy::item_name {
266+ PyObject* components_ () const {
267+ return eigen_to_python_tuple (self->ccomponents ());
233268 }
234269
235270 %pythoncode %{
236- coords = property (coords_ )
271+ components = property (components_ )
237272 %}
238- }
273+ };
274+
275+ %enddef
276+
277+ assign_component_acccess (point3);
278+ assign_component_acccess (direction3);
279+ assign_component_acccess (matrix4);
280+ assign_component_acccess (colour);
281+
282+ %define assign_children_access (item_name, children_type)
283+
284+ %extend ifcopenshell::geometry::taxonomy::item_name {
285+ // swig does not accept auto here as the return type
286+ const std::vector<ifcopenshell::geometry::taxonomy::children_type::ptr>& children_ () const {
287+ return $self->children ;
288+ }
239289
240- %extend ifcopenshell::geometry::taxonomy::direction3 {
241- // @todo refactor in macro
242- PyObject* coords_ () const {
243- auto result = PyTuple_New (3 );
244- for (int i = 0 ; i < 3 ; ++i) {
245- PyTuple_SET_ITEM (result, i, PyFloat_FromDouble ($self->ccomponents ().data ()[i]));
290+ const ifcopenshell::geometry::taxonomy::children_type::ptr& __getitem__ (int index) const {
291+ if (index < 0 || index >= $self->children .size ()) {
292+ throw std::runtime_error (" Index " + std::to_string (index) + " is out of bounds for an array of length " + std::to_string ($self->children .size ()));
246293 }
247- return result ;
294+ return $self-> children [index] ;
248295 }
249296
250297 %pythoncode %{
251- coords = property (coords_)
298+ children = property (children_)
299+ def __iter__ (self):
300+ return iter (self.children )
252301 %}
253- }
302+ };
254303
304+ %enddef
255305
256- %extend ifcopenshell::geometry::taxonomy::loop {
257- const std::vector<ifcopenshell::geometry::taxonomy::edge::ptr>& children_ () const {
258- return $self->children ;
306+ assign_children_access (collection, geom_item);
307+ assign_children_access (loop, edge);
308+ assign_children_access (face, loop);
309+ assign_children_access (shell, face);
310+ assign_children_access (solid, shell);
311+ assign_children_access (loft, face);
312+ assign_children_access (boolean_result, geom_item);
313+
314+ %define assign_matrix_access (item_name)
315+
316+ %extend ifcopenshell::geometry::taxonomy::item_name {
317+ // swig does not accept auto here as the return type
318+ const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix_ () const {
319+ return $self->matrix ;
259320 }
260321
261322 %pythoncode %{
262- children = property (children_ )
323+ matrix = property (matrix_ )
263324 %}
264- }
325+ };
265326
327+ %enddef
328+
329+ assign_matrix_access (line);
330+ assign_matrix_access (circle);
331+ assign_matrix_access (ellipse);
332+ assign_matrix_access (collection);
333+ assign_matrix_access (solid);
334+ assign_matrix_access (face);
335+ assign_matrix_access (plane);
336+ assign_matrix_access (cylinder);
337+ assign_matrix_access (sphere);
338+ assign_matrix_access (torus);
339+ assign_matrix_access (extrusion);
340+ assign_matrix_access (revolve);
266341
267342%extend ifcopenshell::geometry::Settings {
268343 void set_ (const std::string& name, bool val) {
@@ -1131,6 +1206,7 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
11311206
11321207%enddef
11331208
1209+ assign_repr (ifcopenshell::geometry::taxonomy::boolean_result)
11341210assign_repr(ifcopenshell::geometry::taxonomy::bspline_curve)
11351211assign_repr(ifcopenshell::geometry::taxonomy::bspline_surface)
11361212assign_repr(ifcopenshell::geometry::taxonomy::circle)
@@ -1159,4 +1235,5 @@ assign_repr(ifcopenshell::geometry::taxonomy::torus)
11591235assign_repr(ifcopenshell::geometry::taxonomy::style)
11601236assign_repr(ifcopenshell::geometry::taxonomy::sweep_along_curve)
11611237
1238+
11621239#endif
0 commit comments