25#include <eigen3/Eigen/Core>
26#include <boost/python.hpp>
27#include <boost/python/implicit.hpp>
28#include <boost/python/module.hpp>
29#include <boost/python/numpy.hpp>
31namespace py = boost::python;
32namespace np = boost::python::numpy;
46template <
class VectorType>
55 static_assert(VectorType::ColsAtCompileTime == 1 || VectorType::RowsAtCompileTime == 1,
"Passed a Matrix into a Vector generator");
57 if (!PySequence_Check(obj_ptr)
58 || (VectorType::ColsAtCompileTime == 1 && VectorType::RowsAtCompileTime != Eigen::Dynamic
59 && (PySequence_Size(obj_ptr) != VectorType::RowsAtCompileTime))
60 || (VectorType::RowsAtCompileTime == 1 && VectorType::ColsAtCompileTime != Eigen::Dynamic
61 && (PySequence_Size(obj_ptr) != VectorType::ColsAtCompileTime)))
64 if (VectorType::ColsAtCompileTime == 1 && VectorType::RowsAtCompileTime != Eigen::Dynamic && (PySequence_Size(obj_ptr) != VectorType::RowsAtCompileTime))
67 py::list arr = py::extract<py::list>(obj_ptr);
68 for (
long i = 0; i < py::len(arr); i++)
69 if (!py::extract<typename VectorType::Scalar>(arr[i]).check())
75 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
77 py::list arr = py::extract<py::list>(obj_ptr);
78 auto len = py::len(arr);
80 using storage_type = py::converter::rvalue_from_python_storage<VectorType>;
81 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
83 new (storage) VectorType;
84 VectorType& vec = *
static_cast<VectorType*
>(storage);
86 if (VectorType::RowsAtCompileTime == Eigen::Dynamic || VectorType::ColsAtCompileTime == Eigen::Dynamic)
89 for (
long i = 0; i < len; ++i)
90 vec(i) = py::extract<typename VectorType::Scalar>(arr[i]);
92 data->convertible = storage;
101template <
class MatrixType>
110 static_assert(MatrixType::ColsAtCompileTime != 1 && MatrixType::RowsAtCompileTime != 1,
"Passed a Vector into a Matrix generator");
112 auto checkNestedList = [](
const py::list& list) {
113 py::extract<py::list> nested_list(list[0]);
114 if (!nested_list.check())
117 auto cols = py::len(nested_list());
118 for (
long i = 1; i < py::len(list); ++i) {
119 py::extract<py::list> nested_list(list[i]);
120 if (!nested_list.check() || py::len(nested_list) != cols)
122 for (
long j = 0; j < cols; ++j)
123 if (!py::extract<typename MatrixType::Scalar>(nested_list()[j]).check())
130 py::extract<py::list> extract_list(obj_ptr);
131 py::extract<py::list> extract_nested_list(extract_list());
132 if (!extract_list.check()
133 || !checkNestedList(extract_list())
134 || (MatrixType::RowsAtCompileTime != Eigen::Dynamic && MatrixType::RowsAtCompileTime != py::len(extract_list()))
135 || (MatrixType::ColsAtCompileTime != Eigen::Dynamic && MatrixType::ColsAtCompileTime != py::len(extract_nested_list())))
141 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
143 py::list arr = py::extract<py::list>(obj_ptr);
144 auto rows = py::len(arr);
145 auto cols = py::len(py::extract<py::list>(arr[0])());
147 using storage_type = py::converter::rvalue_from_python_storage<MatrixType>;
148 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
150 new (storage) MatrixType;
151 MatrixType& mat = *
static_cast<MatrixType*
>(storage);
154 if (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic)
155 mat.resize(rows, cols);
157 for (
long i = 0; i < rows; ++i)
158 for (
long j = 0; j < cols; ++j)
159 mat(i, j) = py::extract<typename MatrixType::Scalar>(arr[i][j]);
161 data->convertible = storage;
169template <
class QuaternionType>
180 if (!PySequence_Check(obj_ptr)
181 || (PySequence_Size(obj_ptr) != 4))
184 if (PySequence_Size(obj_ptr) != 4)
187 py::list arr = py::extract<py::list>(obj_ptr);
188 for (
long i = 0; i < py::len(arr); i++)
189 if (!py::extract<typename QuaternionType::Scalar>(arr[i]).check())
195 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
197 py::list arr = py::extract<py::list>(obj_ptr);
198 auto len = py::len(arr);
200 using storage_type = py::converter::rvalue_from_python_storage<QuaternionType>;
201 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
203 new (storage) QuaternionType;
204 QuaternionType& vec = *
static_cast<QuaternionType*
>(storage);
206 vec.x() = py::extract<typename QuaternionType::Scalar>(arr[0]);
207 vec.y() = py::extract<typename QuaternionType::Scalar>(arr[1]);
208 vec.z() = py::extract<typename QuaternionType::Scalar>(arr[2]);
209 vec.w() = py::extract<typename QuaternionType::Scalar>(arr[3]);
211 data->convertible = storage;
219template <
class TransformType>
228 static_assert(TransformType::Dim != 1,
"Passed a Vector into a Matrix generator");
230 auto checkNestedList = [](
const py::list& list) {
231 py::extract<py::list> nested_list(list[0]);
232 if (!nested_list.check())
235 auto cols = py::len(nested_list());
236 for (
long i = 1; i < py::len(list); ++i) {
237 py::extract<py::list> nested_list(list[i]);
238 if (!nested_list.check() || py::len(nested_list) != cols)
240 for (
long j = 0; j < cols; ++j)
241 if (!py::extract<typename TransformType::Scalar>(nested_list()[j]).check())
248 py::extract<py::list> extract_list(obj_ptr);
249 py::extract<py::list> extract_nested_list(extract_list());
250 if (!extract_list.check()
251 || !checkNestedList(extract_list())
252 || (TransformType::Dim != py::len(extract_list()))
253 || (TransformType::Dim != py::len(extract_nested_list())))
259 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
261 py::list arr = py::extract<py::list>(obj_ptr);
262 auto rows = py::len(arr);
263 auto cols = py::len(py::extract<py::list>(arr[0])());
265 using storage_type = py::converter::rvalue_from_python_storage<TransformType>;
266 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
268 new (storage) TransformType;
269 TransformType& mat = *
static_cast<TransformType*
>(storage);
275 for (
long i = 0; i < rows; ++i)
276 for (
long j = 0; j < cols; ++j)
277 mat(i, j) = py::extract<typename TransformType::Scalar>(arr[i][j]);
279 data->convertible = storage;
293template <
typename VectorType>
302 static_assert(VectorType::RowsAtCompileTime == 1 || VectorType::ColsAtCompileTime == 1,
"Passed a Matrix into a Vector generator");
303 py::extract<np::ndarray> arr(obj_ptr);
305 || arr().get_nd() != 1
306 || arr().get_dtype() != np::dtype::get_builtin<typename VectorType::Scalar>()
307 || (VectorType::RowsAtCompileTime == 1
308 && VectorType::ColsAtCompileTime != Eigen::Dynamic
309 && VectorType::ColsAtCompileTime != arr().shape(0))
310 || (VectorType::ColsAtCompileTime == 1
311 && VectorType::RowsAtCompileTime != Eigen::Dynamic
312 && VectorType::RowsAtCompileTime != arr().shape(0)))
318 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
320 np::ndarray arr = py::extract<np::ndarray>(obj_ptr);
322 using storage_type = py::converter::rvalue_from_python_storage<VectorType>;
323 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
325 new (storage) VectorType;
326 VectorType& vec = *
static_cast<VectorType*
>(storage);
328 if (VectorType::RowsAtCompileTime == Eigen::Dynamic || VectorType::ColsAtCompileTime == Eigen::Dynamic)
329 vec.resize(arr.shape(0));
332 for (
int i = 0; i < arr.shape(0); ++i)
333 vec(i) = py::extract<typename VectorType::Scalar>(arr[i]);
335 data->convertible = storage;
344template <
typename MatrixType>
353 static_assert(MatrixType::ColsAtCompileTime != 1 && MatrixType::RowsAtCompileTime != 1,
"Passed a Vector into a Matrix generator");
355 py::extract<np::ndarray> arr(obj_ptr);
357 || arr().get_nd() != 2
358 || arr().get_dtype() != np::dtype::get_builtin<typename MatrixType::Scalar>()
359 || (MatrixType::RowsAtCompileTime != Eigen::Dynamic && MatrixType::RowsAtCompileTime != arr().shape(0))
360 || (MatrixType::ColsAtCompileTime != Eigen::Dynamic && MatrixType::ColsAtCompileTime != arr().shape(1)))
366 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
368 np::ndarray arr = py::extract<np::ndarray>(obj_ptr);
370 using storage_type = py::converter::rvalue_from_python_storage<MatrixType>;
371 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
373 new (storage) MatrixType;
374 MatrixType& mat = *
static_cast<MatrixType*
>(storage);
377 if (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic)
378 mat.resize(arr.shape(0), arr.shape(1));
381 for (
int i = 0; i < arr.shape(0); ++i)
382 for (
int j = 0; j < arr.shape(1); ++j)
383 mat(i, j) = py::extract<typename MatrixType::Scalar>(arr[i][j]);
385 data->convertible = storage;
389template <
typename QuaternionType>
399 py::extract<np::ndarray> arr(obj_ptr);
401 || arr().get_nd() != 1
402 || arr().get_dtype() != np::dtype::get_builtin<typename QuaternionType::Scalar>()
403 || 4 != arr().shape(0)
404 || 4 != arr().shape(0))
410 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
412 np::ndarray arr = py::extract<np::ndarray>(obj_ptr);
414 using storage_type = py::converter::rvalue_from_python_storage<QuaternionType>;
415 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
417 new (storage) QuaternionType;
418 QuaternionType& vec = *
static_cast<QuaternionType*
>(storage);
424 vec.x() = py::extract<typename QuaternionType::Scalar>(arr[0]);
425 vec.y() = py::extract<typename QuaternionType::Scalar>(arr[1]);
426 vec.z() = py::extract<typename QuaternionType::Scalar>(arr[2]);
427 vec.w() = py::extract<typename QuaternionType::Scalar>(arr[3]);
429 data->convertible = storage;
433template <
typename TransformType>
442 static_assert(TransformType::Dim != 1,
"Passed a Vector into a Matrix generator");
444 py::extract<np::ndarray> arr(obj_ptr);
446 || arr().get_nd() != 2
447 || arr().get_dtype() != np::dtype::get_builtin<typename TransformType::Scalar>()
448 || TransformType::Dim != arr().shape(0)
449 || TransformType::Dim != arr().shape(1))
455 static void construct(PyObject* obj_ptr, py::converter::rvalue_from_python_stage1_data* data)
457 np::ndarray arr = py::extract<np::ndarray>(obj_ptr);
459 using storage_type = py::converter::rvalue_from_python_storage<TransformType>;
460 void* storage =
reinterpret_cast<storage_type*
>(data)->storage.bytes;
462 new (storage) TransformType;
463 TransformType& mat = *
static_cast<TransformType*
>(storage);
470 for (
int i = 0; i < arr.shape(0); ++i)
471 for (
int j = 0; j < arr.shape(1); ++j)
472 mat(i, j) = py::extract<typename TransformType::Scalar>(arr[i][j]);
474 data->convertible = storage;
487template <
typename VectorType>
489 static PyObject*
convert(
const VectorType& mat)
491 static_assert(VectorType::ColsAtCompileTime == 1 || VectorType::RowsAtCompileTime == 1,
"Passed a Matrix into a Vector generator");
493 np::dtype dt = np::dtype::get_builtin<typename VectorType::Scalar>();
494 auto shape = py::make_tuple(mat.size());
495 np::ndarray mOut = np::empty(shape, dt);
497 for (Eigen::Index i = 0; i < mat.size(); ++i)
500 return py::incref(mOut.ptr());
509template <
typename MatrixType>
511 static PyObject*
convert(
const MatrixType& mat)
513 static_assert(MatrixType::ColsAtCompileTime != 1 && MatrixType::RowsAtCompileTime != 1,
"Passed a Vector into a Matrix generator");
515 np::dtype dt = np::dtype::get_builtin<typename MatrixType::Scalar>();
516 auto shape = py::make_tuple(mat.rows(), mat.cols());
517 np::ndarray mOut = np::empty(shape, dt);
519 for (Eigen::Index i = 0; i < mat.rows(); ++i)
520 for (Eigen::Index j = 0; j < mat.cols(); ++j)
521 mOut[i][j] = mat(i, j);
523 return py::incref(mOut.ptr());
532template <
typename QuaternionType>
534 static PyObject*
convert(
const QuaternionType& mat)
538 np::dtype dt = np::dtype::get_builtin<typename QuaternionType::Scalar>();
539 auto shape = py::make_tuple(4);
540 np::ndarray mOut = np::empty(shape, dt);
542 for (Eigen::Index i = 0; i < 4; ++i)
543 mOut[i] = mat.coeffs()[i];
545 return py::incref(mOut.ptr());
553template <
typename TransformType>
555 static PyObject*
convert(
const TransformType& mat)
557 static_assert(TransformType::Dim != 1,
"Passed a Vector into a Matrix generator");
559 np::dtype dt = np::dtype::get_builtin<typename TransformType::Scalar>();
560 auto shape = py::make_tuple(mat.rows(), mat.cols());
561 np::ndarray mOut = np::empty(shape, dt);
563 for (Eigen::Index i = 0; i < mat.rows(); ++i)
564 for (Eigen::Index j = 0; j < mat.cols(); ++j)
565 mOut[i][j] = mat(i, j);
567 return py::incref(mOut.ptr());
579template <
typename MatrixType>
586 if (isListConvertible)
590 py::to_python_converter<MatrixType, eigen_matrix_to_numpy_array<MatrixType> >();
597template <
typename QuaternionType>
604 if (isListConvertible)
608 py::to_python_converter<QuaternionType, eigen_quaternion_to_numpy_array<QuaternionType> >();
615template <
typename TransformType>
622 if (isListConvertible)
626 py::to_python_converter<TransformType, eigen_transform_to_numpy_array<TransformType> >();
633template <
typename VectorType>
640 if (isListConvertible)
644 py::to_python_converter<VectorType, eigen_vector_to_numpy_array<VectorType> >();
Definition base_types_conversion.h:41
void convertMatrix(bool isListConvertible=true)
Definition eigen_conversion.h:580
void convertQuaternion(bool isListConvertible=true)
Definition eigen_conversion.h:598
void convertVector(bool isListConvertible=true)
Definition eigen_conversion.h:634
void convertTransform(bool isListConvertible=true)
Definition eigen_conversion.h:616
Definition eigen_conversion.h:510
static PyObject * convert(const MatrixType &mat)
Definition eigen_conversion.h:511
Definition eigen_conversion.h:533
static PyObject * convert(const QuaternionType &mat)
Definition eigen_conversion.h:534
Definition eigen_conversion.h:488
static PyObject * convert(const VectorType &mat)
Definition eigen_conversion.h:489
Definition eigen_conversion.h:345
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:351
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:366
numpy_array_to_eigen_matrix()
Definition eigen_conversion.h:346
Definition eigen_conversion.h:390
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:410
numpy_array_to_eigen_quaternion()
Definition eigen_conversion.h:391
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:396
Definition eigen_conversion.h:294
numpy_array_to_eigen_vector()
Definition eigen_conversion.h:295
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:318
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:300
Definition eigen_conversion.h:102
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:108
python_list_to_eigen_matrix()
Definition eigen_conversion.h:103
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:141
Definition eigen_conversion.h:170
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:195
python_list_to_eigen_quaternion()
Definition eigen_conversion.h:171
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:176
Definition eigen_conversion.h:47
python_list_to_eigen_vector()
Definition eigen_conversion.h:48
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data)
Definition eigen_conversion.h:75
static void * convertible(PyObject *obj_ptr)
Definition eigen_conversion.h:53