From 245a0a847fd29867c5fa4b56fa90454880304464 Mon Sep 17 00:00:00 2001 From: jcarpent <jcarpent@laas.fr> Date: Fri, 30 Sep 2016 10:58:19 +0200 Subject: [PATCH] [Python] Add copyable method to create a raw copy of Spatial classes [Python] Introduce struct to expose both std::vector and aligned_vector all: change __se3_* for __pinocchio_* for pragma once all: change namespace from se3 to pinocchio The previous se3 namespace is now deprecated but can still be used all: remove license from files [bindings][pickling] add support for vector<T> aligned_vector<T> map<T> pickling. update model and data classes to make their members picklable [bindings][pickling] 1) fix includes. make picklemap borrow from picklevector 2) use pickle support for rest of data and some more of model vectors python: add converter from Python list to std::vector or aligned_vector python: fix issue on GCC related to namespace bp python: fix namespace issue python/vector: add conversion tolist for std::vector python/utils: return by reference when creating list python/utils: add return of the class for StdVector helpers python: fix return type python/pickle: fix pickling of std::map python: fix potential bug with C++11 python: make the code compliant for casadi bindings python: fix arg name python/pickle: fix compatibility issue Compilation issues with recent version of Boost python: add copy constructor and method to std::vector python: expose operator{==,!=} for std::vector Revert "python: expose operator{==,!=} for std::vector" This reverts commit 6710dd4758791b3eee1ac444945e7f507aece7f6. python/utils: update std-vector exposition python: fix issues with const reference as input argument python: fix pickling of Pinocchio data structure --- copyable.hpp | 34 +++++++++++++++++ pickle-vector.hpp | 51 +++++++++++++++++++++++++ std-aligned-vector.hpp | 84 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 copyable.hpp create mode 100644 pickle-vector.hpp create mode 100644 std-aligned-vector.hpp diff --git a/copyable.hpp b/copyable.hpp new file mode 100644 index 00000000..d91601bd --- /dev/null +++ b/copyable.hpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016-2021 CNRS INRIA +// + +#ifndef __pinocchio_python_utils_copyable_hpp__ +#define __pinocchio_python_utils_copyable_hpp__ + +#include <boost/python.hpp> + +namespace pinocchio +{ + namespace python + { + + namespace bp = boost::python; + + /// + /// \brief Add the Python method copy to allow a copy of this by calling the copy constructor. + /// + template<class C> + struct CopyableVisitor + : public bp::def_visitor< CopyableVisitor<C> > + { + template<class PyClass> + void visit(PyClass & cl) const + { cl.def("copy",©,bp::arg("self"),"Returns a copy of *this."); } + + private: + static C copy(const C & self) { return C(self); } + }; + } // namespace python +} // namespace pinocchio + +#endif // ifndef __pinocchio_python_utils_copyable_hpp__ diff --git a/pickle-vector.hpp b/pickle-vector.hpp new file mode 100644 index 00000000..669a2463 --- /dev/null +++ b/pickle-vector.hpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2019-2020 CNRS INRIA +// + +#ifndef __pinocchio_python_utils_pickle_vector_hpp__ +#define __pinocchio_python_utils_pickle_vector_hpp__ + +#include <boost/python.hpp> +#include <boost/python/tuple.hpp> +#include <boost/python/stl_iterator.hpp> + +namespace pinocchio +{ + namespace python + { + /// + /// \brief Create a pickle interface for the std::vector and aligned vector + /// + /// \tparam VecType Vector Type to pickle + /// + template<typename VecType> + struct PickleVector : boost::python::pickle_suite + { + static boost::python::tuple getinitargs(const VecType&) + { return boost::python::make_tuple(); } + + static boost::python::tuple getstate(boost::python::object op) + { + return boost::python::make_tuple(boost::python::list(boost::python::extract<const VecType&>(op)())); + } + + static void setstate(boost::python::object op, boost::python::tuple tup) + { + if(boost::python::len(tup) > 0) + { + VecType & o = boost::python::extract<VecType&>(op)(); + boost::python::stl_input_iterator<typename VecType::value_type> begin(tup[0]), end; + while(begin != end) + { + o.push_back(*begin); + ++begin; + } + } + } + + static bool getstate_manages_dict() { return true; } + }; + } +} + +#endif // ifndef __pinocchio_python_utils_pickle_vector_hpp__ diff --git a/std-aligned-vector.hpp b/std-aligned-vector.hpp new file mode 100644 index 00000000..13a28243 --- /dev/null +++ b/std-aligned-vector.hpp @@ -0,0 +1,84 @@ +// +// Copyright (c) 2016-2022 CNRS INRIA +// + +#ifndef __pinocchio_python_utils_std_aligned_vector_hpp__ +#define __pinocchio_python_utils_std_aligned_vector_hpp__ + +#include <boost/python.hpp> +#include <string> + +#include "pinocchio/container/aligned-vector.hpp" + +#include "pinocchio/bindings/python/utils/pickle-vector.hpp" +#include "pinocchio/bindings/python/utils/std-vector.hpp" + +namespace pinocchio +{ + namespace python + { + + /// + /// \brief Expose an container::aligned_vector from a type given as template argument. + /// + /// \tparam T Type to expose as container::aligned_vector<T>. + /// \tparam EnableFromPythonListConverter Enables the conversion from a Python list to a container::aligned_vector<T>. + /// + /// \sa StdAlignedVectorPythonVisitor + /// + template<class T, bool NoProxy = false, bool EnableFromPythonListConverter = true> + struct StdAlignedVectorPythonVisitor + : public ::boost::python::vector_indexing_suite<typename container::aligned_vector<T>,NoProxy, internal::contains_vector_derived_policies<typename container::aligned_vector<T>,NoProxy> > + , public StdContainerFromPythonList< container::aligned_vector<T> > + { + typedef container::aligned_vector<T> vector_type; + typedef StdContainerFromPythonList<vector_type,NoProxy> FromPythonListConverter; + typedef T value_type; + + static void expose(const std::string & class_name, + const std::string & doc_string = "") + { + expose(class_name,doc_string,EmptyPythonVisitor()); + } + + template<typename VisitorDerived> + static void expose(const std::string & class_name, + const boost::python::def_visitor<VisitorDerived> & visitor) + { + expose(class_name,"",visitor); + } + + template<typename VisitorDerived> + static void expose(const std::string & class_name, + const std::string & doc_string, + const boost::python::def_visitor<VisitorDerived> & visitor) + { + namespace bp = boost::python; + if(!register_symbolic_link_to_registered_type<vector_type>()) + { + bp::class_<vector_type> cl(class_name.c_str(),doc_string.c_str()); + cl + .def(StdAlignedVectorPythonVisitor()) + + .def(bp::init<size_t, const value_type &>(bp::args("self","size","value"),"Constructor from a given size and a given value.")) + .def(bp::init<const vector_type &>(bp::args("self","other"),"Copy constructor")) + + .def("tolist",&FromPythonListConverter::tolist,bp::arg("self"), + "Returns the aligned_vector as a Python list.") + .def(visitor) +#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION + .def_pickle(PickleVector<vector_type>()) +#endif + .def(CopyableVisitor<vector_type>()) + ; + + // Register conversion + if(EnableFromPythonListConverter) + FromPythonListConverter::register_converter(); + } + } + }; + } // namespace python +} // namespace pinocchio + +#endif // ifndef __pinocchio_python_utils_std_aligned_vector_hpp__ -- GitLab