diff options
Diffstat (limited to 'source/blender/python/mathutils/mathutils_Matrix.c')
-rw-r--r-- | source/blender/python/mathutils/mathutils_Matrix.c | 181 |
1 files changed, 135 insertions, 46 deletions
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 9a0a1b3ca95..64112024dd1 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -182,7 +182,7 @@ static int mathutils_matrix_col_get(BaseMathObject *bmo, int col) return -1; /* for 'translation' size will always be '3' even on 4x4 vec */ - num_row = MIN2(self->num_row, ((VectorObject *)bmo)->size); + num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size); for (row = 0; row < num_row; row++) { bmo->data[row] = MATRIX_ITEM(self, row, col); @@ -203,7 +203,7 @@ static int mathutils_matrix_col_set(BaseMathObject *bmo, int col) return -1; /* for 'translation' size will always be '3' even on 4x4 vec */ - num_row = MIN2(self->num_row, ((VectorObject *)bmo)->size); + num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size); for (row = 0; row < num_row; row++) { MATRIX_ITEM(self, row, col) = bmo->data[row]; @@ -329,9 +329,9 @@ Mathutils_Callback mathutils_matrix_translation_cb = { /* matrix column callbacks, this is so you can do matrix.translation = Vector() */ -//----------------------------------mathutils.Matrix() ----------------- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. -//create a new matrix type +/* ----------------------------------mathutils.Matrix() ----------------- */ +/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */ +/* create a new matrix type */ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { if (kwds && PyDict_Size(kwds)) { @@ -384,13 +384,19 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self) { PyObject *ret = Matrix_copy(self); - PyObject *ret_dummy = matrix_func(ret); - if (ret_dummy) { - Py_DECREF(ret_dummy); - return (PyObject *)ret; + if (ret) { + PyObject *ret_dummy = matrix_func(ret); + if (ret_dummy) { + Py_DECREF(ret_dummy); + return (PyObject *)ret; + } + else { /* error */ + Py_DECREF(ret); + return NULL; + } } - else { /* error */ - Py_DECREF(ret); + else { + /* copy may fail if the read callback errors out */ return NULL; } } @@ -410,7 +416,7 @@ static void matrix_3x3_as_4x4(float mat[16]) /*-----------------------CLASS-METHODS----------------------------*/ -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. +/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */ PyDoc_STRVAR(C_Matrix_Identity_doc, ".. classmethod:: Identity(size)\n" "\n" @@ -518,7 +524,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) const float angle_cos = cosf(angle); const float angle_sin = sinf(angle); - //2D rotation matrix + /* 2D rotation matrix */ mat[0] = angle_cos; mat[1] = angle_sin; mat[2] = -angle_sin; @@ -532,7 +538,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) if (matSize == 4) { matrix_3x3_as_4x4(mat); } - //pass to matrix creation + /* pass to matrix creation */ return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); } @@ -556,8 +562,8 @@ static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value) return Matrix_CreatePyObject(&mat[0][0], 4, 4, Py_NEW, (PyTypeObject *)cls); } -//----------------------------------mathutils.Matrix.Scale() ------------- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. +/* ----------------------------------mathutils.Matrix.Scale() ------------- */ +/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */ PyDoc_STRVAR(C_Matrix_Scale_doc, ".. classmethod:: Scale(factor, size, axis)\n" "\n" @@ -601,7 +607,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) return NULL; } } - if (vec == NULL) { //scaling along axis + if (vec == NULL) { /* scaling along axis */ if (matSize == 2) { mat[0] = factor; mat[3] = factor; @@ -645,11 +651,11 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) if (matSize == 4) { matrix_3x3_as_4x4(mat); } - //pass to matrix creation + /* pass to matrix creation */ return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); } -//----------------------------------mathutils.Matrix.OrthoProjection() --- -//mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. +/* ----------------------------------mathutils.Matrix.OrthoProjection() --- */ +/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */ PyDoc_STRVAR(C_Matrix_OrthoProjection_doc, ".. classmethod:: OrthoProjection(axis, size)\n" "\n" @@ -685,7 +691,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) return NULL; } - if (PyUnicode_Check(axis)) { //ortho projection onto cardinal plane + if (PyUnicode_Check(axis)) { /* ortho projection onto cardinal plane */ Py_ssize_t plane_len; const char *plane = _PyUnicode_AsStringAndSize(axis, &plane_len); if (matSize == 2) { @@ -726,7 +732,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) } } else { - //arbitrary plane + /* arbitrary plane */ int vec_size = (matSize == 2 ? 2 : 3); float tvec[4]; @@ -737,7 +743,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) return NULL; } - //normalize arbitrary axis + /* normalize arbitrary axis */ for (x = 0; x < vec_size; x++) { norm += tvec[x] * tvec[x]; } @@ -766,7 +772,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) if (matSize == 4) { matrix_3x3_as_4x4(mat); } - //pass to matrix creation + /* pass to matrix creation */ return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); } @@ -869,7 +875,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args) if (matSize == 4) { matrix_3x3_as_4x4(mat); } - //pass to matrix creation + /* pass to matrix creation */ return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); } @@ -1196,17 +1202,27 @@ static PyObject *Matrix_invert(MatrixObject *self) if (det != 0) { /* calculate the classical adjoint */ - if (self->num_col == 2) { - mat[0] = MATRIX_ITEM(self, 1, 1); - mat[1] = -MATRIX_ITEM(self, 0, 1); - mat[2] = -MATRIX_ITEM(self, 1, 0); - mat[3] = MATRIX_ITEM(self, 0, 0); - } - else if (self->num_col == 3) { - adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix); - } - else if (self->num_col == 4) { - adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix); + switch (self->num_col) { + case 2: + { + adjoint_m2_m2((float (*)[2])mat, (float (*)[2])self->matrix); + break; + } + case 3: + { + adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix); + break; + } + case 4: + { + adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix); + break; + } + default: + PyErr_Format(PyExc_TypeError, + "Matrix invert(ed): size (%d) unsupported", + (int)self->num_col); + return NULL; } /* divide by determinate */ for (x = 0; x < (self->num_col * self->num_row); x++) { @@ -1236,7 +1252,7 @@ PyDoc_STRVAR(Matrix_inverted_doc, "\n" " Return an inverted copy of the matrix.\n" "\n" -" :return: the inverted matrix.\n" +" :return: the inverted matrix.\n" " :rtype: :class:`Matrix`\n" "\n" " .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n" @@ -1246,6 +1262,77 @@ static PyObject *Matrix_inverted(MatrixObject *self) return matrix__apply_to_copy((PyNoArgsFunction)Matrix_invert, self); } +/*---------------------------matrix.adjugate() ---------------------*/ +PyDoc_STRVAR(Matrix_adjugate_doc, +".. method:: adjugate()\n" +"\n" +" Set the matrix to its adjugate.\n" +"\n" +" .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n" +"\n" +" .. seealso:: <http://en.wikipedia.org/wiki/Adjugate_matrix>\n" +); +static PyObject *Matrix_adjugate(MatrixObject *self) +{ + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + if (self->num_col != self->num_row) { + PyErr_SetString(PyExc_TypeError, + "Matrix.adjugate(d): " + "only square matrices are supported"); + return NULL; + } + + /* calculate the classical adjoint */ + switch (self->num_col) { + case 2: + { + float mat[2][2]; + adjoint_m2_m2(mat, (float (*)[2])self->matrix); + copy_v4_v4((float *)self->matrix, (float *)mat); + break; + } + case 3: + { + float mat[3][3]; + adjoint_m3_m3(mat, (float (*)[3])self->matrix); + copy_m3_m3((float (*)[3])self->matrix, mat); + break; + } + case 4: + { + float mat[4][4]; + adjoint_m4_m4(mat, (float (*)[4])self->matrix); + copy_m4_m4((float (*)[4])self->matrix, mat); + break; + } + default: + PyErr_Format(PyExc_TypeError, + "Matrix adjugate(d): size (%d) unsupported", + (int)self->num_col); + return NULL; + } + + (void)BaseMath_WriteCallback(self); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(Matrix_adjugated_doc, +".. method:: adjugated()\n" +"\n" +" Return an adjugated copy of the matrix.\n" +"\n" +" :return: the adjugated matrix.\n" +" :rtype: :class:`Matrix`\n" +"\n" +" .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n" +); +static PyObject *Matrix_adjugated(MatrixObject *self) +{ + return matrix__apply_to_copy((PyNoArgsFunction)Matrix_adjugate, self); +} + PyDoc_STRVAR(Matrix_rotate_doc, ".. method:: rotate(other)\n" "\n" @@ -1579,7 +1666,7 @@ static PyObject *Matrix_str(MatrixObject *self) maxsize[col] = 0; for (row = 0; row < self->num_row; row++) { int size = BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col)); - maxsize[col] = MAX2(maxsize[col], size); + maxsize[col] = max_ii(maxsize[col], size); } } @@ -1921,7 +2008,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) for (row = 0; row < mat1->num_row; row++) { double dot = 0.0f; for (item = 0; item < mat1->num_col; item++) { - dot += MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col); + dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col)); } mat[(col * mat1->num_row) + row] = (float)dot; } @@ -2000,7 +2087,7 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item) else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->num_row, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) return NULL; if (slicelength <= 0) { @@ -2036,7 +2123,7 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->num_row, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) return -1; if (step == 1) @@ -2281,6 +2368,8 @@ static struct PyMethodDef Matrix_methods[] = { {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc}, {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc}, {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc}, + {"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc}, + {"adjugated", (PyCFunction) Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc}, {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc}, /* TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc}, */ {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc}, @@ -2335,8 +2424,8 @@ PyTypeObject matrix_Type = { NULL, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ matrix_doc, /*tp_doc*/ - (traverseproc)BaseMathObject_traverse, //tp_traverse - (inquiry)BaseMathObject_clear, //tp_clear + (traverseproc)BaseMathObject_traverse, /* tp_traverse */ + (inquiry)BaseMathObject_clear, /*tp_clear*/ (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ NULL, /*tp_iter*/ @@ -2537,7 +2626,7 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx(item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0) return NULL; if (slicelength <= 0) { @@ -2635,8 +2724,8 @@ PyTypeObject matrix_access_Type = { NULL, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ NULL, /*tp_doc*/ - (traverseproc)MatrixAccess_traverse, //tp_traverse - (inquiry)MatrixAccess_clear, //tp_clear + (traverseproc)MatrixAccess_traverse,/*tp_traverse*/ + (inquiry)MatrixAccess_clear, /*tp_clear*/ NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */ |