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.c1056
1 files changed, 586 insertions, 470 deletions
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 76b5424711f..8cd7a5c7d87 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -32,6 +32,10 @@ static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *),
MatrixObject *self);
static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type);
+/* -------------------------------------------------------------------- */
+/** \name Utilities
+ * \{ */
+
static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row)
{
if ((vec->vec_num != mat->col_num) || (row >= mat->row_num)) {
@@ -56,9 +60,242 @@ static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col
return 1;
}
-/* ----------------------------------------------------------------------------
- * matrix row callbacks
- * this is so you can do matrix[i][j] = val OR matrix.row[i][j] = val */
+/** When a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4. */
+static void matrix_3x3_as_4x4(float mat[16])
+{
+ mat[10] = mat[8];
+ mat[9] = mat[7];
+ mat[8] = mat[6];
+ mat[7] = 0.0f;
+ mat[6] = mat[5];
+ mat[5] = mat[4];
+ mat[4] = mat[3];
+ mat[3] = 0.0f;
+}
+
+void matrix_as_3x3(float mat[3][3], MatrixObject *self)
+{
+ copy_v3_v3(mat[0], MATRIX_COL_PTR(self, 0));
+ copy_v3_v3(mat[1], MATRIX_COL_PTR(self, 1));
+ copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2));
+}
+
+static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
+{
+ BLI_assert((mat_dst->col_num == mat_src->col_num) && (mat_dst->row_num == mat_src->row_num));
+ BLI_assert(mat_dst != mat_src);
+
+ memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->col_num * mat_dst->row_num));
+}
+
+static void matrix_unit_internal(MatrixObject *self)
+{
+ const int mat_size = sizeof(float) * (self->col_num * self->row_num);
+ memset(self->matrix, 0x0, mat_size);
+ const int col_row_max = min_ii(self->col_num, self->row_num);
+ const int row_num = self->row_num;
+ for (int col = 0; col < col_row_max; col++) {
+ self->matrix[(col * row_num) + col] = 1.0f;
+ }
+}
+
+/** Transposes memory layout, row/columns don't have to match. */
+static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *mat_src)
+{
+ ushort col, row;
+ uint i = 0;
+
+ for (row = 0; row < mat_src->row_num; row++) {
+ for (col = 0; col < mat_src->col_num; col++) {
+ mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col);
+ }
+ }
+}
+
+/** Assumes `rowsize == colsize` is checked and the read callback has run. */
+static float matrix_determinant_internal(const MatrixObject *self)
+{
+ if (self->col_num == 2) {
+ return determinant_m2(MATRIX_ITEM(self, 0, 0),
+ MATRIX_ITEM(self, 0, 1),
+ MATRIX_ITEM(self, 1, 0),
+ MATRIX_ITEM(self, 1, 1));
+ }
+ if (self->col_num == 3) {
+ return determinant_m3(MATRIX_ITEM(self, 0, 0),
+ MATRIX_ITEM(self, 0, 1),
+ MATRIX_ITEM(self, 0, 2),
+ MATRIX_ITEM(self, 1, 0),
+ MATRIX_ITEM(self, 1, 1),
+ MATRIX_ITEM(self, 1, 2),
+ MATRIX_ITEM(self, 2, 0),
+ MATRIX_ITEM(self, 2, 1),
+ MATRIX_ITEM(self, 2, 2));
+ }
+
+ return determinant_m4((const float(*)[4])self->matrix);
+}
+
+static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort dim)
+{
+ /* calculate the classical adjoint */
+ switch (dim) {
+ case 2: {
+ adjoint_m2_m2((float(*)[2])mat_dst, (const float(*)[2])mat_src);
+ break;
+ }
+ case 3: {
+ adjoint_m3_m3((float(*)[3])mat_dst, (const float(*)[3])mat_src);
+ break;
+ }
+ case 4: {
+ adjoint_m4_m4((float(*)[4])mat_dst, (const float(*)[4])mat_src);
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+}
+
+static void matrix_invert_with_det_n_internal(float *mat_dst,
+ const float *mat_src,
+ const float det,
+ const ushort dim)
+{
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ ushort i, j, k;
+
+ BLI_assert(det != 0.0f);
+
+ adjoint_matrix_n(mat, mat_src, dim);
+
+ /* divide by determinant & set values */
+ k = 0;
+ for (i = 0; i < dim; i++) { /* col_num */
+ for (j = 0; j < dim; j++) { /* row_num */
+ mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det;
+ }
+ }
+}
+
+/**
+ * \param r_mat: can be from `self->matrix` or not.
+ */
+static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
+{
+ float det;
+ BLI_assert(self->col_num == self->row_num);
+ det = matrix_determinant_internal(self);
+
+ if (det != 0.0f) {
+ matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->col_num);
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Similar to `matrix_invert_internal` but should never error.
+ * \param r_mat: can be from `self->matrix` or not.
+ */
+static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
+{
+ float det;
+ float *in_mat = self->matrix;
+ BLI_assert(self->col_num == self->row_num);
+ det = matrix_determinant_internal(self);
+
+ if (det == 0.0f) {
+ const float eps = PSEUDOINVERSE_EPSILON;
+
+ /* We will copy self->matrix into r_mat (if needed),
+ * and modify it in place to add diagonal epsilon. */
+ in_mat = r_mat;
+
+ switch (self->col_num) {
+ case 2: {
+ float(*mat)[2] = (float(*)[2])in_mat;
+
+ if (in_mat != self->matrix) {
+ copy_m2_m2(mat, (const float(*)[2])self->matrix);
+ }
+ mat[0][0] += eps;
+ mat[1][1] += eps;
+
+ if (UNLIKELY((det = determinant_m2(mat[0][0], mat[0][1], mat[1][0], mat[1][1])) == 0.0f)) {
+ unit_m2(mat);
+ det = 1.0f;
+ }
+ break;
+ }
+ case 3: {
+ float(*mat)[3] = (float(*)[3])in_mat;
+
+ if (in_mat != self->matrix) {
+ copy_m3_m3(mat, (const float(*)[3])self->matrix);
+ }
+ mat[0][0] += eps;
+ mat[1][1] += eps;
+ mat[2][2] += eps;
+
+ if (UNLIKELY((det = determinant_m3_array(mat)) == 0.0f)) {
+ unit_m3(mat);
+ det = 1.0f;
+ }
+ break;
+ }
+ case 4: {
+ float(*mat)[4] = (float(*)[4])in_mat;
+
+ if (in_mat != self->matrix) {
+ copy_m4_m4(mat, (const float(*)[4])self->matrix);
+ }
+ mat[0][0] += eps;
+ mat[1][1] += eps;
+ mat[2][2] += eps;
+ mat[3][3] += eps;
+
+ if (UNLIKELY(det = determinant_m4(mat)) == 0.0f) {
+ unit_m4(mat);
+ det = 1.0f;
+ }
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ }
+ }
+
+ matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->col_num);
+}
+
+static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *),
+ MatrixObject *self)
+{
+ PyObject *ret = Matrix_copy(self);
+ if (ret) {
+ PyObject *ret_dummy = matrix_func((MatrixObject *)ret);
+ if (ret_dummy) {
+ Py_DECREF(ret_dummy);
+ return ret;
+ }
+ /* error */
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ /* copy may fail if the read callback errors out */
+ return NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Row Callbacks
+ * This is so you can do `matrix[i][j] = val` or `matrix.row[i][j] = val`.
+ * \{ */
uchar mathutils_matrix_row_cb_index = -1;
@@ -147,9 +384,12 @@ Mathutils_Callback mathutils_matrix_row_cb = {
mathutils_matrix_row_set_index,
};
-/* ----------------------------------------------------------------------------
- * matrix row callbacks
- * this is so you can do matrix.col[i][j] = val */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Column Callbacks
+ * This is so you can do `matrix.col[i][j] = val`.
+ * \{ */
uchar mathutils_matrix_col_cb_index = -1;
@@ -246,10 +486,14 @@ Mathutils_Callback mathutils_matrix_col_cb = {
mathutils_matrix_col_set_index,
};
-/* ----------------------------------------------------------------------------
- * matrix row callbacks
- * this is so you can do matrix.translation = val
- * NOTE: this is _exactly like matrix.col except the 4th component is always omitted. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Translation Callbacks
+ * This is so you can do `matrix.translation = val`.
+ *
+ * \note this is _exactly like matrix.col except the 4th component is always omitted.
+ * \{ */
uchar mathutils_matrix_translation_cb_index = -1;
@@ -326,11 +570,12 @@ Mathutils_Callback mathutils_matrix_translation_cb = {
mathutils_matrix_translation_set_index,
};
-/* matrix column callbacks, this is so you can do `matrix.translation = Vector()`. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: `__new__` / `mathutils.Matrix()`
+ * \{ */
-/* ----------------------------------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)) {
@@ -379,41 +624,13 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
-static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *),
- MatrixObject *self)
-{
- PyObject *ret = Matrix_copy(self);
- if (ret) {
- PyObject *ret_dummy = matrix_func((MatrixObject *)ret);
- if (ret_dummy) {
- Py_DECREF(ret_dummy);
- return ret;
- }
- /* error */
- Py_DECREF(ret);
- return NULL;
- }
-
- /* copy may fail if the read callback errors out */
- return NULL;
-}
-
-/* when a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4 */
-static void matrix_3x3_as_4x4(float mat[16])
-{
- mat[10] = mat[8];
- mat[9] = mat[7];
- mat[8] = mat[6];
- mat[7] = 0.0f;
- mat[6] = mat[5];
- mat[5] = mat[4];
- mat[4] = mat[3];
- mat[3] = 0.0f;
-}
+/** \} */
-/*-----------------------CLASS-METHODS----------------------------*/
+/* -------------------------------------------------------------------- */
+/** \name Matrix Class Methods
+ * \{ */
-/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
+/** Identity constructor: `mathutils.Matrix.Identity()`. */
PyDoc_STRVAR(C_Matrix_Identity_doc,
".. classmethod:: Identity(size)\n"
"\n"
@@ -441,6 +658,7 @@ static PyObject *C_Matrix_Identity(PyObject *cls, PyObject *args)
return Matrix_CreatePyObject(NULL, matSize, matSize, (PyTypeObject *)cls);
}
+/** Rotation constructor: `mathutils.Matrix.Rotation()`. */
PyDoc_STRVAR(C_Matrix_Rotation_doc,
".. classmethod:: Rotation(angle, size, axis)\n"
"\n"
@@ -460,25 +678,8 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
PyObject *vec = NULL;
const char *axis = NULL;
int matSize;
- double angle; /* use double because of precision problems at high values */
- float mat[16] = {
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- };
+ double angle; /* Use double because of precision problems at high values. */
+ float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!PyArg_ParseTuple(args, "di|O:Matrix.Rotation", &angle, &matSize, &vec)) {
return NULL;
@@ -545,6 +746,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
+/** Translation constructor: `mathutils.Matrix.Translation()`. */
PyDoc_STRVAR(C_Matrix_Translation_doc,
".. classmethod:: Translation(vector)\n"
"\n"
@@ -567,7 +769,7 @@ static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value)
return Matrix_CreatePyObject(&mat[0][0], 4, 4, (PyTypeObject *)cls);
}
-/* ----------------------------------mathutils.Matrix.Diagonal() ------------- */
+
PyDoc_STRVAR(C_Matrix_Diagonal_doc,
".. classmethod:: Diagonal(vector)\n"
"\n"
@@ -577,6 +779,7 @@ PyDoc_STRVAR(C_Matrix_Diagonal_doc,
" :type vector: :class:`Vector`\n"
" :return: A diagonal matrix.\n"
" :rtype: :class:`Matrix`\n");
+/** Diagonal constructor: `mathutils.Matrix.Diagonal()`. */
static PyObject *C_Matrix_Diagonal(PyObject *cls, PyObject *value)
{
float mat[16] = {0.0f};
@@ -595,8 +798,8 @@ static PyObject *C_Matrix_Diagonal(PyObject *cls, PyObject *value)
return Matrix_CreatePyObject(mat, size, size, (PyTypeObject *)cls);
}
-/* ----------------------------------mathutils.Matrix.Scale() ------------- */
-/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
+
+/** Scale constructor: `mathutils.Matrix.Scale()`. */
PyDoc_STRVAR(C_Matrix_Scale_doc,
".. classmethod:: Scale(factor, size, axis)\n"
"\n"
@@ -617,24 +820,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
float tvec[3];
float factor;
int matSize;
- float mat[16] = {
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- };
+ float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) {
return NULL;
@@ -700,8 +886,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
/* pass to matrix creation */
return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
-/* ----------------------------------mathutils.Matrix.OrthoProjection() --- */
-/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
+/** Orthographic projection constructor: `mathutils.Matrix.OrthoProjection()`. */
PyDoc_STRVAR(C_Matrix_OrthoProjection_doc,
".. classmethod:: OrthoProjection(axis, size)\n"
"\n"
@@ -721,24 +906,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
int matSize, x;
float norm = 0.0f;
- float mat[16] = {
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- };
+ float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) {
return NULL;
@@ -837,6 +1005,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
+/** Shear constructor: `mathutils.Matrix.Shear()`. */
PyDoc_STRVAR(C_Matrix_Shear_doc,
".. classmethod:: Shear(plane, size, factor)\n"
"\n"
@@ -857,24 +1026,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
int matSize;
const char *plane;
PyObject *fac;
- float mat[16] = {
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- };
+ float mat[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
if (!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) {
return NULL;
@@ -1051,205 +1203,12 @@ static PyObject *C_Matrix_LocRotScale(PyObject *cls, PyObject *args)
return Matrix_CreatePyObject(&mat[0][0], 4, 4, (PyTypeObject *)cls);
}
-void matrix_as_3x3(float mat[3][3], MatrixObject *self)
-{
- copy_v3_v3(mat[0], MATRIX_COL_PTR(self, 0));
- copy_v3_v3(mat[1], MATRIX_COL_PTR(self, 1));
- copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2));
-}
-
-static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
-{
- BLI_assert((mat_dst->col_num == mat_src->col_num) && (mat_dst->row_num == mat_src->row_num));
- BLI_assert(mat_dst != mat_src);
+/** \} */
- memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->col_num * mat_dst->row_num));
-}
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: To Quaternion
+ * \{ */
-static void matrix_unit_internal(MatrixObject *self)
-{
- const int mat_size = sizeof(float) * (self->col_num * self->row_num);
- memset(self->matrix, 0x0, mat_size);
- const int col_row_max = min_ii(self->col_num, self->row_num);
- const int row_num = self->row_num;
- for (int col = 0; col < col_row_max; col++) {
- self->matrix[(col * row_num) + col] = 1.0f;
- }
-}
-
-/* transposes memory layout, rol/col's don't have to match */
-static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *mat_src)
-{
- ushort col, row;
- uint i = 0;
-
- for (row = 0; row < mat_src->row_num; row++) {
- for (col = 0; col < mat_src->col_num; col++) {
- mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col);
- }
- }
-}
-
-/* assumes rowsize == colsize is checked and the read callback has run */
-static float matrix_determinant_internal(const MatrixObject *self)
-{
- if (self->col_num == 2) {
- return determinant_m2(MATRIX_ITEM(self, 0, 0),
- MATRIX_ITEM(self, 0, 1),
- MATRIX_ITEM(self, 1, 0),
- MATRIX_ITEM(self, 1, 1));
- }
- if (self->col_num == 3) {
- return determinant_m3(MATRIX_ITEM(self, 0, 0),
- MATRIX_ITEM(self, 0, 1),
- MATRIX_ITEM(self, 0, 2),
- MATRIX_ITEM(self, 1, 0),
- MATRIX_ITEM(self, 1, 1),
- MATRIX_ITEM(self, 1, 2),
- MATRIX_ITEM(self, 2, 0),
- MATRIX_ITEM(self, 2, 1),
- MATRIX_ITEM(self, 2, 2));
- }
-
- return determinant_m4((const float(*)[4])self->matrix);
-}
-
-static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort dim)
-{
- /* calculate the classical adjoint */
- switch (dim) {
- case 2: {
- adjoint_m2_m2((float(*)[2])mat_dst, (const float(*)[2])mat_src);
- break;
- }
- case 3: {
- adjoint_m3_m3((float(*)[3])mat_dst, (const float(*)[3])mat_src);
- break;
- }
- case 4: {
- adjoint_m4_m4((float(*)[4])mat_dst, (const float(*)[4])mat_src);
- break;
- }
- default:
- BLI_assert_unreachable();
- break;
- }
-}
-
-static void matrix_invert_with_det_n_internal(float *mat_dst,
- const float *mat_src,
- const float det,
- const ushort dim)
-{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- ushort i, j, k;
-
- BLI_assert(det != 0.0f);
-
- adjoint_matrix_n(mat, mat_src, dim);
-
- /* divide by determinant & set values */
- k = 0;
- for (i = 0; i < dim; i++) { /* col_num */
- for (j = 0; j < dim; j++) { /* row_num */
- mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det;
- }
- }
-}
-
-/**
- * \param r_mat: can be from `self->matrix` or not.
- */
-static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
-{
- float det;
- BLI_assert(self->col_num == self->row_num);
- det = matrix_determinant_internal(self);
-
- if (det != 0.0f) {
- matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->col_num);
- return true;
- }
-
- return false;
-}
-
-/**
- * Similar to `matrix_invert_internal` but should never error.
- * \param r_mat: can be from `self->matrix` or not.
- */
-static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
-{
- float det;
- float *in_mat = self->matrix;
- BLI_assert(self->col_num == self->row_num);
- det = matrix_determinant_internal(self);
-
- if (det == 0.0f) {
- const float eps = PSEUDOINVERSE_EPSILON;
-
- /* We will copy self->matrix into r_mat (if needed),
- * and modify it in place to add diagonal epsilon. */
- in_mat = r_mat;
-
- switch (self->col_num) {
- case 2: {
- float(*mat)[2] = (float(*)[2])in_mat;
-
- if (in_mat != self->matrix) {
- copy_m2_m2(mat, (const float(*)[2])self->matrix);
- }
- mat[0][0] += eps;
- mat[1][1] += eps;
-
- if (UNLIKELY((det = determinant_m2(mat[0][0], mat[0][1], mat[1][0], mat[1][1])) == 0.0f)) {
- unit_m2(mat);
- det = 1.0f;
- }
- break;
- }
- case 3: {
- float(*mat)[3] = (float(*)[3])in_mat;
-
- if (in_mat != self->matrix) {
- copy_m3_m3(mat, (const float(*)[3])self->matrix);
- }
- mat[0][0] += eps;
- mat[1][1] += eps;
- mat[2][2] += eps;
-
- if (UNLIKELY((det = determinant_m3_array(mat)) == 0.0f)) {
- unit_m3(mat);
- det = 1.0f;
- }
- break;
- }
- case 4: {
- float(*mat)[4] = (float(*)[4])in_mat;
-
- if (in_mat != self->matrix) {
- copy_m4_m4(mat, (const float(*)[4])self->matrix);
- }
- mat[0][0] += eps;
- mat[1][1] += eps;
- mat[2][2] += eps;
- mat[3][3] += eps;
-
- if (UNLIKELY(det = determinant_m4(mat)) == 0.0f) {
- unit_m4(mat);
- det = 1.0f;
- }
- break;
- }
- default:
- BLI_assert_unreachable();
- }
- }
-
- matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->col_num);
-}
-
-/*-----------------------------METHODS----------------------------*/
PyDoc_STRVAR(Matrix_to_quaternion_doc,
".. method:: to_quaternion()\n"
"\n"
@@ -1282,7 +1241,12 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
return Quaternion_CreatePyObject(quat, NULL);
}
-/*---------------------------matrix.toEuler() --------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: To Euler
+ * \{ */
+
PyDoc_STRVAR(Matrix_to_euler_doc,
".. method:: to_euler(order, euler_compat)\n"
"\n"
@@ -1367,6 +1331,12 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
return Euler_CreatePyObject(eul, order, NULL);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Resize
+ * \{ */
+
PyDoc_STRVAR(Matrix_resize_4x4_doc,
".. method:: resize_4x4()\n"
"\n"
@@ -1411,6 +1381,12 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
Py_RETURN_NONE;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: To NxN
+ * \{ */
+
static PyObject *Matrix_to_NxN(MatrixObject *self, const int col_num, const int row_num)
{
const int mat_size = sizeof(float) * (col_num * row_num);
@@ -1480,6 +1456,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
return Matrix_to_NxN(self, 4, 4);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: To Translation/Scale
+ * \{ */
+
PyDoc_STRVAR(Matrix_to_translation_doc,
".. method:: to_translation()\n"
"\n"
@@ -1539,9 +1521,13 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
return Vector_CreatePyObject(size, 3, NULL);
}
-/*---------------------------matrix.invert() ---------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Invert
+ * \{ */
-/* re-usable checks for invert */
+/** Re-usable checks for invert. */
static bool matrix_invert_is_compat(const MatrixObject *self)
{
if (self->col_num != self->row_num) {
@@ -1763,7 +1749,12 @@ static PyObject *Matrix_inverted_safe(MatrixObject *self)
return Matrix_copy_notest(self, mat);
}
-/*---------------------------matrix.adjugate() ---------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Adjugate
+ * \{ */
+
PyDoc_STRVAR(
Matrix_adjugate_doc,
".. method:: adjugate()\n"
@@ -1852,7 +1843,12 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
Py_RETURN_NONE;
}
-/*---------------------------matrix.decompose() ---------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Decompose
+ * \{ */
+
PyDoc_STRVAR(Matrix_decompose_doc,
".. method:: decompose()\n"
"\n"
@@ -1890,6 +1886,12 @@ static PyObject *Matrix_decompose(MatrixObject *self)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Linear Interpolate (lerp)
+ * \{ */
+
PyDoc_STRVAR(Matrix_lerp_doc,
".. function:: lerp(other, factor)\n"
"\n"
@@ -1947,7 +1949,6 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return Matrix_CreatePyObject(mat, self->col_num, self->row_num, Py_TYPE(self));
}
-/*---------------------------matrix.determinant() ----------------*/
PyDoc_STRVAR(
Matrix_determinant_doc,
".. method:: determinant()\n"
@@ -1973,7 +1974,13 @@ static PyObject *Matrix_determinant(MatrixObject *self)
return PyFloat_FromDouble((double)matrix_determinant_internal(self));
}
-/*---------------------------matrix.transpose() ------------------*/
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Transpose
+ * \{ */
+
PyDoc_STRVAR(
Matrix_transpose_doc,
".. method:: transpose()\n"
@@ -2022,7 +2029,12 @@ static PyObject *Matrix_transposed(MatrixObject *self)
return matrix__apply_to_copy(Matrix_transpose, self);
}
-/*---------------------------matrix.normalize() ------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Normalize
+ * \{ */
+
PyDoc_STRVAR(Matrix_normalize_doc,
".. method:: normalize()\n"
"\n"
@@ -2068,7 +2080,12 @@ static PyObject *Matrix_normalized(MatrixObject *self)
return matrix__apply_to_copy(Matrix_normalize, self);
}
-/*---------------------------matrix.zero() -----------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Zero
+ * \{ */
+
PyDoc_STRVAR(Matrix_zero_doc,
".. method:: zero()\n"
"\n"
@@ -2089,7 +2106,13 @@ static PyObject *Matrix_zero(MatrixObject *self)
Py_RETURN_NONE;
}
-/*---------------------------matrix.identity(() ------------------*/
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Set Identity
+ * \{ */
+
static void matrix_identity_internal(MatrixObject *self)
{
BLI_assert((self->col_num == self->row_num) && (self->row_num <= 4));
@@ -2137,8 +2160,13 @@ static PyObject *Matrix_identity(MatrixObject *self)
Py_RETURN_NONE;
}
-/*---------------------------Matrix.copy() ------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Methods: Copy
+ * \{ */
+/** Copy `Matrix.copy()` */
static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix)
{
return Matrix_CreatePyObject((const float *)matrix, self->col_num, self->row_num, Py_TYPE(self));
@@ -2159,6 +2187,8 @@ static PyObject *Matrix_copy(MatrixObject *self)
return Matrix_copy_notest(self, self->matrix);
}
+
+/** Deep-copy `Matrix.deepcopy()` */
static PyObject *Matrix_deepcopy(MatrixObject *self, PyObject *args)
{
if (!PyC_CheckArgs_DeepCopy(args)) {
@@ -2167,8 +2197,12 @@ static PyObject *Matrix_deepcopy(MatrixObject *self, PyObject *args)
return Matrix_copy(self);
}
-/*----------------------------print object (internal)-------------*/
-/* print the object to screen */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: `__repr__` & `__str__`
+ * \{ */
+
static PyObject *Matrix_repr(MatrixObject *self)
{
int col, row;
@@ -2257,6 +2291,12 @@ static PyObject *Matrix_str(MatrixObject *self)
}
#endif
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Rich Compare
+ * \{ */
+
static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
{
PyObject *res;
@@ -2298,6 +2338,12 @@ static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
return Py_INCREF_RET(res);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Hash (`__hash__`)
+ * \{ */
+
static Py_hash_t Matrix_hash(MatrixObject *self)
{
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
@@ -2315,16 +2361,22 @@ static Py_hash_t Matrix_hash(MatrixObject *self)
return mathutils_array_hash(mat, self->row_num * self->col_num);
}
-/*---------------------SEQUENCE PROTOCOLS------------------------
- * ----------------------------len(object)------------------------
- * sequence length */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Sequence & Mapping Protocol Implementation
+ * \{ */
+
+/** Sequence length: `len(object)`. */
static int Matrix_len(MatrixObject *self)
{
return self->row_num;
}
-/*----------------------------object[]---------------------------
- * sequence accessor (get)
- * the wrapped vector gives direct access to the matrix data */
+
+/**
+ * Sequence accessor (get): `x = object[i]`.
+ * \note the wrapped vector gives direct access to the matrix data.
+ */
static PyObject *Matrix_item_row(MatrixObject *self, int row)
{
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
@@ -2340,7 +2392,10 @@ static PyObject *Matrix_item_row(MatrixObject *self, int row)
return Vector_CreatePyObject_cb(
(PyObject *)self, self->col_num, mathutils_matrix_row_cb_index, row);
}
-/* same but column access */
+/**
+ * Sequence accessor (get): `x = object.col[i]`.
+ * \note the wrapped vector gives direct access to the matrix data.
+ */
static PyObject *Matrix_item_col(MatrixObject *self, int col)
{
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
@@ -2357,9 +2412,7 @@ static PyObject *Matrix_item_col(MatrixObject *self, int col)
(PyObject *)self, self->row_num, mathutils_matrix_col_cb_index, col);
}
-/*----------------------------object[]-------------------------
- * sequence accessor (set) */
-
+/** Sequence accessor (set): `object[i] = x`. */
static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
{
int col;
@@ -2386,6 +2439,8 @@ static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
(void)BaseMath_WriteCallback(self);
return 0;
}
+
+/** Sequence accessor (set): `object.col[i] = x`. */
static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
{
int row;
@@ -2413,8 +2468,7 @@ static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
return 0;
}
-/*----------------------------object[z:y]------------------------
- * Sequence slice (get). */
+/** Sequence slice accessor (get): `x = object[i:j]`. */
static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
{
@@ -2439,8 +2493,8 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
return tuple;
}
-/*----------------------------object[z:y]------------------------
- * Sequence slice (set). */
+
+/** Sequence slice accessor (set): `object[i:j] = x`. */
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value)
{
PyObject *value_fast;
@@ -2500,8 +2554,84 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
(void)BaseMath_WriteCallback(self);
return 0;
}
-/*------------------------NUMERIC PROTOCOLS----------------------
- *------------------------obj + obj------------------------------*/
+
+/** Sequence generic subscript (get): `x = object[...]`. */
+static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i;
+ i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (i < 0) {
+ i += self->row_num;
+ }
+ return Matrix_item_row(self, i);
+ }
+ if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ if (step == 1) {
+ return Matrix_slice(self, start, stop);
+ }
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
+ return NULL;
+ }
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
+}
+
+/** Sequence generic subscript (set): `object[...] = x`. */
+static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ if (i < 0) {
+ i += self->row_num;
+ }
+ return Matrix_ass_item_row(self, i, value);
+ }
+ if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Matrix_ass_slice(self, start, stop, value);
+ }
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
+ return -1;
+ }
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Numeric Protocol Implementation
+ * \{ */
+
+/** Addition: `object + object`. */
static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
{
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
@@ -2534,8 +2664,8 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1));
}
-/*------------------------obj - obj------------------------------
- * subtraction */
+
+/** Subtraction: `object - object`. */
static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
{
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
@@ -2568,8 +2698,8 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1));
}
-/*------------------------obj * obj------------------------------
- * element-wise multiplication */
+
+/** Multiplication (element-wise): `object * object`. */
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
@@ -2631,8 +2761,8 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
Py_TYPE(m2)->tp_name);
return NULL;
}
-/*------------------------obj *= obj------------------------------
- * In place element-wise multiplication */
+
+/** Multiplication in-place (element-wise): `object *= object`. */
static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
{
float scalar;
@@ -2680,8 +2810,8 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
Py_INCREF(m1);
return m1;
}
-/*------------------------obj @ obj------------------------------
- * matrix multiplication */
+
+/** Multiplication (matrix multiply): `object @ object`. */
static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
{
int vec_num;
@@ -2756,8 +2886,8 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
Py_TYPE(m2)->tp_name);
return NULL;
}
-/*------------------------obj @= obj------------------------------
- * In place matrix multiplication */
+
+/** Multiplication in-place (matrix multiply): `object @= object`. */
static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2)
{
MatrixObject *mat1 = NULL, *mat2 = NULL;
@@ -2816,87 +2946,24 @@ static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2)
return m1;
}
-/*-----------------PROTOCOL DECLARATIONS--------------------------*/
-static PySequenceMethods Matrix_SeqMethods = {
- (lenfunc)Matrix_len, /* sq_length */
- (binaryfunc)NULL, /* sq_concat */
- (ssizeargfunc)NULL, /* sq_repeat */
- (ssizeargfunc)Matrix_item_row, /* sq_item */
- (ssizessizeargfunc)NULL, /* sq_slice, deprecated */
- (ssizeobjargproc)Matrix_ass_item_row, /* sq_ass_item */
- (ssizessizeobjargproc)NULL, /* sq_ass_slice, deprecated */
- (objobjproc)NULL, /* sq_contains */
- (binaryfunc)NULL, /* sq_inplace_concat */
- (ssizeargfunc)NULL, /* sq_inplace_repeat */
-};
-
-static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item)
-{
- if (PyIndex_Check(item)) {
- Py_ssize_t i;
- i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred()) {
- return NULL;
- }
- if (i < 0) {
- i += self->row_num;
- }
- return Matrix_item_row(self, i);
- }
- if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- if (step == 1) {
- return Matrix_slice(self, start, stop);
- }
-
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
- return NULL;
- }
-
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
- return NULL;
-}
-
-static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value)
-{
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred()) {
- return -1;
- }
- if (i < 0) {
- i += self->row_num;
- }
- return Matrix_ass_item_row(self, i, value);
- }
- if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
+/** \} */
- if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Protocol Declarations
+ * \{ */
- if (step == 1) {
- return Matrix_ass_slice(self, start, stop, value);
- }
-
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
- return -1;
- }
-
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
- return -1;
-}
+static PySequenceMethods Matrix_SeqMethods = {
+ (lenfunc)Matrix_len, /*sq_length*/
+ (binaryfunc)NULL, /*sq_concat*/
+ (ssizeargfunc)NULL, /*sq_repeat*/
+ (ssizeargfunc)Matrix_item_row, /*sq_item*/
+ (ssizessizeargfunc)NULL, /*sq_slice(DEPRECATED)*/
+ (ssizeobjargproc)Matrix_ass_item_row, /*sq_ass_item*/
+ (ssizessizeobjargproc)NULL, /*sq_ass_slice(DEPRECATED)*/
+ (objobjproc)NULL, /*sq_contains*/
+ (binaryfunc)NULL, /*sq_inplace_concat*/
+ (ssizeargfunc)NULL, /*sq_inplace_repeat*/
+};
static PyMappingMethods Matrix_AsMapping = {
(lenfunc)Matrix_len,
@@ -2924,25 +2991,31 @@ static PyNumberMethods Matrix_NumMethods = {
NULL, /*nb_int*/
NULL, /*nb_reserved*/
NULL, /*nb_float*/
- NULL, /* nb_inplace_add */
- NULL, /* nb_inplace_subtract */
- (binaryfunc)Matrix_imul, /* nb_inplace_multiply */
- NULL, /* nb_inplace_remainder */
- NULL, /* nb_inplace_power */
- NULL, /* nb_inplace_lshift */
- NULL, /* nb_inplace_rshift */
- NULL, /* nb_inplace_and */
- NULL, /* nb_inplace_xor */
- NULL, /* nb_inplace_or */
- NULL, /* nb_floor_divide */
- NULL, /* nb_true_divide */
- NULL, /* nb_inplace_floor_divide */
- NULL, /* nb_inplace_true_divide */
- NULL, /* nb_index */
- (binaryfunc)Matrix_matmul, /* nb_matrix_multiply */
- (binaryfunc)Matrix_imatmul, /* nb_inplace_matrix_multiply */
+ NULL, /*nb_inplace_add*/
+ NULL, /*nb_inplace_subtract*/
+ (binaryfunc)Matrix_imul, /*nb_inplace_multiply*/
+ NULL, /*nb_inplace_remainder*/
+ NULL, /*nb_inplace_power*/
+ NULL, /*nb_inplace_lshift*/
+ NULL, /*nb_inplace_rshift*/
+ NULL, /*nb_inplace_and*/
+ NULL, /*nb_inplace_xor*/
+ NULL, /*nb_inplace_or*/
+ NULL, /*nb_floor_divide*/
+ NULL, /*nb_true_divide*/
+ NULL, /*nb_inplace_floor_divide*/
+ NULL, /*nb_inplace_true_divide*/
+ NULL, /*nb_index*/
+ (binaryfunc)Matrix_matmul, /*nb_matrix_multiply*/
+ (binaryfunc)Matrix_imatmul, /*nb_inplace_matrix_multiply*/
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Get/Set Item Implementation
+ * \{ */
+
PyDoc_STRVAR(Matrix_translation_doc, "The translation component of the matrix.\n\n:type: Vector");
static PyObject *Matrix_translation_get(MatrixObject *self, void *UNUSED(closure))
{
@@ -3099,9 +3172,12 @@ static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void
return NULL;
}
-/*****************************************************************************/
-/* Python attributes get/set structure: */
-/*****************************************************************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Get/Set Item Definitions
+ * \{ */
+
static PyGetSetDef Matrix_getseters[] = {
{"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, Matrix_median_scale_doc, NULL},
{"translation",
@@ -3141,7 +3217,12 @@ static PyGetSetDef Matrix_getseters[] = {
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
-/*-----------------------METHOD DEFINITIONS ----------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Method Definitions
+ * \{ */
+
static struct PyMethodDef Matrix_methods[] = {
/* Derived values. */
{"determinant", (PyCFunction)Matrix_determinant, METH_NOARGS, Matrix_determinant_doc},
@@ -3205,7 +3286,12 @@ static struct PyMethodDef Matrix_methods[] = {
{NULL, NULL, 0, NULL},
};
-/*------------------PY_OBECT DEFINITION--------------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: Python Object Definition
+ * \{ */
+
PyDoc_STRVAR(
matrix_doc,
".. class:: Matrix([rows])\n"
@@ -3268,6 +3354,12 @@ PyTypeObject matrix_Type = {
NULL, /*tp_del*/
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: C/API Constructors
+ * \{ */
+
PyObject *Matrix_CreatePyObject(const float *mat,
const ushort col_num,
const ushort row_num,
@@ -3380,6 +3472,12 @@ PyObject *Matrix_CreatePyObject_alloc(float *mat,
return (PyObject *)self;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix Type: C/API Parse Utilities
+ * \{ */
+
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*/
@@ -3460,8 +3558,11 @@ int Matrix_Parse4x4(PyObject *o, void *p)
return 1;
}
-/* ----------------------------------------------------------------------------
- * special type for alternate access */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix-Access Type: Struct & Internal Functions
+ * \{ */
typedef struct {
PyObject_HEAD /* Required Python macro. */
@@ -3491,7 +3592,11 @@ static void MatrixAccess_dealloc(MatrixAccessObject *self)
Py_TYPE(self)->tp_free(self);
}
-/* sequence access */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix-Access Type: Sequence Protocol
+ * \{ */
static int MatrixAccess_len(MatrixAccessObject *self)
{
@@ -3609,13 +3714,13 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item,
static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
{
- /* Try get values from a collection */
+ /* Try get values from a collection. */
PyObject *ret;
PyObject *iter = NULL;
ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM);
- /* we know this is a tuple so no need to PyIter_Check
- * otherwise it could be NULL (unlikely) if conversion failed */
+ /* We know this is a tuple so no need to #PyIter_Check
+ * otherwise it could be NULL (unlikely) if conversion failed. */
if (ret) {
iter = PyObject_GetIter(ret);
Py_DECREF(ret);
@@ -3630,6 +3735,12 @@ static PyMappingMethods MatrixAccess_AsMapping = {
(objobjargproc)MatrixAccess_ass_subscript,
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix-Access Type: Python Object Definition
+ * \{ */
+
PyTypeObject matrix_access_Type = {
PyVarObject_HEAD_INIT(NULL, 0) "MatrixAccess", /*tp_name*/
sizeof(MatrixAccessObject), /*tp_basicsize*/
@@ -3658,6 +3769,12 @@ PyTypeObject matrix_access_Type = {
(getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Matrix-Access Type: C/API Constructor
+ * \{ */
+
static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type)
{
MatrixAccessObject *matrix_access = (MatrixAccessObject *)PyObject_GC_New(MatrixObject,
@@ -3671,5 +3788,4 @@ static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrix
return (PyObject *)matrix_access;
}
-/* end special access
- * -------------------------------------------------------------------------- */
+/** \} */