Fix and augment v0.8 taxonomy wrapper

This commit is contained in:
Thomas Krijnen
2024-09-01 10:40:23 +02:00
parent b3b14e87ec
commit d4d9fdff1a
3 changed files with 111 additions and 26 deletions
+102 -25
View File
@@ -117,6 +117,7 @@ std::pair<char const*, size_t> vector_to_buffer(const T& t) {
// @this is really annoying, but apparently inheritance
// is lost in swig in the shared_ptr type hiearchy
using namespace ifcopenshell::geometry::taxonomy;
if (!$1) $1 = try_upcast<boolean_result>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__boolean_result_t);
if (!$1) $1 = try_upcast<bspline_curve>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_curve_t);
if (!$1) $1 = try_upcast<bspline_surface>($input, SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_surface_t);
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) {
}
%}
%{
namespace {
// Helper function to create a Python tuple from an Eigen matrix/vector
template <typename T>
PyObject* eigen_to_python_tuple(const Eigen::MatrixBase<T>& mat) {
constexpr auto rows = T::RowsAtCompileTime;
constexpr auto cols = T::ColsAtCompileTime;
if constexpr (rows == 1 || cols == 1) {
// Eigen::Vector (1D array)
PyObject* tuple = PyTuple_New(rows * cols);
for (int i = 0; i < mat.size(); ++i) {
PyTuple_SetItem(tuple, i, PyFloat_FromDouble(mat(i)));
}
return tuple;
} else {
// Eigen::Matrix (2D array)
PyObject* tuple = PyTuple_New(rows);
for (int i = 0; i < rows; ++i) {
PyObject* row = PyTuple_New(cols);
for (int j = 0; j < cols; ++j) {
PyTuple_SetItem(row, j, PyFloat_FromDouble(mat(i, j)));
}
PyTuple_SetItem(tuple, i, row);
}
return tuple;
}
}
}
%}
%shared_ptr(ifcopenshell::geometry::taxonomy::boolean_result);
%shared_ptr(ifcopenshell::geometry::taxonomy::item);
%shared_ptr(ifcopenshell::geometry::taxonomy::implicit_item);
%shared_ptr(ifcopenshell::geometry::taxonomy::piecewise_function);
@@ -223,46 +259,85 @@ std::string taxonomy_item_repr(ifcopenshell::geometry::taxonomy::item::ptr i) {
}
}
%extend ifcopenshell::geometry::taxonomy::point3 {
PyObject* coords_() const {
auto result = PyTuple_New(3);
for (int i = 0; i < 3; ++i) {
PyTuple_SET_ITEM(result, i, PyFloat_FromDouble($self->ccomponents().data()[i]));
}
return result;
%define assign_component_acccess(item_name)
%extend ifcopenshell::geometry::taxonomy::item_name {
PyObject* components_() const {
return eigen_to_python_tuple(self->ccomponents());
}
%pythoncode %{
coords = property(coords_)
components = property(components_)
%}
}
};
%extend ifcopenshell::geometry::taxonomy::direction3 {
// @todo refactor in macro
PyObject* coords_() const {
auto result = PyTuple_New(3);
for (int i = 0; i < 3; ++i) {
PyTuple_SET_ITEM(result, i, PyFloat_FromDouble($self->ccomponents().data()[i]));
}
return result;
}
%enddef
%pythoncode %{
coords = property(coords_)
%}
}
assign_component_acccess(point3);
assign_component_acccess(direction3);
assign_component_acccess(matrix4);
assign_component_acccess(colour);
%define assign_children_access(item_name, children_type)
%extend ifcopenshell::geometry::taxonomy::loop {
const std::vector<ifcopenshell::geometry::taxonomy::edge::ptr>& children_() const {
%extend ifcopenshell::geometry::taxonomy::item_name {
// swig does not accept auto here as the return type
const std::vector<ifcopenshell::geometry::taxonomy::children_type::ptr>& children_() const {
return $self->children;
}
const ifcopenshell::geometry::taxonomy::children_type::ptr& __getitem__(int index) const {
if (index < 0 || index >= $self->children.size()) {
throw std::runtime_error("Index " + std::to_string(index) + " is out of bounds for an array of length " + std::to_string($self->children.size()));
}
return $self->children[index];
}
%pythoncode %{
children = property(children_)
def __iter__(self):
return iter(self.children)
%}
}
};
%enddef
assign_children_access(collection, geom_item);
assign_children_access(loop, edge);
assign_children_access(face, loop);
assign_children_access(shell, face);
assign_children_access(solid, shell);
assign_children_access(loft, face);
assign_children_access(boolean_result, geom_item);
%define assign_matrix_access(item_name)
%extend ifcopenshell::geometry::taxonomy::item_name {
// swig does not accept auto here as the return type
const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix_() const {
return $self->matrix;
}
%pythoncode %{
matrix = property(matrix_)
%}
};
%enddef
assign_matrix_access(line);
assign_matrix_access(circle);
assign_matrix_access(ellipse);
assign_matrix_access(collection);
assign_matrix_access(solid);
assign_matrix_access(face);
assign_matrix_access(plane);
assign_matrix_access(cylinder);
assign_matrix_access(sphere);
assign_matrix_access(torus);
assign_matrix_access(extrusion);
assign_matrix_access(revolve);
%extend ifcopenshell::geometry::Settings {
void set_(const std::string& name, bool val) {
@@ -1131,6 +1206,7 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
%enddef
assign_repr(ifcopenshell::geometry::taxonomy::boolean_result)
assign_repr(ifcopenshell::geometry::taxonomy::bspline_curve)
assign_repr(ifcopenshell::geometry::taxonomy::bspline_surface)
assign_repr(ifcopenshell::geometry::taxonomy::circle)
@@ -1159,4 +1235,5 @@ assign_repr(ifcopenshell::geometry::taxonomy::torus)
assign_repr(ifcopenshell::geometry::taxonomy::style)
assign_repr(ifcopenshell::geometry::taxonomy::sweep_along_curve)
#endif
+2 -1
View File
@@ -247,7 +247,8 @@ PyObject* item_to_pyobject(const ifcopenshell::geometry::taxonomy::item::ptr& i)
auto kind = i->kind();
// @todo this is not automatically generated :(
// we can probably use the dispatch mechanism for this we already have in the kernel
if (kind == BSPLINE_CURVE) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<bspline_curve>(std::static_pointer_cast<bspline_curve>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_curve_t, 0 | SWIG_POINTER_OWN); }
if (kind == BOOLEAN_RESULT) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<boolean_result>(std::static_pointer_cast<boolean_result>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__boolean_result_t, 0 | SWIG_POINTER_OWN); }
else if (kind == BSPLINE_CURVE) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<bspline_curve>(std::static_pointer_cast<bspline_curve>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_curve_t, 0 | SWIG_POINTER_OWN); }
else if (kind == BSPLINE_SURFACE) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<bspline_surface>(std::static_pointer_cast<bspline_surface>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__bspline_surface_t, 0 | SWIG_POINTER_OWN); }
else if (kind == CIRCLE) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<circle>(std::static_pointer_cast<circle>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__circle_t, 0 | SWIG_POINTER_OWN); }
else if (kind == COLLECTION) { return SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<collection>(std::static_pointer_cast<collection>(i))), SWIGTYPE_p_std__shared_ptrT_ifcopenshell__geometry__taxonomy__collection_t, 0 | SWIG_POINTER_OWN); }
+7
View File
@@ -112,8 +112,14 @@ CREATE_VECTOR_TYPEMAP_OUT(IfcGeom::ConversionResultShape *)
}
};
%typemap(out) const item_name::ptr& {
$result = item_to_pyobject(*$1);
};
%enddef
vector_of_item(ifcopenshell::geometry::taxonomy::item)
vector_of_item(ifcopenshell::geometry::taxonomy::boolean_result)
vector_of_item(ifcopenshell::geometry::taxonomy::bspline_curve)
vector_of_item(ifcopenshell::geometry::taxonomy::bspline_surface)
vector_of_item(ifcopenshell::geometry::taxonomy::circle)
@@ -141,3 +147,4 @@ vector_of_item(ifcopenshell::geometry::taxonomy::sphere)
vector_of_item(ifcopenshell::geometry::taxonomy::torus)
vector_of_item(ifcopenshell::geometry::taxonomy::style)
vector_of_item(ifcopenshell::geometry::taxonomy::sweep_along_curve)
vector_of_item(ifcopenshell::geometry::taxonomy::geom_item)