1717#ifndef __eigenpy_details_hpp__
1818#define __eigenpy_details_hpp__
1919
20- #include < boost/python.hpp>
21- #include < Eigen/Core>
22-
23- #include < numpy/numpyconfig.h>
24- #ifdef NPY_1_8_API_VERSION
25- #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
26- #endif
20+ #include " eigenpy/fwd.hpp"
2721
2822#include < numpy/arrayobject.h>
2923#include < iostream>
@@ -73,6 +67,40 @@ namespace eigenpy
7367 bp::object pyMatrixType;
7468 bp::object pyModule;
7569 };
70+
71+ template <typename MatType>
72+ struct EigenObjectAllocator
73+ {
74+ typedef MatType Type;
75+
76+ static void allocate (PyArrayObject * pyArray, void * storage)
77+ {
78+ typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map (pyArray);
79+ new (storage) MatType (numpyMap);
80+ }
81+
82+ static void convert (Type const & mat , PyArrayObject * pyArray)
83+ {
84+ MapNumpy<MatType>::map (pyArray) = mat;
85+ }
86+ };
87+
88+ template <typename MatType>
89+ struct EigenObjectAllocator < eigenpy::Ref<MatType> >
90+ {
91+ typedef eigenpy::Ref<MatType> Type;
92+
93+ static void allocate (PyArrayObject * pyArray, void * storage)
94+ {
95+ typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map (pyArray);
96+ new (storage) Type (numpyMap);
97+ }
98+
99+ static void convert (Type const & mat , PyArrayObject * pyArray)
100+ {
101+ MapNumpy<MatType>::map (pyArray) = mat;
102+ }
103+ };
76104
77105 /* --- TO PYTHON -------------------------------------------------------------- */
78106 template <typename MatType>
@@ -89,24 +117,14 @@ namespace eigenpy
89117 PyArrayObject* pyArray = (PyArrayObject*)
90118 PyArray_SimpleNew (2 , shape, NumpyEquivalentType<T>::type_code);
91119
92- MapNumpy <MatType>::map ( pyArray) = mat ;
120+ EigenObjectAllocator <MatType>::convert (mat, pyArray);
93121
94122 return PyMatrixType::getInstance ().make (pyArray).ptr ();
95123 }
96124 };
97125
98126 /* --- FROM PYTHON ------------------------------------------------------------ */
99127
100- template <typename MatType>
101- struct EigenObjectAllocator
102- {
103- static void allocate (PyArrayObject * pyArray, void * storage)
104- {
105- typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map (pyArray);
106- new (storage) MatType (numpyMap);
107- }
108- };
109-
110128 template <typename MatType>
111129 struct EigenFromPy
112130 {
@@ -120,8 +138,6 @@ namespace eigenpy
120138 // Determine if obj_ptr can be converted in a Eigenvec
121139 static void * convertible (PyArrayObject* obj_ptr)
122140 {
123- typedef typename MatType::Scalar T;
124-
125141 if (!PyArray_Check (obj_ptr))
126142 {
127143#ifndef NDEBUG
@@ -130,16 +146,42 @@ namespace eigenpy
130146 return 0 ;
131147 }
132148
149+ if (MatType::IsVectorAtCompileTime)
150+ {
151+ if (PyArray_DIMS (obj_ptr)[0 ] > 1 && PyArray_DIMS (obj_ptr)[1 ] > 1 )
152+ {
153+ #ifndef NDEBUG
154+ std::cerr << " The number of dimension of the object does not correspond to a vector" << std::endl;
155+ #endif
156+ return 0 ;
157+ }
158+
159+ if (((PyArray_DIMS (obj_ptr)[0 ] == 1 ) && (MatType::ColsAtCompileTime == 1 ))
160+ || ((PyArray_DIMS (obj_ptr)[1 ] == 1 ) && (MatType::RowsAtCompileTime == 1 )))
161+ {
162+ #ifndef NDEBUG
163+ if (MatType::ColsAtCompileTime == 1 )
164+ std::cerr << " The object is not a column vector" << std::endl;
165+ else
166+ std::cerr << " The object is not a row vector" << std::endl;
167+ #endif
168+ return 0 ;
169+ }
170+ }
171+
133172 if (PyArray_NDIM (obj_ptr) != 2 )
173+ {
134174 if ( (PyArray_NDIM (obj_ptr) !=1 ) || (! MatType::IsVectorAtCompileTime) )
135175 {
136176#ifndef NDEBUG
137177 std::cerr << " The number of dimension of the object is not correct." << std::endl;
138178#endif
139179 return 0 ;
140180 }
181+ }
141182
142- if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 )) != NumpyEquivalentType<T>::type_code)
183+ if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 ))
184+ != NumpyEquivalentType<typename MatType::Scalar>::type_code)
143185 {
144186#ifndef NDEBUG
145187 std::cerr << " The internal type as no Eigen equivalent." << std::endl;
@@ -178,6 +220,7 @@ namespace eigenpy
178220 memory->convertible = storage;
179221 }
180222 };
223+
181224#define numpy_import_array () {if (_import_array () < 0 ) {PyErr_Print (); PyErr_SetString (PyExc_ImportError, " numpy.core.multiarray failed to import" ); } }
182225
183226 template <typename MatType,typename EigenEquivalentType>
0 commit comments