14 #include "../generic/py_capi_utils.h"
15 #include "../generic/python_utildefines.h"
17 #ifndef MATH_STANDALONE
42 PyErr_SetString(PyExc_AttributeError,
44 "owner matrix has been resized since this row vector was created");
54 PyErr_SetString(PyExc_AttributeError,
56 "owner matrix has been resized since this column vector was created");
88 memcpy(mat_dst->matrix, mat_src->matrix,
sizeof(
float) * (mat_dst->
col_num * mat_dst->
row_num));
93 const int mat_size =
sizeof(
float) * (
self->col_num *
self->row_num);
94 memset(
self->matrix, 0x0, mat_size);
96 const int row_num =
self->row_num;
97 for (
int col = 0;
col < col_row_max;
col++) {
98 self->matrix[(
col * row_num) +
col] = 1.0f;
108 for (row = 0; row < mat_src->
row_num; row++) {
118 if (
self->col_num == 2) {
124 if (
self->col_num == 3) {
144 adjoint_m2_m2((
float(*)[2])mat_dst, (
const float(*)[2])mat_src);
148 adjoint_m3_m3((
float(*)[3])mat_dst, (
const float(*)[3])mat_src);
152 adjoint_m4_m4((
float(*)[4])mat_dst, (
const float(*)[4])mat_src);
162 const float *mat_src,
175 for (i = 0; i < dim; i++) {
176 for (j = 0; j < dim; j++) {
206 float *in_mat =
self->matrix;
217 switch (
self->col_num) {
221 if (in_mat !=
self->matrix) {
236 if (in_mat !=
self->matrix) {
252 if (in_mat !=
self->matrix) {
281 Py_DECREF(ret_dummy);
295 for (
int row = 0; row <
self->row_num; row++) {
296 for (
int col = 0;
col <
self->col_num;
col++) {
332 for (
col = 0;
col <
self->col_num;
col++) {
351 for (
col = 0;
col <
self->col_num;
col++) {
430 for (row = 0; row < row_num; row++) {
453 for (row = 0; row < row_num; row++) {
527 for (row = 0; row < 3; row++) {
543 for (row = 0; row < 3; row++) {
593 if (kwds && PyDict_Size(kwds)) {
594 PyErr_SetString(PyExc_TypeError,
596 "takes no keyword args");
600 switch (PyTuple_GET_SIZE(args)) {
604 PyObject *arg = PyTuple_GET_ITEM(args, 0);
609 const ushort row_num = PySequence_Size(arg);
611 if (row_num >= 2 && row_num <= 4) {
612 PyObject *item = PySequence_GetItem(arg, 0);
615 const ushort col_num = PySequence_Size(item);
618 if (col_num >= 2 && col_num <= 4) {
633 PyErr_SetString(PyExc_TypeError,
635 "expects no args or a single arg containing 2-4 numeric sequences");
647 ".. classmethod:: Identity(size)\n"
649 " Create an identity matrix.\n"
651 " :arg size: The size of the identity matrix to construct [2, 4].\n"
653 " :return: A new identity matrix.\n"
654 " :rtype: :class:`Matrix`\n");
659 if (!PyArg_ParseTuple(args,
"i:Matrix.Identity", &matSize)) {
663 if (matSize < 2 || matSize > 4) {
664 PyErr_SetString(PyExc_RuntimeError,
665 "Matrix.Identity(): "
666 "size must be between 2 and 4");
675 ".. classmethod:: Rotation(angle, size, axis)\n"
677 " Create a matrix representing a rotation.\n"
679 " :arg angle: The angle of rotation desired, in radians.\n"
680 " :type angle: float\n"
681 " :arg size: The size of the rotation matrix to construct [2, 4].\n"
683 " :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object\n"
684 " (optional when size is 2).\n"
685 " :type axis: string or :class:`Vector`\n"
686 " :return: A new rotation matrix.\n"
687 " :rtype: :class:`Matrix`\n");
690 PyObject *vec =
NULL;
691 const char *axis =
NULL;
694 float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
696 if (!PyArg_ParseTuple(args,
"di|O:Matrix.Rotation", &
angle, &matSize, &vec)) {
700 if (vec && PyUnicode_Check(vec)) {
701 axis = PyUnicode_AsUTF8((PyObject *)vec);
702 if (axis ==
NULL || axis[0] ==
'\0' || axis[1] !=
'\0' || axis[0] <
'X' || axis[0] >
'Z') {
703 PyErr_SetString(PyExc_ValueError,
704 "Matrix.Rotation(): "
705 "3rd argument axis value must be a 3D vector "
706 "or a string in 'X', 'Y', 'Z'");
716 if (!
ELEM(matSize, 2, 3, 4)) {
717 PyErr_SetString(PyExc_ValueError,
718 "Matrix.Rotation(): "
719 "can only return a 2x2 3x3 or 4x4 matrix");
722 if (matSize == 2 && (vec !=
NULL)) {
723 PyErr_SetString(PyExc_ValueError,
724 "Matrix.Rotation(): "
725 "cannot create a 2x2 rotation matrix around arbitrary axis");
728 if ((
ELEM(matSize, 3, 4)) && (axis ==
NULL) && (vec ==
NULL)) {
729 PyErr_SetString(PyExc_ValueError,
730 "Matrix.Rotation(): "
731 "axis of rotation for 3d and 4d matrices is required");
740 tvec, 3, 3, vec,
"Matrix.Rotation(angle, size, axis), invalid 'axis' arg") == -1) {
746 else if (matSize == 2) {
763 ".. classmethod:: Translation(vector)\n"
765 " Create a matrix representing a translation.\n"
767 " :arg vector: The translation vector.\n"
768 " :type vector: :class:`Vector`\n"
769 " :return: An identity matrix with a translation.\n"
770 " :rtype: :class:`Matrix`\n");
778 mat[3], 3, 4, value,
"mathutils.Matrix.Translation(vector), invalid vector arg") == -1) {
786 ".. classmethod:: Diagonal(vector)\n"
788 " Create a diagonal (scaling) matrix using the values from the vector.\n"
790 " :arg vector: The vector of values for the diagonal.\n"
791 " :type vector: :class:`Vector`\n"
792 " :return: A diagonal matrix.\n"
793 " :rtype: :class:`Matrix`\n");
797 float mat[16] = {0.0f};
801 vec, 2, 4, value,
"mathutils.Matrix.Diagonal(vector), invalid vector arg");
807 for (
int i = 0; i <
size; i++) {
808 mat[
size * i + i] = vec[i];
816 ".. classmethod:: Scale(factor, size, axis)\n"
818 " Create a matrix representing a scaling.\n"
820 " :arg factor: The factor of scaling to apply.\n"
821 " :type factor: float\n"
822 " :arg size: The size of the scale matrix to construct [2, 4].\n"
824 " :arg axis: Direction to influence scale. (optional).\n"
825 " :type axis: :class:`Vector`\n"
826 " :return: A new scale matrix.\n"
827 " :rtype: :class:`Matrix`\n");
830 PyObject *vec =
NULL;
835 float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
837 if (!PyArg_ParseTuple(args,
"fi|O:Matrix.Scale", &factor, &matSize, &vec)) {
840 if (!
ELEM(matSize, 2, 3, 4)) {
841 PyErr_SetString(PyExc_ValueError,
843 "can only return a 2x2 3x3 or 4x4 matrix");
847 vec_num = (matSize == 2 ? 2 : 3);
849 tvec, vec_num, vec_num, vec,
"Matrix.Scale(factor, size, axis), invalid 'axis' arg") ==
870 for (
x = 0;
x < vec_num;
x++) {
871 norm += tvec[
x] * tvec[
x];
874 for (
x = 0;
x < vec_num;
x++) {
878 mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
879 mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
880 mat[2] = ((factor - 1) * (tvec[0] * tvec[1]));
881 mat[3] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
884 mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
885 mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
886 mat[2] = ((factor - 1) * (tvec[0] * tvec[2]));
887 mat[3] = ((factor - 1) * (tvec[0] * tvec[1]));
888 mat[4] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
889 mat[5] = ((factor - 1) * (tvec[1] * tvec[2]));
890 mat[6] = ((factor - 1) * (tvec[0] * tvec[2]));
891 mat[7] = ((factor - 1) * (tvec[1] * tvec[2]));
892 mat[8] = 1 + ((factor - 1) * (tvec[2] * tvec[2]));
903 ".. classmethod:: OrthoProjection(axis, size)\n"
905 " Create a matrix to represent an orthographic projection.\n"
907 " :arg axis: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
908 " where a single axis is for a 2D matrix.\n"
909 " Or a vector for an arbitrary axis\n"
910 " :type axis: string or :class:`Vector`\n"
911 " :arg size: The size of the projection matrix to construct [2, 4].\n"
913 " :return: A new projection matrix.\n"
914 " :rtype: :class:`Matrix`\n");
921 float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
923 if (!PyArg_ParseTuple(args,
"Oi:Matrix.OrthoProjection", &axis, &matSize)) {
926 if (!
ELEM(matSize, 2, 3, 4)) {
927 PyErr_SetString(PyExc_ValueError,
928 "Matrix.OrthoProjection(): "
929 "can only return a 2x2 3x3 or 4x4 matrix");
933 if (PyUnicode_Check(axis)) {
934 Py_ssize_t plane_len;
935 const char *plane = PyUnicode_AsUTF8AndSize(axis, &plane_len);
937 if (plane_len == 1 && plane[0] ==
'X') {
940 else if (plane_len == 1 && plane[0] ==
'Y') {
944 PyErr_Format(PyExc_ValueError,
945 "Matrix.OrthoProjection(): "
946 "unknown plane, expected: X, Y, not '%.200s'",
952 if (plane_len == 2 && plane[0] ==
'X' && plane[1] ==
'Y') {
956 else if (plane_len == 2 && plane[0] ==
'X' && plane[1] ==
'Z') {
960 else if (plane_len == 2 && plane[0] ==
'Y' && plane[1] ==
'Z') {
965 PyErr_Format(PyExc_ValueError,
966 "Matrix.OrthoProjection(): "
967 "unknown plane, expected: XY, XZ, YZ, not '%.200s'",
976 const int vec_num = (matSize == 2 ? 2 : 3);
983 "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) {
988 for (
x = 0;
x < vec_num;
x++) {
989 norm += tvec[
x] * tvec[
x];
992 for (
x = 0;
x < vec_num;
x++) {
996 mat[0] = 1 - (tvec[0] * tvec[0]);
997 mat[1] = -(tvec[0] * tvec[1]);
998 mat[2] = -(tvec[0] * tvec[1]);
999 mat[3] = 1 - (tvec[1] * tvec[1]);
1001 else if (matSize > 2) {
1002 mat[0] = 1 - (tvec[0] * tvec[0]);
1003 mat[1] = -(tvec[0] * tvec[1]);
1004 mat[2] = -(tvec[0] * tvec[2]);
1005 mat[3] = -(tvec[0] * tvec[1]);
1006 mat[4] = 1 - (tvec[1] * tvec[1]);
1007 mat[5] = -(tvec[1] * tvec[2]);
1008 mat[6] = -(tvec[0] * tvec[2]);
1009 mat[7] = -(tvec[1] * tvec[2]);
1010 mat[8] = 1 - (tvec[2] * tvec[2]);
1022 ".. classmethod:: Shear(plane, size, factor)\n"
1024 " Create a matrix to represent an shear transformation.\n"
1026 " :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
1027 " where a single axis is for a 2D matrix only.\n"
1028 " :type plane: string\n"
1029 " :arg size: The size of the shear matrix to construct [2, 4].\n"
1030 " :type size: int\n"
1031 " :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix\n"
1032 " pass a pair of floats corresponding with the *plane* axis.\n"
1033 " :type factor: float or float pair\n"
1034 " :return: A new shear matrix.\n"
1035 " :rtype: :class:`Matrix`\n");
1041 float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
1043 if (!PyArg_ParseTuple(args,
"siO:Matrix.Shear", &plane, &matSize, &fac)) {
1046 if (!
ELEM(matSize, 2, 3, 4)) {
1047 PyErr_SetString(PyExc_ValueError,
1049 "can only return a 2x2 3x3 or 4x4 matrix");
1054 float const factor = PyFloat_AsDouble(fac);
1056 if (factor == -1.0f && PyErr_Occurred()) {
1057 PyErr_SetString(PyExc_TypeError,
1059 "the factor to be a float");
1067 if (
STREQ(plane,
"X")) {
1070 else if (
STREQ(plane,
"Y")) {
1074 PyErr_SetString(PyExc_ValueError,
1076 "expected: X, Y or wrong matrix size for shearing plane");
1093 if (
STREQ(plane,
"XY")) {
1097 else if (
STREQ(plane,
"XZ")) {
1101 else if (
STREQ(plane,
"YZ")) {
1106 PyErr_SetString(PyExc_ValueError,
1108 "expected: X, Y, XY, XZ, YZ");
1121 C_Matrix_LocRotScale_doc,
1122 ".. classmethod:: LocRotScale(location, rotation, scale)\n"
1124 " Create a matrix combining translation, rotation and scale,\n"
1125 " acting as the inverse of the decompose() method.\n"
1127 " Any of the inputs may be replaced with None if not needed.\n"
1129 " :arg location: The translation component.\n"
1130 " :type location: :class:`Vector` or None\n"
1131 " :arg rotation: The rotation component.\n"
1132 " :type rotation: 3x3 :class:`Matrix`, :class:`Quaternion`, :class:`Euler` or None\n"
1133 " :arg scale: The scale component.\n"
1134 " :type scale: :class:`Vector` or None\n"
1135 " :return: Combined transformation matrix. \n"
1136 " :rtype: 4x4 :class:`Matrix`\n");
1139 PyObject *loc_obj, *rot_obj, *scale_obj;
1140 float mat[4][4], loc[3];
1142 if (!PyArg_ParseTuple(args,
"OOO:Matrix.LocRotScale", &loc_obj, &rot_obj, &scale_obj)) {
1147 if (loc_obj == Py_None) {
1151 loc, 3, 3, loc_obj,
"Matrix.LocRotScale(), invalid location argument") == -1) {
1156 if (rot_obj == Py_None) {
1185 copy_m4_m3(mat, (
const float(*)[3])mat_obj->matrix);
1188 PyErr_SetString(PyExc_ValueError,
1189 "Matrix.LocRotScale(): "
1190 "inappropriate rotation matrix size - expects 3x3 matrix");
1195 PyErr_SetString(PyExc_ValueError,
1196 "Matrix.LocRotScale(): "
1197 "rotation argument must be Matrix, Quaternion, Euler or None");
1202 if (scale_obj != Py_None) {
1206 scale, 3, 3, scale_obj,
"Matrix.LocRotScale(), invalid scale argument") == -1) {
1225 ".. method:: to_quaternion()\n"
1227 " Return a quaternion representation of the rotation matrix.\n"
1229 " :return: Quaternion representation of the rotation matrix.\n"
1230 " :rtype: :class:`Quaternion`\n");
1240 if ((
self->row_num < 3) || (
self->col_num < 3) || (
self->row_num !=
self->col_num)) {
1241 PyErr_SetString(PyExc_ValueError,
1242 "Matrix.to_quat(): "
1243 "inappropriate matrix size - expects 3x3 or 4x4 matrix");
1247 if (
self->row_num == 3) {
1269 ".. method:: to_euler(order, euler_compat)\n"
1271 " Return an Euler representation of the rotation matrix\n"
1272 " (3x3 or 4x4 matrix only).\n"
1274 " :arg order: Optional rotation order argument in\n"
1275 " ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
1276 " :type order: string\n"
1277 " :arg euler_compat: Optional euler argument the new euler will be made\n"
1278 " compatible with (no axis flipping between them).\n"
1279 " Useful for converting a series of matrices to animation curves.\n"
1280 " :type euler_compat: :class:`Euler`\n"
1281 " :return: Euler representation of the matrix.\n"
1282 " :rtype: :class:`Euler`\n");
1285 const char *order_str =
NULL;
1287 float eul[3], eul_compatf[3];
1296 if (!PyArg_ParseTuple(args,
"|sO!:to_euler", &order_str, &
euler_Type, &eul_compat)) {
1309 if (
self->row_num == 3 &&
self->col_num == 3) {
1312 else if (
self->row_num == 4 &&
self->col_num == 4) {
1316 PyErr_SetString(PyExc_ValueError,
1317 "Matrix.to_euler(): "
1318 "inappropriate matrix size - expects 3x3 or 4x4 matrix");
1359 ".. method:: resize_4x4()\n"
1361 " Resize the matrix to 4x4.\n");
1368 PyErr_SetString(PyExc_ValueError,
1369 "Matrix.resize_4x4(): "
1370 "cannot resize wrapped data - make a copy and resize that");
1373 if (
self->cb_user) {
1374 PyErr_SetString(PyExc_ValueError,
1375 "Matrix.resize_4x4(): "
1376 "cannot resize owned data - make a copy and resize that");
1382 PyErr_SetString(PyExc_MemoryError,
1383 "Matrix.resize_4x4(): "
1384 "problem allocating pointer space");
1390 for (
col = 0;
col <
self->col_num;
col++) {
1410 const int mat_size =
sizeof(
float) * (col_num * row_num);
1412 PyMem_Malloc(mat_size), col_num, row_num, Py_TYPE(
self));
1414 if ((
self->row_num == row_num) && (
self->col_num == col_num)) {
1415 memcpy(pymat->matrix,
self->matrix, mat_size);
1418 if ((
self->col_num < col_num) || (
self->row_num < row_num)) {
1421 const int col_len_src =
min_ii(col_num,
self->col_num);
1422 const int row_len_src =
min_ii(row_num,
self->row_num);
1423 for (
int col = 0;
col < col_len_src;
col++) {
1428 return (PyObject *)pymat;
1432 ".. method:: to_2x2()\n"
1434 " Return a 2x2 copy of this matrix.\n"
1436 " :return: a new matrix.\n"
1437 " :rtype: :class:`Matrix`\n");
1447 ".. method:: to_3x3()\n"
1449 " Return a 3x3 copy of this matrix.\n"
1451 " :return: a new matrix.\n"
1452 " :rtype: :class:`Matrix`\n");
1462 ".. method:: to_4x4()\n"
1464 " Return a 4x4 copy of this matrix.\n"
1466 " :return: a new matrix.\n"
1467 " :rtype: :class:`Matrix`\n");
1484 ".. method:: to_translation()\n"
1486 " Return the translation part of a 4 row matrix.\n"
1488 " :return: Return the translation of a matrix.\n"
1489 " :rtype: :class:`Vector`\n");
1496 if ((
self->row_num < 3) ||
self->col_num < 4) {
1497 PyErr_SetString(PyExc_ValueError,
1498 "Matrix.to_translation(): "
1499 "inappropriate matrix size");
1507 ".. method:: to_scale()\n"
1509 " Return the scale part of a 3x3 or 4x4 matrix.\n"
1511 " :return: Return the scale of a matrix.\n"
1512 " :rtype: :class:`Vector`\n"
1514 " .. note:: This method does not return a negative scale on any axis because it is "
1515 "not possible to obtain this data from the matrix alone.\n");
1527 if ((
self->row_num < 3) || (
self->col_num < 3)) {
1528 PyErr_SetString(PyExc_ValueError,
1529 "Matrix.to_scale(): "
1530 "inappropriate matrix size, 3x3 minimum size");
1551 if (
self->col_num !=
self->row_num) {
1552 PyErr_SetString(PyExc_ValueError,
1553 "Matrix.invert(ed): "
1554 "only square matrices are supported");
1563 switch (PyTuple_GET_SIZE(args)) {
1570 PyErr_SetString(PyExc_TypeError,
1572 "expects a matrix argument or nothing");
1577 PyErr_SetString(PyExc_TypeError,
1579 "matrix argument has different dimensions");
1586 PyErr_SetString(PyExc_ValueError,
1587 "Matrix.invert(ed): "
1588 "takes at most one argument");
1595 PyErr_SetString(PyExc_ValueError,
1596 "Matrix.invert(ed): "
1597 "matrix does not have an inverse");
1602 ".. method:: invert(fallback=None)\n"
1604 " Set the matrix to its inverse.\n"
1606 " :arg fallback: Set the matrix to this value when the inverse cannot be calculated\n"
1607 " (instead of raising a :exc:`ValueError` exception).\n"
1608 " :type fallback: :class:`Matrix`\n"
1610 " .. seealso:: `Inverse matrix <https://en.wikipedia.org/wiki/Inverse_matrix>`__ on "
1630 if (PyTuple_GET_SIZE(args) == 1) {
1637 if (
self != fallback) {
1652 ".. method:: inverted(fallback=None)\n"
1654 " Return an inverted copy of the matrix.\n"
1656 " :arg fallback: return this when the inverse can't be calculated\n"
1657 " (instead of raising a :exc:`ValueError`).\n"
1658 " :type fallback: any\n"
1659 " :return: the inverted matrix or fallback when given.\n"
1660 " :rtype: :class:`Matrix`\n");
1681 if (PyTuple_GET_SIZE(args) == 1) {
1682 PyObject *fallback = PyTuple_GET_ITEM(args, 0);
1683 Py_INCREF(fallback);
1717 Matrix_invert_safe_doc,
1718 ".. method:: invert_safe()\n"
1720 " Set the matrix to its inverse, will never error.\n"
1721 " If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, "
1722 "to get an invertible one.\n"
1723 " If tweaked matrix is still degenerated, set to the identity matrix instead.\n"
1725 " .. seealso:: `Inverse Matrix <https://en.wikipedia.org/wiki/Inverse_matrix>`__ on "
1744 ".. method:: inverted_safe()\n"
1746 " Return an inverted copy of the matrix, will never error.\n"
1747 " If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, "
1748 "to get an invertible one.\n"
1749 " If tweaked matrix is still degenerated, return the identity matrix instead.\n"
1751 " :return: the inverted matrix.\n"
1752 " :rtype: :class:`Matrix`\n");
1777 Matrix_adjugate_doc,
1778 ".. method:: adjugate()\n"
1780 " Set the matrix to its adjugate.\n"
1782 " :raises ValueError: if the matrix cannot be adjugate.\n"
1784 " .. seealso:: `Adjugate matrix <https://en.wikipedia.org/wiki/Adjugate_matrix>`__ on "
1792 if (
self->col_num !=
self->row_num) {
1793 PyErr_SetString(PyExc_ValueError,
1794 "Matrix.adjugate(d): "
1795 "only square matrices are supported");
1800 if (
self->col_num <= 4) {
1805 PyExc_ValueError,
"Matrix adjugate(d): size (%d) unsupported", (
int)
self->col_num);
1814 ".. method:: adjugated()\n"
1816 " Return an adjugated copy of the matrix.\n"
1818 " :return: the adjugated matrix.\n"
1819 " :rtype: :class:`Matrix`\n"
1820 " :raises ValueError: if the matrix cannot be adjugated\n");
1828 ".. method:: rotate(other)\n"
1830 " Rotates the matrix by another mathutils value.\n"
1832 " :arg other: rotation component of mathutils value\n"
1833 " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
1835 " .. note:: If any of the columns are not unit length this may not have desired results.\n");
1838 float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
1848 if (
self->row_num != 3 ||
self->col_num != 3) {
1849 PyErr_SetString(PyExc_ValueError,
1851 "must have 3x3 dimensions");
1871 ".. method:: decompose()\n"
1873 " Return the translation, rotation, and scale components of this matrix.\n"
1875 " :return: tuple of translation, rotation, and scale\n"
1876 " :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)");
1885 if (
self->row_num != 4 ||
self->col_num != 4) {
1886 PyErr_SetString(PyExc_ValueError,
1887 "Matrix.decompose(): "
1888 "inappropriate matrix size - expects 4x4 matrix");
1899 ret = PyTuple_New(3);
1914 ".. function:: lerp(other, factor)\n"
1916 " Returns the interpolation of two matrices. Uses polar decomposition, see"
1917 " \"Matrix Animation and Polar Decomposition\", Shoemake and Duff, 1992.\n"
1919 " :arg other: value to interpolate with.\n"
1920 " :type other: :class:`Matrix`\n"
1921 " :arg factor: The interpolation value in [0.0, 1.0].\n"
1922 " :type factor: float\n"
1923 " :return: The interpolated matrix.\n"
1924 " :rtype: :class:`Matrix`\n");
1930 if (!PyArg_ParseTuple(args,
"O!f:lerp", &
matrix_Type, &mat2, &fac)) {
1935 PyErr_SetString(PyExc_ValueError,
1937 "expects both matrix objects of the same dimensions");
1946 if (
self->col_num == 4 &&
self->row_num == 4) {
1947 #ifdef MATH_STANDALONE
1948 blend_m4_m4m4((
float(*)[4])mat, (
float(*)[4])
self->matrix, (
float(*)[4])mat2->matrix, fac);
1950 interp_m4_m4m4((
float(*)[4])mat, (
float(*)[4])
self->matrix, (
float(*)[4])mat2->matrix, fac);
1953 else if (
self->col_num == 3 &&
self->row_num == 3) {
1954 #ifdef MATH_STANDALONE
1955 blend_m3_m3m3((
float(*)[3])mat, (
float(*)[3])
self->matrix, (
float(*)[3])mat2->matrix, fac);
1957 interp_m3_m3m3((
float(*)[3])mat, (
float(*)[3])
self->matrix, (
float(*)[3])mat2->matrix, fac);
1961 PyErr_SetString(PyExc_ValueError,
1963 "only 3x3 and 4x4 matrices supported");
1971 Matrix_determinant_doc,
1972 ".. method:: determinant()\n"
1974 " Return the determinant of a matrix.\n"
1976 " :return: Return the determinant of a matrix.\n"
1979 " .. seealso:: `Determinant <https://en.wikipedia.org/wiki/Determinant>`__ on Wikipedia.\n");
1986 if (
self->col_num !=
self->row_num) {
1987 PyErr_SetString(PyExc_ValueError,
1988 "Matrix.determinant(): "
1989 "only square matrices are supported");
2003 Matrix_transpose_doc,
2004 ".. method:: transpose()\n"
2006 " Set the matrix to its transpose.\n"
2008 " .. seealso:: `Transpose <https://en.wikipedia.org/wiki/Transpose>`__ on Wikipedia.\n");
2015 if (
self->col_num !=
self->row_num) {
2016 PyErr_SetString(PyExc_ValueError,
2017 "Matrix.transpose(d): "
2018 "only square matrices are supported");
2022 if (
self->col_num == 2) {
2027 else if (
self->col_num == 3) {
2039 ".. method:: transposed()\n"
2041 " Return a new, transposed matrix.\n"
2043 " :return: a transposed matrix\n"
2044 " :rtype: :class:`Matrix`\n");
2057 ".. method:: normalize()\n"
2059 " Normalize each of the matrix columns.\n");
2066 if (
self->col_num !=
self->row_num) {
2067 PyErr_SetString(PyExc_ValueError,
2068 "Matrix.normalize(): "
2069 "only square matrices are supported");
2073 if (
self->col_num == 3) {
2076 else if (
self->col_num == 4) {
2080 PyErr_SetString(PyExc_ValueError,
2081 "Matrix.normalize(): "
2082 "can only use a 3x3 or 4x4 matrix");
2090 ".. method:: normalized()\n"
2092 " Return a column normalized matrix\n"
2094 " :return: a column normalized matrix\n"
2095 " :rtype: :class:`Matrix`\n");
2108 ".. method:: zero()\n"
2110 " Set all the matrix values to zero.\n"
2112 " :rtype: :class:`Matrix`\n");
2138 if (
self->col_num == 2) {
2141 else if (
self->col_num == 3) {
2150 ".. method:: identity()\n"
2152 " Set the matrix to the identity matrix.\n"
2154 " .. note:: An object with a location and rotation of zero, and a scale of one\n"
2155 " will have an identity matrix.\n"
2157 " .. seealso:: `Identity matrix <https://en.wikipedia.org/wiki/Identity_matrix>`__ "
2165 if (
self->col_num !=
self->row_num) {
2166 PyErr_SetString(PyExc_ValueError,
2167 "Matrix.identity(): "
2168 "only square matrices are supported");
2194 ".. method:: copy()\n"
2196 " Returns a copy of this matrix.\n"
2198 " :return: an instance of itself\n"
2199 " :rtype: :class:`Matrix`\n");
2233 for (row = 0; row <
self->row_num; row++) {
2234 rows[row] = PyTuple_New(
self->col_num);
2235 for (
col = 0;
col <
self->col_num;
col++) {
2236 PyTuple_SET_ITEM(rows[row],
col, PyFloat_FromDouble(
MATRIX_ITEM(
self, row,
col)));
2239 switch (
self->row_num) {
2241 return PyUnicode_FromFormat(
2248 return PyUnicode_FromFormat(
2257 return PyUnicode_FromFormat(
2268 Py_FatalError(
"Matrix(): invalid row size!");
2272 #ifndef MATH_STANDALONE
2289 for (
col = 0;
col <
self->col_num;
col++) {
2291 for (row = 0; row <
self->row_num; row++) {
2293 dummy_buf,
sizeof(dummy_buf),
"%.4f",
MATRIX_ITEM(
self, row,
col));
2300 for (row = 0; row <
self->row_num; row++) {
2301 for (
col = 0;
col <
self->col_num;
col++) {
2342 res = ok ? Py_False : Py_True;
2349 res = Py_NotImplemented;
2352 PyErr_BadArgument();
2356 return Py_INCREF_RET(res);
2391 return self->row_num;
2404 if (row < 0 || row >=
self->row_num) {
2405 PyErr_SetString(PyExc_IndexError,
2406 "matrix[attribute]: "
2407 "array index out of range");
2423 if (col < 0 || col >=
self->col_num) {
2424 PyErr_SetString(PyExc_IndexError,
2425 "matrix[attribute]: "
2426 "array index out of range");
2442 if (row >=
self->row_num || row < 0) {
2443 PyErr_SetString(PyExc_IndexError,
"matrix[attribute] = x: bad row");
2448 vec,
self->col_num,
self->col_num, value,
"matrix[i] = value assignment") == -1) {
2453 for (
col = 0;
col <
self->col_num;
col++) {
2471 PyErr_SetString(PyExc_IndexError,
"matrix[attribute] = x: bad col");
2476 vec,
self->row_num,
self->row_num, value,
"matrix[i] = value assignment") == -1) {
2481 for (row = 0; row <
self->row_num; row++) {
2502 begin =
MIN2(begin, end);
2504 tuple = PyTuple_New(end - begin);
2506 PyTuple_SET_ITEM(tuple,
2518 PyObject *value_fast;
2526 begin =
MIN2(begin, end);
2529 if (!(value_fast = PySequence_Fast(value,
"matrix[begin:end] = value"))) {
2534 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
2535 const int size = end - begin;
2540 if (PySequence_Fast_GET_SIZE(value_fast) !=
size) {
2541 Py_DECREF(value_fast);
2542 PyErr_SetString(PyExc_ValueError,
2543 "matrix[begin:end] = []: "
2544 "size mismatch in slice assignment");
2548 memcpy(mat,
self->matrix,
self->col_num *
self->row_num *
sizeof(
float));
2551 for (row = begin; row < end; row++) {
2553 PyObject *item = value_fast_items[row - begin];
2556 vec,
self->col_num,
self->col_num, item,
"matrix[begin:end] = value assignment") ==
2558 Py_DECREF(value_fast);
2562 for (
col = 0;
col <
self->col_num;
col++) {
2563 mat[
col *
self->row_num + row] = vec[
col];
2567 Py_DECREF(value_fast);
2570 memcpy(
self->matrix, mat,
self->col_num *
self->row_num *
sizeof(
float));
2579 if (PyIndex_Check(item)) {
2581 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2582 if (i == -1 && PyErr_Occurred()) {
2590 if (PySlice_Check(item)) {
2591 Py_ssize_t start, stop, step, slicelength;
2593 if (PySlice_GetIndicesEx(item,
self->row_num, &start, &stop, &step, &slicelength) < 0) {
2597 if (slicelength <= 0) {
2598 return PyTuple_New(0);
2604 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with matrices");
2609 PyExc_TypeError,
"matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
2616 if (PyIndex_Check(item)) {
2617 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2618 if (i == -1 && PyErr_Occurred()) {
2626 if (PySlice_Check(item)) {
2627 Py_ssize_t start, stop, step, slicelength;
2629 if (PySlice_GetIndicesEx(item,
self->row_num, &start, &stop, &step, &slicelength) < 0) {
2637 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with matrices");
2642 PyExc_TypeError,
"matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
2662 PyErr_Format(PyExc_TypeError,
2663 "Matrix addition: (%s + %s) "
2664 "invalid type for this operation",
2665 Py_TYPE(m1)->tp_name,
2666 Py_TYPE(m2)->tp_name);
2674 if (mat1->
col_num != mat2->col_num || mat1->
row_num != mat2->row_num) {
2675 PyErr_SetString(PyExc_ValueError,
2677 "matrices must have the same dimensions for this operation");
2696 PyErr_Format(PyExc_TypeError,
2697 "Matrix subtraction: (%s - %s) "
2698 "invalid type for this operation",
2699 Py_TYPE(m1)->tp_name,
2700 Py_TYPE(m2)->tp_name);
2708 if (mat1->
col_num != mat2->col_num || mat1->
row_num != mat2->row_num) {
2709 PyErr_SetString(PyExc_ValueError,
2711 "matrices must have the same dimensions for this operation");
2751 if ((mat1->
row_num != mat2->row_num) || (mat1->
col_num != mat2->col_num)) {
2752 PyErr_SetString(PyExc_ValueError,
2753 "matrix1 * matrix2: matrix1 number of rows/columns "
2754 "and the matrix2 number of rows/columns must be the same");
2764 if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) {
2770 if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) {
2775 PyErr_Format(PyExc_TypeError,
2776 "Element-wise multiplication: "
2777 "not supported between '%.200s' and '%.200s' types",
2778 Py_TYPE(m1)->tp_name,
2779 Py_TYPE(m2)->tp_name);
2805 if ((mat1->
row_num != mat2->row_num) || (mat1->
col_num != mat2->col_num)) {
2806 PyErr_SetString(PyExc_ValueError,
2807 "matrix1 *= matrix2: matrix1 number of rows/columns "
2808 "and the matrix2 number of rows/columns must be the same");
2814 else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) {
2819 PyErr_Format(PyExc_TypeError,
2820 "In place element-wise multiplication: "
2821 "not supported between '%.200s' and '%.200s' types",
2822 Py_TYPE(m1)->tp_name,
2823 Py_TYPE(m2)->tp_name);
2858 if (mat1->
col_num != mat2->row_num) {
2859 PyErr_SetString(PyExc_ValueError,
2860 "matrix1 * matrix2: matrix1 number of columns "
2861 "and the matrix2 number of rows must be the same");
2865 for (
col = 0;
col < mat2->col_num;
col++) {
2866 for (row = 0; row < mat1->
row_num; row++) {
2868 for (item = 0; item < mat1->
col_num; item++) {
2900 PyErr_Format(PyExc_TypeError,
2901 "Matrix multiplication: "
2902 "not supported between '%.200s' and '%.200s' types",
2903 Py_TYPE(m1)->tp_name,
2904 Py_TYPE(m2)->tp_name);
2931 if (mat1->
col_num != mat2->row_num) {
2932 PyErr_SetString(PyExc_ValueError,
2933 "matrix1 * matrix2: matrix1 number of columns "
2934 "and the matrix2 number of rows must be the same");
2938 for (
col = 0;
col < mat2->col_num;
col++) {
2939 for (row = 0; row < mat1->
row_num; row++) {
2941 for (item = 0; item < mat1->
col_num; item++) {
2951 memcpy(mat1->matrix, mat, (mat1->
row_num * mat1->
col_num) *
sizeof(
float));
2954 PyErr_Format(PyExc_TypeError,
2955 "In place matrix multiplication: "
2956 "not supported between '%.200s' and '%.200s' types",
2957 Py_TYPE(m1)->tp_name,
2958 Py_TYPE(m2)->tp_name);
2978 (ssizessizeargfunc)
NULL,
2980 (ssizessizeobjargproc)
NULL,
3037 PyDoc_STRVAR(Matrix_translation_doc,
"The translation component of the matrix.\n\n:type: Vector");
3047 if (
self->row_num != 4 ||
self->col_num != 4) {
3048 PyErr_SetString(PyExc_AttributeError,
3049 "Matrix.translation: "
3050 "inappropriate matrix size, must be 4x4");
3069 if (
self->row_num != 4 ||
self->col_num != 4) {
3070 PyErr_SetString(PyExc_AttributeError,
3071 "Matrix.translation: "
3072 "inappropriate matrix size, must be 4x4");
3088 "Access the matrix by rows (default), (read-only).\n\n:type: Matrix Access");
3096 "Access the matrix by columns, 3x3 and 4x4 only, (read-only).\n\n:type: Matrix Access");
3103 "The average scale applied to each axis (read-only).\n\n:type: float");
3113 if ((
self->row_num < 3) || (
self->col_num < 3)) {
3114 PyErr_SetString(PyExc_AttributeError,
3115 "Matrix.median_scale: "
3116 "inappropriate matrix size, 3x3 minimum");
3126 "True if this is an identity matrix (read-only).\n\n:type: bool");
3136 "True if this matrix results in a negative scale, 3x3 and 4x4 only, "
3137 "(read-only).\n\n:type: bool");
3145 if (
self->row_num == 4 &&
self->col_num == 4) {
3148 if (
self->row_num == 3 &&
self->col_num == 3) {
3152 PyErr_SetString(PyExc_AttributeError,
3153 "Matrix.is_negative: "
3154 "inappropriate matrix size - expects 3x3 or 4x4 matrix");
3159 "True if this matrix is orthogonal, 3x3 and 4x4 only, (read-only).\n\n:type: bool");
3167 if (
self->row_num == 4 &&
self->col_num == 4) {
3170 if (
self->row_num == 3 &&
self->col_num == 3) {
3174 PyErr_SetString(PyExc_AttributeError,
3175 "Matrix.is_orthogonal: "
3176 "inappropriate matrix size - expects 3x3 or 4x4 matrix");
3181 "True if this matrix has got orthogonal axis vectors, 3x3 and 4x4 only, "
3182 "(read-only).\n\n:type: bool");
3190 if (
self->row_num == 4 &&
self->col_num == 4) {
3193 if (
self->row_num == 3 &&
self->col_num == 3) {
3197 PyErr_SetString(PyExc_AttributeError,
3198 "Matrix.is_orthogonal_axis_vectors: "
3199 "inappropriate matrix size - expects 3x3 or 4x4 matrix");
3214 Matrix_translation_doc,
3223 Matrix_is_orthogonal_doc,
3225 {
"is_orthogonal_axis_vectors",
3228 Matrix_is_orthogonal_axis_vectors_doc,
3257 {
"determinant", (PyCFunction)
Matrix_determinant, METH_NOARGS, Matrix_determinant_doc},
3258 {
"decompose", (PyCFunction)
Matrix_decompose, METH_NOARGS, Matrix_decompose_doc},
3261 {
"zero", (PyCFunction)
Matrix_zero, METH_NOARGS, Matrix_zero_doc},
3262 {
"identity", (PyCFunction)
Matrix_identity, METH_NOARGS, Matrix_identity_doc},
3265 {
"transpose", (PyCFunction)
Matrix_transpose, METH_NOARGS, Matrix_transpose_doc},
3266 {
"transposed", (PyCFunction)
Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
3267 {
"normalize", (PyCFunction)
Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
3268 {
"normalized", (PyCFunction)
Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
3269 {
"invert", (PyCFunction)
Matrix_invert, METH_VARARGS, Matrix_invert_doc},
3270 {
"inverted", (PyCFunction)
Matrix_inverted, METH_VARARGS, Matrix_inverted_doc},
3271 {
"invert_safe", (PyCFunction)
Matrix_invert_safe, METH_NOARGS, Matrix_invert_safe_doc},
3273 {
"adjugate", (PyCFunction)
Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
3274 {
"adjugated", (PyCFunction)
Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc},
3275 {
"to_2x2", (PyCFunction)
Matrix_to_2x2, METH_NOARGS, Matrix_to_2x2_doc},
3276 {
"to_3x3", (PyCFunction)
Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
3277 {
"to_4x4", (PyCFunction)
Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc},
3279 {
"resize_4x4", (PyCFunction)
Matrix_resize_4x4, METH_NOARGS, Matrix_resize_4x4_doc},
3280 {
"rotate", (PyCFunction)
Matrix_rotate, METH_O, Matrix_rotate_doc},
3283 {
"to_euler", (PyCFunction)
Matrix_to_euler, METH_VARARGS, Matrix_to_euler_doc},
3285 {
"to_scale", (PyCFunction)
Matrix_to_scale, METH_NOARGS, Matrix_to_scale_doc},
3289 {
"lerp", (PyCFunction)
Matrix_lerp, METH_VARARGS, Matrix_lerp_doc},
3290 {
"copy", (PyCFunction)
Matrix_copy, METH_NOARGS, Matrix_copy_doc},
3291 {
"__copy__", (PyCFunction)
Matrix_copy, METH_NOARGS, Matrix_copy_doc},
3292 {
"__deepcopy__", (PyCFunction)
Matrix_deepcopy, METH_VARARGS, Matrix_copy_doc},
3298 {
"Identity", (PyCFunction)
C_Matrix_Identity, METH_VARARGS | METH_CLASS, C_Matrix_Identity_doc},
3299 {
"Rotation", (PyCFunction)
C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc},
3300 {
"Scale", (PyCFunction)
C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc},
3301 {
"Shear", (PyCFunction)
C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc},
3302 {
"Diagonal", (PyCFunction)
C_Matrix_Diagonal, METH_O | METH_CLASS, C_Matrix_Diagonal_doc},
3305 METH_O | METH_CLASS,
3306 C_Matrix_Translation_doc},
3309 METH_VARARGS | METH_CLASS,
3310 C_Matrix_OrthoProjection_doc},
3313 METH_VARARGS | METH_CLASS,
3314 C_Matrix_LocRotScale_doc},
3326 ".. class:: Matrix([rows])\n"
3328 " This object gives access to Matrices in Blender, supporting square and rectangular\n"
3329 " matrices from 2x2 up to 4x4.\n"
3331 " :param rows: Sequence of rows.\n"
3332 " When omitted, a 4x4 identity matrix is constructed.\n"
3333 " :type rows: 2d number sequence\n");
3335 PyVarObject_HEAD_INIT(
NULL, 0)
"Matrix",
3349 #ifndef MATH_STANDALONE
3357 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3395 PyTypeObject *base_type)
3401 if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) {
3402 PyErr_SetString(PyExc_RuntimeError,
3404 "row and column sizes must be between 2 and 4");
3408 mat_alloc = PyMem_Malloc(col_num * row_num *
sizeof(
float));
3410 PyErr_SetString(PyExc_MemoryError,
3412 "problem allocating data");
3418 self->matrix = mat_alloc;
3419 self->col_num = col_num;
3420 self->row_num = row_num;
3423 self->cb_user =
NULL;
3424 self->cb_type =
self->cb_subtype = 0;
3427 memcpy(
self->matrix, mat, col_num * row_num *
sizeof(
float));
3429 else if (col_num == row_num) {
3435 memset(
self->matrix, 0, col_num * row_num *
sizeof(
float));
3440 PyMem_Free(mat_alloc);
3443 return (PyObject *)
self;
3449 PyTypeObject *base_type)
3454 if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) {
3455 PyErr_SetString(PyExc_RuntimeError,
3457 "row and column sizes must be between 2 and 4");
3463 self->col_num = col_num;
3464 self->row_num = row_num;
3467 self->cb_user =
NULL;
3468 self->cb_type =
self->cb_subtype = 0;
3473 return (PyObject *)
self;
3482 self->cb_user = cb_user;
3483 self->cb_type = cb_type;
3484 self->cb_subtype = cb_subtype;
3485 PyObject_GC_Track(
self);
3487 return (PyObject *)
self;
3493 PyTypeObject *base_type)
3501 return (PyObject *)
self;
3517 PyExc_TypeError,
"expected a mathutils.Matrix, not a %.200s", Py_TYPE(pymat)->tp_name);
3548 PyErr_SetString(PyExc_ValueError,
"matrix must be 2x2");
3565 PyErr_SetString(PyExc_ValueError,
"matrix must be 3x3");
3582 PyErr_SetString(PyExc_ValueError,
"matrix must be 4x4");
3604 Py_VISIT(
self->matrix_user);
3610 Py_CLEAR(
self->matrix_user);
3616 if (
self->matrix_user) {
3617 PyObject_GC_UnTrack(
self);
3621 Py_TYPE(
self)->tp_free(
self);
3632 return (
self->type ==
MAT_ACCESS_ROW) ?
self->matrix_user->row_num :
self->matrix_user->col_num;
3642 int matrix_access_len;
3646 matrix_access_len = matrix_user->
row_num;
3650 matrix_access_len = matrix_user->
col_num;
3654 CLAMP(begin, 0, matrix_access_len);
3656 end = (matrix_access_len + 1) + end;
3658 CLAMP(end, 0, matrix_access_len);
3659 begin =
MIN2(begin, end);
3661 tuple = PyTuple_New(end - begin);
3663 PyTuple_SET_ITEM(tuple,
count - begin, Matrix_item_new(matrix_user,
count));
3673 if (PyIndex_Check(item)) {
3675 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
3676 if (i == -1 && PyErr_Occurred()) {
3691 if (PySlice_Check(item)) {
3692 Py_ssize_t start, stop, step, slicelength;
3694 if (PySlice_GetIndicesEx(item,
MatrixAccess_len(
self), &start, &stop, &step, &slicelength) <
3699 if (slicelength <= 0) {
3700 return PyTuple_New(0);
3706 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with matrix accessors");
3711 PyExc_TypeError,
"matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
3719 if (PyIndex_Check(item)) {
3720 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
3721 if (i == -1 && PyErr_Occurred()) {
3740 PyExc_TypeError,
"matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
3748 PyObject *iter =
NULL;
3754 iter = PyObject_GetIter(
ret);
3774 PyVarObject_HEAD_INIT(
NULL, 0)
"MatrixAccess",
3792 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
3817 return (PyObject *)matrix_access;
typedef float(TangentPoint)[2]
#define BLI_assert_unreachable()
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
bool is_negative_m3(const float mat[3][3])
void unit_m2(float m[2][2])
void negate_m3(float R[3][3])
void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], float t)
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void adjoint_m3_m3(float R[3][3], const float M[3][3])
void unit_m3(float m[3][3])
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], float srcweight)
void copy_m3_m4(float m1[3][3], const float m2[4][4])
#define PSEUDOINVERSE_EPSILON
void unit_m4(float m[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
void normalize_m3(float R[3][3]) ATTR_NONNULL()
float determinant_m2(float a, float b, float c, float d)
bool is_orthogonal_m3(const float mat[3][3])
void rescale_m4(float mat[4][4], const float scale[3])
bool is_orthonormal_m3(const float mat[3][3])
float mat3_to_scale(const float M[3][3])
void adjoint_m4_m4(float R[4][4], const float M[4][4])
float determinant_m4(const float m[4][4])
void copy_m2_m2(float m1[2][2], const float m2[2][2])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], float t)
float determinant_m3_array(const float m[3][3])
bool is_negative_m4(const float mat[4][4])
void transpose_m3(float R[3][3])
bool is_orthogonal_m4(const float mat[4][4])
float determinant_m3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], float srcweight)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void transpose_m4(float R[4][4])
bool is_orthonormal_m4(const float mat[4][4])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
void adjoint_m2_m2(float R[2][2], const float M[2][2])
void mat3_normalized_to_compatible_eulO(float eul[3], const float old[3], short order, const float mat[3][3])
void axis_angle_to_mat3_single(float R[3][3], char axis, float angle)
void mat3_to_quat(float q[4], const float mat[3][3])
void mat3_normalized_to_compatible_eul(float eul[3], const float old[3], float mat[3][3])
void angle_to_mat2(float R[2][2], float angle)
void mat3_normalized_to_eul(float eul[3], const float mat[3][3])
void eulO_to_mat4(float mat[4][4], const float eul[3], short order)
float angle_wrap_rad(float angle)
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
void mat3_normalized_to_eulO(float eul[3], short order, const float mat[3][3])
void quat_to_mat4(float mat[4][4], const float q[4])
void mul_vn_fl(float *array_tar, int size, float f)
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
void copy_vn_fl(float *array_tar, int size, float val)
void mul_vn_vn(float *array_tar, const float *array_src, int size)
MINLINE void zero_v3(float r[3])
void mul_vn_vn_fl(float *array_tar, const float *array_src, int size, float f)
void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
SyclQueue void void size_t num_bytes void
PyObject * BaseMathObject_freeze(BaseMathObject *self)
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
PyObject * mathutils_dynstr_to_py(struct DynStr *ds)
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
void BaseMathObject_dealloc(BaseMathObject *self)
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
char BaseMathObject_is_valid_doc[]
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
char BaseMathObject_is_wrapped_doc[]
char BaseMathObject_is_frozen_doc[]
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
char BaseMathObject_owner_doc[]
char BaseMathObject_freeze_doc[]
int BaseMathObject_clear(BaseMathObject *self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
#define BaseMath_ReadCallback_ForWrite(_self)
#define BaseMath_WriteCallback(_self)
#define BASE_MATH_NEW(struct_name, root_type, base_type)
#define BaseMathObject_Prepare_ForHash(_self)
int column_vector_multiplication(float r_vec[4], VectorObject *vec, MatrixObject *mat)
#define BASE_MATH_FLAG_DEFAULT
#define BaseMath_Prepare_ForWrite(_self)
#define BaseMath_ReadCallback(_self)
short euler_order_from_string(const char *str, const char *error_prefix)
PyObject * Euler_CreatePyObject(const float eul[3], const short order, PyTypeObject *base_type)
#define EulerObject_Check(v)
int Matrix_Parse3x3(PyObject *o, void *p)
static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
static int Matrix_len(MatrixObject *self)
static PyObject * C_Matrix_Identity(PyObject *cls, PyObject *args)
static PyMappingMethods MatrixAccess_AsMapping
static PyGetSetDef Matrix_getseters[]
static PyObject * Matrix_to_4x4(MatrixObject *self)
static PyObject * Matrix_lerp(MatrixObject *self, PyObject *args)
static PyObject * Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static int mathutils_matrix_col_set(BaseMathObject *bmo, int col)
static PyObject * Matrix_richcmpr(PyObject *a, PyObject *b, int op)
static PyObject * C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
int Matrix_ParseAny(PyObject *o, void *p)
static PyObject * matrix_mul_float(MatrixObject *mat, const float scalar)
static int mathutils_matrix_row_set(BaseMathObject *bmo, int row)
static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row)
static int mathutils_matrix_row_get_index(BaseMathObject *bmo, int row, int col)
static PyObject * Matrix_resize_4x4(MatrixObject *self)
static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value)
static int mathutils_matrix_row_set_index(BaseMathObject *bmo, int row, int col)
static PyObject * Matrix_invert_safe(MatrixObject *self)
static int mathutils_matrix_col_get(BaseMathObject *bmo, int col)
static PyObject * Matrix_item_col(MatrixObject *self, int col)
static PyObject * Matrix_to_euler(MatrixObject *self, PyObject *args)
static PyObject * Matrix_imul(PyObject *m1, PyObject *m2)
static PyObject * Matrix_translation_get(MatrixObject *self, void *UNUSED(closure))
static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *mat_src)
static void matrix_identity_internal(MatrixObject *self)
static PyObject * Matrix_normalize(MatrixObject *self)
static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNUSED(closure))
static PyObject * Matrix_add(PyObject *m1, PyObject *m2)
static PyObject * matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *), MatrixObject *self)
static PyObject * Matrix_to_quaternion(MatrixObject *self)
static int mathutils_matrix_row_check(BaseMathObject *bmo)
static PyObject * Matrix_mul(PyObject *m1, PyObject *m2)
static int MatrixAccess_clear(MatrixAccessObject *self)
static float matrix_determinant_internal(const MatrixObject *self)
static PyObject * Matrix_str(MatrixObject *self)
static PyObject * Matrix_row_get(MatrixObject *self, void *UNUSED(closure))
PyObject * Matrix_CreatePyObject(const float *mat, const ushort col_num, const ushort row_num, PyTypeObject *base_type)
static PyObject * Matrix_to_3x3(MatrixObject *self)
PyDoc_STRVAR(C_Matrix_Identity_doc, ".. classmethod:: Identity(size)\n" "\n" " Create an identity matrix.\n" "\n" " :arg size: The size of the identity matrix to construct [2, 4].\n" " :type size: int\n" " :return: A new identity matrix.\n" " :rtype: :class:`Matrix`\n")
static void matrix_unit_internal(MatrixObject *self)
Mathutils_Callback mathutils_matrix_col_cb
static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort dim)
static bool matrix_invert_is_compat(const MatrixObject *self)
static bool matrix_is_identity(MatrixObject *self)
static PyObject * Matrix_inverted_noargs(MatrixObject *self)
static int mathutils_matrix_translation_set_index(BaseMathObject *bmo, int col, int row)
PyTypeObject matrix_access_Type
static PyObject * Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closure))
static PyNumberMethods Matrix_NumMethods
static PyObject * C_Matrix_Translation(PyObject *cls, PyObject *value)
static PyObject * Matrix_transposed(MatrixObject *self)
static PyObject * Matrix_col_get(MatrixObject *self, void *UNUSED(closure))
static PyObject * MatrixAccess_iter(MatrixAccessObject *self)
static PyObject * Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure))
static PyObject * C_Matrix_Rotation(PyObject *cls, PyObject *args)
static PyObject * Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void *UNUSED(closure))
static PySequenceMethods Matrix_SeqMethods
static PyObject * Matrix_decompose(MatrixObject *self)
static PyObject * Matrix_subscript(MatrixObject *self, PyObject *item)
static int mathutils_matrix_col_get_index(BaseMathObject *bmo, int col, int row)
static PyObject * Matrix_repr(MatrixObject *self)
static PyObject * C_Matrix_Scale(PyObject *cls, PyObject *args)
static PyObject * MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
static int mathutils_matrix_translation_get_index(BaseMathObject *bmo, int col, int row)
static void matrix_invert_with_det_n_internal(float *mat_dst, const float *mat_src, const float det, const ushort dim)
static PyObject * Matrix_is_identity_get(MatrixObject *self, void *UNUSED(closure))
static PyObject * Matrix_deepcopy(MatrixObject *self, PyObject *args)
static PyObject * Matrix_rotate(MatrixObject *self, PyObject *value)
static PyObject * Matrix_item_row(MatrixObject *self, int row)
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
static bool Matrix_ParseCheck(MatrixObject *pymat)
static int MatrixAccess_len(MatrixAccessObject *self)
static PyMappingMethods Matrix_AsMapping
static PyObject * Matrix_copy(MatrixObject *self)
static void matrix_3x3_as_4x4(float mat[16])
int Matrix_Parse2x2(PyObject *o, void *p)
Mathutils_Callback mathutils_matrix_row_cb
static int mathutils_matrix_translation_get(BaseMathObject *bmo, int col)
static int MatrixAccess_traverse(MatrixAccessObject *self, visitproc visit, void *arg)
static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
Mathutils_Callback mathutils_matrix_translation_cb
static PyObject * Matrix_inverted_safe(MatrixObject *self)
static PyObject * Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure))
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value)
static PyObject * Matrix_to_NxN(MatrixObject *self, const int col_num, const int row_num)
int Matrix_Parse4x4(PyObject *o, void *p)
static PyObject * C_Matrix_Diagonal(PyObject *cls, PyObject *value)
PyObject * Matrix_CreatePyObject_wrap(float *mat, const ushort col_num, const ushort row_num, PyTypeObject *base_type)
uchar mathutils_matrix_col_cb_index
static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
uchar mathutils_matrix_row_cb_index
static PyObject * Matrix_invert(MatrixObject *self, PyObject *args)
static PyObject * Matrix_imatmul(PyObject *m1, PyObject *m2)
static void matrix_invert_raise_degenerate(void)
static PyObject * Matrix_to_scale(MatrixObject *self)
static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, PyObject *value)
PyObject * Matrix_CreatePyObject_cb(PyObject *cb_user, const ushort col_num, const ushort row_num, uchar cb_type, uchar cb_subtype)
static int mathutils_matrix_row_get(BaseMathObject *bmo, int row)
static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col)
static PyObject * Matrix_normalized(MatrixObject *self)
static PyObject * Matrix_adjugated(MatrixObject *self)
static PyObject * Matrix_to_translation(MatrixObject *self)
static PyObject * C_Matrix_Shear(PyObject *cls, PyObject *args)
static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, bool check_type)
static int mathutils_matrix_translation_check(BaseMathObject *bmo)
static void MatrixAccess_dealloc(MatrixAccessObject *self)
PyObject * Matrix_CreatePyObject_alloc(float *mat, const ushort col_num, const ushort row_num, PyTypeObject *base_type)
static PyObject * Matrix_inverted(MatrixObject *self, PyObject *args)
static PyObject * Matrix_adjugate(MatrixObject *self)
static struct PyMethodDef Matrix_methods[]
static int mathutils_matrix_col_check(BaseMathObject *bmo)
static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
static PyObject * Matrix_zero(MatrixObject *self)
static PyObject * Matrix_matmul(PyObject *m1, PyObject *m2)
static Py_hash_t Matrix_hash(MatrixObject *self)
static PyObject * Matrix_transpose(MatrixObject *self)
static int mathutils_matrix_col_set_index(BaseMathObject *bmo, int col, int row)
static PyObject * MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item)
static int mathutils_matrix_translation_set(BaseMathObject *bmo, int col)
static PyObject * Matrix_to_2x2(MatrixObject *self)
static PyObject * C_Matrix_LocRotScale(PyObject *cls, PyObject *args)
static PyObject * Matrix_determinant(MatrixObject *self)
static PyObject * Matrix_sub(PyObject *m1, PyObject *m2)
static PyObject * Matrix_copy_notest(MatrixObject *self, const float *matrix)
static PyObject * MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type)
static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
static PyObject * Matrix_slice(MatrixObject *self, int begin, int end)
static PyObject * Matrix_identity(MatrixObject *self)
uchar mathutils_matrix_translation_cb_index
#define MATRIX_COL_PTR(_mat, _col)
#define MatrixObject_Check(v)
#define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col)
#define MATRIX_ITEM(_mat, _row, _col)
PyObject * Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
#define QuaternionObject_Check(v)
PyObject * Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
#define VectorObject_Check(v)
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
int PyC_CheckArgs_DeepCopy(PyObject *args)
#define PyTuple_SET_ITEMS(op_arg,...)
PyObject_HEAD MatrixObject * matrix_user