diff --git a/cmake b/cmake index 000a90190d1dca8b028f437095f2fddff0f9839b..5cb34667bde62b5676e2b869dc6d13d598a4e2e3 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 000a90190d1dca8b028f437095f2fddff0f9839b +Subproject commit 5cb34667bde62b5676e2b869dc6d13d598a4e2e3 diff --git a/include/eigenpy/angle-axis.hpp b/include/eigenpy/angle-axis.hpp index ea78f4dff615ad9b0ab3fad268642d80630b2f73..d5ad5aa14c93ec81a9289d74ccb1c0530f9397fd 100644 --- a/include/eigenpy/angle-axis.hpp +++ b/include/eigenpy/angle-axis.hpp @@ -34,8 +34,6 @@ namespace eigenpy } }; - BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxAngleAxis_overload,call<Eigen::AngleAxisd>::isApprox,2,3) - template<typename AngleAxis> class AngleAxisVisitor : public bp::def_visitor< AngleAxisVisitor<AngleAxis> > @@ -48,6 +46,8 @@ namespace eigenpy typedef typename Eigen::Quaternion<Scalar,0> Quaternion; typedef Eigen::RotationBase<AngleAxis,3> RotationBase; + BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxAngleAxis_overload,call<AngleAxis>::isApprox,2,3) + public: template<class PyClass> diff --git a/include/eigenpy/eigen-allocator.hpp b/include/eigenpy/eigen-allocator.hpp index 343f76811e353a42a7cd6dcada9992007633f3dc..ca66b7be6c84c67d68624e8df8d8bacba7434148 100644 --- a/include/eigenpy/eigen-allocator.hpp +++ b/include/eigenpy/eigen-allocator.hpp @@ -19,50 +19,67 @@ namespace eigenpy template<typename MatType, bool IsVectorAtCompileTime = MatType::IsVectorAtCompileTime> struct init_matrix_or_array { + static MatType * run(int rows, int cols, void * storage) + { + if(storage) + return new (storage) MatType(rows,cols); + else + return new MatType(rows,cols); + } + static MatType * run(PyArrayObject * pyArray, void * storage = NULL) { assert(PyArray_NDIM(pyArray) == 1 || PyArray_NDIM(pyArray) == 2); int rows = -1, cols = -1; - if(PyArray_NDIM(pyArray) == 2) + const int ndim = PyArray_NDIM(pyArray); + if(ndim == 2) { rows = (int)PyArray_DIMS(pyArray)[0]; cols = (int)PyArray_DIMS(pyArray)[1]; } - else if(PyArray_NDIM(pyArray) == 1) + else if(ndim == 1) { rows = (int)PyArray_DIMS(pyArray)[0]; cols = 1; } - if(storage) - return new (storage) MatType(rows,cols); - else - return new MatType(rows,cols); + return run(rows,cols,storage); } }; template<typename MatType> struct init_matrix_or_array<MatType,true> { + static MatType * run(int rows, int cols, void * storage) + { + if(storage) + return new (storage) MatType(rows,cols); + else + return new MatType(rows,cols); + } + + static MatType * run(int size, void * storage) + { + if(storage) + return new (storage) MatType(size); + else + return new MatType(size); + } + static MatType * run(PyArrayObject * pyArray, void * storage = NULL) { - if(PyArray_NDIM(pyArray) == 1) + const int ndim = PyArray_NDIM(pyArray); + if(ndim == 1) { - const int rows_or_cols = (int)PyArray_DIMS(pyArray)[0]; - if(storage) - return new (storage) MatType(rows_or_cols); - else - return new MatType(rows_or_cols); + const int size = (int)PyArray_DIMS(pyArray)[0]; + return run(size,storage); } else { const int rows = (int)PyArray_DIMS(pyArray)[0]; const int cols = (int)PyArray_DIMS(pyArray)[1]; - if(storage) - return new (storage) MatType(rows,cols); - else - return new MatType(rows,cols); + return run(rows,cols,storage); } } }; diff --git a/include/eigenpy/eigen-from-python.hpp b/include/eigenpy/eigen-from-python.hpp index 1a55bcbaba45bdba843a86a979c41bf5f046fb3c..ee879f6f1fb39d6f828bca5f191eb17681022921 100644 --- a/include/eigenpy/eigen-from-python.hpp +++ b/include/eigenpy/eigen-from-python.hpp @@ -275,13 +275,13 @@ namespace eigenpy memory->convertible = storage->storage.bytes; } - template<typename MatType> + template<typename MatType, typename _Scalar> struct EigenFromPy { typedef typename MatType::Scalar Scalar; /// \brief Determine if pyObj can be converted into a MatType object - static void* convertible(PyArrayObject* pyArray); + static void* convertible(PyObject* pyObj); /// \brief Allocate memory and copy pyObj in the new storage static void construct(PyObject* pyObj, @@ -290,12 +290,14 @@ namespace eigenpy static void registration(); }; - template<typename MatType> - void* EigenFromPy<MatType>::convertible(PyArrayObject* pyArray) + template<typename MatType, typename _Scalar> + void* EigenFromPy<MatType,_Scalar>::convertible(PyObject* pyObj) { - if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyArray))) + if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyObj))) return 0; + PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj); + if(!np_type_is_convertible_into_scalar<Scalar>(EIGENPY_GET_PY_ARRAY_TYPE(pyArray))) return 0; @@ -403,15 +405,15 @@ namespace eigenpy return pyArray; } - template<typename MatType> - void EigenFromPy<MatType>::construct(PyObject* pyObj, - bp::converter::rvalue_from_python_stage1_data* memory) + template<typename MatType, typename _Scalar> + void EigenFromPy<MatType,_Scalar>::construct(PyObject* pyObj, + bp::converter::rvalue_from_python_stage1_data* memory) { eigen_from_py_construct<MatType>(pyObj,memory); } - template<typename MatType> - void EigenFromPy<MatType>::registration() + template<typename MatType, typename _Scalar> + void EigenFromPy<MatType,_Scalar>::registration() { bp::converter::registry::push_back (reinterpret_cast<void *(*)(_object *)>(&EigenFromPy::convertible), @@ -431,7 +433,7 @@ namespace eigenpy // Add conversion to Eigen::EigenBase<MatType> typedef Eigen::EigenBase<MatType> EigenBase; - EigenFromPy<EigenBase>::registration(); + EigenFromPy<EigenBase,typename MatType::Scalar>::registration(); // Add conversion to Eigen::PlainObjectBase<MatType> typedef Eigen::PlainObjectBase<MatType> PlainObjectBase; @@ -464,7 +466,7 @@ namespace eigenpy }; template<typename MatType> - struct EigenFromPy< Eigen::EigenBase<MatType> > : EigenFromPy<MatType> + struct EigenFromPy< Eigen::EigenBase<MatType>, typename MatType::Scalar > : EigenFromPy<MatType> { typedef EigenFromPy<MatType> EigenFromPyDerived; typedef Eigen::EigenBase<MatType> Base; @@ -500,13 +502,14 @@ namespace eigenpy typedef typename MatType::Scalar Scalar; /// \brief Determine if pyObj can be converted into a MatType object - static void* convertible(PyArrayObject * pyArray) + static void* convertible(PyObject * pyObj) { - if(!call_PyArray_Check(reinterpret_cast<PyObject*>(pyArray))) + if(!call_PyArray_Check(pyObj)) return 0; + PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj); if(!PyArray_ISWRITEABLE(pyArray)) return 0; - return EigenFromPy<MatType>::convertible(pyArray); + return EigenFromPy<MatType>::convertible(pyObj); } static void registration() @@ -524,9 +527,9 @@ namespace eigenpy typedef typename MatType::Scalar Scalar; /// \brief Determine if pyObj can be converted into a MatType object - static void* convertible(PyArrayObject * pyArray) + static void* convertible(PyObject * pyObj) { - return EigenFromPy<MatType>::convertible(pyArray); + return EigenFromPy<MatType>::convertible(pyObj); } static void registration() diff --git a/include/eigenpy/eigen-to-python.hpp b/include/eigenpy/eigen-to-python.hpp index bd89fec522f79a56932f8e0fd33732284f6bb6aa..8b1ac1d088637fcbc33f0143e7233591243b1089 100644 --- a/include/eigenpy/eigen-to-python.hpp +++ b/include/eigenpy/eigen-to-python.hpp @@ -50,7 +50,7 @@ namespace eigenpy { namespace bp = boost::python; - template<typename MatType> + template<typename MatType, typename _Scalar> struct EigenToPy { static PyObject* convert(typename boost::add_reference<typename boost::add_const<MatType>::type>::type mat) @@ -82,8 +82,8 @@ namespace eigenpy } }; - template<typename MatType, int Options, typename Stride> - struct EigenToPy< Eigen::Ref<MatType,Options,Stride> > + template<typename MatType, int Options, typename Stride, typename _Scalar> + struct EigenToPy< Eigen::Ref<MatType,Options,Stride>,_Scalar > { static PyObject* convert(const Eigen::Ref<MatType,Options,Stride> & mat) { diff --git a/include/eigenpy/fwd.hpp b/include/eigenpy/fwd.hpp index 506a1d93a2b055b7914a59f8b2a784cef1ab8560..02ec33450b7c1c6f24e63fe3e96d8a2b6b8a88f2 100644 --- a/include/eigenpy/fwd.hpp +++ b/include/eigenpy/fwd.hpp @@ -28,8 +28,8 @@ namespace eigenpy { - template<typename MatType> struct EigenToPy; - template<typename MatType> struct EigenFromPy; + template<typename MatType, typename Scalar = typename boost::remove_reference<MatType>::type::Scalar> struct EigenToPy; + template<typename MatType, typename Scalar = typename boost::remove_reference<MatType>::type::Scalar> struct EigenFromPy; } #endif // ifndef __eigenpy_fwd_hpp__ diff --git a/include/eigenpy/quaternion.hpp b/include/eigenpy/quaternion.hpp index 6d5f1ffc8c83bf32e4d248a7ac95937f3346dbdf..05d88a64cc237c18645f65c03258d05c15462fff 100644 --- a/include/eigenpy/quaternion.hpp +++ b/include/eigenpy/quaternion.hpp @@ -88,8 +88,6 @@ namespace eigenpy } }; - BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Eigen::Quaterniond>::isApprox,2,3) - template<typename Quaternion> class QuaternionVisitor : public bp::def_visitor< QuaternionVisitor<Quaternion> > @@ -103,6 +101,8 @@ namespace eigenpy typedef typename QuaternionBase::Matrix3 Matrix3; typedef typename QuaternionBase::AngleAxisType AngleAxis; + + BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Quaternion>::isApprox,2,3) public: diff --git a/include/eigenpy/user-type.hpp b/include/eigenpy/user-type.hpp index 7181063e5dd21f7b2cdff398cda4de8518c813e8..20c12cabf02f5b1bf7d79686298105534a61e224 100644 --- a/include/eigenpy/user-type.hpp +++ b/include/eigenpy/user-type.hpp @@ -16,13 +16,13 @@ namespace eigenpy template<typename T, int type_code = NumpyEquivalentType<T>::type_code> struct SpecialMethods { - static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) {}; - static PyObject * getitem(void * /*ip*/, void * /*ap*/) { return NULL; }; - static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) { return -1; } - static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/, - long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) {}; - static npy_bool nonzero(void * /*ip*/, void * /*array*/) { return (npy_bool)false; }; - static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/, + inline static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) /*{}*/; + inline static PyObject * getitem(void * /*ip*/, void * /*ap*/) /*{ return NULL; }*/; + inline static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) /*{ return -1; }*/; + inline static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/, + long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) /*{}*/; + inline static npy_bool nonzero(void * /*ip*/, void * /*array*/) /*{ return (npy_bool)false; }*/; + inline static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/, void * /*op*/, npy_intp /*n*/, void * /*arr*/); // static void cast(void * /*from*/, void * /*to*/, npy_intp /*n*/, void * /*fromarr*/, void * /*toarr*/) {}; }; @@ -30,7 +30,7 @@ namespace eigenpy template<typename T> struct SpecialMethods<T,NPY_USERDEF> { - static void copyswap(void * dst, void * src, int swap, void * /*arr*/) + inline static void copyswap(void * dst, void * src, int swap, void * /*arr*/) { // std::cout << "copyswap" << std::endl; if (src != NULL) @@ -48,7 +48,7 @@ namespace eigenpy } } - static PyObject * getitem(void * ip, void * ap) + inline static PyObject * getitem(void * ip, void * ap) { // std::cout << "getitem" << std::endl; PyArrayObject * py_array = static_cast<PyArrayObject *>(ap); @@ -68,7 +68,7 @@ namespace eigenpy } } - static int setitem(PyObject * src_obj, void * dest_ptr, void * array) + inline static int setitem(PyObject * src_obj, void * dest_ptr, void * array) { // std::cout << "setitem" << std::endl; if(array == NULL) @@ -103,8 +103,8 @@ namespace eigenpy return 0; } - static void copyswapn(void * dst, long dstride, void * src, long sstride, - long n, int swap, void * array) + inline static void copyswapn(void * dst, long dstride, void * src, long sstride, + long n, int swap, void * array) { // std::cout << "copyswapn" << std::endl; @@ -122,7 +122,7 @@ namespace eigenpy } } - static npy_bool nonzero(void * ip, void * array) + inline static npy_bool nonzero(void * ip, void * array) { // std::cout << "nonzero" << std::endl; static const T ZeroValue = T(0); @@ -141,8 +141,8 @@ namespace eigenpy } } - static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1, - void * op, npy_intp n, void * /*arr*/) + inline static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1, + void * op, npy_intp n, void * /*arr*/) { T res = T(0); char *ip0 = (char*)ip0_, *ip1 = (char*)ip1_; diff --git a/package.xml b/package.xml index 75bd76e0d8348e74a06c9a9bf90c59d5b63b6236..337205aaa6d6bfc66142d662c80f3db8f27414c2 100644 --- a/package.xml +++ b/package.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <package format="3"> <name>eigenpy</name> - <version>2.5.0</version> + <version>2.6.0</version> <description>Bindings between Numpy and Eigen using Boost.Python</description> <maintainer email="justin.carpentier@inria.fr">Justin Carpentier</maintainer> <maintainer email="opensource@wolfgangmerkt.com">Wolfgang Merkt</maintainer> diff --git a/unittest/user_type.cpp b/unittest/user_type.cpp index b128648a3bb33174c9564b339f227e43300bb3ff..a6fdeee89031774403abbd52537aa1bf2ab80b30 100644 --- a/unittest/user_type.cpp +++ b/unittest/user_type.cpp @@ -89,7 +89,8 @@ void expose_custom_type(const std::string & name) .def("__repr__",&Type::print) ; - eigenpy::registerNewType<Type>(); + int code = eigenpy::registerNewType<Type>(); + std::cout << "code: " << code << std::endl; eigenpy::registerCommonUfunc<Type>(); }