fix py dense

This commit is contained in:
AndreaRigoni
2026-03-05 14:26:05 +00:00
parent 69920acd61
commit 42db99759f
8 changed files with 174 additions and 37 deletions

View File

@@ -3,6 +3,8 @@
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include "Math/Dense.h"
#include "Math/Transform.h"
#include "Math/Geometry.h"
@@ -32,34 +34,104 @@ PYBIND11_MAKE_OPAQUE(uLib::Vector<Vector4f>);
PYBIND11_MAKE_OPAQUE(uLib::Vector<Vector4i>);
PYBIND11_MAKE_OPAQUE(uLib::Vector<Vector3d>);
PYBIND11_MAKE_OPAQUE(uLib::Vector<Vector4d>);
PYBIND11_MAKE_OPAQUE(uLib::Vector<Voxel>);
PYBIND11_MAKE_OPAQUE(uLib::Vector<VoxRaytracer::RayData::Element>);
template <typename MatrixType>
void bind_eigen_type(py::module_ &m, const char *name) {
using Scalar = typename MatrixType::Scalar;
constexpr bool is_vector = MatrixType::IsVectorAtCompileTime;
// Default constructor (zeros)
m.def(name, []() -> MatrixType {
if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
return MatrixType(); // Empty dynamic matrix
} else {
return MatrixType::Zero(); // Zero static matrix
}
});
// Specialized constructor for dynamic matrices
if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
m.def(name, [](int rows, int cols) -> MatrixType {
MatrixType mat;
mat.setZero(rows, cols);
return mat;
});
}
// Initialize from list
m.def(name, [](py::list l) -> MatrixType {
MatrixType mat;
if constexpr (is_vector) {
mat.setZero(l.size());
for (size_t i = 0; i < l.size(); ++i) {
mat(i) = l[i].cast<Scalar>();
}
} else {
int rows = MatrixType::RowsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::RowsAtCompileTime;
int cols = MatrixType::ColsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::ColsAtCompileTime;
mat.setZero(rows, cols);
for (size_t i = 0; i < (size_t)l.size(); ++i) {
mat(i / cols, i % cols) = l[i].cast<Scalar>();
}
}
return mat;
});
// Initialize from py::array
m.def(name, [](py::array_t<Scalar, py::array::c_style | py::array::forcecast> arr) -> MatrixType {
auto buf = arr.request();
MatrixType mat;
if constexpr (is_vector) {
mat.setZero(buf.size);
Scalar* ptr = static_cast<Scalar*>(buf.ptr);
for (ssize_t i = 0; i < buf.size; ++i) mat(i) = ptr[i];
} else {
int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1;
int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1;
mat.setZero(rows, cols);
Scalar* ptr = static_cast<Scalar*>(buf.ptr);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
mat(i, j) = ptr[i * cols + j];
}
}
}
return mat;
});
}
void init_math(py::module_ &m) {
// 1. Basic Eigen Types (Vectors and Matrices)
py::class_<Vector1f>(m, "Vector1f").def(py::init<>());
py::class_<Vector2f>(m, "Vector2f").def(py::init<>());
py::class_<Vector3f>(m, "Vector3f").def(py::init<>());
py::class_<Vector4f>(m, "Vector4f").def(py::init<>());
py::class_<Vector1i>(m, "Vector1i").def(py::init<>());
py::class_<Vector2i>(m, "Vector2i").def(py::init<>());
py::class_<Vector3i>(m, "Vector3i").def(py::init<>());
py::class_<Vector4i>(m, "Vector4i").def(py::init<>());
py::class_<Vector1d>(m, "Vector1d").def(py::init<>());
py::class_<Vector2d>(m, "Vector2d").def(py::init<>());
py::class_<Vector3d>(m, "Vector3d").def(py::init<>());
py::class_<Vector4d>(m, "Vector4d").def(py::init<>());
bind_eigen_type<Vector1f>(m, "Vector1f");
bind_eigen_type<Vector2f>(m, "Vector2f");
bind_eigen_type<Vector3f>(m, "Vector3f");
bind_eigen_type<Vector4f>(m, "Vector4f");
bind_eigen_type<Vector1i>(m, "Vector1i");
bind_eigen_type<Vector2i>(m, "Vector2i");
bind_eigen_type<Vector3i>(m, "Vector3i");
bind_eigen_type<Vector4i>(m, "Vector4i");
bind_eigen_type<Vector1d>(m, "Vector1d");
bind_eigen_type<Vector2d>(m, "Vector2d");
bind_eigen_type<Vector3d>(m, "Vector3d");
bind_eigen_type<Vector4d>(m, "Vector4d");
py::class_<Matrix2f>(m, "Matrix2f").def(py::init<>());
py::class_<Matrix3f>(m, "Matrix3f").def(py::init<>());
py::class_<Matrix4f>(m, "Matrix4f").def(py::init<>());
py::class_<Matrix2i>(m, "Matrix2i").def(py::init<>());
py::class_<Matrix3i>(m, "Matrix3i").def(py::init<>());
py::class_<Matrix4i>(m, "Matrix4i").def(py::init<>());
py::class_<Matrix2d>(m, "Matrix2d").def(py::init<>());
py::class_<Matrix3d>(m, "Matrix3d").def(py::init<>());
py::class_<Matrix4d>(m, "Matrix4d").def(py::init<>());
bind_eigen_type<Matrix2f>(m, "Matrix2f");
bind_eigen_type<Matrix3f>(m, "Matrix3f");
bind_eigen_type<Matrix4f>(m, "Matrix4f");
bind_eigen_type<Matrix2i>(m, "Matrix2i");
bind_eigen_type<Matrix3i>(m, "Matrix3i");
bind_eigen_type<Matrix4i>(m, "Matrix4i");
bind_eigen_type<Matrix2d>(m, "Matrix2d");
bind_eigen_type<Matrix3d>(m, "Matrix3d");
bind_eigen_type<Matrix4d>(m, "Matrix4d");
bind_eigen_type<MatrixXi>(m, "MatrixXi");
bind_eigen_type<MatrixXf>(m, "MatrixXf");
bind_eigen_type<MatrixXd>(m, "MatrixXd");
// 2. Homogeneous types
py::class_<HPoint3f>(m, "HPoint3f")