diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp
index 3de4d3de4..4ea986415 100644
--- a/src/Base/Matrix.cpp
+++ b/src/Base/Matrix.cpp
@@ -455,6 +455,7 @@ void Matrix4D::transform (const Vector3f& rclVct, const Matrix4D& rclMtrx)
(*this) *= rclMtrx;
move(rclVct);
}
+
void Matrix4D::transform (const Vector3d& rclVct, const Matrix4D& rclMtrx)
{
move(-rclVct);
@@ -601,6 +602,24 @@ void Matrix4D::inverseGauss (void)
setGLMatrix(inversematrix);
}
+void Matrix4D::getMatrix (double dMtrx[16]) const
+{
+ short iz, is;
+
+ for (iz = 0; iz < 4; iz++)
+ for (is = 0; is < 4; is++)
+ dMtrx[ 4*iz + is ] = dMtrx4D[iz][is];
+}
+
+void Matrix4D::setMatrix (const double dMtrx[16])
+{
+ short iz, is;
+
+ for (iz = 0; iz < 4; iz++)
+ for (is = 0; is < 4; is++)
+ dMtrx4D[iz][is] = dMtrx[ 4*iz + is ];
+}
+
void Matrix4D::getGLMatrix (double dMtrx[16]) const
{
short iz, is;
diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h
index 3634405d5..8e62b9fb6 100644
--- a/src/Base/Matrix.h
+++ b/src/Base/Matrix.h
@@ -90,6 +90,8 @@ public:
double determinant() const;
//@}
+ void getMatrix (double dMtrx[16]) const;
+ void setMatrix (const double dMtrx[16]);
/// get the matrix in OpenGL style
void getGLMatrix (double dMtrx[16]) const;
/// set the matrix in OpenGL style
diff --git a/src/Base/MatrixPy.xml b/src/Base/MatrixPy.xml
index fdb59df88..c91da2aa2 100644
--- a/src/Base/MatrixPy.xml
+++ b/src/Base/MatrixPy.xml
@@ -11,6 +11,7 @@
Constructor="true"
Delete="true"
NumberProtocol="true"
+ RichCompare="true"
FatherNamespace="Base">
@@ -82,6 +83,22 @@ Compute the inverse matrix, if possible
+
+
+
+transpose() -> None
+Transpose the matrix.
+
+
+
+
+
+
+transposed() -> Matrix
+Returns a transposed copy of this matrix.
+
+
+
@@ -90,6 +107,23 @@ Compute the determinant of the matrix
+
+
+
+isOrthogonal() -> Float
+Checks if the matrix is orthogonal, i.e. M * M^T = k*I and returns
+the multiple of the identity matrix. If it's not orthogonal 0 is returned.
+
+
+
+
+
+
+submatrix(int) -> Matrix
+Get the sub-matrix. The parameter must be in the range [1,4].
+
+
+
The matrix elements
diff --git a/src/Base/MatrixPyImp.cpp b/src/Base/MatrixPyImp.cpp
index 132bfda51..fb524fc7a 100644
--- a/src/Base/MatrixPyImp.cpp
+++ b/src/Base/MatrixPyImp.cpp
@@ -133,6 +133,36 @@ PyObject* MatrixPy::number_multiply_handler(PyObject *self, PyObject *other)
return new MatrixPy(a*b);
}
+PyObject* MatrixPy::richCompare(PyObject *v, PyObject *w, int op)
+{
+ if (PyObject_TypeCheck(v, &(MatrixPy::Type)) &&
+ PyObject_TypeCheck(w, &(MatrixPy::Type))) {
+ Matrix4D m1 = static_cast(v)->value();
+ Matrix4D m2 = static_cast(w)->value();
+
+ PyObject *res=0;
+ if (op != Py_EQ && op != Py_NE) {
+ PyErr_SetString(PyExc_TypeError,
+ "no ordering relation is defined for Matrix");
+ return 0;
+ }
+ else if (op == Py_EQ) {
+ res = (m1 == m2) ? Py_True : Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+ else {
+ res = (m1 != m2) ? Py_True : Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "Cannot compare Matrix with other type");
+ return 0;
+ }
+}
+
PyObject* MatrixPy::move(PyObject * args)
{
double x,y,z;
@@ -349,6 +379,93 @@ PyObject* MatrixPy::determinant(PyObject * args)
return PyFloat_FromDouble(getMatrixPtr()->determinant());
}
+PyObject* MatrixPy::submatrix(PyObject * args)
+{
+ int dim;
+ if (!PyArg_ParseTuple(args, "i", &dim))
+ return NULL;
+ if (dim < 1 || dim > 4) {
+ PyErr_SetString(PyExc_IndexError, "Dimension out of range");
+ return NULL;
+ }
+
+ const Base::Matrix4D& mat = *getMatrixPtr();
+ Base::Matrix4D sub;
+ switch (dim)
+ {
+ case 1:
+ sub[0][0] = mat[0][0];
+ case 2:
+ sub[0][0] = mat[0][0]; sub[0][1] = mat[0][1];
+ sub[1][0] = mat[1][0]; sub[1][1] = mat[1][1];
+ case 3:
+ sub[0][0] = mat[0][0]; sub[0][1] = mat[0][1]; sub[0][2] = mat[0][2];
+ sub[1][0] = mat[1][0]; sub[1][1] = mat[1][1]; sub[1][2] = mat[1][2];
+ sub[2][0] = mat[2][0]; sub[2][1] = mat[2][1]; sub[2][2] = mat[2][2];
+ default:
+ sub = mat;
+ }
+
+ return new MatrixPy(sub);
+}
+
+PyObject* MatrixPy::isOrthogonal(PyObject * args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return 0;
+ const Base::Matrix4D& mat = *getMatrixPtr();
+ Base::Matrix4D trp = mat;
+ trp.transpose();
+ trp = trp * mat;
+
+ double mult = trp[0][0];
+ for (int i=0; (i<4) && (mult!=0.0); i++) {
+ for (int j=0; (j<4) && (mult!=0.0); j++) {
+ if (i != j) {
+ if (trp[i][j] != 0.0) {
+ mult = 0.0;
+ break;
+ }
+ }
+ else { // the diagonal
+ if (trp[i][j] != mult) {
+ mult = 0.0;
+ break;
+ }
+ }
+ }
+ }
+
+ return Py::new_reference_to(Py::Float(mult));
+}
+
+PyObject* MatrixPy::transposed(PyObject * args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ PY_TRY {
+ Base::Matrix4D m = *getMatrixPtr();
+ m.transpose();
+ return new MatrixPy(m);
+ }
+ PY_CATCH;
+
+ Py_Return;
+}
+
+PyObject* MatrixPy::transpose(PyObject * args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ PY_TRY {
+ getMatrixPtr()->transpose();
+ Py_Return;
+ }
+ PY_CATCH;
+}
+
Py::Float MatrixPy::getA11(void) const
{
double val = (*this->getMatrixPtr())[0][0];
@@ -527,12 +644,26 @@ void MatrixPy::setA44(Py::Float arg)
Py::List MatrixPy::getA(void) const
{
- return Py::List();
+ double mat[16];
+ this->getMatrixPtr()->getMatrix(mat);
+ Py::List list(16);
+ for (int i=0; i<16; i++) {
+ list[i] = Py::Float(mat[i]);
+ }
+ return list;
}
-void MatrixPy::setA(Py::List /*arg*/)
+void MatrixPy::setA(Py::List arg)
{
+ double mat[16];
+ this->getMatrixPtr()->getMatrix(mat);
+ int index=0;
+ for (Py::List::iterator it = arg.begin(); it != arg.end() && index < 16; ++it) {
+ mat[index++] = (double)Py::Float(*it);
+ }
+
+ this->getMatrixPtr()->setMatrix(mat);
}
PyObject *MatrixPy::getCustomAttributes(const char* /*attr*/) const
diff --git a/src/Base/VectorPyImp.cpp b/src/Base/VectorPyImp.cpp
index b5546ca7a..3476ac06a 100644
--- a/src/Base/VectorPyImp.cpp
+++ b/src/Base/VectorPyImp.cpp
@@ -237,8 +237,8 @@ PyObject* VectorPy::richCompare(PyObject *v, PyObject *w, int op)
}
}
else {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ PyErr_SetString(PyExc_TypeError, "Cannot compare Matrix with other type");
+ return 0;
}
}