From 19d55fa22703be16e05e70b2d89eaecaf2074791 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 20 Jun 2017 21:22:59 +0200 Subject: [PATCH] fix issues in CoordinateSystem class and expose to Python --- src/App/Application.cpp | 14 ++- src/Base/CMakeLists.txt | 3 + src/Base/CoordinateSystem.cpp | 44 ++++++- src/Base/CoordinateSystemPy.xml | 83 +++++++++++++ src/Base/CoordinateSystemPyImp.cpp | 185 +++++++++++++++++++++++++++++ 5 files changed, 321 insertions(+), 8 deletions(-) create mode 100644 src/Base/CoordinateSystemPy.xml create mode 100644 src/Base/CoordinateSystemPyImp.cpp diff --git a/src/App/Application.cpp b/src/App/Application.cpp index b97333e1de..23925fe2a7 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -277,12 +278,13 @@ Application::Application(std::map &mConfig) PyModule_AddObject(pBaseModule, "FreeCADError", Base::BaseExceptionFreeCADError); // Python types - Base::Interpreter().addType(&Base::VectorPy ::Type,pBaseModule,"Vector"); - Base::Interpreter().addType(&Base::MatrixPy ::Type,pBaseModule,"Matrix"); - Base::Interpreter().addType(&Base::BoundBoxPy ::Type,pBaseModule,"BoundBox"); - Base::Interpreter().addType(&Base::PlacementPy ::Type,pBaseModule,"Placement"); - Base::Interpreter().addType(&Base::RotationPy ::Type,pBaseModule,"Rotation"); - Base::Interpreter().addType(&Base::AxisPy ::Type,pBaseModule,"Axis"); + Base::Interpreter().addType(&Base::VectorPy ::Type,pBaseModule,"Vector"); + Base::Interpreter().addType(&Base::MatrixPy ::Type,pBaseModule,"Matrix"); + Base::Interpreter().addType(&Base::BoundBoxPy ::Type,pBaseModule,"BoundBox"); + Base::Interpreter().addType(&Base::PlacementPy ::Type,pBaseModule,"Placement"); + Base::Interpreter().addType(&Base::RotationPy ::Type,pBaseModule,"Rotation"); + Base::Interpreter().addType(&Base::AxisPy ::Type,pBaseModule,"Axis"); + Base::Interpreter().addType(&Base::CoordinateSystemPy::Type,pBaseModule,"CoordinateSystem"); Base::Interpreter().addType(&App::MaterialPy::Type, pAppModule, "Material"); diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index 3761c1a197..61befd5e6d 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -76,6 +76,7 @@ endif() generate_from_xml(BaseClassPy) generate_from_xml(BoundBoxPy) +generate_from_xml(CoordinateSystemPy) generate_from_xml(PersistencePy) generate_from_xml(VectorPy) generate_from_xml(MatrixPy) @@ -152,6 +153,7 @@ SET(FreeCADBase_XML_SRCS AxisPy.xml BaseClassPy.xml BoundBoxPy.xml + CoordinateSystemPy.xml MatrixPy.xml PersistencePy.xml PlacementPy.xml @@ -220,6 +222,7 @@ SET(FreeCADBase_CPP_SRCS Builder3D.cpp Console.cpp CoordinateSystem.cpp + CoordinateSystemPyImp.cpp Debugger.cpp Exception.cpp ExceptionFactory.cpp diff --git a/src/Base/CoordinateSystem.cpp b/src/Base/CoordinateSystem.cpp index ee944fb7cc..cab175f24b 100644 --- a/src/Base/CoordinateSystem.cpp +++ b/src/Base/CoordinateSystem.cpp @@ -48,8 +48,13 @@ void CoordinateSystem::setAxes(const Axis& v, const Vector3d& xd) if (yd.Sqr() < Base::Vector3d::epsilon()) throw Base::ValueError("Direction is parallel to Z direction"); ydir = yd; + ydir.Normalize(); xdir = ydir % v.getDirection(); - axis = v; + xdir.Normalize(); + axis.setBase(v.getBase()); + Base::Vector3d zdir = v.getDirection(); + zdir.Normalize(); + axis.setDirection(zdir); } void CoordinateSystem::setAxes(const Vector3d& n, const Vector3d& xd) @@ -60,8 +65,12 @@ void CoordinateSystem::setAxes(const Vector3d& n, const Vector3d& xd) if (yd.Sqr() < Base::Vector3d::epsilon()) throw Base::ValueError("Direction is parallel to Z direction"); ydir = yd; + ydir.Normalize(); xdir = ydir % n; - axis.setDirection(n); + xdir.Normalize(); + Base::Vector3d zdir = n; + zdir.Normalize(); + axis.setDirection(zdir); } void CoordinateSystem::setAxis(const Axis& v) @@ -75,7 +84,9 @@ void CoordinateSystem::setXDirection(const Vector3d& dir) if (yd.Sqr() < Base::Vector3d::epsilon()) throw Base::ValueError("Direction is parallel to Z direction"); ydir = yd; + ydir.Normalize(); xdir = ydir % axis.getDirection(); + xdir.Normalize(); } void CoordinateSystem::setYDirection(const Vector3d& dir) @@ -84,7 +95,9 @@ void CoordinateSystem::setYDirection(const Vector3d& dir) if (xd.Sqr() < Base::Vector3d::epsilon()) throw Base::ValueError("Direction is parallel to Z direction"); xdir = xd; + xdir.Normalize(); ydir = axis.getDirection() % xdir; + ydir.Normalize(); } void CoordinateSystem::setZDirection(const Vector3d& dir) @@ -94,6 +107,7 @@ void CoordinateSystem::setZDirection(const Vector3d& dir) Placement CoordinateSystem::displacement(const CoordinateSystem& cs) const { +#if 0 // align the Z axes Base::Rotation rotZ(getZDirection(), cs.getZDirection()); @@ -112,6 +126,32 @@ Placement CoordinateSystem::displacement(const CoordinateSystem& cs) const rot = rotX * rotZ; return Placement(mov, rot); +#else + const Base::Vector3d& a = axis.getBase(); + const Base::Vector3d& zdir = axis.getDirection(); + Base::Matrix4D At; + At[0][0] = xdir.x; At[1][0] = ydir.x; At[2][0] = zdir.x; + At[0][1] = xdir.y; At[1][1] = ydir.y; At[2][1] = zdir.y; + At[0][2] = xdir.z; At[1][2] = ydir.z; At[2][2] = zdir.z; + Base::Vector3d at = At * a; + At[0][3] = -at.x; At[1][3] = -at.y; At[2][3] = -at.z; + + const Base::Vector3d& b = cs.axis.getBase(); + const Base::Vector3d& cszdir = cs.axis.getDirection(); + Base::Matrix4D B; + B[0][0] = cs.xdir.x; B[0][1] = cs.ydir.x; B[0][2] = cszdir.x; B[0][3] = b.x; + B[1][0] = cs.xdir.y; B[1][1] = cs.ydir.y; B[1][2] = cszdir.y; B[1][3] = b.y; + B[2][0] = cs.xdir.z; B[2][1] = cs.ydir.z; B[2][2] = cszdir.z; B[2][3] = b.z; + + //Base::Matrix4D C; + //C = B * At; + //Placement p(C); + //return p; + Placement PAt(At); + Placement PB(B); + Placement C = PB * PAt; + return C; +#endif } void CoordinateSystem::transformTo(Vector3d& p) diff --git a/src/Base/CoordinateSystemPy.xml b/src/Base/CoordinateSystemPy.xml new file mode 100644 index 0000000000..dc87ef5022 --- /dev/null +++ b/src/Base/CoordinateSystemPy.xml @@ -0,0 +1,83 @@ + + + + + + This is the CoordinateSystem export class + + + + + setAxes(Axis or Vector z, Vector x) +Set axis or z direction and x direction + + + + + displacement(CoordinateSystem) +Computes the placement from this to the passed coordinate system + + + + + transformTo(Vector) +Computes the coordinates of the point in coordinates of this system + + + + + + transform(Rotation or Placement) +Applies the rotation or placement on this coordinate system + + + + + + setPlacment(Placement) +Set placement to the coordinate system. + + + + + + Set or get axis + + + + + + Set or get x direction + + + + + + Set or get y direction + + + + + + Set or get z direction + + + + + + Set or get position + + + + + diff --git a/src/Base/CoordinateSystemPyImp.cpp b/src/Base/CoordinateSystemPyImp.cpp new file mode 100644 index 0000000000..18255183ee --- /dev/null +++ b/src/Base/CoordinateSystemPyImp.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright (c) 2017 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 51 Franklin Street, * + * Fifth Floor, Boston, MA 02110-1301, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#include "CoordinateSystem.h" +#include "GeometryPyCXX.h" +#include +#include +#include +#include +#include + +using namespace Base; + +// returns a string which represents the object e.g. when printed in python +std::string CoordinateSystemPy::representation(void) const +{ + return std::string(""); +} + +PyObject *CoordinateSystemPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of CoordinateSystemPy and the Twin object + return new CoordinateSystemPy(new CoordinateSystem); +} + +// constructor method +int CoordinateSystemPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/) +{ + return 0; +} + +PyObject* CoordinateSystemPy::setAxes(PyObject * args) +{ + PyObject *axis, *xdir; + if (PyArg_ParseTuple(args, "O!O!", &(AxisPy::Type), &axis, &(VectorPy::Type), &xdir)) { + getCoordinateSystemPtr()->setAxes(*static_cast(axis)->getAxisPtr(), + *static_cast(xdir)->getVectorPtr()); + Py_Return; + } + + PyErr_Clear(); + if (PyArg_ParseTuple(args, "O!O!", &(VectorPy::Type), &axis, &(VectorPy::Type), &xdir)) { + getCoordinateSystemPtr()->setAxes(*static_cast(axis)->getVectorPtr(), + *static_cast(xdir)->getVectorPtr()); + Py_Return; + } + + PyErr_SetString(PyExc_TypeError, "Axis and Vector or Vector and Vector expected"); + return 0; +} + +PyObject* CoordinateSystemPy::displacement(PyObject * args) +{ + PyObject *cs; + if (!PyArg_ParseTuple(args, "O!", &(CoordinateSystemPy::Type), &cs)) + return 0; + Placement p = getCoordinateSystemPtr()->displacement( + *static_cast(cs)->getCoordinateSystemPtr()); + return new PlacementPy(new Placement(p)); +} + +PyObject* CoordinateSystemPy::transformTo(PyObject * args) +{ + PyObject *vec; + if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) + return 0; + Vector3d v = static_cast(vec)->value(); + getCoordinateSystemPtr()->transformTo(v); + return new VectorPy(new Vector3d(v)); +} + +PyObject* CoordinateSystemPy::transform(PyObject * args) +{ + PyObject *plm; + if (PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) { + getCoordinateSystemPtr()->transform(*static_cast(plm)->getPlacementPtr()); + Py_Return; + } + + PyErr_Clear(); + if (PyArg_ParseTuple(args, "O!", &(RotationPy::Type), &plm)) { + getCoordinateSystemPtr()->transform(*static_cast(plm)->getRotationPtr()); + Py_Return; + } + + PyErr_SetString(PyExc_TypeError, "Rotation or placement expected"); + return 0; +} + +PyObject* CoordinateSystemPy::setPlacement(PyObject * args) +{ + PyObject *plm; + if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) + return NULL; + getCoordinateSystemPtr()->setPlacement(*static_cast(plm)->getPlacementPtr()); + Py_Return; +} + +Py::Object CoordinateSystemPy::getAxis(void) const +{ + const Axis& axis = getCoordinateSystemPtr()->getAxis(); + return Py::asObject(new AxisPy(new Axis(axis))); +} + +void CoordinateSystemPy::setAxis(Py::Object arg) +{ + if (PyObject_TypeCheck(arg.ptr(), &(Base::AxisPy::Type))) { + AxisPy *axis = static_cast(arg.ptr()); + getCoordinateSystemPtr()->setAxis(*axis->getAxisPtr()); + return; + } + + throw Py::TypeError("not an Axis"); +} + +Py::Object CoordinateSystemPy::getXDirection(void) const +{ + return Py::Vector(getCoordinateSystemPtr()->getXDirection()); +} + +void CoordinateSystemPy::setXDirection(Py::Object arg) +{ + getCoordinateSystemPtr()->setXDirection(Py::Vector(arg).toVector()); +} + +Py::Object CoordinateSystemPy::getYDirection(void) const +{ + return Py::Vector(getCoordinateSystemPtr()->getYDirection()); +} + +void CoordinateSystemPy::setYDirection(Py::Object arg) +{ + getCoordinateSystemPtr()->setYDirection(Py::Vector(arg).toVector()); +} + +Py::Object CoordinateSystemPy::getZDirection(void) const +{ + return Py::Vector(getCoordinateSystemPtr()->getZDirection()); +} + +void CoordinateSystemPy::setZDirection(Py::Object arg) +{ + getCoordinateSystemPtr()->setZDirection(Py::Vector(arg).toVector()); +} + +Py::Object CoordinateSystemPy::getPosition(void) const +{ + return Py::Vector(getCoordinateSystemPtr()->getPosition()); +} + +void CoordinateSystemPy::setPosition(Py::Object arg) +{ + getCoordinateSystemPtr()->setPosition(Py::Vector(arg).toVector()); +} + +PyObject *CoordinateSystemPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int CoordinateSystemPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +}