From 3bd8ad3d81b9b3f6b16ec35b8c43712778d5f97c Mon Sep 17 00:00:00 2001 From: ahcorde Date: Fri, 17 Dec 2021 13:04:11 +0100 Subject: [PATCH] Add Line2 pybind11 interface Signed-off-by: ahcorde --- src/python/CMakeLists.txt | 1 - src/python_pybind11/CMakeLists.txt | 1 + src/python_pybind11/src/Line2.hh | 135 ++++++++++++++++++ .../src/_ignition_math_pybind11.cc | 8 +- .../test}/Line2_TEST.py | 0 5 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/python_pybind11/src/Line2.hh rename src/{python => python_pybind11/test}/Line2_TEST.py (100%) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 01284951e..940e5fd55 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -99,7 +99,6 @@ if (PYTHONLIBS_FOUND) Helpers_TEST Inertial_TEST Kmeans_TEST - Line2_TEST Line3_TEST MassMatrix3_TEST Material_TEST diff --git a/src/python_pybind11/CMakeLists.txt b/src/python_pybind11/CMakeLists.txt index 368492352..c4efa65c4 100644 --- a/src/python_pybind11/CMakeLists.txt +++ b/src/python_pybind11/CMakeLists.txt @@ -62,6 +62,7 @@ if (${pybind11_FOUND}) if (BUILD_TESTING) # Add the Python tests set(python_tests + Line2_TEST Vector2_TEST Vector3_TEST Vector4_TEST diff --git a/src/python_pybind11/src/Line2.hh b/src/python_pybind11/src/Line2.hh new file mode 100644 index 000000000..0bcb97b6b --- /dev/null +++ b/src/python_pybind11/src/Line2.hh @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2021 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. + * +*/ + +#ifndef IGNITION_MATH_PYTHON__LINE2_HH_ +#define IGNITION_MATH_PYTHON__LINE2_HH_ + +#include + +#include +#include + +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace ignition +{ +namespace math +{ +namespace python +{ +/// Define a pybind11 wrapper for an ignition::math::Line2 +/** + * \param[in] module a pybind11 module to add the definition to + * \param[in] typestr name of the type used by Python + */ +template +void defineMathLine2(py::module &m, const std::string &typestr) +{ + using Class = ignition::math::Line2; + 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&, + const ignition::math::Vector2&>()) + .def(py::init()) + .def(py::self != py::self) + .def(py::self == py::self) + .def("set", + py::overload_cast&, + const ignition::math::Vector2&>(&Class::Set), + "Set the start and end point of the line segment") + .def("set", + py::overload_cast(&Class::Set), + "Set the start and end point of the line segment") + .def("cross_product", + py::overload_cast(&Class::CrossProduct, py::const_), + "Return the cross product of this line and the given line.") + .def("cross_product", + py::overload_cast&>( + &Class::CrossProduct, py::const_), + "Return the cross product of this line and the given line.") + .def("collinear", + py::overload_cast&, double>( + &Class::Collinear, py::const_), + py::arg("_pt") = ignition::math::Vector2::Zero, + py::arg("_epsilon") = 1e-6, + "Check if the given point is collinear with this line.") + .def("collinear", + py::overload_cast(&Class::Collinear, py::const_), + py::arg("_pt") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if the given point is collinear with this line.") + .def("parallel", + &Class::Parallel, + py::arg("_line") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if the given line is parallel with this line.") + .def("on_segment", + &Class::OnSegment, + "Return whether the given point is on this line segment.") + .def("within", + &Class::Within, + "Check if the given point is between the start and end " + "points of the line segment. This does not imply that the point is " + "on the segment.") + .def("intersect", + py::overload_cast< + const Class&, + ignition::math::Vector2&, + double>( + &Class::Intersect, py::const_), + py::arg("_line") = Class(0, 0, 0, 0), + py::arg("_pt") = ignition::math::Vector2::Zero, + py::arg("_epsilon") = 1e-6, + "Check if this line intersects the given line segment.") + .def("intersect", + py::overload_cast(&Class::Intersect, py::const_), + py::arg("_line") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if this line intersects the given line segment.") + .def("length", + &Class::Length, + "Get the length of the line") + .def("slope", + &Class::Slope, + "Get the slope of the line") + .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); +} + +} // namespace python +} // namespace math +} // namespace ignition + +#endif // IGNITION_MATH_PYTHON__LINE2_HH_ diff --git a/src/python_pybind11/src/_ignition_math_pybind11.cc b/src/python_pybind11/src/_ignition_math_pybind11.cc index da0029102..bebee1f8b 100644 --- a/src/python_pybind11/src/_ignition_math_pybind11.cc +++ b/src/python_pybind11/src/_ignition_math_pybind11.cc @@ -14,6 +14,7 @@ #include +#include "Line2.hh" #include "Vector2.hh" #include "Vector3.hh" #include "Vector4.hh" @@ -24,9 +25,6 @@ PYBIND11_MODULE(math, m) { m.doc() = "Ignition Math Python Library."; - - - ignition::math::python::defineMathVector2(m, "Vector2d"); ignition::math::python::defineMathVector2(m, "Vector2i"); ignition::math::python::defineMathVector2(m, "Vector2f"); @@ -38,4 +36,8 @@ PYBIND11_MODULE(math, m) ignition::math::python::defineMathVector4(m, "Vector4d"); ignition::math::python::defineMathVector4(m, "Vector4i"); ignition::math::python::defineMathVector4(m, "Vector4f"); + + ignition::math::python::defineMathLine2(m, "Line2i"); + ignition::math::python::defineMathLine2(m, "Line2d"); + ignition::math::python::defineMathLine2(m, "Line2f"); } diff --git a/src/python/Line2_TEST.py b/src/python_pybind11/test/Line2_TEST.py similarity index 100% rename from src/python/Line2_TEST.py rename to src/python_pybind11/test/Line2_TEST.py