Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/python/mathutils/mathutils_Matrix.c')
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c181
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; */