Changeset View
Changeset View
Standalone View
Standalone View
source/blender/python/mathutils/mathutils_Matrix.c
| Show First 20 Lines • Show All 2,250 Lines • ▼ Show 20 Lines | else { | ||||
| /*parsed well - now set in matrix*/ | /*parsed well - now set in matrix*/ | ||||
| memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); | memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float)); | ||||
| (void)BaseMath_WriteCallback(self); | (void)BaseMath_WriteCallback(self); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| /*------------------------NUMERIC PROTOCOLS---------------------- | |||||
| *------------------------obj + obj------------------------------*/ | /* Numeric Protocols */ | ||||
| /* element-wise addition: obj + obj */ | |||||
| static PyObject *Matrix_add(PyObject *m1, PyObject *m2) | static PyObject *Matrix_add(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | return mathtutils_generic_elem_op(m1, m2, ADD); | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | |||||
| mat1 = (MatrixObject *)m1; | |||||
| mat2 = (MatrixObject *)m2; | |||||
| if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { | |||||
| PyErr_Format(PyExc_TypeError, | |||||
| "Matrix addition: (%s + %s) " | |||||
| "invalid type for this operation", | |||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | |||||
| return NULL; | |||||
| } | } | ||||
| if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) | /* element-wise addition in-place: obj += obj */ | ||||
| return NULL; | static PyObject *Matrix_iadd(PyObject *m1, PyObject *m2) | ||||
| { | |||||
| if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { | return mathtutils_generic_elem_op_inplace(m1, m2, ADD); | ||||
| PyErr_SetString(PyExc_ValueError, | |||||
| "Matrix addition: " | |||||
| "matrices must have the same dimensions for this operation"); | |||||
| return NULL; | |||||
| } | } | ||||
| add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); | /* element-wise subtraction: obj - obj */ | ||||
| return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); | |||||
| } | |||||
| /*------------------------obj - obj------------------------------ | |||||
| * subtraction */ | |||||
| static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) | static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | return mathtutils_generic_elem_op(m1, m2, SUB); | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | |||||
| mat1 = (MatrixObject *)m1; | |||||
| mat2 = (MatrixObject *)m2; | |||||
| if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { | |||||
| PyErr_Format(PyExc_TypeError, | |||||
| "Matrix subtraction: (%s - %s) " | |||||
| "invalid type for this operation", | |||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | |||||
| return NULL; | |||||
| } | |||||
| if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) | |||||
| return NULL; | |||||
| if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { | |||||
| PyErr_SetString(PyExc_ValueError, | |||||
| "Matrix addition: " | |||||
| "matrices must have the same dimensions for this operation"); | |||||
| return NULL; | |||||
| } | } | ||||
| sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); | /* element-wise subtraction in-place: obj -= obj */ | ||||
| static PyObject *Matrix_isub(PyObject *m1, PyObject *m2) | |||||
| return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); | |||||
| } | |||||
| /*------------------------obj * obj------------------------------ | |||||
| * element-wise multiplication */ | |||||
| static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) | |||||
| { | { | ||||
| float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | return mathtutils_generic_elem_op_inplace(m1, m2, SUB); | ||||
| mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar); | |||||
| return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat)); | |||||
| } | } | ||||
| /* element-wise multiplication: obj * obj */ | |||||
| static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) | static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| float scalar; | return mathtutils_generic_elem_op(m1, m2, MUL); | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | |||||
| if (MatrixObject_Check(m1)) { | |||||
| mat1 = (MatrixObject *)m1; | |||||
| if (BaseMath_ReadCallback(mat1) == -1) | |||||
| return NULL; | |||||
| } | |||||
| if (MatrixObject_Check(m2)) { | |||||
| mat2 = (MatrixObject *)m2; | |||||
| if (BaseMath_ReadCallback(mat2) == -1) | |||||
| return NULL; | |||||
| } | |||||
| if (mat1 && mat2) { | |||||
| #ifdef USE_MATHUTILS_ELEM_MUL | |||||
| /* MATRIX * MATRIX */ | |||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | |||||
| if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { | |||||
| PyErr_SetString(PyExc_ValueError, | |||||
| "matrix1 * matrix2: matrix1 number of rows/columns " | |||||
| "and the matrix2 number of rows/columns must be the same"); | |||||
| return NULL; | |||||
| } | |||||
| mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); | |||||
| return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); | |||||
| #endif | |||||
| } | |||||
| else if (mat2) { | |||||
| /*FLOAT/INT * MATRIX */ | |||||
| if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) { | |||||
| return matrix_mul_float(mat2, scalar); | |||||
| } | |||||
| } | |||||
| else if (mat1) { | |||||
| /* MATRIX * FLOAT/INT */ | |||||
| if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) { | |||||
| return matrix_mul_float(mat1, scalar); | |||||
| } | |||||
| } | } | ||||
| PyErr_Format(PyExc_TypeError, | /* element-wise multiplication in-place: obj *= obj */ | ||||
| "Element-wise multiplication: " | |||||
| "not supported between '%.200s' and '%.200s' types", | |||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | |||||
| return NULL; | |||||
| } | |||||
| /*------------------------obj *= obj------------------------------ | |||||
| * Inplace element-wise multiplication */ | |||||
| static PyObject *Matrix_imul(PyObject *m1, PyObject *m2) | static PyObject *Matrix_imul(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| float scalar; | return mathtutils_generic_elem_op_inplace(m1, m2, MUL); | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | |||||
| if (MatrixObject_Check(m1)) { | |||||
| mat1 = (MatrixObject *)m1; | |||||
| if (BaseMath_ReadCallback(mat1) == -1) | |||||
| return NULL; | |||||
| } | |||||
| if (MatrixObject_Check(m2)) { | |||||
| mat2 = (MatrixObject *)m2; | |||||
| if (BaseMath_ReadCallback(mat2) == -1) | |||||
| return NULL; | |||||
| } | } | ||||
| if (mat1 && mat2) { | /* element-wise division: obj / obj */ | ||||
| #ifdef USE_MATHUTILS_ELEM_MUL | static PyObject *Matrix_div(PyObject *m1, PyObject *m2) | ||||
| /* MATRIX *= MATRIX */ | { | ||||
| if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { | return mathtutils_generic_elem_op(m1, m2, DIV); | ||||
| PyErr_SetString(PyExc_ValueError, | |||||
| "matrix1 *= matrix2: matrix1 number of rows/columns " | |||||
| "and the matrix2 number of rows/columns must be the same"); | |||||
| return NULL; | |||||
| } | } | ||||
| mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); | /* element-wise division in-place: obj / obj */ | ||||
| #else | static PyObject *Matrix_idiv(PyObject *m1, PyObject *m2) | ||||
| PyErr_Format(PyExc_TypeError, | { | ||||
| "Inplace element-wise multiplication: " | return mathtutils_generic_elem_op_inplace(m1, m2, DIV); | ||||
| "not supported between '%.200s' and '%.200s' types", | |||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | |||||
| return NULL; | |||||
| #endif | |||||
| } | |||||
| else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) { | |||||
| /* MATRIX *= FLOAT/INT */ | |||||
| mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar); | |||||
| } | |||||
| else { | |||||
| PyErr_Format(PyExc_TypeError, | |||||
| "Inplace element-wise multiplication: " | |||||
| "not supported between '%.200s' and '%.200s' types", | |||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | |||||
| return NULL; | |||||
| } | } | ||||
| (void)BaseMath_WriteCallback(mat1); | /* matrix multiplication: obj @ obj */ | ||||
| Py_INCREF(m1); | |||||
| return m1; | |||||
| } | |||||
| /*------------------------obj @ obj------------------------------ | |||||
| * matrix multiplication */ | |||||
| static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) | static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| int vec_size; | int vec_size; | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | MatrixObject *mat1 = NULL, *mat2 = NULL; | ||||
| if (MatrixObject_Check(m1)) { | if (MatrixObject_Check(m1)) { | ||||
| mat1 = (MatrixObject *)m1; | mat1 = (MatrixObject *)m1; | ||||
| Show All 9 Lines | static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) | ||||
| if (mat1 && mat2) { | if (mat1 && mat2) { | ||||
| /* MATRIX @ MATRIX */ | /* MATRIX @ MATRIX */ | ||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | ||||
| int col, row, item; | int col, row, item; | ||||
| if (mat1->num_col != mat2->num_row) { | if (mat1->num_col != mat2->num_row) { | ||||
| PyErr_SetString(PyExc_ValueError, | PyErr_SetString(PyExc_ValueError, | ||||
| "matrix1 * matrix2: matrix1 number of columns " | "matrix1 @ matrix2: matrix1 number of columns " | ||||
| "and the matrix2 number of rows must be the same"); | "and the matrix2 number of rows must be the same"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| for (col = 0; col < mat2->num_col; col++) { | for (col = 0; col < mat2->num_col; col++) { | ||||
| for (row = 0; row < mat1->num_row; row++) { | for (row = 0; row < mat1->num_row; row++) { | ||||
| double dot = 0.0f; | double dot = 0.0f; | ||||
| for (item = 0; item < mat1->num_col; item++) { | for (item = 0; item < mat1->num_col; item++) { | ||||
| Show All 28 Lines | static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) | ||||
| } | } | ||||
| PyErr_Format(PyExc_TypeError, | PyErr_Format(PyExc_TypeError, | ||||
| "Matrix multiplication: " | "Matrix multiplication: " | ||||
| "not supported between '%.200s' and '%.200s' types", | "not supported between '%.200s' and '%.200s' types", | ||||
| Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /*------------------------obj @= obj------------------------------ | |||||
| * inplace matrix multiplication */ | /* matrix multiplication in-place: obj @= obj */ | ||||
| static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2) | static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2) | ||||
| { | { | ||||
| MatrixObject *mat1 = NULL, *mat2 = NULL; | MatrixObject *mat1 = NULL, *mat2 = NULL; | ||||
| if (MatrixObject_Check(m1)) { | if (MatrixObject_Check(m1)) { | ||||
| mat1 = (MatrixObject *)m1; | mat1 = (MatrixObject *)m1; | ||||
| if (BaseMath_ReadCallback(mat1) == -1) | if (BaseMath_ReadCallback(mat1) == -1) | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (MatrixObject_Check(m2)) { | if (MatrixObject_Check(m2)) { | ||||
| mat2 = (MatrixObject *)m2; | mat2 = (MatrixObject *)m2; | ||||
| if (BaseMath_ReadCallback(mat2) == -1) | if (BaseMath_ReadCallback(mat2) == -1) | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (mat1 && mat2) { | if (mat1 && mat2) { | ||||
| /* MATRIX @= MATRIX */ | /* MATRIX @= MATRIX */ | ||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | ||||
| int col, row, item; | int col, row, item; | ||||
| if (mat1->num_col != mat2->num_row) { | if (mat1->num_col != mat2->num_row) { | ||||
| PyErr_SetString(PyExc_ValueError, | PyErr_SetString(PyExc_ValueError, | ||||
| "matrix1 * matrix2: matrix1 number of columns " | "matrix1 @ matrix2: matrix1 number of columns " | ||||
| "and the matrix2 number of rows must be the same"); | "and the matrix2 number of rows must be the same"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| for (col = 0; col < mat2->num_col; col++) { | for (col = 0; col < mat2->num_col; col++) { | ||||
| for (row = 0; row < mat1->num_row; row++) { | for (row = 0; row < mat1->num_row; row++) { | ||||
| double dot = 0.0f; | double dot = 0.0f; | ||||
| for (item = 0; item < mat1->num_col; item++) { | for (item = 0; item < mat1->num_col; item++) { | ||||
| Show All 16 Lines | else { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| (void)BaseMath_WriteCallback(mat1); | (void)BaseMath_WriteCallback(mat1); | ||||
| Py_INCREF(m1); | Py_INCREF(m1); | ||||
| return m1; | return m1; | ||||
| } | } | ||||
| /* negation: -obj */ | |||||
| static PyObject *Matrix_neg(MatrixObject *self) | |||||
| { | |||||
| float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; | |||||
| if (BaseMath_ReadCallback(self) == -1) | |||||
| return NULL; | |||||
| negate_vn_vn(mat, self->matrix, self->num_col * self->num_row); | |||||
| return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self)); | |||||
| } | |||||
| /*-----------------PROTOCOL DECLARATIONS--------------------------*/ | /*-----------------PROTOCOL DECLARATIONS--------------------------*/ | ||||
| static PySequenceMethods Matrix_SeqMethods = { | static PySequenceMethods Matrix_SeqMethods = { | ||||
| (lenfunc) Matrix_len, /* sq_length */ | (lenfunc) Matrix_len, /* sq_length */ | ||||
| (binaryfunc) NULL, /* sq_concat */ | (binaryfunc) NULL, /* sq_concat */ | ||||
| (ssizeargfunc) NULL, /* sq_repeat */ | (ssizeargfunc) NULL, /* sq_repeat */ | ||||
| (ssizeargfunc) Matrix_item_row, /* sq_item */ | (ssizeargfunc) Matrix_item_row, /* sq_item */ | ||||
| (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ | (ssizessizeargfunc) NULL, /* sq_slice, deprecated */ | ||||
| (ssizeobjargproc) Matrix_ass_item_row, /* sq_ass_item */ | (ssizeobjargproc) Matrix_ass_item_row, /* sq_ass_item */ | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
| static PyNumberMethods Matrix_NumMethods = { | static PyNumberMethods Matrix_NumMethods = { | ||||
| (binaryfunc) Matrix_add, /*nb_add*/ | (binaryfunc) Matrix_add, /*nb_add*/ | ||||
| (binaryfunc) Matrix_sub, /*nb_subtract*/ | (binaryfunc) Matrix_sub, /*nb_subtract*/ | ||||
| (binaryfunc) Matrix_mul, /*nb_multiply*/ | (binaryfunc) Matrix_mul, /*nb_multiply*/ | ||||
| NULL, /*nb_remainder*/ | NULL, /*nb_remainder*/ | ||||
| NULL, /*nb_divmod*/ | NULL, /*nb_divmod*/ | ||||
| NULL, /*nb_power*/ | NULL, /*nb_power*/ | ||||
| (unaryfunc) 0, /*nb_negative*/ | (unaryfunc) Matrix_neg, /*nb_negative*/ | ||||
| (unaryfunc) 0, /*tp_positive*/ | (unaryfunc) 0, /*tp_positive*/ | ||||
| (unaryfunc) 0, /*tp_absolute*/ | (unaryfunc) 0, /*tp_absolute*/ | ||||
| (inquiry) 0, /*tp_bool*/ | (inquiry) 0, /*tp_bool*/ | ||||
| (unaryfunc) Matrix_inverted_noargs, /*nb_invert*/ | (unaryfunc) Matrix_inverted_noargs, /*nb_invert*/ | ||||
| NULL, /*nb_lshift*/ | NULL, /*nb_lshift*/ | ||||
| (binaryfunc)0, /*nb_rshift*/ | (binaryfunc)0, /*nb_rshift*/ | ||||
| NULL, /*nb_and*/ | NULL, /*nb_and*/ | ||||
| NULL, /*nb_xor*/ | NULL, /*nb_xor*/ | ||||
| NULL, /*nb_or*/ | NULL, /*nb_or*/ | ||||
| NULL, /*nb_int*/ | NULL, /*nb_int*/ | ||||
| NULL, /*nb_reserved*/ | NULL, /*nb_reserved*/ | ||||
| NULL, /*nb_float*/ | NULL, /*nb_float*/ | ||||
| NULL, /* nb_inplace_add */ | (binaryfunc) Matrix_iadd, /* nb_inplace_add */ | ||||
| NULL, /* nb_inplace_subtract */ | (binaryfunc) Matrix_isub, /* nb_inplace_subtract */ | ||||
| (binaryfunc) Matrix_imul, /* nb_inplace_multiply */ | (binaryfunc) Matrix_imul, /* nb_inplace_multiply */ | ||||
| NULL, /* nb_inplace_remainder */ | NULL, /* nb_inplace_remainder */ | ||||
| NULL, /* nb_inplace_power */ | NULL, /* nb_inplace_power */ | ||||
| NULL, /* nb_inplace_lshift */ | NULL, /* nb_inplace_lshift */ | ||||
| NULL, /* nb_inplace_rshift */ | NULL, /* nb_inplace_rshift */ | ||||
| NULL, /* nb_inplace_and */ | NULL, /* nb_inplace_and */ | ||||
| NULL, /* nb_inplace_xor */ | NULL, /* nb_inplace_xor */ | ||||
| NULL, /* nb_inplace_or */ | NULL, /* nb_inplace_or */ | ||||
| NULL, /* nb_floor_divide */ | NULL, /* nb_floor_divide */ | ||||
| NULL, /* nb_true_divide */ | (binaryfunc) Matrix_div, /* nb_true_divide */ | ||||
| NULL, /* nb_inplace_floor_divide */ | NULL, /* nb_inplace_floor_divide */ | ||||
| NULL, /* nb_inplace_true_divide */ | (binaryfunc) Matrix_idiv, /* nb_inplace_true_divide */ | ||||
| NULL, /* nb_index */ | NULL, /* nb_index */ | ||||
| (binaryfunc) Matrix_matmul, /* nb_matrix_multiply */ | (binaryfunc) Matrix_matmul, /* nb_matrix_multiply */ | ||||
| (binaryfunc) Matrix_imatmul, /* nb_inplace_matrix_multiply */ | (binaryfunc) Matrix_imatmul, /* nb_inplace_matrix_multiply */ | ||||
| }; | }; | ||||
| PyDoc_STRVAR(Matrix_translation_doc, | PyDoc_STRVAR(Matrix_translation_doc, | ||||
| "The translation component of the matrix.\n\n:type: Vector" | "The translation component of the matrix.\n\n:type: Vector" | ||||
| ); | ); | ||||
| ▲ Show 20 Lines • Show All 662 Lines • Show Last 20 Lines | |||||