From 83284a3cdd9c0e70334f42ff0aa7464cb1a46d82 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Tue, 3 Sep 2019 17:38:15 +0800 Subject: [PATCH] Base: add Python number protocol support to Placement/Rotation --- src/Base/MatrixPyImp.cpp | 9 +- src/Base/PlacementPy.xml | 7 ++ src/Base/PlacementPyImp.cpp | 193 ++++++++++++++++++++++++++++++++++++ src/Base/RotationPy.xml | 1 + src/Base/RotationPyImp.cpp | 193 ++++++++++++++++++++++++++++++++++++ src/Base/VectorPyImp.cpp | 7 ++ 6 files changed, 408 insertions(+), 2 deletions(-) diff --git a/src/Base/MatrixPyImp.cpp b/src/Base/MatrixPyImp.cpp index de1247d91010..4391128f41e3 100644 --- a/src/Base/MatrixPyImp.cpp +++ b/src/Base/MatrixPyImp.cpp @@ -94,7 +94,7 @@ int MatrixPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyObject* MatrixPy::number_add_handler(PyObject *self, PyObject *other) { if (!PyObject_TypeCheck(self, &(MatrixPy::Type))) { - PyErr_SetString(PyExc_TypeError, "First arg must be Matrix"); + PyErr_SetString(PyExc_NotImplementedError, ""); return 0; } if (!PyObject_TypeCheck(other, &(MatrixPy::Type))) { @@ -109,7 +109,7 @@ PyObject* MatrixPy::number_add_handler(PyObject *self, PyObject *other) PyObject* MatrixPy::number_subtract_handler(PyObject *self, PyObject *other) { if (!PyObject_TypeCheck(self, &(MatrixPy::Type))) { - PyErr_SetString(PyExc_TypeError, "First arg must be Matrix"); + PyErr_SetString(PyExc_NotImplementedError, ""); return 0; } if (!PyObject_TypeCheck(other, &(MatrixPy::Type))) { @@ -138,6 +138,11 @@ PyObject* MatrixPy::number_multiply_handler(PyObject *self, PyObject *other) return new MatrixPy(a*b); } + if (PyObject_TypeCheck(other, &(PlacementPy::Type))) { + auto b = static_cast(other)->value(); + return new MatrixPy(a*b.toMatrix()); + } + if (PyObject_TypeCheck(other, &(MatrixPy::Type))) { Base::Matrix4D b = static_cast(other)->value(); return new MatrixPy(a*b); diff --git a/src/Base/PlacementPy.xml b/src/Base/PlacementPy.xml index 0df8551191bd..97ce441e8dfc 100644 --- a/src/Base/PlacementPy.xml +++ b/src/Base/PlacementPy.xml @@ -10,6 +10,7 @@ Namespace="Base" Constructor="true" Delete="true" + NumberProtocol="true" RichCompare="true" FatherNamespace="Base"> @@ -118,5 +119,11 @@ Placement(Base, Axis, Angle) -- define position and rotation + public: + PlacementPy(const Placement & pla, PyTypeObject *T = &Type) + :PyObjectBase(new Placement(pla),T){} + Placement value() const + { return *(getPlacementPtr()); } + diff --git a/src/Base/PlacementPyImp.cpp b/src/Base/PlacementPyImp.cpp index 03f858221bd8..cbdd2a134d2c 100644 --- a/src/Base/PlacementPyImp.cpp +++ b/src/Base/PlacementPyImp.cpp @@ -308,3 +308,196 @@ int PlacementPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { return 0; } + +PyObject* PlacementPy::number_multiply_handler(PyObject *self, PyObject *other) +{ + if (PyObject_TypeCheck(self, &(PlacementPy::Type))) { + Base::Placement a = static_cast(self)->value(); + + if (PyObject_TypeCheck(other, &(VectorPy::Type))) { + Vector3d res; + a.multVec(static_cast(other)->value(),res); + return new VectorPy(res); + } + + if (PyObject_TypeCheck(other, &(RotationPy::Type))) { + Placement b(Vector3d(),static_cast(other)->value()); + return new PlacementPy(a*b); + } + + if (PyObject_TypeCheck(other, &(PlacementPy::Type))) { + const auto &b = static_cast(other)->value(); + return new PlacementPy(a*b); + } + + if (PyObject_TypeCheck(other, &(MatrixPy::Type))) { + const auto &b = static_cast(other)->value(); + return new MatrixPy(a.toMatrix()*b); + } + } + + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_power_handler (PyObject* self, PyObject* other, PyObject* arg) +{ + if (!PyObject_TypeCheck(self, &(PlacementPy::Type)) || + +#if PY_MAJOR_VERSION < 3 + !PyInt_Check(other) +#else + !PyLong_Check(other) +#endif + || arg != Py_None + ) + { + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; + } + + auto a = static_cast(self)->value(); + + long b = Py::Int(other); + if(!b) + return new PlacementPy(Placement()); + + if(b < 0) { + b = 1+b; + a.invert(); + } + auto res = a; + for(;b;--b) + res *= a; + return new PlacementPy(res); +} + +PyObject* PlacementPy::number_add_handler(PyObject * /*self*/, PyObject * /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject* PlacementPy::number_subtract_handler(PyObject * /*self*/, PyObject * /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_divide_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_remainder_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_negative_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_positive_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_absolute_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +int PlacementPy::number_nonzero_handler (PyObject* /*self*/) +{ + return 1; +} + +PyObject * PlacementPy::number_invert_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_lshift_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_rshift_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_and_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_xor_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_or_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +int PlacementPy::number_coerce_handler (PyObject ** /*self*/, PyObject ** /*other*/) +{ + return 1; +} +#endif + +PyObject * PlacementPy::number_int_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +PyObject * PlacementPy::number_long_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} +#endif + +PyObject * PlacementPy::number_float_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +PyObject * PlacementPy::number_oct_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * PlacementPy::number_hex_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} +#endif diff --git a/src/Base/RotationPy.xml b/src/Base/RotationPy.xml index a33cde5035c9..16b492004ecf 100644 --- a/src/Base/RotationPy.xml +++ b/src/Base/RotationPy.xml @@ -10,6 +10,7 @@ Namespace="Base" Constructor="true" Delete="true" + NumberProtocol="true" RichCompare="true" FatherNamespace="Base"> diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index 8611010ddd36..d3c17ed21cbc 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -384,4 +384,197 @@ int RotationPy::setCustomAttributes(const char* attr, PyObject* obj) return 0; } +PyObject* RotationPy::number_multiply_handler(PyObject *self, PyObject *other) +{ + if (PyObject_TypeCheck(self, &(RotationPy::Type))) { + auto a = static_cast(self)->value(); + + if (PyObject_TypeCheck(other, &(VectorPy::Type))) { + Vector3d res; + a.multVec(static_cast(other)->value(),res); + return new VectorPy(res); + } + + if (PyObject_TypeCheck(other, &(PlacementPy::Type))) { + const auto &b = static_cast(other)->value(); + return new PlacementPy(Placement(Vector3d(),a)*b); + } + + if (PyObject_TypeCheck(other, &(RotationPy::Type))) { + const auto &b = static_cast(other)->value(); + return new RotationPy(a*b); + } + + if (PyObject_TypeCheck(other, &(MatrixPy::Type))) { + const auto &b = static_cast(other)->value(); + Matrix4D mat; + a.getValue(mat); + return new MatrixPy(mat*b); + } + } + + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_power_handler (PyObject* self, PyObject* other, PyObject* arg) +{ + if (!PyObject_TypeCheck(self, &(RotationPy::Type)) || + +#if PY_MAJOR_VERSION < 3 + !PyInt_Check(other) +#else + !PyLong_Check(other) +#endif + || arg != Py_None + ) + { + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; + } + + Rotation a = static_cast(self)->value(); + + long b = Py::Int(other); + if(!b) + return new RotationPy(Rotation()); + + if(b < 0) { + b = 1+b; + a.invert(); + } + auto res = a; + for(;b;--b) + res *= a; + return new RotationPy(res); +} + +PyObject* RotationPy::number_add_handler(PyObject * /*self*/, PyObject * /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject* RotationPy::number_subtract_handler(PyObject * /*self*/, PyObject * /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_divide_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_remainder_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_negative_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_positive_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_absolute_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +int RotationPy::number_nonzero_handler (PyObject* /*self*/) +{ + return 1; +} + +PyObject * RotationPy::number_invert_handler (PyObject* /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_lshift_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_rshift_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_and_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_xor_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} +PyObject * RotationPy::number_or_handler (PyObject* /*self*/, PyObject* /*other*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +int RotationPy::number_coerce_handler (PyObject ** /*self*/, PyObject ** /*other*/) +{ + return 1; +} +#endif + +PyObject * RotationPy::number_int_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +PyObject * RotationPy::number_long_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} +#endif + +PyObject * RotationPy::number_float_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +#if PY_MAJOR_VERSION < 3 +PyObject * RotationPy::number_oct_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} + +PyObject * RotationPy::number_hex_handler (PyObject * /*self*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not implemented"); + return 0; +} +#endif diff --git a/src/Base/VectorPyImp.cpp b/src/Base/VectorPyImp.cpp index 19b0684be610..a0271bd82d10 100644 --- a/src/Base/VectorPyImp.cpp +++ b/src/Base/VectorPyImp.cpp @@ -151,6 +151,13 @@ PyObject* VectorPy::number_multiply_handler(PyObject *self, PyObject *other) return new MatrixPy(b); } + if (PyObject_TypeCheck(other, &PlacementPy::Type)) { + Base::Placement b = static_cast(other)->value(); + Vector3d res; + b.multVec(a,res); + return new VectorPy(res); + } + if (PyObject_TypeCheck(other, &RotationPy::Type)) { Base::Rotation b = static_cast(other)->value(); return new VectorPy(b.multVec(a));