From 6a6607392832a8bc8083fb2c21637e5a528ee4dc Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 18 May 2016 11:26:27 +0200 Subject: [PATCH 1/3] + implement rich compare protocol of Python interface for Placement & Rotation --- src/Base/PlacementPy.xml | 7 +++-- src/Base/PlacementPyImp.cpp | 31 +++++++++++++++++++++ src/Base/RotationPy.xml | 5 ++-- src/Base/RotationPyImp.cpp | 55 +++++++++++++++++++++++++++++-------- 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/Base/PlacementPy.xml b/src/Base/PlacementPy.xml index cfdc208c1..9916fc482 100644 --- a/src/Base/PlacementPy.xml +++ b/src/Base/PlacementPy.xml @@ -9,7 +9,8 @@ FatherInclude="Base/PyObjectBase.h" Namespace="Base" Constructor="true" - Delete="true" + Delete="true" + RichCompare="true" FatherNamespace="Base"> @@ -75,7 +76,7 @@ Placement(Base, Axis, Angle) -- define position and rotation - + isNull() -> Bool @@ -83,7 +84,7 @@ Placement(Base, Axis, Angle) -- define position and rotation - + Vector to the Base Position of the Placement diff --git a/src/Base/PlacementPyImp.cpp b/src/Base/PlacementPyImp.cpp index cd959cc54..3f1096513 100644 --- a/src/Base/PlacementPyImp.cpp +++ b/src/Base/PlacementPyImp.cpp @@ -118,6 +118,37 @@ int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/) return -1; } +PyObject* PlacementPy::richCompare(PyObject *v, PyObject *w, int op) +{ + if (PyObject_TypeCheck(v, &(PlacementPy::Type)) && + PyObject_TypeCheck(w, &(PlacementPy::Type))) { + Base::Placement p1 = *static_cast(v)->getPlacementPtr(); + Base::Placement p2 = *static_cast(w)->getPlacementPtr(); + + PyObject *res=0; + if (op != Py_EQ && op != Py_NE) { + PyErr_SetString(PyExc_TypeError, + "no ordering relation is defined for Placement"); + return 0; + } + else if (op == Py_EQ) { + res = (p1 == p2) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + else { + res = (p1 != p2) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + } + else { + // This always returns False + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + PyObject* PlacementPy::move(PyObject * args) { PyObject *vec; diff --git a/src/Base/RotationPy.xml b/src/Base/RotationPy.xml index e510c39b9..f7ab91cea 100644 --- a/src/Base/RotationPy.xml +++ b/src/Base/RotationPy.xml @@ -10,6 +10,7 @@ Namespace="Base" Constructor="true" Delete="true" + RichCompare="true" FatherNamespace="Base"> @@ -59,7 +60,7 @@ - + isNull() -> Bool @@ -67,7 +68,7 @@ - + The rotation elements (as quaternion) diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index d5d9687f9..7f9a1fe1c 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -77,14 +77,14 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); double angle; if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &o, &angle)) { - // NOTE: The last parameter defines the rotation angle in degree. + // NOTE: The last parameter defines the rotation angle in degree. getRotationPtr()->setValue(static_cast(o)->value(), Base::toRadians(angle)); return 0; } PyErr_Clear(); if (PyArg_ParseTuple(args, "O!d", &(Base::MatrixPy::Type), &o, &angle)) { - // NOTE: The last parameter defines the rotation angle in degree. + // NOTE: The last parameter defines the rotation angle in degree. getRotationPtr()->setValue(static_cast(o)->value()); return 0; } @@ -164,6 +164,37 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) return -1; } +PyObject* RotationPy::richCompare(PyObject *v, PyObject *w, int op) +{ + if (PyObject_TypeCheck(v, &(RotationPy::Type)) && + PyObject_TypeCheck(w, &(RotationPy::Type))) { + Base::Rotation r1 = *static_cast(v)->getRotationPtr(); + Base::Rotation r2 = *static_cast(w)->getRotationPtr(); + + PyObject *res=0; + if (op != Py_EQ && op != Py_NE) { + PyErr_SetString(PyExc_TypeError, + "no ordering relation is defined for Rotation"); + return 0; + } + else if (op == Py_EQ) { + res = (r1 == r2) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + else { + res = (r1 != r2) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + } + else { + // This always returns False + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + PyObject* RotationPy::invert(PyObject * args) { if (!PyArg_ParseTuple(args, "")) @@ -205,16 +236,16 @@ PyObject* RotationPy::toEuler(PyObject * args) return Py::new_reference_to(tuple); } -PyObject* RotationPy::isNull(PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - Base::Rotation rot = * getRotationPtr(); - Base::Rotation nullrot(0,0,0,1); - Base::Rotation nullrotinv(0,0,0,-1); - bool null = (rot == nullrot) | (rot == nullrotinv); - return Py_BuildValue("O", (null ? Py_True : Py_False)); -} +PyObject* RotationPy::isNull(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + Base::Rotation rot = * getRotationPtr(); + Base::Rotation nullrot(0,0,0,1); + Base::Rotation nullrotinv(0,0,0,-1); + bool null = (rot == nullrot) | (rot == nullrotinv); + return Py_BuildValue("O", (null ? Py_True : Py_False)); +} Py::Tuple RotationPy::getQ(void) const { From 205cf94594a122024103b12f01578c59721c831e Mon Sep 17 00:00:00 2001 From: Kurt Kremitzki Date: Tue, 17 May 2016 19:38:38 -0500 Subject: [PATCH 2/3] Fix "construcion" typo --- src/Mod/Draft/DraftTools.py | 2 +- src/Mod/Sketcher/App/Sketch.cpp | 4 ++-- src/Mod/Sketcher/App/Sketch.h | 2 +- src/Mod/Sketcher/App/SketchObjectPy.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 11ff3c6cd..3783afa4e 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -3208,7 +3208,7 @@ class ToggleConstructionMode(): def GetResources(self): return {'Pixmap' : 'Draft_Construction', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggle construcion Mode"), + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggle Construction Mode"), 'Accel' : "C, M", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggles the Construction Mode for next objects.")} diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index 5df50da57..09533ac6c 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -562,13 +562,13 @@ int Sketch::addEllipse(const Part::GeomEllipse &elip, bool fixed) return Geoms.size()-1; } -std::vector Sketch::extractGeometry(bool withConstrucionElements, +std::vector Sketch::extractGeometry(bool withConstructionElements, bool withExternalElements) const { std::vector temp; temp.reserve(Geoms.size()); for (std::vector::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it) - if ((!it->external || withExternalElements) && (!it->geo->Construction || withConstrucionElements)) + if ((!it->external || withExternalElements) && (!it->geo->Construction || withConstructionElements)) temp.push_back(it->geo->clone()); return temp; diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h index ad40385ae..e1248e09a 100644 --- a/src/Mod/Sketcher/App/Sketch.h +++ b/src/Mod/Sketcher/App/Sketch.h @@ -77,7 +77,7 @@ public: /// add unspecified geometry int addGeometry(const std::vector &geo, bool fixed=false); /// returns the actual geometry - std::vector extractGeometry(bool withConstrucionElements=true, + std::vector extractGeometry(bool withConstructionElements=true, bool withExternalElements=false) const; /// get the geometry as python objects Py::Tuple getPyGeometry(void) const; diff --git a/src/Mod/Sketcher/App/SketchObjectPy.xml b/src/Mod/Sketcher/App/SketchObjectPy.xml index ac5939936..b8eb29b8d 100644 --- a/src/Mod/Sketcher/App/SketchObjectPy.xml +++ b/src/Mod/Sketcher/App/SketchObjectPy.xml @@ -30,7 +30,7 @@ - switch a geometry to a construcion line + switch a geometry to a construction line From 885050d33e60b40ac9cf463129f8ab9b0097b0f4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 18 May 2016 18:08:40 +0200 Subject: [PATCH 3/3] + fix == operator of Rotation class, + add method isSame() --- src/Base/Rotation.cpp | 20 ++++++++++++++++---- src/Base/Rotation.h | 1 + src/Base/RotationPy.xml | 22 +++++++++++++++++++--- src/Base/RotationPyImp.cpp | 22 ++++++++++++++++++++-- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Base/Rotation.cpp b/src/Base/Rotation.cpp index bbefa4b6e..db71026ea 100644 --- a/src/Base/Rotation.cpp +++ b/src/Base/Rotation.cpp @@ -294,10 +294,12 @@ Rotation Rotation::operator*(const Rotation & q) const bool Rotation::operator==(const Rotation & q) const { - bool equal = true; - for (int i=0; i<4;i++) - equal &= (fabs(this->quat[i] - q.quat[i]) < 0.005 ); - return equal; + if (this->quat[0] == q.quat[0] && + this->quat[1] == q.quat[1] && + this->quat[2] == q.quat[2] && + this->quat[3] == q.quat[3]) + return true; + return false; } bool Rotation::operator!=(const Rotation & q) const @@ -305,6 +307,16 @@ bool Rotation::operator!=(const Rotation & q) const return !(*this == q); } +bool Rotation::isSame(const Rotation& q) const +{ + if ((this->quat[0] == q.quat[0] || this->quat[0] == -q.quat[0]) && + (this->quat[1] == q.quat[1] || this->quat[1] == -q.quat[1]) && + (this->quat[2] == q.quat[2] || this->quat[2] == -q.quat[2]) && + (this->quat[3] == q.quat[3] || this->quat[3] == -q.quat[3])) + return true; + return false; +} + void Rotation::multVec(const Vector3d & src, Vector3d & dst) const { double x = this->quat[0]; diff --git a/src/Base/Rotation.h b/src/Base/Rotation.h index a0ecf21dc..7ded2c723 100644 --- a/src/Base/Rotation.h +++ b/src/Base/Rotation.h @@ -79,6 +79,7 @@ public: void multVec(const Vector3d & src, Vector3d & dst) const; void scaleAngle(const double scaleFactor); + bool isSame(const Rotation&) const; //@} static Rotation slerp(const Rotation & rot0, const Rotation & rot1, double t); diff --git a/src/Base/RotationPy.xml b/src/Base/RotationPy.xml index f7ab91cea..42a64d142 100644 --- a/src/Base/RotationPy.xml +++ b/src/Base/RotationPy.xml @@ -30,12 +30,28 @@ - move(Vector) - Move the matrix along the vector + invert() -> None + Sets the rotation to its inverse - + + + + inverted() -> Rotation + Returns the inverse of the rotation + + + + + + + isSame(Rotation) + Checks if the two quaternions perform the same rotation + + + + multiply(Rotation) diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index 7f9a1fe1c..65cd3849a 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -203,6 +203,14 @@ PyObject* RotationPy::invert(PyObject * args) Py_Return; } +PyObject* RotationPy::inverted(PyObject * args) +{ + if (!PyArg_ParseTuple(args, "")) + return 0; + Rotation mult = this->getRotationPtr()->inverse(); + return new RotationPy(new Rotation(mult)); +} + PyObject* RotationPy::multiply(PyObject * args) { PyObject *rot; @@ -236,14 +244,24 @@ PyObject* RotationPy::toEuler(PyObject * args) return Py::new_reference_to(tuple); } +PyObject* RotationPy::isSame(PyObject *args) +{ + PyObject *rot; + if (!PyArg_ParseTuple(args, "O!", &(RotationPy::Type), &rot)) + return NULL; + Base::Rotation rot1 = * getRotationPtr(); + Base::Rotation rot2 = * static_cast(rot)->getRotationPtr(); + bool same = rot1.isSame(rot2); + return Py_BuildValue("O", (same ? Py_True : Py_False)); +} + PyObject* RotationPy::isNull(PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; Base::Rotation rot = * getRotationPtr(); Base::Rotation nullrot(0,0,0,1); - Base::Rotation nullrotinv(0,0,0,-1); - bool null = (rot == nullrot) | (rot == nullrotinv); + bool null = rot.isSame(nullrot); return Py_BuildValue("O", (null ? Py_True : Py_False)); }