From 62b65e05edb1ec824a7bf645881d546ef2da6f78 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Wed, 26 Jan 2022 18:56:08 -0800 Subject: [PATCH 1/3] Angle: hide c++ headers from pybind Angle.hh Reduce the number of headers included in the _ignition_math_pybind11.cc translation unit. Signed-off-by: Steve Peters --- src/python_pybind11/src/Angle.cc | 1 + src/python_pybind11/src/Angle.hh | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python_pybind11/src/Angle.cc b/src/python_pybind11/src/Angle.cc index f57fc5cd2..a0574c17e 100644 --- a/src/python_pybind11/src/Angle.cc +++ b/src/python_pybind11/src/Angle.cc @@ -17,6 +17,7 @@ #include +#include #include #include "Angle.hh" diff --git a/src/python_pybind11/src/Angle.hh b/src/python_pybind11/src/Angle.hh index 604ded4d4..f0b304d0e 100644 --- a/src/python_pybind11/src/Angle.hh +++ b/src/python_pybind11/src/Angle.hh @@ -21,8 +21,6 @@ #include -#include - namespace py = pybind11; namespace ignition From 490ae769451681479e599aa33f06947f0dde11f2 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Wed, 26 Jan 2022 19:01:37 -0800 Subject: [PATCH 2/3] Vector2: move pybind template helper to .cc file This isolates the template code into its own translation unit. Signed-off-by: Steve Peters --- src/python_pybind11/CMakeLists.txt | 1 + src/python_pybind11/src/Vector2.cc | 142 ++++++++++++++++++ src/python_pybind11/src/Vector2.hh | 109 +------------- .../src/_ignition_math_pybind11.cc | 4 +- 4 files changed, 148 insertions(+), 108 deletions(-) create mode 100644 src/python_pybind11/src/Vector2.cc diff --git a/src/python_pybind11/CMakeLists.txt b/src/python_pybind11/CMakeLists.txt index 55d816260..3b491b87a 100644 --- a/src/python_pybind11/CMakeLists.txt +++ b/src/python_pybind11/CMakeLists.txt @@ -28,6 +28,7 @@ pybind11_add_module(math SHARED src/Spline.cc src/StopWatch.cc src/Temperature.cc + src/Vector2.cc src/Vector3Stats.cc ) diff --git a/src/python_pybind11/src/Vector2.cc b/src/python_pybind11/src/Vector2.cc new file mode 100644 index 000000000..910020d39 --- /dev/null +++ b/src/python_pybind11/src/Vector2.cc @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2022 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include + +#include +#include +#include + +#include "Vector2.hh" + +using namespace pybind11::literals; + +namespace ignition +{ +namespace math +{ +namespace python +{ +/// Template helper function +template +void helpDefineMathVector2(py::module &m, const std::string &typestr) +{ + using Class = ignition::math::Vector2; + auto toString = [](const Class &si) { + std::stringstream stream; + stream << si; + return stream.str(); + }; + std::string pyclass_name = typestr; + py::class_(m, + pyclass_name.c_str(), + py::buffer_protocol(), + py::dynamic_attr()) + .def(py::init<>()) + .def(py::init()) + .def(py::init()) + .def("sum", &Class::Sum, "Return the sum of the values") + .def("distance", &Class::Distance, "Calc distance to the given point") + .def("length", + &Class::Length, + "Returns the length (magnitude) of the vector") + .def("squared_length", + &Class::SquaredLength, + "Return the square of the length (magnitude) of the vector") + .def("normalize", &Class::Normalize, "Normalize the vector length") + .def("normalized", &Class::Normalized, "Return a normalized vector") + .def("round", + &Class::Round, + "Round to near whole number, return the result.") + .def("rounded", &Class::Rounded, "Get a rounded version of this vector") + .def("set", &Class::Set, "Set the contents of the vector") + .def("dot", + &Class::Dot, + "Return the dot product of this vector and another vector") + .def("abs_dot", &Class::AbsDot, + "Return the absolute dot product of this vector and " + "another vector. This is similar to the Dot function, except the " + "absolute value of each component of the vector is used.") + .def("abs", + &Class::Abs, + "Get the absolute value of the vector") + .def("max", + py::overload_cast(&Class::Max), + "Set this vector's components to the maximum of itself and the " + "passed in vector") + .def("max", py::overload_cast<>(&Class::Max, py::const_), + "Get the maximum value in the vector") + .def("min", py::overload_cast(&Class::Min), + "Set this vector's components to the minimum of itself and the " + "passed in vector") + .def("min", py::overload_cast<>(&Class::Min, py::const_), + "Get the minimum value in the vector") + .def(py::self + py::self) + .def(py::self += py::self) + .def(py::self + T()) + .def(py::self += T()) + .def(py::self * py::self) + .def(py::self *= py::self) + .def(py::self * T()) + .def(py::self *= T()) + .def(py::self - py::self) + .def(py::self -= py::self) + .def(py::self - T()) + .def(py::self -= T()) + .def(py::self / py::self) + .def(py::self /= py::self) + .def(py::self / T()) + .def(py::self /= T()) + .def(py::self != py::self) + .def(py::self == py::self) + .def(-py::self) + .def("equal", &Class::Equal, "Equal to operator") + .def("is_finite", + &Class::IsFinite, + "See if a point is finite (e.g., not nan)") + .def("correct", &Class::Correct, "Corrects any nan values") + .def("x", py::overload_cast<>(&Class::X), "Get the x value.") + .def("y", py::overload_cast<>(&Class::Y), "Get the y value.") + .def("x", py::overload_cast(&Class::X), "Set the x value.") + .def("y", py::overload_cast(&Class::Y), "Set the y value.") + .def_readonly_static("ZERO", &Class::Zero, "math::Vector2(0, 0)") + .def_readonly_static("ONE", &Class::One, "math::Vector2(1, 1)") + .def_readonly_static("NAN", &Class::NaN, "math::Vector3(NaN, NaN)") + .def("__copy__", [](const Class &self) { + return Class(self); + }) + .def("__deepcopy__", [](const Class &self, py::dict) { + return Class(self); + }, "memo"_a) + .def("__getitem__", + py::overload_cast(&Class::operator[], py::const_)) + .def("__setitem__", + [](Class* vec, unsigned index, T val) { (*vec)[index] = val; }) + .def("__str__", toString) + .def("__repr__", toString); +} + +void defineMathVector2(py::module &m, const std::string &typestr) +{ + helpDefineMathVector2(m, typestr + "d"); + helpDefineMathVector2(m, typestr + "f"); + helpDefineMathVector2(m, typestr + "i"); +} + +} // namespace python +} // namespace gazebo +} // namespace ignition diff --git a/src/python_pybind11/src/Vector2.hh b/src/python_pybind11/src/Vector2.hh index 98ce5a9a3..ef2258ac3 100644 --- a/src/python_pybind11/src/Vector2.hh +++ b/src/python_pybind11/src/Vector2.hh @@ -15,18 +15,14 @@ * */ -#ifndef IGNITION_MATH_PYTHON__VECTOR2D_HH_ -#define IGNITION_MATH_PYTHON__VECTOR2D_HH_ +#ifndef IGNITION_MATH_PYTHON__VECTOR2_HH_ +#define IGNITION_MATH_PYTHON__VECTOR2_HH_ #include #include -#include - -#include namespace py = pybind11; -using namespace pybind11::literals; namespace ignition { @@ -38,106 +34,9 @@ namespace python /** * \param[in] module a pybind11 module to add the definition to */ -template -void defineMathVector2(py::module &m, const std::string &typestr) -{ - using Class = ignition::math::Vector2; - auto toString = [](const Class &si) { - std::stringstream stream; - stream << si; - return stream.str(); - }; - std::string pyclass_name = typestr; - py::class_(m, - pyclass_name.c_str(), - py::buffer_protocol(), - py::dynamic_attr()) - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def("sum", &Class::Sum, "Return the sum of the values") - .def("distance", &Class::Distance, "Calc distance to the given point") - .def("length", - &Class::Length, - "Returns the length (magnitude) of the vector") - .def("squared_length", - &Class::SquaredLength, - "Return the square of the length (magnitude) of the vector") - .def("normalize", &Class::Normalize, "Normalize the vector length") - .def("normalized", &Class::Normalized, "Return a normalized vector") - .def("round", - &Class::Round, - "Round to near whole number, return the result.") - .def("rounded", &Class::Rounded, "Get a rounded version of this vector") - .def("set", &Class::Set, "Set the contents of the vector") - .def("dot", - &Class::Dot, - "Return the dot product of this vector and another vector") - .def("abs_dot", &Class::AbsDot, - "Return the absolute dot product of this vector and " - "another vector. This is similar to the Dot function, except the " - "absolute value of each component of the vector is used.") - .def("abs", - &Class::Abs, - "Get the absolute value of the vector") - .def("max", - py::overload_cast(&Class::Max), - "Set this vector's components to the maximum of itself and the " - "passed in vector") - .def("max", py::overload_cast<>(&Class::Max, py::const_), - "Get the maximum value in the vector") - .def("min", py::overload_cast(&Class::Min), - "Set this vector's components to the minimum of itself and the " - "passed in vector") - .def("min", py::overload_cast<>(&Class::Min, py::const_), - "Get the minimum value in the vector") - .def(py::self + py::self) - .def(py::self += py::self) - .def(py::self + T()) - .def(py::self += T()) - .def(py::self * py::self) - .def(py::self *= py::self) - .def(py::self * T()) - .def(py::self *= T()) - .def(py::self - py::self) - .def(py::self -= py::self) - .def(py::self - T()) - .def(py::self -= T()) - .def(py::self / py::self) - .def(py::self /= py::self) - .def(py::self / T()) - .def(py::self /= T()) - .def(py::self != py::self) - .def(py::self == py::self) - .def(-py::self) - .def("equal", &Class::Equal, "Equal to operator") - .def("is_finite", - &Class::IsFinite, - "See if a point is finite (e.g., not nan)") - .def("correct", &Class::Correct, "Corrects any nan values") - .def("x", py::overload_cast<>(&Class::X), "Get the x value.") - .def("y", py::overload_cast<>(&Class::Y), "Get the y value.") - .def("x", py::overload_cast(&Class::X), "Set the x value.") - .def("y", py::overload_cast(&Class::Y), "Set the y value.") - .def_readonly_static("ZERO", &Class::Zero, "math::Vector2(0, 0)") - .def_readonly_static("ONE", &Class::One, "math::Vector2(1, 1)") - .def_readonly_static("NAN", &Class::NaN, "math::Vector3(NaN, NaN)") - .def("__copy__", [](const Class &self) { - return Class(self); - }) - .def("__deepcopy__", [](const Class &self, py::dict) { - return Class(self); - }, "memo"_a) - .def("__getitem__", - py::overload_cast(&Class::operator[], py::const_)) - .def("__setitem__", - [](Class* vec, unsigned index, T val) { (*vec)[index] = val; }) - .def("__str__", toString) - .def("__repr__", toString); -} - +void defineMathVector2(py::module &m, const std::string &typestr); } // namespace python } // namespace gazebo } // namespace ignition -#endif // IGNITION_MATH_PYTHON__VECTOR2D_HH_ +#endif // IGNITION_MATH_PYTHON__VECTOR2_HH_ diff --git a/src/python_pybind11/src/_ignition_math_pybind11.cc b/src/python_pybind11/src/_ignition_math_pybind11.cc index 31d19dc96..c60742cbc 100644 --- a/src/python_pybind11/src/_ignition_math_pybind11.cc +++ b/src/python_pybind11/src/_ignition_math_pybind11.cc @@ -118,9 +118,7 @@ PYBIND11_MODULE(math, m) ignition::math::python::defineMathTemperature(m, "Temperature"); - ignition::math::python::defineMathVector2(m, "Vector2d"); - ignition::math::python::defineMathVector2(m, "Vector2i"); - ignition::math::python::defineMathVector2(m, "Vector2f"); + ignition::math::python::defineMathVector2(m, "Vector2"); ignition::math::python::defineMathVector3(m, "Vector3d"); ignition::math::python::defineMathVector3(m, "Vector3i"); From 213d924e9f81b25289329a253a7caabd6042a4e7 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Thu, 27 Jan 2022 11:53:12 -0800 Subject: [PATCH 3/3] Move template back to header file Signed-off-by: Steve Peters --- src/python_pybind11/src/Vector2.cc | 105 ---------------------------- src/python_pybind11/src/Vector2.hh | 106 +++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 105 deletions(-) diff --git a/src/python_pybind11/src/Vector2.cc b/src/python_pybind11/src/Vector2.cc index 910020d39..09de45755 100644 --- a/src/python_pybind11/src/Vector2.cc +++ b/src/python_pybind11/src/Vector2.cc @@ -17,119 +17,14 @@ #include -#include -#include -#include - #include "Vector2.hh" -using namespace pybind11::literals; - namespace ignition { namespace math { namespace python { -/// Template helper function -template -void helpDefineMathVector2(py::module &m, const std::string &typestr) -{ - using Class = ignition::math::Vector2; - auto toString = [](const Class &si) { - std::stringstream stream; - stream << si; - return stream.str(); - }; - std::string pyclass_name = typestr; - py::class_(m, - pyclass_name.c_str(), - py::buffer_protocol(), - py::dynamic_attr()) - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def("sum", &Class::Sum, "Return the sum of the values") - .def("distance", &Class::Distance, "Calc distance to the given point") - .def("length", - &Class::Length, - "Returns the length (magnitude) of the vector") - .def("squared_length", - &Class::SquaredLength, - "Return the square of the length (magnitude) of the vector") - .def("normalize", &Class::Normalize, "Normalize the vector length") - .def("normalized", &Class::Normalized, "Return a normalized vector") - .def("round", - &Class::Round, - "Round to near whole number, return the result.") - .def("rounded", &Class::Rounded, "Get a rounded version of this vector") - .def("set", &Class::Set, "Set the contents of the vector") - .def("dot", - &Class::Dot, - "Return the dot product of this vector and another vector") - .def("abs_dot", &Class::AbsDot, - "Return the absolute dot product of this vector and " - "another vector. This is similar to the Dot function, except the " - "absolute value of each component of the vector is used.") - .def("abs", - &Class::Abs, - "Get the absolute value of the vector") - .def("max", - py::overload_cast(&Class::Max), - "Set this vector's components to the maximum of itself and the " - "passed in vector") - .def("max", py::overload_cast<>(&Class::Max, py::const_), - "Get the maximum value in the vector") - .def("min", py::overload_cast(&Class::Min), - "Set this vector's components to the minimum of itself and the " - "passed in vector") - .def("min", py::overload_cast<>(&Class::Min, py::const_), - "Get the minimum value in the vector") - .def(py::self + py::self) - .def(py::self += py::self) - .def(py::self + T()) - .def(py::self += T()) - .def(py::self * py::self) - .def(py::self *= py::self) - .def(py::self * T()) - .def(py::self *= T()) - .def(py::self - py::self) - .def(py::self -= py::self) - .def(py::self - T()) - .def(py::self -= T()) - .def(py::self / py::self) - .def(py::self /= py::self) - .def(py::self / T()) - .def(py::self /= T()) - .def(py::self != py::self) - .def(py::self == py::self) - .def(-py::self) - .def("equal", &Class::Equal, "Equal to operator") - .def("is_finite", - &Class::IsFinite, - "See if a point is finite (e.g., not nan)") - .def("correct", &Class::Correct, "Corrects any nan values") - .def("x", py::overload_cast<>(&Class::X), "Get the x value.") - .def("y", py::overload_cast<>(&Class::Y), "Get the y value.") - .def("x", py::overload_cast(&Class::X), "Set the x value.") - .def("y", py::overload_cast(&Class::Y), "Set the y value.") - .def_readonly_static("ZERO", &Class::Zero, "math::Vector2(0, 0)") - .def_readonly_static("ONE", &Class::One, "math::Vector2(1, 1)") - .def_readonly_static("NAN", &Class::NaN, "math::Vector3(NaN, NaN)") - .def("__copy__", [](const Class &self) { - return Class(self); - }) - .def("__deepcopy__", [](const Class &self, py::dict) { - return Class(self); - }, "memo"_a) - .def("__getitem__", - py::overload_cast(&Class::operator[], py::const_)) - .def("__setitem__", - [](Class* vec, unsigned index, T val) { (*vec)[index] = val; }) - .def("__str__", toString) - .def("__repr__", toString); -} - void defineMathVector2(py::module &m, const std::string &typestr) { helpDefineMathVector2(m, typestr + "d"); diff --git a/src/python_pybind11/src/Vector2.hh b/src/python_pybind11/src/Vector2.hh index ef2258ac3..171980d88 100644 --- a/src/python_pybind11/src/Vector2.hh +++ b/src/python_pybind11/src/Vector2.hh @@ -21,8 +21,12 @@ #include #include +#include + +#include namespace py = pybind11; +using namespace pybind11::literals; namespace ignition { @@ -30,6 +34,108 @@ namespace math { namespace python { +/// Help define a pybind11 wrapper for an ignition::math::Vector2 +/** + * \param[in] module a pybind11 module to add the definition to + */ +template +void helpDefineMathVector2(py::module &m, const std::string &typestr) +{ + using Class = ignition::math::Vector2; + auto toString = [](const Class &si) { + std::stringstream stream; + stream << si; + return stream.str(); + }; + std::string pyclass_name = typestr; + py::class_(m, + pyclass_name.c_str(), + py::buffer_protocol(), + py::dynamic_attr()) + .def(py::init<>()) + .def(py::init()) + .def(py::init()) + .def("sum", &Class::Sum, "Return the sum of the values") + .def("distance", &Class::Distance, "Calc distance to the given point") + .def("length", + &Class::Length, + "Returns the length (magnitude) of the vector") + .def("squared_length", + &Class::SquaredLength, + "Return the square of the length (magnitude) of the vector") + .def("normalize", &Class::Normalize, "Normalize the vector length") + .def("normalized", &Class::Normalized, "Return a normalized vector") + .def("round", + &Class::Round, + "Round to near whole number, return the result.") + .def("rounded", &Class::Rounded, "Get a rounded version of this vector") + .def("set", &Class::Set, "Set the contents of the vector") + .def("dot", + &Class::Dot, + "Return the dot product of this vector and another vector") + .def("abs_dot", &Class::AbsDot, + "Return the absolute dot product of this vector and " + "another vector. This is similar to the Dot function, except the " + "absolute value of each component of the vector is used.") + .def("abs", + &Class::Abs, + "Get the absolute value of the vector") + .def("max", + py::overload_cast(&Class::Max), + "Set this vector's components to the maximum of itself and the " + "passed in vector") + .def("max", py::overload_cast<>(&Class::Max, py::const_), + "Get the maximum value in the vector") + .def("min", py::overload_cast(&Class::Min), + "Set this vector's components to the minimum of itself and the " + "passed in vector") + .def("min", py::overload_cast<>(&Class::Min, py::const_), + "Get the minimum value in the vector") + .def(py::self + py::self) + .def(py::self += py::self) + .def(py::self + T()) + .def(py::self += T()) + .def(py::self * py::self) + .def(py::self *= py::self) + .def(py::self * T()) + .def(py::self *= T()) + .def(py::self - py::self) + .def(py::self -= py::self) + .def(py::self - T()) + .def(py::self -= T()) + .def(py::self / py::self) + .def(py::self /= py::self) + .def(py::self / T()) + .def(py::self /= T()) + .def(py::self != py::self) + .def(py::self == py::self) + .def(-py::self) + .def("equal", &Class::Equal, "Equal to operator") + .def("is_finite", + &Class::IsFinite, + "See if a point is finite (e.g., not nan)") + .def("correct", &Class::Correct, "Corrects any nan values") + .def("x", py::overload_cast<>(&Class::X), "Get the x value.") + .def("y", py::overload_cast<>(&Class::Y), "Get the y value.") + .def("x", py::overload_cast(&Class::X), "Set the x value.") + .def("y", py::overload_cast(&Class::Y), "Set the y value.") + .def_readonly_static("ZERO", &Class::Zero, "math::Vector2(0, 0)") + .def_readonly_static("ONE", &Class::One, "math::Vector2(1, 1)") + .def_readonly_static("NAN", &Class::NaN, "math::Vector3(NaN, NaN)") + .def("__copy__", [](const Class &self) { + return Class(self); + }) + .def("__deepcopy__", [](const Class &self, py::dict) { + return Class(self); + }, "memo"_a) + .def("__getitem__", + py::overload_cast(&Class::operator[], py::const_)) + .def("__setitem__", + [](Class* vec, unsigned index, T val) { (*vec)[index] = val; }) + .def("__str__", toString) + .def("__repr__", toString); +} + /// Define a pybind11 wrapper for an ignition::math::Vector2 /** * \param[in] module a pybind11 module to add the definition to