diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 392f24d414..275ff5e3e7 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -96,6 +96,18 @@ public: inline double* operator [] (unsigned short usNdx); /// Index operator inline const double* operator[] (unsigned short usNdx) const; + /// Get vector of row + inline Vector3d getRow(unsigned short usNdx) const; + /// Get vector of column + inline Vector3d getCol(unsigned short usNdx) const; + /// Get vector of trace + inline Vector3d trace() const; + /// Set row to vector + inline void setRow(unsigned short usNdx, const Vector3d&); + /// Set column to vector + inline void setCol(unsigned short usNdx, const Vector3d&); + /// Set trace to vector + inline void setTrace(const Vector3d&); /// Compute the determinant of the matrix double determinant() const; /// Analyse the transformation @@ -370,6 +382,42 @@ inline const double* Matrix4D::operator[] (unsigned short usNdx) const return dMtrx4D[usNdx]; } +inline Vector3d Matrix4D::getRow(unsigned short usNdx) const +{ + return Vector3d(dMtrx4D[usNdx][0], dMtrx4D[usNdx][1], dMtrx4D[usNdx][2]); +} + +inline Vector3d Matrix4D::getCol(unsigned short usNdx) const +{ + return Vector3d(dMtrx4D[0][usNdx], dMtrx4D[1][usNdx], dMtrx4D[2][usNdx]); +} + +inline Vector3d Matrix4D::trace() const +{ + return Vector3d(dMtrx4D[0][0], dMtrx4D[1][1], dMtrx4D[2][2]); +} + +inline void Matrix4D::setRow(unsigned short usNdx, const Vector3d& v) +{ + dMtrx4D[usNdx][0] = v.x; + dMtrx4D[usNdx][1] = v.y; + dMtrx4D[usNdx][2] = v.z; +} + +inline void Matrix4D::setCol(unsigned short usNdx, const Vector3d& v) +{ + dMtrx4D[0][usNdx] = v.x; + dMtrx4D[1][usNdx] = v.y; + dMtrx4D[2][usNdx] = v.z; +} + +inline void Matrix4D::setTrace(const Vector3d& v) +{ + dMtrx4D[0][0] = v.x; + dMtrx4D[1][1] = v.y; + dMtrx4D[2][2] = v.z; +} + } // namespace Base diff --git a/src/Base/MatrixPy.xml b/src/Base/MatrixPy.xml index f83d545bce..e48119d5c6 100644 --- a/src/Base/MatrixPy.xml +++ b/src/Base/MatrixPy.xml @@ -52,6 +52,54 @@ Return 0 is no scale factor, 1 for uniform scaling, -1 for non-uniform scaling. transform(Vector,Matrix) - return the dot product of the two vectors + + + +col(index) +Return the vector of a column + + + + + + +setCol(index, Vector) +Set the vector of a column + + + + + + +row(index) +Return the vector of a row + + + + + + +setRow(index, Vector) +Set the vector of a row + + + + + + +trace() +Return the trace of the 3x3 sub-matrix as vector + + + + + + +setTrace(Vector) +Set the trace of the 3x3 sub-matrix + + + rotateX(float) - rotate around X diff --git a/src/Base/MatrixPyImp.cpp b/src/Base/MatrixPyImp.cpp index 0b04fa714d..4f9dc2a3eb 100644 --- a/src/Base/MatrixPyImp.cpp +++ b/src/Base/MatrixPyImp.cpp @@ -87,6 +87,42 @@ int MatrixPy::PyInit(PyObject* args, PyObject* /*kwd*/) return 0; } + PyErr_Clear(); + PyObject *o1; + PyObject *o2; + PyObject *o3; + PyObject *o4 = nullptr; + if (PyArg_ParseTuple(args, "O!O!O!|O!", &(Base::VectorPy::Type), &o1 + , &(Base::VectorPy::Type), &o2 + , &(Base::VectorPy::Type), &o3 + , &(Base::VectorPy::Type), &o4)) { + Base::Vector3d v1 = Py::Vector(o1, false).toVector(); + Base::Vector3d v2 = Py::Vector(o2, false).toVector(); + Base::Vector3d v3 = Py::Vector(o3, false).toVector(); + Base::Vector3d v4; + if (o4) + v4 = Py::Vector(o4, false).toVector(); + MatrixPy::PointerType ptr = this->getMatrixPtr(); + + (*ptr)[0][0] = v1.x; + (*ptr)[1][0] = v1.y; + (*ptr)[2][0] = v1.z; + + (*ptr)[0][1] = v2.x; + (*ptr)[1][1] = v2.y; + (*ptr)[2][1] = v2.z; + + (*ptr)[0][2] = v3.x; + (*ptr)[1][2] = v3.y; + (*ptr)[2][2] = v3.z; + + (*ptr)[0][3] = v4.x; + (*ptr)[1][3] = v4.y; + (*ptr)[2][3] = v4.z; + + return 0; + } + PyErr_SetString(Base::BaseExceptionFreeCADError, "matrix or up to 16 floats expected"); return -1; } @@ -94,7 +130,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_NotImplementedError, ""); + PyErr_SetString(PyExc_TypeError, "First arg must be Matrix"); return nullptr; } if (!PyObject_TypeCheck(other, &(MatrixPy::Type))) { @@ -109,7 +145,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_NotImplementedError, ""); + PyErr_SetString(PyExc_TypeError, "First arg must be Matrix"); return nullptr; } if (!PyObject_TypeCheck(other, &(MatrixPy::Type))) { @@ -342,6 +378,91 @@ PyObject* MatrixPy::transform(PyObject * args) Py_Return; } +PyObject* MatrixPy::col(PyObject * args) +{ + int index; + if (PyArg_ParseTuple(args, "i", &index)) { + index = index % 4; + Matrix4D* mat = getMatrixPtr(); + Base::Vector3d v = mat->getCol(index); + return Py::new_reference_to(Py::Vector(v)); + } + + PyErr_SetString(Base::BaseExceptionFreeCADError, "int expected"); + return nullptr; +} + +PyObject* MatrixPy::setCol(PyObject * args) +{ + int index; + PyObject* o; + if (PyArg_ParseTuple(args, "iO!", &index, &(VectorPy::Type), &o)) { + index = index % 4; + Base::Vector3d v = Py::Vector(o, false).toVector(); + Matrix4D* mat = getMatrixPtr(); + mat->setCol(index, v); + Py_Return; + } + + PyErr_SetString(Base::BaseExceptionFreeCADError, "int and Vector expected"); + return nullptr; +} + +PyObject* MatrixPy::row(PyObject * args) +{ + int index; + if (PyArg_ParseTuple(args, "i", &index)) { + index = index % 4; + Matrix4D* mat = getMatrixPtr(); + Base::Vector3d v = mat->getRow(index); + return Py::new_reference_to(Py::Vector(v)); + } + + PyErr_SetString(Base::BaseExceptionFreeCADError, "int expected"); + return nullptr; +} + +PyObject* MatrixPy::setRow(PyObject * args) +{ + int index; + PyObject* o; + if (PyArg_ParseTuple(args, "iO!", &index, &(VectorPy::Type), &o)) { + index = index % 4; + Base::Vector3d v = Py::Vector(o, false).toVector(); + Matrix4D* mat = getMatrixPtr(); + mat->setRow(index, v); + Py_Return; + } + + PyErr_SetString(Base::BaseExceptionFreeCADError, "int and Vector expected"); + return nullptr; +} + +PyObject* MatrixPy::trace(PyObject * args) +{ + if (PyArg_ParseTuple(args, "")) { + Matrix4D* mat = getMatrixPtr(); + Base::Vector3d v = mat->trace(); + return Py::new_reference_to(Py::Vector(v)); + } + + return nullptr; +} + +PyObject* MatrixPy::setTrace(PyObject * args) +{ + PyObject* o; + if (PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &o)) { + Base::Vector3d v = Py::Vector(o, false).toVector(); + Matrix4D* mat = getMatrixPtr(); + mat->setTrace(v); + Py_Return; + } + + PyErr_SetString(Base::BaseExceptionFreeCADError, "Vector expected"); + return nullptr; +} + PyObject* MatrixPy::rotateX(PyObject * args) { double angle = 0; @@ -555,8 +676,8 @@ PyObject* MatrixPy::isOrthogonal(PyObject * args) bool ok = true; double mult = trp[0][0]; - for (int i=0; i<4 && ok; i++) { - for (int j=0; j<4 && ok; j++) { + for (unsigned short i=0; i<4 && ok; i++) { + for (unsigned short j=0; j<4 && ok; j++) { if (i != j) { if (fabs(trp[i][j]) > eps) { ok = false; @@ -622,7 +743,7 @@ Py::Float MatrixPy::getA11() const void MatrixPy::setA11(Py::Float arg) { - (*this->getMatrixPtr())[0][0] = (double)arg; + (*this->getMatrixPtr())[0][0] = static_cast(arg); } Py::Float MatrixPy::getA12() const @@ -633,7 +754,7 @@ Py::Float MatrixPy::getA12() const void MatrixPy::setA12(Py::Float arg) { - (*this->getMatrixPtr())[0][1] = (double)arg; + (*this->getMatrixPtr())[0][1] = static_cast(arg); } Py::Float MatrixPy::getA13() const @@ -644,7 +765,7 @@ Py::Float MatrixPy::getA13() const void MatrixPy::setA13(Py::Float arg) { - (*this->getMatrixPtr())[0][2] = (double)arg; + (*this->getMatrixPtr())[0][2] = static_cast(arg); } Py::Float MatrixPy::getA14() const @@ -655,7 +776,7 @@ Py::Float MatrixPy::getA14() const void MatrixPy::setA14(Py::Float arg) { - (*this->getMatrixPtr())[0][3] = (double)arg; + (*this->getMatrixPtr())[0][3] = static_cast(arg); } Py::Float MatrixPy::getA21() const @@ -666,7 +787,7 @@ Py::Float MatrixPy::getA21() const void MatrixPy::setA21(Py::Float arg) { - (*this->getMatrixPtr())[1][0] = (double)arg; + (*this->getMatrixPtr())[1][0] = static_cast(arg); } Py::Float MatrixPy::getA22() const @@ -677,7 +798,7 @@ Py::Float MatrixPy::getA22() const void MatrixPy::setA22(Py::Float arg) { - (*this->getMatrixPtr())[1][1] = (double)arg; + (*this->getMatrixPtr())[1][1] = static_cast(arg); } Py::Float MatrixPy::getA23() const @@ -688,7 +809,7 @@ Py::Float MatrixPy::getA23() const void MatrixPy::setA23(Py::Float arg) { - (*this->getMatrixPtr())[1][2] = (double)arg; + (*this->getMatrixPtr())[1][2] = static_cast(arg); } Py::Float MatrixPy::getA24() const @@ -699,7 +820,7 @@ Py::Float MatrixPy::getA24() const void MatrixPy::setA24(Py::Float arg) { - (*this->getMatrixPtr())[1][3] = (double)arg; + (*this->getMatrixPtr())[1][3] = static_cast(arg); } Py::Float MatrixPy::getA31() const @@ -710,7 +831,7 @@ Py::Float MatrixPy::getA31() const void MatrixPy::setA31(Py::Float arg) { - (*this->getMatrixPtr())[2][0] = (double)arg; + (*this->getMatrixPtr())[2][0] = static_cast(arg); } Py::Float MatrixPy::getA32() const @@ -721,7 +842,7 @@ Py::Float MatrixPy::getA32() const void MatrixPy::setA32(Py::Float arg) { - (*this->getMatrixPtr())[2][1] = (double)arg; + (*this->getMatrixPtr())[2][1] = static_cast(arg); } Py::Float MatrixPy::getA33() const @@ -732,7 +853,7 @@ Py::Float MatrixPy::getA33() const void MatrixPy::setA33(Py::Float arg) { - (*this->getMatrixPtr())[2][2] = (double)arg; + (*this->getMatrixPtr())[2][2] = static_cast(arg); } Py::Float MatrixPy::getA34() const @@ -743,7 +864,7 @@ Py::Float MatrixPy::getA34() const void MatrixPy::setA34(Py::Float arg) { - (*this->getMatrixPtr())[2][3] = (double)arg; + (*this->getMatrixPtr())[2][3] = static_cast(arg); } Py::Float MatrixPy::getA41() const @@ -754,7 +875,7 @@ Py::Float MatrixPy::getA41() const void MatrixPy::setA41(Py::Float arg) { - (*this->getMatrixPtr())[3][0] = (double)arg; + (*this->getMatrixPtr())[3][0] = static_cast(arg); } Py::Float MatrixPy::getA42() const @@ -765,7 +886,7 @@ Py::Float MatrixPy::getA42() const void MatrixPy::setA42(Py::Float arg) { - (*this->getMatrixPtr())[3][1] = (double)arg; + (*this->getMatrixPtr())[3][1] = static_cast(arg); } Py::Float MatrixPy::getA43() const @@ -776,7 +897,7 @@ Py::Float MatrixPy::getA43() const void MatrixPy::setA43(Py::Float arg) { - (*this->getMatrixPtr())[3][2] = (double)arg; + (*this->getMatrixPtr())[3][2] = static_cast(arg); } Py::Float MatrixPy::getA44() const @@ -787,7 +908,7 @@ Py::Float MatrixPy::getA44() const void MatrixPy::setA44(Py::Float arg) { - (*this->getMatrixPtr())[3][3] = (double)arg; + (*this->getMatrixPtr())[3][3] = static_cast(arg); } Py::Sequence MatrixPy::getA() const @@ -808,7 +929,7 @@ void MatrixPy::setA(Py::Sequence arg) int index=0; for (Py::Sequence::iterator it = arg.begin(); it != arg.end() && index < 16; ++it) { - mat[index++] = (double)Py::Float(*it); + mat[index++] = static_cast(Py::Float(*it)); } this->getMatrixPtr()->setMatrix(mat);