Skip to content

Commit 4f8980b

Browse files
committed
core: externalize defaut implementation for EigenFromPy
1 parent 5e7ae5b commit 4f8980b

File tree

1 file changed

+115
-105
lines changed

1 file changed

+115
-105
lines changed

include/eigenpy/eigen-from-python.hpp

Lines changed: 115 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -89,140 +89,150 @@ namespace eigenpy
8989
typedef typename MatType::Scalar Scalar;
9090

9191
/// \brief Determine if pyObj can be converted into a MatType object
92-
static void* convertible(PyArrayObject* pyArray)
92+
static void* convertible(PyArrayObject* pyArray);
93+
94+
/// \brief Allocate memory and copy pyObj in the new storage
95+
static void construct(PyObject* pyObj,
96+
bp::converter::rvalue_from_python_stage1_data* memory);
97+
98+
static void registration();
99+
};
100+
101+
template<typename MatType>
102+
void* EigenFromPy<MatType>::convertible(PyArrayObject* pyArray)
103+
{
104+
if(!PyArray_Check(pyArray))
105+
return 0;
106+
107+
if(!np_type_is_convertible_into_scalar<Scalar>(EIGENPY_GET_PY_ARRAY_TYPE(pyArray)))
108+
return 0;
109+
110+
if(MatType::IsVectorAtCompileTime)
93111
{
94-
if(!PyArray_Check(pyArray))
95-
return 0;
112+
const Eigen::DenseIndex size_at_compile_time
113+
= MatType::IsRowMajor
114+
? MatType::ColsAtCompileTime
115+
: MatType::RowsAtCompileTime;
96116

97-
if(!np_type_is_convertible_into_scalar<Scalar>(EIGENPY_GET_PY_ARRAY_TYPE(pyArray)))
98-
return 0;
99-
100-
if(MatType::IsVectorAtCompileTime)
117+
switch(PyArray_NDIM(pyArray))
101118
{
102-
const Eigen::DenseIndex size_at_compile_time
103-
= MatType::IsRowMajor
104-
? MatType::ColsAtCompileTime
105-
: MatType::RowsAtCompileTime;
106-
107-
switch(PyArray_NDIM(pyArray))
119+
case 0:
120+
return 0;
121+
case 1:
108122
{
109-
case 0:
110-
return 0;
111-
case 1:
123+
if(size_at_compile_time != Eigen::Dynamic)
124+
{
125+
// check that the sizes at compile time matche
126+
if(PyArray_DIMS(pyArray)[0] == size_at_compile_time)
127+
return pyArray;
128+
else
129+
return 0;
130+
}
131+
else // This is a dynamic MatType
132+
return pyArray;
133+
}
134+
case 2:
135+
{
136+
// Special care of scalar matrix of dimension 1x1.
137+
if(PyArray_DIMS(pyArray)[0] == 1 && PyArray_DIMS(pyArray)[1] == 1)
112138
{
113139
if(size_at_compile_time != Eigen::Dynamic)
114140
{
115-
// check that the sizes at compile time matche
116-
if(PyArray_DIMS(pyArray)[0] == size_at_compile_time)
141+
if(size_at_compile_time == 1)
117142
return pyArray;
118143
else
119144
return 0;
120145
}
121146
else // This is a dynamic MatType
122147
return pyArray;
123148
}
124-
case 2:
149+
150+
if(PyArray_DIMS(pyArray)[0] > 1 && PyArray_DIMS(pyArray)[1] > 1)
151+
{
152+
return 0;
153+
}
154+
155+
if(((PyArray_DIMS(pyArray)[0] == 1) && (MatType::ColsAtCompileTime == 1))
156+
|| ((PyArray_DIMS(pyArray)[1] == 1) && (MatType::RowsAtCompileTime == 1)))
125157
{
126-
// Special care of scalar matrix of dimension 1x1.
127-
if(PyArray_DIMS(pyArray)[0] == 1 && PyArray_DIMS(pyArray)[1] == 1)
128-
{
129-
if(size_at_compile_time != Eigen::Dynamic)
130-
{
131-
if(size_at_compile_time == 1)
132-
return pyArray;
133-
else
134-
return 0;
135-
}
136-
else // This is a dynamic MatType
137-
return pyArray;
138-
}
139-
140-
if(PyArray_DIMS(pyArray)[0] > 1 && PyArray_DIMS(pyArray)[1] > 1)
141-
{
142-
return 0;
143-
}
144-
145-
if(((PyArray_DIMS(pyArray)[0] == 1) && (MatType::ColsAtCompileTime == 1))
146-
|| ((PyArray_DIMS(pyArray)[1] == 1) && (MatType::RowsAtCompileTime == 1)))
147-
{
158+
return 0;
159+
}
160+
161+
if(size_at_compile_time != Eigen::Dynamic)
162+
{ // This is a fixe size vector
163+
const Eigen::DenseIndex pyArray_size
164+
= PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]
165+
? PyArray_DIMS(pyArray)[0]
166+
: PyArray_DIMS(pyArray)[1];
167+
if(size_at_compile_time != pyArray_size)
148168
return 0;
149-
}
150-
151-
if(size_at_compile_time != Eigen::Dynamic)
152-
{ // This is a fixe size vector
153-
const Eigen::DenseIndex pyArray_size
154-
= PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]
155-
? PyArray_DIMS(pyArray)[0]
156-
: PyArray_DIMS(pyArray)[1];
157-
if(size_at_compile_time != pyArray_size)
158-
return 0;
159-
}
160-
break;
161169
}
162-
default:
163-
return 0;
170+
break;
164171
}
172+
default:
173+
return 0;
165174
}
166-
else // this is a matrix
175+
}
176+
else // this is a matrix
177+
{
178+
if(PyArray_NDIM(pyArray) == 1) // We can always convert a vector into a matrix
167179
{
168-
if(PyArray_NDIM(pyArray) == 1) // We can always convert a vector into a matrix
169-
{
170-
return pyArray;
171-
}
172-
173-
if(PyArray_NDIM(pyArray) != 2)
174-
{
175-
return 0;
176-
}
177-
178-
if(PyArray_NDIM(pyArray) == 2)
179-
{
180-
const int R = (int)PyArray_DIMS(pyArray)[0];
181-
const int C = (int)PyArray_DIMS(pyArray)[1];
182-
183-
if( (MatType::RowsAtCompileTime!=R)
184-
&& (MatType::RowsAtCompileTime!=Eigen::Dynamic) )
185-
return 0;
186-
if( (MatType::ColsAtCompileTime!=C)
187-
&& (MatType::ColsAtCompileTime!=Eigen::Dynamic) )
188-
return 0;
189-
}
180+
return pyArray;
190181
}
191-
192-
#ifdef NPY_1_8_API_VERSION
193-
if(!(PyArray_FLAGS(pyArray)))
194-
#else
195-
if(!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
196-
#endif
182+
183+
if(PyArray_NDIM(pyArray) != 2)
197184
{
198185
return 0;
199186
}
200187

201-
return pyArray;
202-
}
203-
204-
/// \brief Allocate memory and copy pyObj in the new storage
205-
static void construct(PyObject* pyObj,
206-
bp::converter::rvalue_from_python_stage1_data* memory)
207-
{
208-
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
209-
assert((PyArray_DIMS(pyArray)[0]<INT_MAX) && (PyArray_DIMS(pyArray)[1]<INT_MAX));
210-
211-
void* storage = reinterpret_cast<bp::converter::rvalue_from_python_storage<MatType>*>
212-
(reinterpret_cast<void*>(memory))->storage.bytes;
213-
214-
EigenAllocator<MatType>::allocate(pyArray,storage);
215-
216-
memory->convertible = storage;
188+
if(PyArray_NDIM(pyArray) == 2)
189+
{
190+
const int R = (int)PyArray_DIMS(pyArray)[0];
191+
const int C = (int)PyArray_DIMS(pyArray)[1];
192+
193+
if( (MatType::RowsAtCompileTime!=R)
194+
&& (MatType::RowsAtCompileTime!=Eigen::Dynamic) )
195+
return 0;
196+
if( (MatType::ColsAtCompileTime!=C)
197+
&& (MatType::ColsAtCompileTime!=Eigen::Dynamic) )
198+
return 0;
199+
}
217200
}
218201

219-
static void registration()
202+
#ifdef NPY_1_8_API_VERSION
203+
if(!(PyArray_FLAGS(pyArray)))
204+
#else
205+
if(!(PyArray_FLAGS(pyArray) & NPY_ALIGNED))
206+
#endif
220207
{
221-
bp::converter::registry::push_back
222-
(reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
223-
&EigenFromPy::construct,bp::type_id<MatType>());
208+
return 0;
224209
}
225-
};
210+
211+
return pyArray;
212+
}
213+
214+
template<typename MatType>
215+
void EigenFromPy<MatType>::construct(PyObject* pyObj,
216+
bp::converter::rvalue_from_python_stage1_data* memory)
217+
{
218+
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
219+
assert((PyArray_DIMS(pyArray)[0]<INT_MAX) && (PyArray_DIMS(pyArray)[1]<INT_MAX));
220+
221+
void* storage = reinterpret_cast<bp::converter::rvalue_from_python_storage<MatType>*>
222+
(reinterpret_cast<void*>(memory))->storage.bytes;
223+
224+
EigenAllocator<MatType>::allocate(pyArray,storage);
225+
226+
memory->convertible = storage;
227+
}
228+
229+
template<typename MatType>
230+
void EigenFromPy<MatType>::registration()
231+
{
232+
bp::converter::registry::push_back
233+
(reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible),
234+
&EigenFromPy::construct,bp::type_id<MatType>());
235+
}
226236

227237
template<typename MatType>
228238
struct EigenFromPyConverter

0 commit comments

Comments
 (0)