diff options
author | Campbell Barton <campbell@blender.org> | 2022-05-25 05:33:15 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-05-25 05:37:27 +0300 |
commit | ae73bd3d9ebcbbc3729d4f3f23927012c6ac3abd (patch) | |
tree | 3faf07d520f7a5e07433acf0aba4011a2ea544f4 /source/blender/python/mathutils/mathutils_Matrix.c | |
parent | b0da080c2cb951c167c6154de75e154532ab0f0d (diff) |
Cleanup: use doxy sections for mathutils types
Also minor improvements & corrections to comments.
Diffstat (limited to 'source/blender/python/mathutils/mathutils_Matrix.c')
-rw-r--r-- | source/blender/python/mathutils/mathutils_Matrix.c | 1056 |
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 - * -------------------------------------------------------------------------- */ +/** \} */ |