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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/python/mathutils
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/python/mathutils')
-rw-r--r--source/blender/python/mathutils/CMakeLists.txt64
-rw-r--r--source/blender/python/mathutils/mathutils.c941
-rw-r--r--source/blender/python/mathutils/mathutils.h121
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c1520
-rw-r--r--source/blender/python/mathutils/mathutils_Color.h22
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c1224
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.h28
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c5371
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h48
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2382
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.h22
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c5250
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.h40
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c2117
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.h5
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c2702
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.c152
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.c668
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.h1
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c1687
20 files changed, 12379 insertions, 11986 deletions
diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt
index 7b0c042d50a..a58260a84f6 100644
--- a/source/blender/python/mathutils/CMakeLists.txt
+++ b/source/blender/python/mathutils/CMakeLists.txt
@@ -16,48 +16,48 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../../blenlib
- ../../blenkernel
- ../../bmesh
- ../../depsgraph
- ../../makesdna
- ../../../../intern/guardedalloc
+ .
+ ../../blenlib
+ ../../blenkernel
+ ../../bmesh
+ ../../depsgraph
+ ../../makesdna
+ ../../../../intern/guardedalloc
)
set(INC_SYS
- ${PYTHON_INCLUDE_DIRS}
+ ${PYTHON_INCLUDE_DIRS}
)
set(SRC
- mathutils.c
- mathutils_Color.c
- mathutils_Euler.c
- mathutils_Matrix.c
- mathutils_Quaternion.c
- mathutils_Vector.c
- mathutils_bvhtree.c
- mathutils_geometry.c
- mathutils_interpolate.c
- mathutils_kdtree.c
- mathutils_noise.c
+ mathutils.c
+ mathutils_Color.c
+ mathutils_Euler.c
+ mathutils_Matrix.c
+ mathutils_Quaternion.c
+ mathutils_Vector.c
+ mathutils_bvhtree.c
+ mathutils_geometry.c
+ mathutils_interpolate.c
+ mathutils_kdtree.c
+ mathutils_noise.c
- mathutils.h
- mathutils_Color.h
- mathutils_Euler.h
- mathutils_Matrix.h
- mathutils_Quaternion.h
- mathutils_Vector.h
- mathutils_bvhtree.h
- mathutils_geometry.h
- mathutils_interpolate.h
- mathutils_kdtree.h
- mathutils_noise.h
+ mathutils.h
+ mathutils_Color.h
+ mathutils_Euler.h
+ mathutils_Matrix.h
+ mathutils_Quaternion.h
+ mathutils_Vector.h
+ mathutils_bvhtree.h
+ mathutils_geometry.h
+ mathutils_interpolate.h
+ mathutils_kdtree.h
+ mathutils_noise.h
)
set(LIB
- bf_blenlib
- bf_python_ext
+ bf_blenlib
+ bf_python_ext
)
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 41738ced41a..32ffa4ad2da 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -31,59 +31,60 @@
# include "BLI_dynstr.h"
#endif
-PyDoc_STRVAR(M_Mathutils_doc,
-"This module provides access to math operations.\n"
-"\n"
-".. note::\n"
-"\n"
-" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
-" such as tuples, lists."
-"\n\n"
-"Submodules:\n"
-"\n"
-".. toctree::\n"
-" :maxdepth: 1\n"
-"\n"
-" mathutils.geometry.rst\n"
-" mathutils.bvhtree.rst\n"
-" mathutils.kdtree.rst\n"
-" mathutils.interpolate.rst\n"
-" mathutils.noise.rst\n"
-"\n"
-"The :mod:`mathutils` module provides the following classes:\n"
-"\n"
-"- :class:`Color`,\n"
-"- :class:`Euler`,\n"
-"- :class:`Matrix`,\n"
-"- :class:`Quaternion`,\n"
-"- :class:`Vector`,\n"
-);
+PyDoc_STRVAR(
+ M_Mathutils_doc,
+ "This module provides access to math operations.\n"
+ "\n"
+ ".. note::\n"
+ "\n"
+ " Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
+ " such as tuples, lists."
+ "\n\n"
+ "Submodules:\n"
+ "\n"
+ ".. toctree::\n"
+ " :maxdepth: 1\n"
+ "\n"
+ " mathutils.geometry.rst\n"
+ " mathutils.bvhtree.rst\n"
+ " mathutils.kdtree.rst\n"
+ " mathutils.interpolate.rst\n"
+ " mathutils.noise.rst\n"
+ "\n"
+ "The :mod:`mathutils` module provides the following classes:\n"
+ "\n"
+ "- :class:`Color`,\n"
+ "- :class:`Euler`,\n"
+ "- :class:`Matrix`,\n"
+ "- :class:`Quaternion`,\n"
+ "- :class:`Vector`,\n");
static int mathutils_array_parse_fast(float *array,
int size,
PyObject *value_fast,
const char *error_prefix)
{
- PyObject *item;
- PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
-
- int i;
-
- i = size;
- do {
- i--;
- if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
- PyErr_Occurred())
- {
- PyErr_Format(PyExc_TypeError,
- "%.200s: sequence index %d expected a number, "
- "found '%.200s' type, ",
- error_prefix, i, Py_TYPE(item)->tp_name);
- size = -1;
- break;
- }
- } while (i);
-
- return size;
+ PyObject *item;
+ PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
+
+ int i;
+
+ i = size;
+ do {
+ i--;
+ if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
+ PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: sequence index %d expected a number, "
+ "found '%.200s' type, ",
+ error_prefix,
+ i,
+ Py_TYPE(item)->tp_name);
+ size = -1;
+ break;
+ }
+ } while (i);
+
+ return size;
}
/**
@@ -93,271 +94,289 @@ static int mathutils_array_parse_fast(float *array,
*/
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
{
- int i;
- Py_uhash_t x; /* Unsigned for defined overflow behavior. */
- Py_hash_t y;
- Py_uhash_t mult;
- Py_ssize_t len;
-
- mult = _PyHASH_MULTIPLIER;
- len = array_len;
- x = 0x345678UL;
- i = 0;
- while (--len >= 0) {
- y = _Py_HashDouble((double)(array[i++]));
- if (y == -1) {
- return -1;
- }
- x = (x ^ y) * mult;
- /* the cast might truncate len; that doesn't change hash stability */
- mult += (Py_hash_t)(82520UL + len + len);
- }
- x += 97531UL;
- if (x == (Py_uhash_t)-1) {
- x = -2;
- }
- return x;
+ int i;
+ Py_uhash_t x; /* Unsigned for defined overflow behavior. */
+ Py_hash_t y;
+ Py_uhash_t mult;
+ Py_ssize_t len;
+
+ mult = _PyHASH_MULTIPLIER;
+ len = array_len;
+ x = 0x345678UL;
+ i = 0;
+ while (--len >= 0) {
+ y = _Py_HashDouble((double)(array[i++]));
+ if (y == -1) {
+ return -1;
+ }
+ x = (x ^ y) * mult;
+ /* the cast might truncate len; that doesn't change hash stability */
+ mult += (Py_hash_t)(82520UL + len + len);
+ }
+ x += 97531UL;
+ if (x == (Py_uhash_t)-1) {
+ x = -2;
+ }
+ return x;
}
/* helper function returns length of the 'value', -1 on error */
-int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
+int mathutils_array_parse(
+ float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
{
- const unsigned int flag = array_max;
- int size;
+ const unsigned int flag = array_max;
+ int size;
- array_max &= ~MU_ARRAY_FLAGS;
+ array_max &= ~MU_ARRAY_FLAGS;
#if 1 /* approx 6x speedup for mathutils types */
- if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
- (size = EulerObject_Check(value) ? 3 : 0) ||
- (size = QuaternionObject_Check(value) ? 4 : 0) ||
- (size = ColorObject_Check(value) ? 3 : 0))
- {
- if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
- return -1;
- }
-
- if (flag & MU_ARRAY_SPILL) {
- CLAMP_MAX(size, array_max);
- }
-
- if (size > array_max || size < array_min) {
- if (array_max == array_min) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected %d",
- error_prefix, size, array_max);
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected [%d - %d]",
- error_prefix, size, array_min, array_max);
- }
- return -1;
- }
-
- memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float));
- }
- else
+ if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
+ (size = EulerObject_Check(value) ? 3 : 0) ||
+ (size = QuaternionObject_Check(value) ? 4 : 0) ||
+ (size = ColorObject_Check(value) ? 3 : 0)) {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
+ if (size > array_max || size < array_min) {
+ if (array_max == array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected %d",
+ error_prefix,
+ size,
+ array_max);
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected [%d - %d]",
+ error_prefix,
+ size,
+ array_min,
+ array_max);
+ }
+ return -1;
+ }
+
+ memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float));
+ }
+ else
#endif
- {
- PyObject *value_fast = NULL;
-
- /* non list/tuple cases */
- if (!(value_fast = PySequence_Fast(value, error_prefix))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
-
- size = PySequence_Fast_GET_SIZE(value_fast);
-
- if (flag & MU_ARRAY_SPILL) {
- CLAMP_MAX(size, array_max);
- }
-
- if (size > array_max || size < array_min) {
- if (array_max == array_min) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected %d",
- error_prefix, size, array_max);
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected [%d - %d]",
- error_prefix, size, array_min, array_max);
- }
- Py_DECREF(value_fast);
- return -1;
- }
-
- size = mathutils_array_parse_fast(array, size, value_fast, error_prefix);
- Py_DECREF(value_fast);
- }
-
- if (size != -1) {
- if (flag & MU_ARRAY_ZERO) {
- int size_left = array_max - size;
- if (size_left) {
- memset(&array[size], 0, sizeof(float) * size_left);
- }
- }
- }
-
- return size;
+ {
+ PyObject *value_fast = NULL;
+
+ /* non list/tuple cases */
+ if (!(value_fast = PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
+
+ size = PySequence_Fast_GET_SIZE(value_fast);
+
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
+ if (size > array_max || size < array_min) {
+ if (array_max == array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected %d",
+ error_prefix,
+ size,
+ array_max);
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected [%d - %d]",
+ error_prefix,
+ size,
+ array_min,
+ array_max);
+ }
+ Py_DECREF(value_fast);
+ return -1;
+ }
+
+ size = mathutils_array_parse_fast(array, size, value_fast, error_prefix);
+ Py_DECREF(value_fast);
+ }
+
+ if (size != -1) {
+ if (flag & MU_ARRAY_ZERO) {
+ int size_left = array_max - size;
+ if (size_left) {
+ memset(&array[size], 0, sizeof(float) * size_left);
+ }
+ }
+ }
+
+ return size;
}
/* on error, -1 is returned and no allocation is made */
-int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix)
+int mathutils_array_parse_alloc(float **array,
+ int array_min,
+ PyObject *value,
+ const char *error_prefix)
{
- int size;
+ int size;
#if 1 /* approx 6x speedup for mathutils types */
- if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
- (size = EulerObject_Check(value) ? 3 : 0) ||
- (size = QuaternionObject_Check(value) ? 4 : 0) ||
- (size = ColorObject_Check(value) ? 3 : 0))
- {
- if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
- return -1;
- }
-
- if (size < array_min) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected > %d",
- error_prefix, size, array_min);
- return -1;
- }
-
- *array = PyMem_Malloc(size * sizeof(float));
- memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
- return size;
- }
- else
+ if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
+ (size = EulerObject_Check(value) ? 3 : 0) ||
+ (size = QuaternionObject_Check(value) ? 4 : 0) ||
+ (size = ColorObject_Check(value) ? 3 : 0)) {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+
+ if (size < array_min) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected > %d",
+ error_prefix,
+ size,
+ array_min);
+ return -1;
+ }
+
+ *array = PyMem_Malloc(size * sizeof(float));
+ memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
+ return size;
+ }
+ else
#endif
- {
- PyObject *value_fast = NULL;
- // *array = NULL;
- int ret;
-
- /* non list/tuple cases */
- if (!(value_fast = PySequence_Fast(value, error_prefix))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
-
- size = PySequence_Fast_GET_SIZE(value_fast);
-
- if (size < array_min) {
- Py_DECREF(value_fast);
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected > %d",
- error_prefix, size, array_min);
- return -1;
- }
-
- *array = PyMem_Malloc(size * sizeof(float));
-
- ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
- Py_DECREF(value_fast);
-
- if (ret == -1) {
- PyMem_Free(*array);
- }
-
- return ret;
- }
+ {
+ PyObject *value_fast = NULL;
+ // *array = NULL;
+ int ret;
+
+ /* non list/tuple cases */
+ if (!(value_fast = PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
+
+ size = PySequence_Fast_GET_SIZE(value_fast);
+
+ if (size < array_min) {
+ Py_DECREF(value_fast);
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected > %d",
+ error_prefix,
+ size,
+ array_min);
+ return -1;
+ }
+
+ *array = PyMem_Malloc(size * sizeof(float));
+
+ ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
+ Py_DECREF(value_fast);
+
+ if (ret == -1) {
+ PyMem_Free(*array);
+ }
+
+ return ret;
+ }
}
/* parse an array of vectors */
-int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
+int mathutils_array_parse_alloc_v(float **array,
+ int array_dim,
+ PyObject *value,
+ const char *error_prefix)
{
- PyObject *value_fast;
- const int array_dim_flag = array_dim;
- int i, size;
+ PyObject *value_fast;
+ const int array_dim_flag = array_dim;
+ int i, size;
- /* non list/tuple cases */
- if (!(value_fast = PySequence_Fast(value, error_prefix))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
+ /* non list/tuple cases */
+ if (!(value_fast = PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
- size = PySequence_Fast_GET_SIZE(value_fast);
+ size = PySequence_Fast_GET_SIZE(value_fast);
- if (size != 0) {
- PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
- float *fp;
+ if (size != 0) {
+ PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
+ float *fp;
- array_dim &= ~MU_ARRAY_FLAGS;
+ array_dim &= ~MU_ARRAY_FLAGS;
- fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
+ fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
- for (i = 0; i < size; i++, fp += array_dim) {
- PyObject *item = value_fast_items[i];
+ for (i = 0; i < size; i++, fp += array_dim) {
+ PyObject *item = value_fast_items[i];
- if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
- PyMem_Free(*array);
- *array = NULL;
- size = -1;
- break;
- }
- }
- }
+ if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
+ PyMem_Free(*array);
+ *array = NULL;
+ size = -1;
+ break;
+ }
+ }
+ }
- Py_DECREF(value_fast);
- return size;
+ Py_DECREF(value_fast);
+ return size;
}
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
{
- if (EulerObject_Check(value)) {
- if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
- return -1;
- }
- else {
- eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
- return 0;
- }
- }
- else if (QuaternionObject_Check(value)) {
- if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
- return -1;
- }
- else {
- float tquat[4];
- normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
- quat_to_mat3(rmat, tquat);
- return 0;
- }
- }
- else if (MatrixObject_Check(value)) {
- if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
- return -1;
- }
- else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: matrix must have minimum 3x3 dimensions",
- error_prefix);
- return -1;
- }
- else {
- matrix_as_3x3(rmat, (MatrixObject *)value);
- normalize_m3(rmat);
- return 0;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "%.200s: expected a Euler, Quaternion or Matrix type, "
- "found %.200s", error_prefix, Py_TYPE(value)->tp_name);
- return -1;
- }
+ if (EulerObject_Check(value)) {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+ else {
+ eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
+ return 0;
+ }
+ }
+ else if (QuaternionObject_Check(value)) {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+ else {
+ float tquat[4];
+ normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
+ quat_to_mat3(rmat, tquat);
+ return 0;
+ }
+ }
+ else if (MatrixObject_Check(value)) {
+ if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
+ return -1;
+ }
+ else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
+ PyErr_Format(
+ PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
+ return -1;
+ }
+ else {
+ matrix_as_3x3(rmat, (MatrixObject *)value);
+ normalize_m3(rmat);
+ return 0;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: expected a Euler, Quaternion or Matrix type, "
+ "found %.200s",
+ error_prefix,
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
}
-
/* ----------------------------------MATRIX FUNCTIONS-------------------- */
-
/* Utility functions */
/* LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon */
@@ -374,45 +393,45 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
{
- /* solid, fast routine across all platforms
- * with constant time behavior */
- int ai = *(int *)(&af);
- int bi = *(int *)(&bf);
- int test = SIGNMASK(ai ^ bi);
- int diff, v1, v2;
-
- assert((0 == test) || (0xFFFFFFFF == test));
- diff = (ai ^ (test & 0x7fffffff)) - bi;
- v1 = maxDiff + diff;
- v2 = maxDiff - diff;
- return (v1 | v2) >= 0;
+ /* solid, fast routine across all platforms
+ * with constant time behavior */
+ int ai = *(int *)(&af);
+ int bi = *(int *)(&bf);
+ int test = SIGNMASK(ai ^ bi);
+ int diff, v1, v2;
+
+ assert((0 == test) || (0xFFFFFFFF == test));
+ diff = (ai ^ (test & 0x7fffffff)) - bi;
+ v1 = maxDiff + diff;
+ v2 = maxDiff - diff;
+ return (v1 | v2) >= 0;
}
/*---------------------- EXPP_VectorsAreEqual -------------------------
* Builds on EXPP_FloatsAreEqual to test vectors */
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
{
- int x;
- for (x = 0; x < size; x++) {
- if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) {
- return 0;
- }
- }
- return 1;
+ int x;
+ for (x = 0; x < size; x++) {
+ if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) {
+ return 0;
+ }
+ }
+ return 1;
}
#ifndef MATH_STANDALONE
/* dynstr as python string utility functions, frees 'ds'! */
PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
{
- const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */
- char *ds_buf = PyMem_Malloc(ds_len + 1);
- PyObject *ret;
- BLI_dynstr_get_cstring_ex(ds, ds_buf);
- BLI_dynstr_free(ds);
- ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
- PyMem_Free(ds_buf);
- return ret;
+ const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */
+ char *ds_buf = PyMem_Malloc(ds_len + 1);
+ PyObject *ret;
+ BLI_dynstr_get_cstring_ex(ds, ds_buf);
+ BLI_dynstr_free(ds);
+ ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
+ PyMem_Free(ds_buf);
+ return ret;
}
#endif
@@ -424,183 +443,174 @@ static Mathutils_Callback *mathutils_callbacks[MATHUTILS_TOT_CB] = {NULL};
unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb)
{
- unsigned char i;
+ unsigned char i;
- /* find the first free slot */
- for (i = 0; mathutils_callbacks[i]; i++) {
- if (mathutils_callbacks[i] == cb) {
- /* already registered? */
- return i;
- }
- }
+ /* find the first free slot */
+ for (i = 0; mathutils_callbacks[i]; i++) {
+ if (mathutils_callbacks[i] == cb) {
+ /* already registered? */
+ return i;
+ }
+ }
- BLI_assert(i + 1 < MATHUTILS_TOT_CB);
+ BLI_assert(i + 1 < MATHUTILS_TOT_CB);
- mathutils_callbacks[i] = cb;
- return i;
+ mathutils_callbacks[i] = cb;
+ return i;
}
/* use macros to check for NULL */
int _BaseMathObject_ReadCallback(BaseMathObject *self)
{
- Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
- if (LIKELY(cb->get(self, self->cb_subtype) != -1)) {
- return 0;
- }
-
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_RuntimeError,
- "%s read, user has become invalid",
- Py_TYPE(self)->tp_name);
- }
- return -1;
+ Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
+ if (LIKELY(cb->get(self, self->cb_subtype) != -1)) {
+ return 0;
+ }
+
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_RuntimeError, "%s read, user has become invalid", Py_TYPE(self)->tp_name);
+ }
+ return -1;
}
int _BaseMathObject_WriteCallback(BaseMathObject *self)
{
- Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
- if (LIKELY(cb->set(self, self->cb_subtype) != -1)) {
- return 0;
- }
-
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_RuntimeError,
- "%s write, user has become invalid",
- Py_TYPE(self)->tp_name);
- }
- return -1;
+ Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
+ if (LIKELY(cb->set(self, self->cb_subtype) != -1)) {
+ return 0;
+ }
+
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_RuntimeError, "%s write, user has become invalid", Py_TYPE(self)->tp_name);
+ }
+ return -1;
}
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
{
- Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
- if (LIKELY(cb->get_index(self, self->cb_subtype, index) != -1)) {
- return 0;
- }
-
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_RuntimeError,
- "%s read index, user has become invalid",
- Py_TYPE(self)->tp_name);
- }
- return -1;
+ Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
+ if (LIKELY(cb->get_index(self, self->cb_subtype, index) != -1)) {
+ return 0;
+ }
+
+ if (!PyErr_Occurred()) {
+ PyErr_Format(
+ PyExc_RuntimeError, "%s read index, user has become invalid", Py_TYPE(self)->tp_name);
+ }
+ return -1;
}
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
{
- Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
- if (LIKELY(cb->set_index(self, self->cb_subtype, index) != -1)) {
- return 0;
- }
-
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_RuntimeError,
- "%s write index, user has become invalid",
- Py_TYPE(self)->tp_name);
- }
- return -1;
+ Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
+ if (LIKELY(cb->set_index(self, self->cb_subtype, index) != -1)) {
+ return 0;
+ }
+
+ if (!PyErr_Occurred()) {
+ PyErr_Format(
+ PyExc_RuntimeError, "%s write index, user has become invalid", Py_TYPE(self)->tp_name);
+ }
+ return -1;
}
void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self)
{
- PyErr_Format(PyExc_TypeError,
- "%s is frozen (immutable)",
- Py_TYPE(self)->tp_name);
+ PyErr_Format(PyExc_TypeError, "%s is frozen (immutable)", Py_TYPE(self)->tp_name);
}
void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
{
- PyErr_Format(PyExc_TypeError,
- "%s is not frozen (mutable), call freeze first",
- Py_TYPE(self)->tp_name);
+ PyErr_Format(
+ PyExc_TypeError, "%s is not frozen (mutable), call freeze first", Py_TYPE(self)->tp_name);
}
/* BaseMathObject generic functions for all mathutils types */
char BaseMathObject_owner_doc[] = "The item this is wrapping or None (read-only).";
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
{
- PyObject *ret = self->cb_user ? self->cb_user : Py_None;
- return Py_INCREF_RET(ret);
+ PyObject *ret = self->cb_user ? self->cb_user : Py_None;
+ return Py_INCREF_RET(ret);
}
-char BaseMathObject_is_wrapped_doc[] = "True when this object wraps external data (read-only).\n\n:type: boolean";
+char BaseMathObject_is_wrapped_doc[] =
+ "True when this object wraps external data (read-only).\n\n:type: boolean";
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
{
- return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0);
+ return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0);
}
-char BaseMathObject_is_frozen_doc[] = "True when this object has been frozen (read-only).\n\n:type: boolean";
+char BaseMathObject_is_frozen_doc[] =
+ "True when this object has been frozen (read-only).\n\n:type: boolean";
PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
{
- return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_FROZEN) != 0);
+ return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_FROZEN) != 0);
}
char BaseMathObject_freeze_doc[] =
-".. function:: freeze()\n"
-"\n"
-" Make this object immutable.\n"
-"\n"
-" After this the object can be hashed, used in dictionaries & sets.\n"
-"\n"
-" :return: An instance of this object.\n"
-;
+ ".. function:: freeze()\n"
+ "\n"
+ " Make this object immutable.\n"
+ "\n"
+ " After this the object can be hashed, used in dictionaries & sets.\n"
+ "\n"
+ " :return: An instance of this object.\n";
PyObject *BaseMathObject_freeze(BaseMathObject *self)
{
- if ((self->flag & BASE_MATH_FLAG_IS_WRAP) || (self->cb_user != NULL)) {
- PyErr_SetString(PyExc_TypeError, "Cannot freeze wrapped/owned data");
- return NULL;
- }
+ if ((self->flag & BASE_MATH_FLAG_IS_WRAP) || (self->cb_user != NULL)) {
+ PyErr_SetString(PyExc_TypeError, "Cannot freeze wrapped/owned data");
+ return NULL;
+ }
- self->flag |= BASE_MATH_FLAG_IS_FROZEN;
+ self->flag |= BASE_MATH_FLAG_IS_FROZEN;
- return Py_INCREF_RET((PyObject *)self);
+ return Py_INCREF_RET((PyObject *)self);
}
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
{
- Py_VISIT(self->cb_user);
- return 0;
+ Py_VISIT(self->cb_user);
+ return 0;
}
int BaseMathObject_clear(BaseMathObject *self)
{
- Py_CLEAR(self->cb_user);
- return 0;
+ Py_CLEAR(self->cb_user);
+ return 0;
}
void BaseMathObject_dealloc(BaseMathObject *self)
{
- /* only free non wrapped */
- if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) {
- PyMem_Free(self->data);
- }
+ /* only free non wrapped */
+ if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) {
+ PyMem_Free(self->data);
+ }
- if (self->cb_user) {
- PyObject_GC_UnTrack(self);
- BaseMathObject_clear(self);
- }
+ if (self->cb_user) {
+ PyObject_GC_UnTrack(self);
+ BaseMathObject_clear(self);
+ }
- Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
+ Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
}
/*----------------------------MODULE INIT-------------------------*/
static struct PyMethodDef M_Mathutils_methods[] = {
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef M_Mathutils_module_def = {
- PyModuleDef_HEAD_INIT,
- "mathutils", /* m_name */
- M_Mathutils_doc, /* m_doc */
- 0, /* m_size */
- M_Mathutils_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils", /* m_name */
+ M_Mathutils_doc, /* m_doc */
+ 0, /* m_size */
+ M_Mathutils_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
-
/* submodules only */
#include "mathutils_geometry.h"
#include "mathutils_interpolate.h"
@@ -612,68 +622,69 @@ static struct PyModuleDef M_Mathutils_module_def = {
PyMODINIT_FUNC PyInit_mathutils(void)
{
- PyObject *mod;
- PyObject *submodule;
- PyObject *sys_modules = PyImport_GetModuleDict();
-
- if (PyType_Ready(&vector_Type) < 0) {
- return NULL;
- }
- if (PyType_Ready(&matrix_Type) < 0) {
- return NULL;
- }
- if (PyType_Ready(&matrix_access_Type) < 0) {
- return NULL;
- }
- if (PyType_Ready(&euler_Type) < 0) {
- return NULL;
- }
- if (PyType_Ready(&quaternion_Type) < 0) {
- return NULL;
- }
- if (PyType_Ready(&color_Type) < 0) {
- return NULL;
- }
-
- mod = PyModule_Create(&M_Mathutils_module_def);
-
- /* each type has its own new() function */
- PyModule_AddObject(mod, vector_Type.tp_name, (PyObject *)&vector_Type);
- PyModule_AddObject(mod, matrix_Type.tp_name, (PyObject *)&matrix_Type);
- PyModule_AddObject(mod, euler_Type.tp_name, (PyObject *)&euler_Type);
- PyModule_AddObject(mod, quaternion_Type.tp_name, (PyObject *)&quaternion_Type);
- PyModule_AddObject(mod, color_Type.tp_name, (PyObject *)&color_Type);
-
- /* submodule */
- PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry()));
- /* XXX, python doesn't do imports with this usefully yet
- * 'from mathutils.geometry import PolyFill'
- * ...fails without this. */
- PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
-
- PyModule_AddObject(mod, "interpolate", (submodule = PyInit_mathutils_interpolate()));
- /* XXX, python doesnt do imports with this usefully yet
- * 'from mathutils.geometry import PolyFill'
- * ...fails without this. */
- PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+ PyObject *mod;
+ PyObject *submodule;
+ PyObject *sys_modules = PyImport_GetModuleDict();
+
+ if (PyType_Ready(&vector_Type) < 0) {
+ return NULL;
+ }
+ if (PyType_Ready(&matrix_Type) < 0) {
+ return NULL;
+ }
+ if (PyType_Ready(&matrix_access_Type) < 0) {
+ return NULL;
+ }
+ if (PyType_Ready(&euler_Type) < 0) {
+ return NULL;
+ }
+ if (PyType_Ready(&quaternion_Type) < 0) {
+ return NULL;
+ }
+ if (PyType_Ready(&color_Type) < 0) {
+ return NULL;
+ }
+
+ mod = PyModule_Create(&M_Mathutils_module_def);
+
+ /* each type has its own new() function */
+ PyModule_AddObject(mod, vector_Type.tp_name, (PyObject *)&vector_Type);
+ PyModule_AddObject(mod, matrix_Type.tp_name, (PyObject *)&matrix_Type);
+ PyModule_AddObject(mod, euler_Type.tp_name, (PyObject *)&euler_Type);
+ PyModule_AddObject(mod, quaternion_Type.tp_name, (PyObject *)&quaternion_Type);
+ PyModule_AddObject(mod, color_Type.tp_name, (PyObject *)&color_Type);
+
+ /* submodule */
+ PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry()));
+ /* XXX, python doesn't do imports with this usefully yet
+ * 'from mathutils.geometry import PolyFill'
+ * ...fails without this. */
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+
+ PyModule_AddObject(mod, "interpolate", (submodule = PyInit_mathutils_interpolate()));
+ /* XXX, python doesnt do imports with this usefully yet
+ * 'from mathutils.geometry import PolyFill'
+ * ...fails without this. */
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
#ifndef MATH_STANDALONE
- /* Noise submodule */
- PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));
- PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+ /* Noise submodule */
+ PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
- /* BVHTree submodule */
- PyModule_AddObject(mod, "bvhtree", (submodule = PyInit_mathutils_bvhtree()));
- PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+ /* BVHTree submodule */
+ PyModule_AddObject(mod, "bvhtree", (submodule = PyInit_mathutils_bvhtree()));
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
- /* KDTree_3d submodule */
- PyModule_AddObject(mod, "kdtree", (submodule = PyInit_mathutils_kdtree()));
- PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+ /* KDTree_3d submodule */
+ PyModule_AddObject(mod, "kdtree", (submodule = PyInit_mathutils_kdtree()));
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
#endif
- mathutils_matrix_row_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_row_cb);
- mathutils_matrix_col_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_col_cb);
- mathutils_matrix_translation_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_translation_cb);
+ mathutils_matrix_row_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_row_cb);
+ mathutils_matrix_col_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_col_cb);
+ mathutils_matrix_translation_cb_index = Mathutils_RegisterCallback(
+ &mathutils_matrix_translation_cb);
- return mod;
+ return mod;
}
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index bc5490a3acd..4ec2c869499 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -32,37 +32,39 @@ extern char BaseMathObject_is_frozen_doc[];
extern char BaseMathObject_owner_doc[];
#define BASE_MATH_NEW(struct_name, root_type, base_type) \
- (struct_name *)((base_type ? (base_type)->tp_alloc(base_type, 0) : _PyObject_GC_New(&(root_type))));
-
+ (struct_name *)((base_type ? (base_type)->tp_alloc(base_type, 0) : \
+ _PyObject_GC_New(&(root_type))));
/** BaseMathObject.flag */
enum {
- /**
- * Do not own the memory used in this vector,
- * \note This is error prone if the memory may be freed while this vector is in use.
- * Prefer using callbacks where possible, see: #Mathutils_RegisterCallback
- */
- BASE_MATH_FLAG_IS_WRAP = (1 << 0),
- /**
- * Prevent changes to the vector so it can be used as a set or dictionary key for example.
- * (typical use cases for tuple).
- */
- BASE_MATH_FLAG_IS_FROZEN = (1 << 1),
+ /**
+ * Do not own the memory used in this vector,
+ * \note This is error prone if the memory may be freed while this vector is in use.
+ * Prefer using callbacks where possible, see: #Mathutils_RegisterCallback
+ */
+ BASE_MATH_FLAG_IS_WRAP = (1 << 0),
+ /**
+ * Prevent changes to the vector so it can be used as a set or dictionary key for example.
+ * (typical use cases for tuple).
+ */
+ BASE_MATH_FLAG_IS_FROZEN = (1 << 1),
};
#define BASE_MATH_FLAG_DEFAULT 0
-#define BASE_MATH_MEMBERS(_data) \
- PyObject_VAR_HEAD \
- float *_data; /* array of data (alias), wrapped status depends on wrapped status */ \
- PyObject *cb_user; /* if this vector references another object, otherwise NULL, \
- * *Note* this owns its reference */ \
- unsigned char cb_type; /* which user funcs do we adhere to, RNA, etc */ \
- unsigned char cb_subtype; /* subtype: location, rotation... \
- * to avoid defining many new functions for every attribute of the same type */ \
- unsigned char flag /* wrapped data type? */ \
+#define BASE_MATH_MEMBERS(_data) \
+ PyObject_VAR_HEAD float \
+ *_data; /* array of data (alias), wrapped status depends on wrapped status */ \
+ PyObject * \
+ cb_user; /* if this vector references another object, otherwise NULL, \
+ * *Note* this owns its reference */ \
+ unsigned char cb_type; /* which user funcs do we adhere to, RNA, etc */ \
+ unsigned char \
+ cb_subtype; /* subtype: location, rotation... \
+ * to avoid defining many new functions for every attribute of the same type */ \
+ unsigned char flag /* wrapped data type? */
typedef struct {
- BASE_MATH_MEMBERS(data);
+ BASE_MATH_MEMBERS(data);
} BaseMathObject;
/* types */
@@ -73,8 +75,7 @@ typedef struct {
#include "mathutils_Color.h"
/* avoid checking all types */
-#define BaseMathObject_CheckExact(v) \
- (Py_TYPE(v)->tp_dealloc == (destructor)BaseMathObject_dealloc)
+#define BaseMathObject_CheckExact(v) (Py_TYPE(v)->tp_dealloc == (destructor)BaseMathObject_dealloc)
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *);
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *);
@@ -94,18 +95,23 @@ int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int flo
typedef struct Mathutils_Callback Mathutils_Callback;
-typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */
-typedef int (*BaseMathGetFunc)(BaseMathObject *, int); /* gets the vector from the user */
-typedef int (*BaseMathSetFunc)(BaseMathObject *, int); /* sets the users vector values once its modified */
-typedef int (*BaseMathGetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
-typedef int (*BaseMathSetIndexFunc)(BaseMathObject *, int, int); /* same as above but only for an index */
+typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */
+typedef int (*BaseMathGetFunc)(BaseMathObject *, int); /* gets the vector from the user */
+typedef int (*BaseMathSetFunc)(BaseMathObject *,
+ int); /* sets the users vector values once its modified */
+typedef int (*BaseMathGetIndexFunc)(BaseMathObject *,
+ int,
+ int); /* same as above but only for an index */
+typedef int (*BaseMathSetIndexFunc)(BaseMathObject *,
+ int,
+ int); /* same as above but only for an index */
struct Mathutils_Callback {
- BaseMathCheckFunc check;
- BaseMathGetFunc get;
- BaseMathSetFunc set;
- BaseMathGetIndexFunc get_index;
- BaseMathSetIndexFunc set_index;
+ BaseMathCheckFunc check;
+ BaseMathGetFunc get;
+ BaseMathSetFunc set;
+ BaseMathGetIndexFunc get_index;
+ BaseMathSetIndexFunc set_index;
};
unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb);
@@ -120,44 +126,55 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
/* since this is called so often avoid where possible */
#define BaseMath_ReadCallback(_self) \
- (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self) : 0))
+ (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self) : 0))
#define BaseMath_WriteCallback(_self) \
- (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self) : 0))
+ (((_self)->cb_user ? _BaseMathObject_WriteCallback((BaseMathObject *)_self) : 0))
#define BaseMath_ReadIndexCallback(_self, _index) \
- (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index) : 0))
+ (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index) : 0))
#define BaseMath_WriteIndexCallback(_self, _index) \
- (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index) : 0))
+ (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index) : 0))
/* support BASE_MATH_FLAG_IS_FROZEN */
#define BaseMath_ReadCallback_ForWrite(_self) \
- (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
- (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : (BaseMath_ReadCallback(_self)))
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \
+ (BaseMath_ReadCallback(_self)))
#define BaseMath_ReadIndexCallback_ForWrite(_self, _index) \
- (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
- (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : (BaseMath_ReadIndexCallback(_self, _index)))
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \
+ (BaseMath_ReadIndexCallback(_self, _index)))
#define BaseMath_Prepare_ForWrite(_self) \
- (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
- (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : 0)
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \
+ 0)
#define BaseMathObject_Prepare_ForHash(_self) \
- (UNLIKELY(((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) == 0) ? \
- (_BaseMathObject_RaiseNotFrozenExc((BaseMathObject *)_self), -1) : 0)
+ (UNLIKELY(((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) == 0) ? \
+ (_BaseMathObject_RaiseNotFrozenExc((BaseMathObject *)_self), -1) : \
+ 0)
/* utility func */
-int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
-int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix);
-int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix);
+int mathutils_array_parse(
+ float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
+int mathutils_array_parse_alloc(float **array,
+ int array_min,
+ PyObject *value,
+ const char *error_prefix);
+int mathutils_array_parse_alloc_v(float **array,
+ int array_dim,
+ PyObject *value,
+ const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
Py_hash_t mathutils_array_hash(const float *float_array, size_t array_len);
/* zero remaining unused elements of the array */
-#define MU_ARRAY_ZERO (1u << 30)
+#define MU_ARRAY_ZERO (1u << 30)
/* ignore larger py sequences than requested (just use first elements),
* handy when using 3d vectors as 2d */
-#define MU_ARRAY_SPILL (1u << 31)
+#define MU_ARRAY_SPILL (1u << 31)
#define MU_ARRAY_FLAGS (MU_ARRAY_ZERO | MU_ARRAY_SPILL)
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index 98e85782989..4e21a8e0389 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -39,30 +38,32 @@
/* makes a new color for you to play with */
static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- float col[3] = {0.0f, 0.0f, 0.0f};
-
- if (kwds && PyDict_Size(kwds)) {
- PyErr_SetString(PyExc_TypeError,
- "mathutils.Color(): "
- "takes no keyword args");
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- break;
- case 1:
- if ((mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1) {
- return NULL;
- }
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "mathutils.Color(): "
- "more than a single arg given");
- return NULL;
- }
- return Color_CreatePyObject(col, type);
+ float col[3] = {0.0f, 0.0f, 0.0f};
+
+ if (kwds && PyDict_Size(kwds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "mathutils.Color(): "
+ "takes no keyword args");
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ break;
+ case 1:
+ if ((mathutils_array_parse(
+ col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) ==
+ -1) {
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "mathutils.Color(): "
+ "more than a single arg given");
+ return NULL;
+ }
+ return Color_CreatePyObject(col, type);
}
/* -----------------------------METHODS---------------------------- */
@@ -70,50 +71,49 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* note: BaseMath_ReadCallback must be called beforehand */
static PyObject *Color_ToTupleExt(ColorObject *self, int ndigits)
{
- PyObject *ret;
- int i;
-
- ret = PyTuple_New(COLOR_SIZE);
-
- if (ndigits >= 0) {
- for (i = 0; i < COLOR_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits)));
- }
- }
- else {
- for (i = 0; i < COLOR_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i]));
- }
- }
-
- return ret;
+ PyObject *ret;
+ int i;
+
+ ret = PyTuple_New(COLOR_SIZE);
+
+ if (ndigits >= 0) {
+ for (i = 0; i < COLOR_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits)));
+ }
+ }
+ else {
+ for (i = 0; i < COLOR_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i]));
+ }
+ }
+
+ return ret;
}
PyDoc_STRVAR(Color_copy_doc,
-".. function:: copy()\n"
-"\n"
-" Returns a copy of this color.\n"
-"\n"
-" :return: A copy of the color.\n"
-" :rtype: :class:`Color`\n"
-"\n"
-" .. note:: use this to get a copy of a wrapped color with\n"
-" no reference to the original data.\n"
-);
+ ".. function:: copy()\n"
+ "\n"
+ " Returns a copy of this color.\n"
+ "\n"
+ " :return: A copy of the color.\n"
+ " :rtype: :class:`Color`\n"
+ "\n"
+ " .. note:: use this to get a copy of a wrapped color with\n"
+ " no reference to the original data.\n");
static PyObject *Color_copy(ColorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Color_CreatePyObject(self->col, Py_TYPE(self));
+ return Color_CreatePyObject(self->col, Py_TYPE(self));
}
static PyObject *Color_deepcopy(ColorObject *self, PyObject *args)
{
- if (!PyC_CheckArgs_DeepCopy(args)) {
- return NULL;
- }
- return Color_copy(self);
+ if (!PyC_CheckArgs_DeepCopy(args)) {
+ return NULL;
+ }
+ return Color_copy(self);
}
/* ----------------------------print object (internal)-------------- */
@@ -121,35 +121,35 @@ static PyObject *Color_deepcopy(ColorObject *self, PyObject *args)
static PyObject *Color_repr(ColorObject *self)
{
- PyObject *ret, *tuple;
+ PyObject *ret, *tuple;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- tuple = Color_ToTupleExt(self, -1);
+ tuple = Color_ToTupleExt(self, -1);
- ret = PyUnicode_FromFormat("Color(%R)", tuple);
+ ret = PyUnicode_FromFormat("Color(%R)", tuple);
- Py_DECREF(tuple);
- return ret;
+ Py_DECREF(tuple);
+ return ret;
}
#ifndef MATH_STANDALONE
static PyObject *Color_str(ColorObject *self)
{
- DynStr *ds;
+ DynStr *ds;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- ds = BLI_dynstr_new();
+ ds = BLI_dynstr_new();
- BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>",
- self->col[0], self->col[1], self->col[2]);
+ BLI_dynstr_appendf(
+ ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>", self->col[0], self->col[1], self->col[2]);
- return mathutils_dynstr_to_py(ds); /* frees ds */
+ return mathutils_dynstr_to_py(ds); /* frees ds */
}
#endif
@@ -157,53 +157,53 @@ static PyObject *Color_str(ColorObject *self)
/* returns -1 exception, 0 false, 1 true */
static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
{
- PyObject *res;
- int ok = -1; /* zero is true */
-
- if (ColorObject_Check(a) && ColorObject_Check(b)) {
- ColorObject *colA = (ColorObject *)a;
- ColorObject *colB = (ColorObject *)b;
-
- if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) {
- return NULL;
- }
-
- ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
- }
-
- switch (op) {
- case Py_NE:
- ok = !ok;
- ATTR_FALLTHROUGH;
- case Py_EQ:
- res = ok ? Py_False : Py_True;
- break;
-
- case Py_LT:
- case Py_LE:
- case Py_GT:
- case Py_GE:
- res = Py_NotImplemented;
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
-
- return Py_INCREF_RET(res);
+ PyObject *res;
+ int ok = -1; /* zero is true */
+
+ if (ColorObject_Check(a) && ColorObject_Check(b)) {
+ ColorObject *colA = (ColorObject *)a;
+ ColorObject *colB = (ColorObject *)b;
+
+ if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) {
+ return NULL;
+ }
+
+ ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
+ }
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok;
+ ATTR_FALLTHROUGH;
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ return Py_INCREF_RET(res);
}
static Py_hash_t Color_hash(ColorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- if (BaseMathObject_Prepare_ForHash(self) == -1) {
- return -1;
- }
+ if (BaseMathObject_Prepare_ForHash(self) == -1) {
+ return -1;
+ }
- return mathutils_array_hash(self->col, COLOR_SIZE);
+ return mathutils_array_hash(self->col, COLOR_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -211,525 +211,523 @@ static Py_hash_t Color_hash(ColorObject *self)
/* sequence length */
static int Color_len(ColorObject *UNUSED(self))
{
- return COLOR_SIZE;
+ return COLOR_SIZE;
}
/* ----------------------------object[]--------------------------- */
/* sequence accessor (get) */
static PyObject *Color_item(ColorObject *self, int i)
{
- if (i < 0) {
- i = COLOR_SIZE - i;
- }
-
- if (i < 0 || i >= COLOR_SIZE) {
- PyErr_SetString(PyExc_IndexError,
- "color[item]: "
- "array index out of range");
- return NULL;
- }
-
- if (BaseMath_ReadIndexCallback(self, i) == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(self->col[i]);
-
+ if (i < 0) {
+ i = COLOR_SIZE - i;
+ }
+
+ if (i < 0 || i >= COLOR_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "color[item]: "
+ "array index out of range");
+ return NULL;
+ }
+
+ if (BaseMath_ReadIndexCallback(self, i) == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(self->col[i]);
}
/* ----------------------------object[]------------------------- */
/* sequence accessor (set) */
static int Color_ass_item(ColorObject *self, int i, PyObject *value)
{
- float f;
-
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
-
- f = PyFloat_AsDouble(value);
- if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "color[item] = x: "
- "assigned value not a number");
- return -1;
- }
-
- if (i < 0) {
- i = COLOR_SIZE - i;
- }
-
- if (i < 0 || i >= COLOR_SIZE) {
- PyErr_SetString(PyExc_IndexError, "color[item] = x: "
- "array assignment index out of range");
- return -1;
- }
-
- self->col[i] = f;
-
- if (BaseMath_WriteIndexCallback(self, i) == -1) {
- return -1;
- }
-
- return 0;
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ f = PyFloat_AsDouble(value);
+ if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "color[item] = x: "
+ "assigned value not a number");
+ return -1;
+ }
+
+ if (i < 0) {
+ i = COLOR_SIZE - i;
+ }
+
+ if (i < 0 || i >= COLOR_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "color[item] = x: "
+ "array assignment index out of range");
+ return -1;
+ }
+
+ self->col[i] = f;
+
+ if (BaseMath_WriteIndexCallback(self, i) == -1) {
+ return -1;
+ }
+
+ return 0;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (get) */
static PyObject *Color_slice(ColorObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- CLAMP(begin, 0, COLOR_SIZE);
- if (end < 0) {
- end = (COLOR_SIZE + 1) + end;
- }
- CLAMP(end, 0, COLOR_SIZE);
- begin = MIN2(begin, end);
-
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count]));
- }
-
- return tuple;
+ PyObject *tuple;
+ int count;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ CLAMP(begin, 0, COLOR_SIZE);
+ if (end < 0) {
+ end = (COLOR_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, COLOR_SIZE);
+ begin = MIN2(begin, end);
+
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count]));
+ }
+
+ return tuple;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (set) */
static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
{
- int i, size;
- float col[COLOR_SIZE];
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- CLAMP(begin, 0, COLOR_SIZE);
- if (end < 0) {
- end = (COLOR_SIZE + 1) + end;
- }
- CLAMP(end, 0, COLOR_SIZE);
- begin = MIN2(begin, end);
-
- if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1) {
- return -1;
- }
-
- if (size != (end - begin)) {
- PyErr_SetString(PyExc_ValueError,
- "color[begin:end] = []: "
- "size mismatch in slice assignment");
- return -1;
- }
-
- for (i = 0; i < COLOR_SIZE; i++) {
- self->col[begin + i] = col[i];
- }
-
- (void)BaseMath_WriteCallback(self);
- return 0;
+ int i, size;
+ float col[COLOR_SIZE];
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ CLAMP(begin, 0, COLOR_SIZE);
+ if (end < 0) {
+ end = (COLOR_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, COLOR_SIZE);
+ begin = MIN2(begin, end);
+
+ if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) ==
+ -1) {
+ return -1;
+ }
+
+ if (size != (end - begin)) {
+ PyErr_SetString(PyExc_ValueError,
+ "color[begin:end] = []: "
+ "size mismatch in slice assignment");
+ return -1;
+ }
+
+ for (i = 0; i < COLOR_SIZE; i++) {
+ self->col[begin + i] = col[i];
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static PyObject *Color_subscript(ColorObject *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 += COLOR_SIZE;
- }
- return Color_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return Color_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with color");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "color indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ 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 += COLOR_SIZE;
+ }
+ return Color_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return Color_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
+ }
}
static int Color_ass_subscript(ColorObject *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 += COLOR_SIZE;
- }
- return Color_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
-
- if (step == 1) {
- return Color_ass_slice(self, start, stop, value);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with color");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "color indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ 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 += COLOR_SIZE;
+ }
+ return Color_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Color_ass_slice(self, start, stop, value);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
/* -----------------PROTCOL DECLARATIONS-------------------------- */
static PySequenceMethods Color_SeqMethods = {
- (lenfunc) Color_len, /* sq_length */
- (binaryfunc) NULL, /* sq_concat */
- (ssizeargfunc) NULL, /* sq_repeat */
- (ssizeargfunc) Color_item, /* sq_item */
- NULL, /* sq_slice, deprecated */
- (ssizeobjargproc) Color_ass_item, /* sq_ass_item */
- NULL, /* sq_ass_slice, deprecated */
- (objobjproc) NULL, /* sq_contains */
- (binaryfunc) NULL, /* sq_inplace_concat */
- (ssizeargfunc) NULL, /* sq_inplace_repeat */
+ (lenfunc)Color_len, /* sq_length */
+ (binaryfunc)NULL, /* sq_concat */
+ (ssizeargfunc)NULL, /* sq_repeat */
+ (ssizeargfunc)Color_item, /* sq_item */
+ NULL, /* sq_slice, deprecated */
+ (ssizeobjargproc)Color_ass_item, /* sq_ass_item */
+ NULL, /* sq_ass_slice, deprecated */
+ (objobjproc)NULL, /* sq_contains */
+ (binaryfunc)NULL, /* sq_inplace_concat */
+ (ssizeargfunc)NULL, /* sq_inplace_repeat */
};
static PyMappingMethods Color_AsMapping = {
- (lenfunc)Color_len,
- (binaryfunc)Color_subscript,
- (objobjargproc)Color_ass_subscript,
+ (lenfunc)Color_len,
+ (binaryfunc)Color_subscript,
+ (objobjargproc)Color_ass_subscript,
};
/* numeric */
-
/* addition: obj + obj */
static PyObject *Color_add(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL, *color2 = NULL;
- float col[COLOR_SIZE];
-
- if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
- PyErr_Format(PyExc_TypeError,
- "Color addition: (%s + %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- color1 = (ColorObject *)v1;
- color2 = (ColorObject *)v2;
-
- if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
- return NULL;
- }
-
- add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
-
- return Color_CreatePyObject(col, Py_TYPE(v1));
+ ColorObject *color1 = NULL, *color2 = NULL;
+ float col[COLOR_SIZE];
+
+ if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Color addition: (%s + %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ color1 = (ColorObject *)v1;
+ color2 = (ColorObject *)v2;
+
+ if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
+ return NULL;
+ }
+
+ add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
+
+ return Color_CreatePyObject(col, Py_TYPE(v1));
}
/* addition in-place: obj += obj */
static PyObject *Color_iadd(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL, *color2 = NULL;
-
- if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
- PyErr_Format(PyExc_TypeError,
- "Color addition: (%s += %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- color1 = (ColorObject *)v1;
- color2 = (ColorObject *)v2;
-
- if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
- return NULL;
- }
-
- add_vn_vn(color1->col, color2->col, COLOR_SIZE);
-
- (void)BaseMath_WriteCallback(color1);
- Py_INCREF(v1);
- return v1;
+ ColorObject *color1 = NULL, *color2 = NULL;
+
+ if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Color addition: (%s += %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ color1 = (ColorObject *)v1;
+ color2 = (ColorObject *)v2;
+
+ if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
+ return NULL;
+ }
+
+ add_vn_vn(color1->col, color2->col, COLOR_SIZE);
+
+ (void)BaseMath_WriteCallback(color1);
+ Py_INCREF(v1);
+ return v1;
}
/* subtraction: obj - obj */
static PyObject *Color_sub(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL, *color2 = NULL;
- float col[COLOR_SIZE];
-
- if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
- PyErr_Format(PyExc_TypeError,
- "Color subtraction: (%s - %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- color1 = (ColorObject *)v1;
- color2 = (ColorObject *)v2;
-
- if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
- return NULL;
- }
-
- sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
-
- return Color_CreatePyObject(col, Py_TYPE(v1));
+ ColorObject *color1 = NULL, *color2 = NULL;
+ float col[COLOR_SIZE];
+
+ if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Color subtraction: (%s - %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ color1 = (ColorObject *)v1;
+ color2 = (ColorObject *)v2;
+
+ if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
+ return NULL;
+ }
+
+ sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
+
+ return Color_CreatePyObject(col, Py_TYPE(v1));
}
/* subtraction in-place: obj -= obj */
static PyObject *Color_isub(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL, *color2 = NULL;
-
- if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
- PyErr_Format(PyExc_TypeError,
- "Color subtraction: (%s -= %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- color1 = (ColorObject *)v1;
- color2 = (ColorObject *)v2;
-
- if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
- return NULL;
- }
-
- sub_vn_vn(color1->col, color2->col, COLOR_SIZE);
-
- (void)BaseMath_WriteCallback(color1);
- Py_INCREF(v1);
- return v1;
+ ColorObject *color1 = NULL, *color2 = NULL;
+
+ if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Color subtraction: (%s -= %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ color1 = (ColorObject *)v1;
+ color2 = (ColorObject *)v2;
+
+ if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
+ return NULL;
+ }
+
+ sub_vn_vn(color1->col, color2->col, COLOR_SIZE);
+
+ (void)BaseMath_WriteCallback(color1);
+ Py_INCREF(v1);
+ return v1;
}
static PyObject *color_mul_float(ColorObject *color, const float scalar)
{
- float tcol[COLOR_SIZE];
- mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar);
- return Color_CreatePyObject(tcol, Py_TYPE(color));
+ float tcol[COLOR_SIZE];
+ mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar);
+ return Color_CreatePyObject(tcol, Py_TYPE(color));
}
-
static PyObject *Color_mul(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL, *color2 = NULL;
- float scalar;
-
- if (ColorObject_Check(v1)) {
- color1 = (ColorObject *)v1;
- if (BaseMath_ReadCallback(color1) == -1) {
- return NULL;
- }
- }
- if (ColorObject_Check(v2)) {
- color2 = (ColorObject *)v2;
- if (BaseMath_ReadCallback(color2) == -1) {
- return NULL;
- }
- }
-
-
- /* make sure v1 is always the vector */
- if (color1 && color2) {
- /* col * col, don't support yet! */
- }
- else if (color1) {
- if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
- return color_mul_float(color1, scalar);
- }
- }
- else if (color2) {
- if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */
- return color_mul_float(color2, scalar);
- }
- }
- else {
- BLI_assert(!"internal error");
- }
-
- PyErr_Format(PyExc_TypeError,
- "Color multiplication: not supported between "
- "'%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ ColorObject *color1 = NULL, *color2 = NULL;
+ float scalar;
+
+ if (ColorObject_Check(v1)) {
+ color1 = (ColorObject *)v1;
+ if (BaseMath_ReadCallback(color1) == -1) {
+ return NULL;
+ }
+ }
+ if (ColorObject_Check(v2)) {
+ color2 = (ColorObject *)v2;
+ if (BaseMath_ReadCallback(color2) == -1) {
+ return NULL;
+ }
+ }
+
+ /* make sure v1 is always the vector */
+ if (color1 && color2) {
+ /* col * col, don't support yet! */
+ }
+ else if (color1) {
+ if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
+ return color_mul_float(color1, scalar);
+ }
+ }
+ else if (color2) {
+ if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */
+ return color_mul_float(color2, scalar);
+ }
+ }
+ else {
+ BLI_assert(!"internal error");
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Color multiplication: not supported between "
+ "'%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
}
static PyObject *Color_div(PyObject *v1, PyObject *v2)
{
- ColorObject *color1 = NULL;
- float scalar;
-
- if (ColorObject_Check(v1)) {
- color1 = (ColorObject *)v1;
- if (BaseMath_ReadCallback(color1) == -1) {
- return NULL;
- }
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "Color division not supported in this order");
- return NULL;
- }
-
- /* make sure v1 is always the vector */
- if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
- if (scalar == 0.0f) {
- PyErr_SetString(PyExc_ZeroDivisionError,
- "Color division: divide by zero error");
- return NULL;
- }
- return color_mul_float(color1, 1.0f / scalar);
- }
-
- PyErr_Format(PyExc_TypeError,
- "Color multiplication: not supported between "
- "'%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ ColorObject *color1 = NULL;
+ float scalar;
+
+ if (ColorObject_Check(v1)) {
+ color1 = (ColorObject *)v1;
+ if (BaseMath_ReadCallback(color1) == -1) {
+ return NULL;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "Color division not supported in this order");
+ return NULL;
+ }
+
+ /* make sure v1 is always the vector */
+ if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
+ if (scalar == 0.0f) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error");
+ return NULL;
+ }
+ return color_mul_float(color1, 1.0f / scalar);
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Color multiplication: not supported between "
+ "'%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
}
/* multiplication in-place: obj *= obj */
static PyObject *Color_imul(PyObject *v1, PyObject *v2)
{
- ColorObject *color = (ColorObject *)v1;
- float scalar;
-
- if (BaseMath_ReadCallback_ForWrite(color) == -1) {
- return NULL;
- }
-
- /* only support color *= float */
- if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */
- mul_vn_fl(color->col, COLOR_SIZE, scalar);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Color multiplication: (%s *= %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(color);
- Py_INCREF(v1);
- return v1;
+ ColorObject *color = (ColorObject *)v1;
+ float scalar;
+
+ if (BaseMath_ReadCallback_ForWrite(color) == -1) {
+ return NULL;
+ }
+
+ /* only support color *= float */
+ if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */
+ mul_vn_fl(color->col, COLOR_SIZE, scalar);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Color multiplication: (%s *= %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(color);
+ Py_INCREF(v1);
+ return v1;
}
/* multiplication in-place: obj *= obj */
static PyObject *Color_idiv(PyObject *v1, PyObject *v2)
{
- ColorObject *color = (ColorObject *)v1;
- float scalar;
-
- if (BaseMath_ReadCallback_ForWrite(color) == -1) {
- return NULL;
- }
-
- /* only support color /= float */
- if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */
- if (scalar == 0.0f) {
- PyErr_SetString(PyExc_ZeroDivisionError,
- "Color division: divide by zero error");
- return NULL;
- }
-
- mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Color division: (%s /= %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(color);
- Py_INCREF(v1);
- return v1;
+ ColorObject *color = (ColorObject *)v1;
+ float scalar;
+
+ if (BaseMath_ReadCallback_ForWrite(color) == -1) {
+ return NULL;
+ }
+
+ /* only support color /= float */
+ if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */
+ if (scalar == 0.0f) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error");
+ return NULL;
+ }
+
+ mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Color division: (%s /= %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(color);
+ Py_INCREF(v1);
+ return v1;
}
/* -obj
* returns the negative of this object */
static PyObject *Color_neg(ColorObject *self)
{
- float tcol[COLOR_SIZE];
+ float tcol[COLOR_SIZE];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- negate_vn_vn(tcol, self->col, COLOR_SIZE);
- return Color_CreatePyObject(tcol, Py_TYPE(self));
+ negate_vn_vn(tcol, self->col, COLOR_SIZE);
+ return Color_CreatePyObject(tcol, Py_TYPE(self));
}
-
static PyNumberMethods Color_NumMethods = {
- (binaryfunc) Color_add, /*nb_add*/
- (binaryfunc) Color_sub, /*nb_subtract*/
- (binaryfunc) Color_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc) Color_neg, /*nb_negative*/
- (unaryfunc) Color_copy, /*tp_positive*/
- (unaryfunc) NULL, /*tp_absolute*/
- (inquiry) NULL, /*tp_bool*/
- (unaryfunc) NULL, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)NULL, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- Color_iadd, /* nb_inplace_add */
- Color_isub, /* nb_inplace_subtract */
- Color_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 */
- Color_div, /* nb_true_divide */
- NULL, /* nb_inplace_floor_divide */
- Color_idiv, /* nb_inplace_true_divide */
- NULL, /* nb_index */
+ (binaryfunc)Color_add, /*nb_add*/
+ (binaryfunc)Color_sub, /*nb_subtract*/
+ (binaryfunc)Color_mul, /*nb_multiply*/
+ NULL, /*nb_remainder*/
+ NULL, /*nb_divmod*/
+ NULL, /*nb_power*/
+ (unaryfunc)Color_neg, /*nb_negative*/
+ (unaryfunc)Color_copy, /*tp_positive*/
+ (unaryfunc)NULL, /*tp_absolute*/
+ (inquiry)NULL, /*tp_bool*/
+ (unaryfunc)NULL, /*nb_invert*/
+ NULL, /*nb_lshift*/
+ (binaryfunc)NULL, /*nb_rshift*/
+ NULL, /*nb_and*/
+ NULL, /*nb_xor*/
+ NULL, /*nb_or*/
+ NULL, /*nb_int*/
+ NULL, /*nb_reserved*/
+ NULL, /*nb_float*/
+ Color_iadd, /* nb_inplace_add */
+ Color_isub, /* nb_inplace_subtract */
+ Color_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 */
+ Color_div, /* nb_true_divide */
+ NULL, /* nb_inplace_floor_divide */
+ Color_idiv, /* nb_inplace_true_divide */
+ NULL, /* nb_index */
};
/* color channel, vector.r/g/b */
@@ -739,12 +737,12 @@ PyDoc_STRVAR(Color_channel_b_doc, "Blue color channel.\n\n:type: float");
static PyObject *Color_channel_get(ColorObject *self, void *type)
{
- return Color_item(self, POINTER_AS_INT(type));
+ return Color_item(self, POINTER_AS_INT(type));
}
static int Color_channel_set(ColorObject *self, PyObject *value, void *type)
{
- return Color_ass_item(self, POINTER_AS_INT(type), value);
+ return Color_ass_item(self, POINTER_AS_INT(type), value);
}
/* color channel (HSV), color.h/s/v */
@@ -754,258 +752,290 @@ PyDoc_STRVAR(Color_channel_hsv_v_doc, "HSV Value component in [0, 1].\n\n:type:
static PyObject *Color_channel_hsv_get(ColorObject *self, void *type)
{
- float hsv[3];
- int i = POINTER_AS_INT(type);
+ float hsv[3];
+ int i = POINTER_AS_INT(type);
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
+ rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
- return PyFloat_FromDouble(hsv[i]);
+ return PyFloat_FromDouble(hsv[i]);
}
static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
{
- float hsv[3];
- int i = POINTER_AS_INT(type);
- float f = PyFloat_AsDouble(value);
-
- if (f == -1 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "color.h/s/v = value: "
- "assigned value not a number");
- return -1;
- }
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- rgb_to_hsv_v(self->col, hsv);
- CLAMP(f, 0.0f, 1.0f);
- hsv[i] = f;
- hsv_to_rgb_v(hsv, self->col);
-
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
-
- return 0;
+ float hsv[3];
+ int i = POINTER_AS_INT(type);
+ float f = PyFloat_AsDouble(value);
+
+ if (f == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "color.h/s/v = value: "
+ "assigned value not a number");
+ return -1;
+ }
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ rgb_to_hsv_v(self->col, hsv);
+ CLAMP(f, 0.0f, 1.0f);
+ hsv[i] = f;
+ hsv_to_rgb_v(hsv, self->col);
+
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
+
+ return 0;
}
/* color channel (HSV), color.h/s/v */
PyDoc_STRVAR(Color_hsv_doc, "HSV Values in [0, 1].\n\n:type: float triplet");
static PyObject *Color_hsv_get(ColorObject *self, void *UNUSED(closure))
{
- float hsv[3];
- PyObject *ret;
+ float hsv[3];
+ PyObject *ret;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
+ rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
- ret = PyTuple_New(3);
- PyTuple_SET_ITEMS(ret,
- PyFloat_FromDouble(hsv[0]),
- PyFloat_FromDouble(hsv[1]),
- PyFloat_FromDouble(hsv[2]));
- return ret;
+ ret = PyTuple_New(3);
+ PyTuple_SET_ITEMS(
+ ret, PyFloat_FromDouble(hsv[0]), PyFloat_FromDouble(hsv[1]), PyFloat_FromDouble(hsv[2]));
+ return ret;
}
static int Color_hsv_set(ColorObject *self, PyObject *value, void *UNUSED(closure))
{
- float hsv[3];
+ float hsv[3];
- if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1) {
- return -1;
- }
+ if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1) {
+ return -1;
+ }
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
- CLAMP(hsv[0], 0.0f, 1.0f);
- CLAMP(hsv[1], 0.0f, 1.0f);
- CLAMP(hsv[2], 0.0f, 1.0f);
+ CLAMP(hsv[0], 0.0f, 1.0f);
+ CLAMP(hsv[1], 0.0f, 1.0f);
+ CLAMP(hsv[2], 0.0f, 1.0f);
- hsv_to_rgb_v(hsv, self->col);
+ hsv_to_rgb_v(hsv, self->col);
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Color_getseters[] = {
- {(char *)"r", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_r_doc, (void *)0},
- {(char *)"g", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_g_doc, (void *)1},
- {(char *)"b", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_b_doc, (void *)2},
-
- {(char *)"h", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_h_doc, (void *)0},
- {(char *)"s", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_s_doc, (void *)1},
- {(char *)"v", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_v_doc, (void *)2},
-
- {(char *)"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, (char *)Color_hsv_doc, (void *)0},
-
- {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
- {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
- {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {(char *)"r",
+ (getter)Color_channel_get,
+ (setter)Color_channel_set,
+ Color_channel_r_doc,
+ (void *)0},
+ {(char *)"g",
+ (getter)Color_channel_get,
+ (setter)Color_channel_set,
+ Color_channel_g_doc,
+ (void *)1},
+ {(char *)"b",
+ (getter)Color_channel_get,
+ (setter)Color_channel_set,
+ Color_channel_b_doc,
+ (void *)2},
+
+ {(char *)"h",
+ (getter)Color_channel_hsv_get,
+ (setter)Color_channel_hsv_set,
+ (char *)Color_channel_hsv_h_doc,
+ (void *)0},
+ {(char *)"s",
+ (getter)Color_channel_hsv_get,
+ (setter)Color_channel_hsv_set,
+ (char *)Color_channel_hsv_s_doc,
+ (void *)1},
+ {(char *)"v",
+ (getter)Color_channel_hsv_get,
+ (setter)Color_channel_hsv_set,
+ (char *)Color_channel_hsv_v_doc,
+ (void *)2},
+
+ {(char *)"hsv",
+ (getter)Color_hsv_get,
+ (setter)Color_hsv_set,
+ (char *)Color_hsv_doc,
+ (void *)0},
+
+ {(char *)"is_wrapped",
+ (getter)BaseMathObject_is_wrapped_get,
+ (setter)NULL,
+ BaseMathObject_is_wrapped_doc,
+ NULL},
+ {(char *)"is_frozen",
+ (getter)BaseMathObject_is_frozen_get,
+ (setter)NULL,
+ BaseMathObject_is_frozen_doc,
+ NULL},
+ {(char *)"owner",
+ (getter)BaseMathObject_owner_get,
+ (setter)NULL,
+ BaseMathObject_owner_doc,
+ NULL},
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
-
/* -----------------------METHOD DEFINITIONS ---------------------- */
static struct PyMethodDef Color_methods[] = {
- {"copy", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
- {"__copy__", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
- {"__deepcopy__", (PyCFunction) Color_deepcopy, METH_VARARGS, Color_copy_doc},
+ {"copy", (PyCFunction)Color_copy, METH_NOARGS, Color_copy_doc},
+ {"__copy__", (PyCFunction)Color_copy, METH_NOARGS, Color_copy_doc},
+ {"__deepcopy__", (PyCFunction)Color_deepcopy, METH_VARARGS, Color_copy_doc},
- /* base-math methods */
- {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
- {NULL, NULL, 0, NULL},
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+ {NULL, NULL, 0, NULL},
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
PyDoc_STRVAR(color_doc,
-".. class:: Color(rgb)\n"
-"\n"
-" This object gives access to Colors in Blender.\n"
-"\n"
-" :param rgb: (r, g, b) color values\n"
-" :type rgb: 3d vector\n"
-);
+ ".. class:: Color(rgb)\n"
+ "\n"
+ " This object gives access to Colors in Blender.\n"
+ "\n"
+ " :param rgb: (r, g, b) color values\n"
+ " :type rgb: 3d vector\n");
PyTypeObject color_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "Color", /* tp_name */
- sizeof(ColorObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc) Color_repr, /* tp_repr */
- &Color_NumMethods, /* tp_as_number */
- &Color_SeqMethods, /* tp_as_sequence */
- &Color_AsMapping, /* tp_as_mapping */
- (hashfunc)Color_hash, /* tp_hash */
- NULL, /* tp_call */
+ PyVarObject_HEAD_INIT(NULL, 0) "Color", /* tp_name */
+ sizeof(ColorObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)BaseMathObject_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ NULL, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ (reprfunc)Color_repr, /* tp_repr */
+ &Color_NumMethods, /* tp_as_number */
+ &Color_SeqMethods, /* tp_as_sequence */
+ &Color_AsMapping, /* tp_as_mapping */
+ (hashfunc)Color_hash, /* tp_hash */
+ NULL, /* tp_call */
#ifndef MATH_STANDALONE
- (reprfunc) Color_str, /* tp_str */
+ (reprfunc)Color_str, /* tp_str */
#else
- NULL, /* tp_str */
+ NULL, /* tp_str */
#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- color_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Color_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Color_methods, /* tp_methods */
- NULL, /* tp_members */
- Color_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Color_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ NULL, /* tp_getattro */
+ NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ color_doc, /* tp_doc */
+ (traverseproc)BaseMathObject_traverse, /* tp_traverse */
+ (inquiry)BaseMathObject_clear, /* tp_clear */
+ (richcmpfunc)Color_richcmpr, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ NULL, /* tp_iter */
+ NULL, /* tp_iternext */
+ Color_methods, /* tp_methods */
+ NULL, /* tp_members */
+ Color_getseters, /* tp_getset */
+ NULL, /* tp_base */
+ NULL, /* tp_dict */
+ NULL, /* tp_descr_get */
+ NULL, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ NULL, /* tp_init */
+ NULL, /* tp_alloc */
+ Color_new, /* tp_new */
+ NULL, /* tp_free */
+ NULL, /* tp_is_gc */
+ NULL, /* tp_bases */
+ NULL, /* tp_mro */
+ NULL, /* tp_cache */
+ NULL, /* tp_subclasses */
+ NULL, /* tp_weaklist */
+ NULL, /* tp_del */
};
-PyObject *Color_CreatePyObject(
- const float col[3],
- PyTypeObject *base_type)
+PyObject *Color_CreatePyObject(const float col[3], PyTypeObject *base_type)
{
- ColorObject *self;
- float *col_alloc;
-
- col_alloc = PyMem_Malloc(COLOR_SIZE * sizeof(float));
- if (UNLIKELY(col_alloc == NULL)) {
- PyErr_SetString(PyExc_MemoryError,
- "Color(): "
- "problem allocating data");
- return NULL;
- }
-
- self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
- if (self) {
- self->col = col_alloc;
-
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- /* NEW */
- if (col) {
- copy_v3_v3(self->col, col);
- }
- else {
- zero_v3(self->col);
- }
-
- self->flag = BASE_MATH_FLAG_DEFAULT;
- }
- else {
- PyMem_Free(col_alloc);
- }
-
- return (PyObject *)self;
+ ColorObject *self;
+ float *col_alloc;
+
+ col_alloc = PyMem_Malloc(COLOR_SIZE * sizeof(float));
+ if (UNLIKELY(col_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Color(): "
+ "problem allocating data");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
+ if (self) {
+ self->col = col_alloc;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ /* NEW */
+ if (col) {
+ copy_v3_v3(self->col, col);
+ }
+ else {
+ zero_v3(self->col);
+ }
+
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(col_alloc);
+ }
+
+ return (PyObject *)self;
}
-PyObject *Color_CreatePyObject_wrap(
- float col[3],
- PyTypeObject *base_type)
+PyObject *Color_CreatePyObject_wrap(float col[3], PyTypeObject *base_type)
{
- ColorObject *self;
+ ColorObject *self;
- self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
- if (self) {
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
+ self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
- /* WRAP */
- self->col = col;
- self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
- }
+ /* WRAP */
+ self->col = col;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+ }
- return (PyObject *)self;
+ return (PyObject *)self;
}
PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype)
-{
- ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, NULL);
- if (self) {
- Py_INCREF(cb_user);
- self->cb_user = cb_user;
- self->cb_type = cb_type;
- self->cb_subtype = cb_subtype;
- PyObject_GC_Track(self);
- }
-
- return (PyObject *)self;
+ unsigned char cb_type,
+ unsigned char cb_subtype)
+{
+ ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, NULL);
+ if (self) {
+ Py_INCREF(cb_user);
+ self->cb_user = cb_user;
+ self->cb_type = cb_type;
+ self->cb_subtype = cb_subtype;
+ PyObject_GC_Track(self);
+ }
+
+ return (PyObject *)self;
}
diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h
index 6dc56f8aacb..51e1746ae74 100644
--- a/source/blender/python/mathutils/mathutils_Color.h
+++ b/source/blender/python/mathutils/mathutils_Color.h
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#ifndef __MATHUTILS_COLOR_H__
#define __MATHUTILS_COLOR_H__
@@ -27,7 +26,7 @@ extern PyTypeObject color_Type;
#define ColorObject_CheckExact(v) (Py_TYPE(v) == &color_Type)
typedef struct {
- BASE_MATH_MEMBERS(col);
+ BASE_MATH_MEMBERS(col);
} ColorObject;
/* struct data contains a pointer to the actual data that the
@@ -36,17 +35,12 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both*/
/* prototypes */
-PyObject *Color_CreatePyObject(
- const float col[3],
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Color_CreatePyObject_wrap(
- float col[3],
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-PyObject *Color_CreatePyObject_cb(
- PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype
- ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Color_CreatePyObject(const float col[3],
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
+PyObject *Color_CreatePyObject_wrap(float col[3], PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
+ unsigned char cb_type,
+ unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
#endif /* __MATHUTILS_COLOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index 4177fc489bb..56662465b52 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -38,291 +37,289 @@
/* makes a new euler for you to play with */
static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *seq = NULL;
- const char *order_str = NULL;
-
- float eul[EULER_SIZE] = {0.0f, 0.0f, 0.0f};
- short order = EULER_ORDER_XYZ;
-
- if (kwds && PyDict_Size(kwds)) {
- PyErr_SetString(PyExc_TypeError,
- "mathutils.Euler(): "
- "takes no keyword args");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) {
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- break;
- case 2:
- if ((order = euler_order_from_string(order_str, "mathutils.Euler()")) == -1) {
- return NULL;
- }
- ATTR_FALLTHROUGH;
- case 1:
- if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1) {
- return NULL;
- }
- break;
- }
- return Euler_CreatePyObject(eul, order, type);
+ PyObject *seq = NULL;
+ const char *order_str = NULL;
+
+ float eul[EULER_SIZE] = {0.0f, 0.0f, 0.0f};
+ short order = EULER_ORDER_XYZ;
+
+ if (kwds && PyDict_Size(kwds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "mathutils.Euler(): "
+ "takes no keyword args");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str)) {
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ break;
+ case 2:
+ if ((order = euler_order_from_string(order_str, "mathutils.Euler()")) == -1) {
+ return NULL;
+ }
+ ATTR_FALLTHROUGH;
+ case 1:
+ if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1) {
+ return NULL;
+ }
+ break;
+ }
+ return Euler_CreatePyObject(eul, order, type);
}
/* internal use, assume read callback is done */
static const char *euler_order_str(EulerObject *self)
{
- static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
- return order[self->order - EULER_ORDER_XYZ];
+ static const char order[][4] = {"XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX"};
+ return order[self->order - EULER_ORDER_XYZ];
}
short euler_order_from_string(const char *str, const char *error_prefix)
{
- if ((str[0] && str[1] && str[2] && str[3] == '\0')) {
+ if ((str[0] && str[1] && str[2] && str[3] == '\0')) {
#ifdef __LITTLE_ENDIAN__
-# define MAKE_ID3(a, b, c) (((a)) | ((b) << 8) | ((c) << 16))
+# define MAKE_ID3(a, b, c) (((a)) | ((b) << 8) | ((c) << 16))
#else
-# define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
+# define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
#endif
- switch (*((PY_INT32_T *)str)) {
- case MAKE_ID3('X', 'Y', 'Z'): return EULER_ORDER_XYZ;
- case MAKE_ID3('X', 'Z', 'Y'): return EULER_ORDER_XZY;
- case MAKE_ID3('Y', 'X', 'Z'): return EULER_ORDER_YXZ;
- case MAKE_ID3('Y', 'Z', 'X'): return EULER_ORDER_YZX;
- case MAKE_ID3('Z', 'X', 'Y'): return EULER_ORDER_ZXY;
- case MAKE_ID3('Z', 'Y', 'X'): return EULER_ORDER_ZYX;
- }
+ switch (*((PY_INT32_T *)str)) {
+ case MAKE_ID3('X', 'Y', 'Z'):
+ return EULER_ORDER_XYZ;
+ case MAKE_ID3('X', 'Z', 'Y'):
+ return EULER_ORDER_XZY;
+ case MAKE_ID3('Y', 'X', 'Z'):
+ return EULER_ORDER_YXZ;
+ case MAKE_ID3('Y', 'Z', 'X'):
+ return EULER_ORDER_YZX;
+ case MAKE_ID3('Z', 'X', 'Y'):
+ return EULER_ORDER_ZXY;
+ case MAKE_ID3('Z', 'Y', 'X'):
+ return EULER_ORDER_ZYX;
+ }
#undef MAKE_ID3
- }
+ }
- PyErr_Format(PyExc_ValueError,
- "%s: invalid euler order '%s'",
- error_prefix, str);
- return -1;
+ PyErr_Format(PyExc_ValueError, "%s: invalid euler order '%s'", error_prefix, str);
+ return -1;
}
/* note: BaseMath_ReadCallback must be called beforehand */
static PyObject *Euler_ToTupleExt(EulerObject *self, int ndigits)
{
- PyObject *ret;
- int i;
-
- ret = PyTuple_New(EULER_SIZE);
-
- if (ndigits >= 0) {
- for (i = 0; i < EULER_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits)));
- }
- }
- else {
- for (i = 0; i < EULER_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i]));
- }
- }
-
- return ret;
+ PyObject *ret;
+ int i;
+
+ ret = PyTuple_New(EULER_SIZE);
+
+ if (ndigits >= 0) {
+ for (i = 0; i < EULER_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->eul[i], ndigits)));
+ }
+ }
+ else {
+ for (i = 0; i < EULER_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->eul[i]));
+ }
+ }
+
+ return ret;
}
/* -----------------------------METHODS----------------------------
* return a quaternion representation of the euler */
PyDoc_STRVAR(Euler_to_quaternion_doc,
-".. method:: to_quaternion()\n"
-"\n"
-" Return a quaternion representation of the euler.\n"
-"\n"
-" :return: Quaternion representation of the euler.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. method:: to_quaternion()\n"
+ "\n"
+ " Return a quaternion representation of the euler.\n"
+ "\n"
+ " :return: Quaternion representation of the euler.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Euler_to_quaternion(EulerObject *self)
{
- float quat[4];
+ float quat[4];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- eulO_to_quat(quat, self->eul, self->order);
+ eulO_to_quat(quat, self->eul, self->order);
- return Quaternion_CreatePyObject(quat, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
/* return a matrix representation of the euler */
PyDoc_STRVAR(Euler_to_matrix_doc,
-".. method:: to_matrix()\n"
-"\n"
-" Return a matrix representation of the euler.\n"
-"\n"
-" :return: A 3x3 rotation matrix representation of the euler.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: to_matrix()\n"
+ "\n"
+ " Return a matrix representation of the euler.\n"
+ "\n"
+ " :return: A 3x3 rotation matrix representation of the euler.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Euler_to_matrix(EulerObject *self)
{
- float mat[9];
+ float mat[9];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
+ eulO_to_mat3((float(*)[3])mat, self->eul, self->order);
- return Matrix_CreatePyObject(mat, 3, 3, NULL);
+ return Matrix_CreatePyObject(mat, 3, 3, NULL);
}
PyDoc_STRVAR(Euler_zero_doc,
-".. method:: zero()\n"
-"\n"
-" Set all values to zero.\n"
-);
+ ".. method:: zero()\n"
+ "\n"
+ " Set all values to zero.\n");
static PyObject *Euler_zero(EulerObject *self)
{
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return NULL;
+ }
- zero_v3(self->eul);
+ zero_v3(self->eul);
- if (BaseMath_WriteCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return NULL;
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Euler_rotate_axis_doc,
-".. method:: rotate_axis(axis, angle)\n"
-"\n"
-" Rotates the euler a certain amount and returning a unique euler rotation\n"
-" (no 720 degree pitches).\n"
-"\n"
-" :arg axis: single character in ['X, 'Y', 'Z'].\n"
-" :type axis: string\n"
-" :arg angle: angle in radians.\n"
-" :type angle: float\n"
-);
+ ".. method:: rotate_axis(axis, angle)\n"
+ "\n"
+ " Rotates the euler a certain amount and returning a unique euler rotation\n"
+ " (no 720 degree pitches).\n"
+ "\n"
+ " :arg axis: single character in ['X, 'Y', 'Z'].\n"
+ " :type axis: string\n"
+ " :arg angle: angle in radians.\n"
+ " :type angle: float\n");
static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args)
{
- float angle = 0.0f;
- int axis; /* actually a character */
-
- if (!PyArg_ParseTuple(args, "Cf:rotate_axis", &axis, &angle)) {
- PyErr_SetString(PyExc_TypeError,
- "Euler.rotate_axis(): "
- "expected an axis 'X', 'Y', 'Z' and an angle (float)");
- return NULL;
- }
+ float angle = 0.0f;
+ int axis; /* actually a character */
- if (!(ELEM(axis, 'X', 'Y', 'Z'))) {
- PyErr_SetString(PyExc_ValueError,
- "Euler.rotate_axis(): "
- "expected axis to be 'X', 'Y' or 'Z'");
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "Cf:rotate_axis", &axis, &angle)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Euler.rotate_axis(): "
+ "expected an axis 'X', 'Y', 'Z' and an angle (float)");
+ return NULL;
+ }
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (!(ELEM(axis, 'X', 'Y', 'Z'))) {
+ PyErr_SetString(PyExc_ValueError,
+ "Euler.rotate_axis(): "
+ "expected axis to be 'X', 'Y' or 'Z'");
+ return NULL;
+ }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- rotate_eulO(self->eul, self->order, (char)axis, angle);
+ rotate_eulO(self->eul, self->order, (char)axis, angle);
- (void)BaseMath_WriteCallback(self);
+ (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Euler_rotate_doc,
-".. method:: rotate(other)\n"
-"\n"
-" Rotates the euler by another mathutils value.\n"
-"\n"
-" :arg other: rotation component of mathutils value\n"
-" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
-);
+ ".. method:: rotate(other)\n"
+ "\n"
+ " Rotates the euler by another mathutils value.\n"
+ "\n"
+ " :arg other: rotation component of mathutils value\n"
+ " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
static PyObject *Euler_rotate(EulerObject *self, PyObject *value)
{
- float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
+ float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1) {
- return NULL;
- }
+ if (mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1) {
+ return NULL;
+ }
- eulO_to_mat3(self_rmat, self->eul, self->order);
- mul_m3_m3m3(rmat, other_rmat, self_rmat);
+ eulO_to_mat3(self_rmat, self->eul, self->order);
+ mul_m3_m3m3(rmat, other_rmat, self_rmat);
- mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat);
+ mat3_to_compatible_eulO(self->eul, self->eul, self->order, rmat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Euler_make_compatible_doc,
-".. method:: make_compatible(other)\n"
-"\n"
-" Make this euler compatible with another,\n"
-" so interpolating between them works as intended.\n"
-"\n"
-" .. note:: the rotation order is not taken into account for this function.\n"
-);
+ ".. method:: make_compatible(other)\n"
+ "\n"
+ " Make this euler compatible with another,\n"
+ " so interpolating between them works as intended.\n"
+ "\n"
+ " .. note:: the rotation order is not taken into account for this function.\n");
static PyObject *Euler_make_compatible(EulerObject *self, PyObject *value)
{
- float teul[EULER_SIZE];
+ float teul[EULER_SIZE];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value,
- "euler.make_compatible(other), invalid 'other' arg") == -1)
- {
- return NULL;
- }
+ if (mathutils_array_parse(teul,
+ EULER_SIZE,
+ EULER_SIZE,
+ value,
+ "euler.make_compatible(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
- compatible_eul(self->eul, teul);
+ compatible_eul(self->eul, teul);
- (void)BaseMath_WriteCallback(self);
+ (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
/* ----------------------------Euler.rotate()-----------------------
* return a copy of the euler */
PyDoc_STRVAR(Euler_copy_doc,
-".. function:: copy()\n"
-"\n"
-" Returns a copy of this euler.\n"
-"\n"
-" :return: A copy of the euler.\n"
-" :rtype: :class:`Euler`\n"
-"\n"
-" .. note:: use this to get a copy of a wrapped euler with\n"
-" no reference to the original data.\n"
-);
+ ".. function:: copy()\n"
+ "\n"
+ " Returns a copy of this euler.\n"
+ "\n"
+ " :return: A copy of the euler.\n"
+ " :rtype: :class:`Euler`\n"
+ "\n"
+ " .. note:: use this to get a copy of a wrapped euler with\n"
+ " no reference to the original data.\n");
static PyObject *Euler_copy(EulerObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Euler_CreatePyObject(self->eul, self->order, Py_TYPE(self));
+ return Euler_CreatePyObject(self->eul, self->order, Py_TYPE(self));
}
static PyObject *Euler_deepcopy(EulerObject *self, PyObject *args)
{
- if (!PyC_CheckArgs_DeepCopy(args)) {
- return NULL;
- }
- return Euler_copy(self);
+ if (!PyC_CheckArgs_DeepCopy(args)) {
+ return NULL;
+ }
+ return Euler_copy(self);
}
/* ----------------------------print object (internal)--------------
@@ -330,87 +327,94 @@ static PyObject *Euler_deepcopy(EulerObject *self, PyObject *args)
static PyObject *Euler_repr(EulerObject *self)
{
- PyObject *ret, *tuple;
+ PyObject *ret, *tuple;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- tuple = Euler_ToTupleExt(self, -1);
+ tuple = Euler_ToTupleExt(self, -1);
- ret = PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self));
+ ret = PyUnicode_FromFormat("Euler(%R, '%s')", tuple, euler_order_str(self));
- Py_DECREF(tuple);
- return ret;
+ Py_DECREF(tuple);
+ return ret;
}
#ifndef MATH_STANDALONE
static PyObject *Euler_str(EulerObject *self)
{
- DynStr *ds;
+ DynStr *ds;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- ds = BLI_dynstr_new();
+ ds = BLI_dynstr_new();
- BLI_dynstr_appendf(ds, "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
- self->eul[0], self->eul[1], self->eul[2], euler_order_str(self));
+ BLI_dynstr_appendf(ds,
+ "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
+ self->eul[0],
+ self->eul[1],
+ self->eul[2],
+ euler_order_str(self));
- return mathutils_dynstr_to_py(ds); /* frees ds */
+ return mathutils_dynstr_to_py(ds); /* frees ds */
}
#endif
static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op)
{
- PyObject *res;
- int ok = -1; /* zero is true */
-
- if (EulerObject_Check(a) && EulerObject_Check(b)) {
- EulerObject *eulA = (EulerObject *)a;
- EulerObject *eulB = (EulerObject *)b;
-
- if (BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) {
- return NULL;
- }
-
- ok = ((eulA->order == eulB->order) && EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ? 0 : -1;
- }
-
- switch (op) {
- case Py_NE:
- ok = !ok;
- ATTR_FALLTHROUGH;
- case Py_EQ:
- res = ok ? Py_False : Py_True;
- break;
-
- case Py_LT:
- case Py_LE:
- case Py_GT:
- case Py_GE:
- res = Py_NotImplemented;
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
-
- return Py_INCREF_RET(res);
+ PyObject *res;
+ int ok = -1; /* zero is true */
+
+ if (EulerObject_Check(a) && EulerObject_Check(b)) {
+ EulerObject *eulA = (EulerObject *)a;
+ EulerObject *eulB = (EulerObject *)b;
+
+ if (BaseMath_ReadCallback(eulA) == -1 || BaseMath_ReadCallback(eulB) == -1) {
+ return NULL;
+ }
+
+ ok = ((eulA->order == eulB->order) &&
+ EXPP_VectorsAreEqual(eulA->eul, eulB->eul, EULER_SIZE, 1)) ?
+ 0 :
+ -1;
+ }
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok;
+ ATTR_FALLTHROUGH;
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ return Py_INCREF_RET(res);
}
static Py_hash_t Euler_hash(EulerObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- if (BaseMathObject_Prepare_ForHash(self) == -1) {
- return -1;
- }
+ if (BaseMathObject_Prepare_ForHash(self) == -1) {
+ return -1;
+ }
- return mathutils_array_hash(self->eul, EULER_SIZE);
+ return mathutils_array_hash(self->eul, EULER_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -418,449 +422,451 @@ static Py_hash_t Euler_hash(EulerObject *self)
/* sequence length */
static int Euler_len(EulerObject *UNUSED(self))
{
- return EULER_SIZE;
+ return EULER_SIZE;
}
/* ----------------------------object[]--------------------------- */
/* sequence accessor (get) */
static PyObject *Euler_item(EulerObject *self, int i)
{
- if (i < 0) {
- i = EULER_SIZE - i;
- }
-
- if (i < 0 || i >= EULER_SIZE) {
- PyErr_SetString(PyExc_IndexError,
- "euler[attribute]: "
- "array index out of range");
- return NULL;
- }
-
- if (BaseMath_ReadIndexCallback(self, i) == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(self->eul[i]);
-
+ if (i < 0) {
+ i = EULER_SIZE - i;
+ }
+
+ if (i < 0 || i >= EULER_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "euler[attribute]: "
+ "array index out of range");
+ return NULL;
+ }
+
+ if (BaseMath_ReadIndexCallback(self, i) == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(self->eul[i]);
}
/* ----------------------------object[]------------------------- */
/* sequence accessor (set) */
static int Euler_ass_item(EulerObject *self, int i, PyObject *value)
{
- float f;
-
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
-
- f = PyFloat_AsDouble(value);
- if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "euler[attribute] = x: "
- "assigned value not a number");
- return -1;
- }
-
- if (i < 0) {
- i = EULER_SIZE - i;
- }
-
- if (i < 0 || i >= EULER_SIZE) {
- PyErr_SetString(PyExc_IndexError,
- "euler[attribute] = x: "
- "array assignment index out of range");
- return -1;
- }
-
- self->eul[i] = f;
-
- if (BaseMath_WriteIndexCallback(self, i) == -1) {
- return -1;
- }
-
- return 0;
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ f = PyFloat_AsDouble(value);
+ if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "euler[attribute] = x: "
+ "assigned value not a number");
+ return -1;
+ }
+
+ if (i < 0) {
+ i = EULER_SIZE - i;
+ }
+
+ if (i < 0 || i >= EULER_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "euler[attribute] = x: "
+ "array assignment index out of range");
+ return -1;
+ }
+
+ self->eul[i] = f;
+
+ if (BaseMath_WriteIndexCallback(self, i) == -1) {
+ return -1;
+ }
+
+ return 0;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (get) */
static PyObject *Euler_slice(EulerObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- CLAMP(begin, 0, EULER_SIZE);
- if (end < 0) {
- end = (EULER_SIZE + 1) + end;
- }
- CLAMP(end, 0, EULER_SIZE);
- begin = MIN2(begin, end);
-
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count]));
- }
-
- return tuple;
+ PyObject *tuple;
+ int count;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ CLAMP(begin, 0, EULER_SIZE);
+ if (end < 0) {
+ end = (EULER_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, EULER_SIZE);
+ begin = MIN2(begin, end);
+
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->eul[count]));
+ }
+
+ return tuple;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (set) */
static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq)
{
- int i, size;
- float eul[EULER_SIZE];
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- CLAMP(begin, 0, EULER_SIZE);
- if (end < 0) {
- end = (EULER_SIZE + 1) + end;
- }
- CLAMP(end, 0, EULER_SIZE);
- begin = MIN2(begin, end);
-
- if ((size = mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) == -1) {
- return -1;
- }
-
- if (size != (end - begin)) {
- PyErr_SetString(PyExc_ValueError,
- "euler[begin:end] = []: "
- "size mismatch in slice assignment");
- return -1;
- }
-
- for (i = 0; i < EULER_SIZE; i++) {
- self->eul[begin + i] = eul[i];
- }
-
- (void)BaseMath_WriteCallback(self);
- return 0;
+ int i, size;
+ float eul[EULER_SIZE];
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ CLAMP(begin, 0, EULER_SIZE);
+ if (end < 0) {
+ end = (EULER_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, EULER_SIZE);
+ begin = MIN2(begin, end);
+
+ if ((size = mathutils_array_parse(eul, 0, EULER_SIZE, seq, "mathutils.Euler[begin:end] = []")) ==
+ -1) {
+ return -1;
+ }
+
+ if (size != (end - begin)) {
+ PyErr_SetString(PyExc_ValueError,
+ "euler[begin:end] = []: "
+ "size mismatch in slice assignment");
+ return -1;
+ }
+
+ for (i = 0; i < EULER_SIZE; i++) {
+ self->eul[begin + i] = eul[i];
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static PyObject *Euler_subscript(EulerObject *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 += EULER_SIZE;
- }
- return Euler_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return Euler_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with eulers");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "euler indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ 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 += EULER_SIZE;
+ }
+ return Euler_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return Euler_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with eulers");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
+ }
}
-
static int Euler_ass_subscript(EulerObject *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 += EULER_SIZE;
- }
- return Euler_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
-
- if (step == 1) {
- return Euler_ass_slice(self, start, stop, value);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with euler");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "euler indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ 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 += EULER_SIZE;
+ }
+ return Euler_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Euler_ass_slice(self, start, stop, value);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with euler");
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
/* -----------------PROTCOL DECLARATIONS-------------------------- */
static PySequenceMethods Euler_SeqMethods = {
- (lenfunc) Euler_len, /* sq_length */
- (binaryfunc) NULL, /* sq_concat */
- (ssizeargfunc) NULL, /* sq_repeat */
- (ssizeargfunc) Euler_item, /* sq_item */
- (ssizessizeargfunc) NULL, /* sq_slice, deprecated */
- (ssizeobjargproc) Euler_ass_item, /* sq_ass_item */
- (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */
- (objobjproc) NULL, /* sq_contains */
- (binaryfunc) NULL, /* sq_inplace_concat */
- (ssizeargfunc) NULL, /* sq_inplace_repeat */
+ (lenfunc)Euler_len, /* sq_length */
+ (binaryfunc)NULL, /* sq_concat */
+ (ssizeargfunc)NULL, /* sq_repeat */
+ (ssizeargfunc)Euler_item, /* sq_item */
+ (ssizessizeargfunc)NULL, /* sq_slice, deprecated */
+ (ssizeobjargproc)Euler_ass_item, /* 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 Euler_AsMapping = {
- (lenfunc)Euler_len,
- (binaryfunc)Euler_subscript,
- (objobjargproc)Euler_ass_subscript,
+ (lenfunc)Euler_len,
+ (binaryfunc)Euler_subscript,
+ (objobjargproc)Euler_ass_subscript,
};
/* euler axis, euler.x/y/z */
-PyDoc_STRVAR(Euler_axis_doc,
-"Euler axis angle in radians.\n\n:type: float"
-);
+PyDoc_STRVAR(Euler_axis_doc, "Euler axis angle in radians.\n\n:type: float");
static PyObject *Euler_axis_get(EulerObject *self, void *type)
{
- return Euler_item(self, POINTER_AS_INT(type));
+ return Euler_item(self, POINTER_AS_INT(type));
}
static int Euler_axis_set(EulerObject *self, PyObject *value, void *type)
{
- return Euler_ass_item(self, POINTER_AS_INT(type), value);
+ return Euler_ass_item(self, POINTER_AS_INT(type), value);
}
/* rotation order */
-PyDoc_STRVAR(Euler_order_doc,
-"Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']"
-);
+PyDoc_STRVAR(
+ Euler_order_doc,
+ "Euler rotation order.\n\n:type: string in ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']");
static PyObject *Euler_order_get(EulerObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- /* can read order too */
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ /* can read order too */
+ return NULL;
+ }
- return PyUnicode_FromString(euler_order_str(self));
+ return PyUnicode_FromString(euler_order_str(self));
}
static int Euler_order_set(EulerObject *self, PyObject *value, void *UNUSED(closure))
{
- const char *order_str;
- short order;
-
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
-
- if (((order_str = _PyUnicode_AsString(value)) == NULL) ||
- ((order = euler_order_from_string(order_str, "euler.order")) == -1))
- {
- return -1;
- }
-
- self->order = order;
- (void)BaseMath_WriteCallback(self); /* order can be written back */
- return 0;
+ const char *order_str;
+ short order;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ if (((order_str = _PyUnicode_AsString(value)) == NULL) ||
+ ((order = euler_order_from_string(order_str, "euler.order")) == -1)) {
+ return -1;
+ }
+
+ self->order = order;
+ (void)BaseMath_WriteCallback(self); /* order can be written back */
+ return 0;
}
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Euler_getseters[] = {
- {(char *)"x", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)0},
- {(char *)"y", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)1},
- {(char *)"z", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)2},
- {(char *)"order", (getter)Euler_order_get, (setter)Euler_order_set, Euler_order_doc, (void *)NULL},
-
- {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
- {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
- {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {(char *)"x", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)0},
+ {(char *)"y", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)1},
+ {(char *)"z", (getter)Euler_axis_get, (setter)Euler_axis_set, Euler_axis_doc, (void *)2},
+ {(char *)"order",
+ (getter)Euler_order_get,
+ (setter)Euler_order_set,
+ Euler_order_doc,
+ (void *)NULL},
+
+ {(char *)"is_wrapped",
+ (getter)BaseMathObject_is_wrapped_get,
+ (setter)NULL,
+ BaseMathObject_is_wrapped_doc,
+ NULL},
+ {(char *)"is_frozen",
+ (getter)BaseMathObject_is_frozen_get,
+ (setter)NULL,
+ BaseMathObject_is_frozen_doc,
+ NULL},
+ {(char *)"owner",
+ (getter)BaseMathObject_owner_get,
+ (setter)NULL,
+ BaseMathObject_owner_doc,
+ NULL},
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
-
/* -----------------------METHOD DEFINITIONS ---------------------- */
static struct PyMethodDef Euler_methods[] = {
- {"zero", (PyCFunction) Euler_zero, METH_NOARGS, Euler_zero_doc},
- {"to_matrix", (PyCFunction) Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc},
- {"to_quaternion", (PyCFunction) Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc},
- {"rotate_axis", (PyCFunction) Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},
- {"rotate", (PyCFunction) Euler_rotate, METH_O, Euler_rotate_doc},
- {"make_compatible", (PyCFunction) Euler_make_compatible, METH_O, Euler_make_compatible_doc},
- {"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
- {"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
- {"__deepcopy__", (PyCFunction) Euler_deepcopy, METH_VARARGS, Euler_copy_doc},
-
- /* base-math methods */
- {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
- {NULL, NULL, 0, NULL},
+ {"zero", (PyCFunction)Euler_zero, METH_NOARGS, Euler_zero_doc},
+ {"to_matrix", (PyCFunction)Euler_to_matrix, METH_NOARGS, Euler_to_matrix_doc},
+ {"to_quaternion", (PyCFunction)Euler_to_quaternion, METH_NOARGS, Euler_to_quaternion_doc},
+ {"rotate_axis", (PyCFunction)Euler_rotate_axis, METH_VARARGS, Euler_rotate_axis_doc},
+ {"rotate", (PyCFunction)Euler_rotate, METH_O, Euler_rotate_doc},
+ {"make_compatible", (PyCFunction)Euler_make_compatible, METH_O, Euler_make_compatible_doc},
+ {"copy", (PyCFunction)Euler_copy, METH_NOARGS, Euler_copy_doc},
+ {"__copy__", (PyCFunction)Euler_copy, METH_NOARGS, Euler_copy_doc},
+ {"__deepcopy__", (PyCFunction)Euler_deepcopy, METH_VARARGS, Euler_copy_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+ {NULL, NULL, 0, NULL},
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
-PyDoc_STRVAR(euler_doc,
-".. class:: Euler(angles, order='XYZ')\n"
-"\n"
-" This object gives access to Eulers in Blender.\n"
-"\n"
-" .. seealso:: `Euler angles <https://en.wikipedia.org/wiki/Euler_angles>`__ on Wikipedia.\n"
-"\n"
-" :param angles: Three angles, in radians.\n"
-" :type angles: 3d vector\n"
-" :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
-" :type order: str\n"
-);
+PyDoc_STRVAR(
+ euler_doc,
+ ".. class:: Euler(angles, order='XYZ')\n"
+ "\n"
+ " This object gives access to Eulers in Blender.\n"
+ "\n"
+ " .. seealso:: `Euler angles <https://en.wikipedia.org/wiki/Euler_angles>`__ on Wikipedia.\n"
+ "\n"
+ " :param angles: Three angles, in radians.\n"
+ " :type angles: 3d vector\n"
+ " :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
+ " :type order: str\n");
PyTypeObject euler_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "Euler", /* tp_name */
- sizeof(EulerObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc) Euler_repr, /* tp_repr */
- NULL, /* tp_as_number */
- &Euler_SeqMethods, /* tp_as_sequence */
- &Euler_AsMapping, /* tp_as_mapping */
- (hashfunc)Euler_hash, /* tp_hash */
- NULL, /* tp_call */
+ PyVarObject_HEAD_INIT(NULL, 0) "Euler", /* tp_name */
+ sizeof(EulerObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)BaseMathObject_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ NULL, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ (reprfunc)Euler_repr, /* tp_repr */
+ NULL, /* tp_as_number */
+ &Euler_SeqMethods, /* tp_as_sequence */
+ &Euler_AsMapping, /* tp_as_mapping */
+ (hashfunc)Euler_hash, /* tp_hash */
+ NULL, /* tp_call */
#ifndef MATH_STANDALONE
- (reprfunc) Euler_str, /* tp_str */
+ (reprfunc)Euler_str, /* tp_str */
#else
- NULL, /* tp_str */
+ NULL, /* tp_str */
#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- euler_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Euler_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Euler_methods, /* tp_methods */
- NULL, /* tp_members */
- Euler_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Euler_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ NULL, /* tp_getattro */
+ NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ euler_doc, /* tp_doc */
+ (traverseproc)BaseMathObject_traverse, /* tp_traverse */
+ (inquiry)BaseMathObject_clear, /* tp_clear */
+ (richcmpfunc)Euler_richcmpr, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ NULL, /* tp_iter */
+ NULL, /* tp_iternext */
+ Euler_methods, /* tp_methods */
+ NULL, /* tp_members */
+ Euler_getseters, /* tp_getset */
+ NULL, /* tp_base */
+ NULL, /* tp_dict */
+ NULL, /* tp_descr_get */
+ NULL, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ NULL, /* tp_init */
+ NULL, /* tp_alloc */
+ Euler_new, /* tp_new */
+ NULL, /* tp_free */
+ NULL, /* tp_is_gc */
+ NULL, /* tp_bases */
+ NULL, /* tp_mro */
+ NULL, /* tp_cache */
+ NULL, /* tp_subclasses */
+ NULL, /* tp_weaklist */
+ NULL, /* tp_del */
};
-
-PyObject *Euler_CreatePyObject(
- const float eul[3], const short order,
- PyTypeObject *base_type)
+PyObject *Euler_CreatePyObject(const float eul[3], const short order, PyTypeObject *base_type)
{
- EulerObject *self;
- float *eul_alloc;
-
- eul_alloc = PyMem_Malloc(EULER_SIZE * sizeof(float));
- if (UNLIKELY(eul_alloc == NULL)) {
- PyErr_SetString(PyExc_MemoryError,
- "Euler(): "
- "problem allocating data");
- return NULL;
- }
-
- self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
- if (self) {
- self->eul = eul_alloc;
-
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- if (eul) {
- copy_v3_v3(self->eul, eul);
- }
- else {
- zero_v3(self->eul);
- }
-
- self->flag = BASE_MATH_FLAG_DEFAULT;
- self->order = order;
- }
- else {
- PyMem_Free(eul_alloc);
- }
-
- return (PyObject *)self;
+ EulerObject *self;
+ float *eul_alloc;
+
+ eul_alloc = PyMem_Malloc(EULER_SIZE * sizeof(float));
+ if (UNLIKELY(eul_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Euler(): "
+ "problem allocating data");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
+ if (self) {
+ self->eul = eul_alloc;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ if (eul) {
+ copy_v3_v3(self->eul, eul);
+ }
+ else {
+ zero_v3(self->eul);
+ }
+
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ self->order = order;
+ }
+ else {
+ PyMem_Free(eul_alloc);
+ }
+
+ return (PyObject *)self;
}
-PyObject *Euler_CreatePyObject_wrap(
- float eul[3], const short order,
- PyTypeObject *base_type)
+PyObject *Euler_CreatePyObject_wrap(float eul[3], const short order, PyTypeObject *base_type)
{
- EulerObject *self;
+ EulerObject *self;
- self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
- if (self) {
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
+ self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
- self->eul = eul;
- self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+ self->eul = eul;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
- self->order = order;
- }
+ self->order = order;
+ }
- return (PyObject *)self;
+ return (PyObject *)self;
}
-PyObject *Euler_CreatePyObject_cb(
- PyObject *cb_user, const short order,
- unsigned char cb_type, unsigned char cb_subtype)
+PyObject *Euler_CreatePyObject_cb(PyObject *cb_user,
+ const short order,
+ unsigned char cb_type,
+ unsigned char cb_subtype)
{
- EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, NULL);
- if (self) {
- Py_INCREF(cb_user);
- self->cb_user = cb_user;
- self->cb_type = cb_type;
- self->cb_subtype = cb_subtype;
- PyObject_GC_Track(self);
- }
-
- return (PyObject *)self;
+ EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, NULL);
+ if (self) {
+ Py_INCREF(cb_user);
+ self->cb_user = cb_user;
+ self->cb_type = cb_type;
+ self->cb_subtype = cb_subtype;
+ PyObject_GC_Track(self);
+ }
+
+ return (PyObject *)self;
}
diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h
index 55ca3cd6df6..c56962395e5 100644
--- a/source/blender/python/mathutils/mathutils_Euler.h
+++ b/source/blender/python/mathutils/mathutils_Euler.h
@@ -26,8 +26,8 @@ extern PyTypeObject euler_Type;
#define EulerObject_CheckExact(v) (Py_TYPE(v) == &euler_Type)
typedef struct {
- BASE_MATH_MEMBERS(eul);
- unsigned char order; /* rotation order */
+ BASE_MATH_MEMBERS(eul);
+ unsigned char order; /* rotation order */
} EulerObject;
@@ -37,20 +37,18 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Euler_CreatePyObject(
- const float eul[3], const short order,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Euler_CreatePyObject_wrap(
- float eul[3], const short order,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-PyObject *Euler_CreatePyObject_cb(
- PyObject *cb_user, const short order,
- unsigned char cb_type, unsigned char cb_subtype
- ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Euler_CreatePyObject(const float eul[3],
+ const short order,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
+PyObject *Euler_CreatePyObject_wrap(float eul[3],
+ const short order,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+PyObject *Euler_CreatePyObject_cb(PyObject *cb_user,
+ const short order,
+ unsigned char cb_type,
+ unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
short euler_order_from_string(const char *str, const char *error_prefix);
-
#endif /* __MATHUTILS_EULER_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 724fcd263d4..6ccb3c2a291 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -35,8 +34,8 @@
#endif
typedef enum eMatrixAccess_t {
- MAT_ACCESS_ROW,
- MAT_ACCESS_COL,
+ MAT_ACCESS_ROW,
+ MAT_ACCESS_COL,
} eMatrixAccess_t;
static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix);
@@ -48,28 +47,28 @@ static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrix
static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row)
{
- if ((vec->size != mat->num_col) || (row >= mat->num_row)) {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix(): "
- "owner matrix has been resized since this row vector was created");
- return 0;
- }
- else {
- return 1;
- }
+ if ((vec->size != mat->num_col) || (row >= mat->num_row)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix(): "
+ "owner matrix has been resized since this row vector was created");
+ return 0;
+ }
+ else {
+ return 1;
+ }
}
static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col)
{
- if ((vec->size != mat->num_row) || (col >= mat->num_col)) {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix(): "
- "owner matrix has been resized since this column vector was created");
- return 0;
- }
- else {
- return 1;
- }
+ if ((vec->size != mat->num_row) || (col >= mat->num_col)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix(): "
+ "owner matrix has been resized since this column vector was created");
+ return 0;
+ }
+ else {
+ return 1;
+ }
}
/* ----------------------------------------------------------------------------
@@ -80,90 +79,89 @@ unsigned char mathutils_matrix_row_cb_index = -1;
static int mathutils_matrix_row_check(BaseMathObject *bmo)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- return BaseMath_ReadCallback(self);
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ return BaseMath_ReadCallback(self);
}
static int mathutils_matrix_row_get(BaseMathObject *bmo, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int col;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int col;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
- if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
+ if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
+ return -1;
+ }
- for (col = 0; col < self->num_col; col++) {
- bmo->data[col] = MATRIX_ITEM(self, row, col);
- }
+ for (col = 0; col < self->num_col; col++) {
+ bmo->data[col] = MATRIX_ITEM(self, row, col);
+ }
- return 0;
+ return 0;
}
static int mathutils_matrix_row_set(BaseMathObject *bmo, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int col;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int col;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
- if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+ if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
+ return -1;
+ }
- for (col = 0; col < self->num_col; col++) {
- MATRIX_ITEM(self, row, col) = bmo->data[col];
- }
+ for (col = 0; col < self->num_col; col++) {
+ MATRIX_ITEM(self, row, col) = bmo->data[col];
+ }
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static int mathutils_matrix_row_get_index(BaseMathObject *bmo, int row, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
- if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
+ if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
+ return -1;
+ }
- bmo->data[col] = MATRIX_ITEM(self, row, col);
- return 0;
+ bmo->data[col] = MATRIX_ITEM(self, row, col);
+ return 0;
}
static int mathutils_matrix_row_set_index(BaseMathObject *bmo, int row, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
- if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+ if (!matrix_row_vector_check(self, (VectorObject *)bmo, row)) {
+ return -1;
+ }
- MATRIX_ITEM(self, row, col) = bmo->data[col];
+ MATRIX_ITEM(self, row, col) = bmo->data[col];
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
Mathutils_Callback mathutils_matrix_row_cb = {
- mathutils_matrix_row_check,
- mathutils_matrix_row_get,
- mathutils_matrix_row_set,
- mathutils_matrix_row_get_index,
- mathutils_matrix_row_set_index,
+ mathutils_matrix_row_check,
+ mathutils_matrix_row_get,
+ mathutils_matrix_row_set,
+ mathutils_matrix_row_get_index,
+ mathutils_matrix_row_set_index,
};
-
/* ----------------------------------------------------------------------------
* matrix row callbacks
* this is so you can do matrix.col[i][j] = val */
@@ -172,98 +170,97 @@ unsigned char mathutils_matrix_col_cb_index = -1;
static int mathutils_matrix_col_check(BaseMathObject *bmo)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- return BaseMath_ReadCallback(self);
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ return BaseMath_ReadCallback(self);
}
static int mathutils_matrix_col_get(BaseMathObject *bmo, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int num_row;
- int row;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int num_row;
+ int row;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
- if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
+ if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
+ return -1;
+ }
- /* for 'translation' size will always be '3' even on 4x4 vec */
- num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size);
+ /* for 'translation' size will always be '3' even on 4x4 vec */
+ num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size);
- for (row = 0; row < num_row; row++) {
- bmo->data[row] = MATRIX_ITEM(self, row, col);
- }
+ for (row = 0; row < num_row; row++) {
+ bmo->data[row] = MATRIX_ITEM(self, row, col);
+ }
- return 0;
+ return 0;
}
static int mathutils_matrix_col_set(BaseMathObject *bmo, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int num_row;
- int row;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int num_row;
+ int row;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
- if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+ if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
+ return -1;
+ }
- /* for 'translation' size will always be '3' even on 4x4 vec */
- num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size);
+ /* for 'translation' size will always be '3' even on 4x4 vec */
+ num_row = min_ii(self->num_row, ((VectorObject *)bmo)->size);
- for (row = 0; row < num_row; row++) {
- MATRIX_ITEM(self, row, col) = bmo->data[row];
- }
+ for (row = 0; row < num_row; row++) {
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
+ }
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static int mathutils_matrix_col_get_index(BaseMathObject *bmo, int col, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
- if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
+ if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
+ return -1;
+ }
- bmo->data[row] = MATRIX_ITEM(self, row, col);
- return 0;
+ bmo->data[row] = MATRIX_ITEM(self, row, col);
+ return 0;
}
static int mathutils_matrix_col_set_index(BaseMathObject *bmo, int col, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
- if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+ if (!matrix_col_vector_check(self, (VectorObject *)bmo, col)) {
+ return -1;
+ }
- MATRIX_ITEM(self, row, col) = bmo->data[row];
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
Mathutils_Callback mathutils_matrix_col_cb = {
- mathutils_matrix_col_check,
- mathutils_matrix_col_get,
- mathutils_matrix_col_set,
- mathutils_matrix_col_get_index,
- mathutils_matrix_col_set_index,
+ mathutils_matrix_col_check,
+ mathutils_matrix_col_get,
+ mathutils_matrix_col_set,
+ mathutils_matrix_col_get_index,
+ mathutils_matrix_col_set_index,
};
-
/* ----------------------------------------------------------------------------
* matrix row callbacks
* this is so you can do matrix.translation = val
@@ -273,78 +270,77 @@ unsigned char mathutils_matrix_translation_cb_index = -1;
static int mathutils_matrix_translation_check(BaseMathObject *bmo)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- return BaseMath_ReadCallback(self);
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ return BaseMath_ReadCallback(self);
}
static int mathutils_matrix_translation_get(BaseMathObject *bmo, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int row;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int row;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- for (row = 0; row < 3; row++) {
- bmo->data[row] = MATRIX_ITEM(self, row, col);
- }
+ for (row = 0; row < 3; row++) {
+ bmo->data[row] = MATRIX_ITEM(self, row, col);
+ }
- return 0;
+ return 0;
}
static int mathutils_matrix_translation_set(BaseMathObject *bmo, int col)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int row;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ int row;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- for (row = 0; row < 3; row++) {
- MATRIX_ITEM(self, row, col) = bmo->data[row];
- }
+ for (row = 0; row < 3; row++) {
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
+ }
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static int mathutils_matrix_translation_get_index(BaseMathObject *bmo, int col, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- bmo->data[row] = MATRIX_ITEM(self, row, col);
- return 0;
+ bmo->data[row] = MATRIX_ITEM(self, row, col);
+ return 0;
}
static int mathutils_matrix_translation_set_index(BaseMathObject *bmo, int col, int row)
{
- MatrixObject *self = (MatrixObject *)bmo->cb_user;
+ MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- MATRIX_ITEM(self, row, col) = bmo->data[row];
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
Mathutils_Callback mathutils_matrix_translation_cb = {
- mathutils_matrix_translation_check,
- mathutils_matrix_translation_get,
- mathutils_matrix_translation_set,
- mathutils_matrix_translation_get_index,
- mathutils_matrix_translation_set_index,
+ mathutils_matrix_translation_check,
+ mathutils_matrix_translation_get,
+ mathutils_matrix_translation_set,
+ mathutils_matrix_translation_get_index,
+ mathutils_matrix_translation_set_index,
};
-
/* matrix column callbacks, this is so you can do matrix.translation = Vector() */
/* ----------------------------------mathutils.Matrix() ----------------- */
@@ -352,644 +348,696 @@ Mathutils_Callback mathutils_matrix_translation_cb = {
/* create a new matrix type */
static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- if (kwds && PyDict_Size(kwds)) {
- PyErr_SetString(PyExc_TypeError,
- "Matrix(): "
- "takes no keyword args");
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- return Matrix_CreatePyObject(NULL, 4, 4, type);
- case 1:
- {
- PyObject *arg = PyTuple_GET_ITEM(args, 0);
-
- /* Input is now as a sequence of rows so length of sequence
- * is the number of rows */
- /* -1 is an error, size checks will account for this */
- const unsigned short num_row = PySequence_Size(arg);
-
- if (num_row >= 2 && num_row <= 4) {
- PyObject *item = PySequence_GetItem(arg, 0);
- /* Since each item is a row, number of items is the
- * same as the number of columns */
- const unsigned short num_col = PySequence_Size(item);
- Py_XDECREF(item);
-
- if (num_col >= 2 && num_col <= 4) {
- /* sane row & col size, new matrix and assign as slice */
- PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type);
- if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
- return matrix;
- }
- else { /* matrix ok, slice assignment not */
- Py_DECREF(matrix);
- }
- }
- }
- break;
- }
- }
-
- /* will overwrite error */
- PyErr_SetString(PyExc_TypeError,
- "Matrix(): "
- "expects no args or a single arg containing 2-4 numeric sequences");
- return NULL;
+ if (kwds && PyDict_Size(kwds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix(): "
+ "takes no keyword args");
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ return Matrix_CreatePyObject(NULL, 4, 4, type);
+ case 1: {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+
+ /* Input is now as a sequence of rows so length of sequence
+ * is the number of rows */
+ /* -1 is an error, size checks will account for this */
+ const unsigned short num_row = PySequence_Size(arg);
+
+ if (num_row >= 2 && num_row <= 4) {
+ PyObject *item = PySequence_GetItem(arg, 0);
+ /* Since each item is a row, number of items is the
+ * same as the number of columns */
+ const unsigned short num_col = PySequence_Size(item);
+ Py_XDECREF(item);
+
+ if (num_col >= 2 && num_col <= 4) {
+ /* sane row & col size, new matrix and assign as slice */
+ PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type);
+ if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
+ return matrix;
+ }
+ else { /* matrix ok, slice assignment not */
+ Py_DECREF(matrix);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* will overwrite error */
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix(): "
+ "expects no args or a single arg containing 2-4 numeric sequences");
+ return NULL;
}
static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self)
{
- PyObject *ret = Matrix_copy(self);
- if (ret) {
- PyObject *ret_dummy = matrix_func(ret);
- if (ret_dummy) {
- Py_DECREF(ret_dummy);
- return (PyObject *)ret;
- }
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
- }
- else {
- /* copy may fail if the read callback errors out */
- return NULL;
- }
+ PyObject *ret = Matrix_copy(self);
+ if (ret) {
+ PyObject *ret_dummy = matrix_func(ret);
+ if (ret_dummy) {
+ Py_DECREF(ret_dummy);
+ return (PyObject *)ret;
+ }
+ else { /* error */
+ Py_DECREF(ret);
+ return NULL;
+ }
+ }
+ else {
+ /* 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;
+ 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----------------------------*/
/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
PyDoc_STRVAR(C_Matrix_Identity_doc,
-".. classmethod:: Identity(size)\n"
-"\n"
-" 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"
-);
+ ".. 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 PyObject *C_Matrix_Identity(PyObject *cls, PyObject *args)
{
- int matSize;
+ int matSize;
- if (!PyArg_ParseTuple(args, "i:Matrix.Identity", &matSize)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "i:Matrix.Identity", &matSize)) {
+ return NULL;
+ }
- if (matSize < 2 || matSize > 4) {
- PyErr_SetString(PyExc_RuntimeError,
- "Matrix.Identity(): "
- "size must be between 2 and 4");
- return NULL;
- }
+ if (matSize < 2 || matSize > 4) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Matrix.Identity(): "
+ "size must be between 2 and 4");
+ return NULL;
+ }
- return Matrix_CreatePyObject(NULL, matSize, matSize, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(NULL, matSize, matSize, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Matrix_Rotation_doc,
-".. classmethod:: Rotation(angle, size, axis)\n"
-"\n"
-" Create a matrix representing a rotation.\n"
-"\n"
-" :arg angle: The angle of rotation desired, in radians.\n"
-" :type angle: float\n"
-" :arg size: The size of the rotation matrix to construct [2, 4].\n"
-" :type size: int\n"
-" :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object\n"
-" (optional when size is 2).\n"
-" :type axis: string or :class:`Vector`\n"
-" :return: A new rotation matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. classmethod:: Rotation(angle, size, axis)\n"
+ "\n"
+ " Create a matrix representing a rotation.\n"
+ "\n"
+ " :arg angle: The angle of rotation desired, in radians.\n"
+ " :type angle: float\n"
+ " :arg size: The size of the rotation matrix to construct [2, 4].\n"
+ " :type size: int\n"
+ " :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object\n"
+ " (optional when size is 2).\n"
+ " :type axis: string or :class:`Vector`\n"
+ " :return: A new rotation matrix.\n"
+ " :rtype: :class:`Matrix`\n");
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,
- };
-
- if (!PyArg_ParseTuple(args, "di|O:Matrix.Rotation", &angle, &matSize, &vec)) {
- return NULL;
- }
-
- if (vec && PyUnicode_Check(vec)) {
- axis = _PyUnicode_AsString((PyObject *)vec);
- if (axis == NULL || axis[0] == '\0' || axis[1] != '\0' || axis[0] < 'X' || axis[0] > 'Z') {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Rotation(): "
- "3rd argument axis value must be a 3D vector "
- "or a string in 'X', 'Y', 'Z'");
- return NULL;
- }
- else {
- /* use the string */
- vec = NULL;
- }
- }
-
- angle = angle_wrap_rad(angle);
-
- if (matSize != 2 && matSize != 3 && matSize != 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Rotation(): "
- "can only return a 2x2 3x3 or 4x4 matrix");
- return NULL;
- }
- if (matSize == 2 && (vec != NULL)) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Rotation(): "
- "cannot create a 2x2 rotation matrix around arbitrary axis");
- return NULL;
- }
- if ((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Rotation(): "
- "axis of rotation for 3d and 4d matrices is required");
- return NULL;
- }
-
- /* check for valid vector/axis above */
- if (vec) {
- float tvec[3];
-
- if (mathutils_array_parse(tvec, 3, 3, vec, "Matrix.Rotation(angle, size, axis), invalid 'axis' arg") == -1) {
- return NULL;
- }
-
- axis_angle_to_mat3((float (*)[3])mat, tvec, angle);
- }
- else if (matSize == 2) {
- angle_to_mat2((float (*)[2])mat, angle);
-
- }
- else {
- /* valid axis checked above */
- axis_angle_to_mat3_single((float (*)[3])mat, axis[0], angle);
- }
-
- if (matSize == 4) {
- matrix_3x3_as_4x4(mat);
- }
- /* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
+ 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,
+ };
+
+ if (!PyArg_ParseTuple(args, "di|O:Matrix.Rotation", &angle, &matSize, &vec)) {
+ return NULL;
+ }
+
+ if (vec && PyUnicode_Check(vec)) {
+ axis = _PyUnicode_AsString((PyObject *)vec);
+ if (axis == NULL || axis[0] == '\0' || axis[1] != '\0' || axis[0] < 'X' || axis[0] > 'Z') {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Rotation(): "
+ "3rd argument axis value must be a 3D vector "
+ "or a string in 'X', 'Y', 'Z'");
+ return NULL;
+ }
+ else {
+ /* use the string */
+ vec = NULL;
+ }
+ }
+
+ angle = angle_wrap_rad(angle);
+
+ if (matSize != 2 && matSize != 3 && matSize != 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Rotation(): "
+ "can only return a 2x2 3x3 or 4x4 matrix");
+ return NULL;
+ }
+ if (matSize == 2 && (vec != NULL)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Rotation(): "
+ "cannot create a 2x2 rotation matrix around arbitrary axis");
+ return NULL;
+ }
+ if ((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Rotation(): "
+ "axis of rotation for 3d and 4d matrices is required");
+ return NULL;
+ }
+
+ /* check for valid vector/axis above */
+ if (vec) {
+ float tvec[3];
+
+ if (mathutils_array_parse(
+ tvec, 3, 3, vec, "Matrix.Rotation(angle, size, axis), invalid 'axis' arg") == -1) {
+ return NULL;
+ }
+
+ axis_angle_to_mat3((float(*)[3])mat, tvec, angle);
+ }
+ else if (matSize == 2) {
+ angle_to_mat2((float(*)[2])mat, angle);
+ }
+ else {
+ /* valid axis checked above */
+ axis_angle_to_mat3_single((float(*)[3])mat, axis[0], angle);
+ }
+
+ if (matSize == 4) {
+ matrix_3x3_as_4x4(mat);
+ }
+ /* pass to matrix creation */
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
-
PyDoc_STRVAR(C_Matrix_Translation_doc,
-".. classmethod:: Translation(vector)\n"
-"\n"
-" Create a matrix representing a translation.\n"
-"\n"
-" :arg vector: The translation vector.\n"
-" :type vector: :class:`Vector`\n"
-" :return: An identity matrix with a translation.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. classmethod:: Translation(vector)\n"
+ "\n"
+ " Create a matrix representing a translation.\n"
+ "\n"
+ " :arg vector: The translation vector.\n"
+ " :type vector: :class:`Vector`\n"
+ " :return: An identity matrix with a translation.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value)
{
- float mat[4][4];
+ float mat[4][4];
- unit_m4(mat);
+ unit_m4(mat);
- if (mathutils_array_parse(mat[3], 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(
+ mat[3], 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1) {
+ return NULL;
+ }
- return Matrix_CreatePyObject(&mat[0][0], 4, 4, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(&mat[0][0], 4, 4, (PyTypeObject *)cls);
}
/* ----------------------------------mathutils.Matrix.Scale() ------------- */
/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
PyDoc_STRVAR(C_Matrix_Scale_doc,
-".. classmethod:: Scale(factor, size, axis)\n"
-"\n"
-" Create a matrix representing a scaling.\n"
-"\n"
-" :arg factor: The factor of scaling to apply.\n"
-" :type factor: float\n"
-" :arg size: The size of the scale matrix to construct [2, 4].\n"
-" :type size: int\n"
-" :arg axis: Direction to influence scale. (optional).\n"
-" :type axis: :class:`Vector`\n"
-" :return: A new scale matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. classmethod:: Scale(factor, size, axis)\n"
+ "\n"
+ " Create a matrix representing a scaling.\n"
+ "\n"
+ " :arg factor: The factor of scaling to apply.\n"
+ " :type factor: float\n"
+ " :arg size: The size of the scale matrix to construct [2, 4].\n"
+ " :type size: int\n"
+ " :arg axis: Direction to influence scale. (optional).\n"
+ " :type axis: :class:`Vector`\n"
+ " :return: A new scale matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
{
- PyObject *vec = NULL;
- int vec_size;
- 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,
- };
-
- if (!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) {
- return NULL;
- }
- if (matSize != 2 && matSize != 3 && matSize != 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Scale(): "
- "can only return a 2x2 3x3 or 4x4 matrix");
- return NULL;
- }
- if (vec) {
- vec_size = (matSize == 2 ? 2 : 3);
- if (mathutils_array_parse(tvec, vec_size, vec_size, vec,
- "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1)
- {
- return NULL;
- }
- }
- if (vec == NULL) { /* scaling along axis */
- if (matSize == 2) {
- mat[0] = factor;
- mat[3] = factor;
- }
- else {
- mat[0] = factor;
- mat[4] = factor;
- mat[8] = factor;
- }
- }
- else {
- /* scaling in arbitrary direction
- * normalize arbitrary axis */
- float norm = 0.0f;
- int x;
- for (x = 0; x < vec_size; x++) {
- norm += tvec[x] * tvec[x];
- }
- norm = sqrtf(norm);
- for (x = 0; x < vec_size; x++) {
- tvec[x] /= norm;
- }
- if (matSize == 2) {
- mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
- mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
- mat[2] = ((factor - 1) * (tvec[0] * tvec[1]));
- mat[3] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
- }
- else {
- mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
- mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
- mat[2] = ((factor - 1) * (tvec[0] * tvec[2]));
- mat[3] = ((factor - 1) * (tvec[0] * tvec[1]));
- mat[4] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
- mat[5] = ((factor - 1) * (tvec[1] * tvec[2]));
- mat[6] = ((factor - 1) * (tvec[0] * tvec[2]));
- mat[7] = ((factor - 1) * (tvec[1] * tvec[2]));
- mat[8] = 1 + ((factor - 1) * (tvec[2] * tvec[2]));
- }
- }
- if (matSize == 4) {
- matrix_3x3_as_4x4(mat);
- }
- /* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
+ PyObject *vec = NULL;
+ int vec_size;
+ 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,
+ };
+
+ if (!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) {
+ return NULL;
+ }
+ if (matSize != 2 && matSize != 3 && matSize != 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Scale(): "
+ "can only return a 2x2 3x3 or 4x4 matrix");
+ return NULL;
+ }
+ if (vec) {
+ vec_size = (matSize == 2 ? 2 : 3);
+ if (mathutils_array_parse(tvec,
+ vec_size,
+ vec_size,
+ vec,
+ "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) {
+ return NULL;
+ }
+ }
+ if (vec == NULL) { /* scaling along axis */
+ if (matSize == 2) {
+ mat[0] = factor;
+ mat[3] = factor;
+ }
+ else {
+ mat[0] = factor;
+ mat[4] = factor;
+ mat[8] = factor;
+ }
+ }
+ else {
+ /* scaling in arbitrary direction
+ * normalize arbitrary axis */
+ float norm = 0.0f;
+ int x;
+ for (x = 0; x < vec_size; x++) {
+ norm += tvec[x] * tvec[x];
+ }
+ norm = sqrtf(norm);
+ for (x = 0; x < vec_size; x++) {
+ tvec[x] /= norm;
+ }
+ if (matSize == 2) {
+ mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
+ mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
+ mat[2] = ((factor - 1) * (tvec[0] * tvec[1]));
+ mat[3] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
+ }
+ else {
+ mat[0] = 1 + ((factor - 1) * (tvec[0] * tvec[0]));
+ mat[1] = ((factor - 1) * (tvec[0] * tvec[1]));
+ mat[2] = ((factor - 1) * (tvec[0] * tvec[2]));
+ mat[3] = ((factor - 1) * (tvec[0] * tvec[1]));
+ mat[4] = 1 + ((factor - 1) * (tvec[1] * tvec[1]));
+ mat[5] = ((factor - 1) * (tvec[1] * tvec[2]));
+ mat[6] = ((factor - 1) * (tvec[0] * tvec[2]));
+ mat[7] = ((factor - 1) * (tvec[1] * tvec[2]));
+ mat[8] = 1 + ((factor - 1) * (tvec[2] * tvec[2]));
+ }
+ }
+ if (matSize == 4) {
+ matrix_3x3_as_4x4(mat);
+ }
+ /* 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. */
PyDoc_STRVAR(C_Matrix_OrthoProjection_doc,
-".. classmethod:: OrthoProjection(axis, size)\n"
-"\n"
-" Create a matrix to represent an orthographic projection.\n"
-"\n"
-" :arg axis: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
-" where a single axis is for a 2D matrix.\n"
-" Or a vector for an arbitrary axis\n"
-" :type axis: string or :class:`Vector`\n"
-" :arg size: The size of the projection matrix to construct [2, 4].\n"
-" :type size: int\n"
-" :return: A new projection matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. classmethod:: OrthoProjection(axis, size)\n"
+ "\n"
+ " Create a matrix to represent an orthographic projection.\n"
+ "\n"
+ " :arg axis: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
+ " where a single axis is for a 2D matrix.\n"
+ " Or a vector for an arbitrary axis\n"
+ " :type axis: string or :class:`Vector`\n"
+ " :arg size: The size of the projection matrix to construct [2, 4].\n"
+ " :type size: int\n"
+ " :return: A new projection matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
{
- PyObject *axis;
-
- 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,
- };
-
- if (!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) {
- return NULL;
- }
- if (matSize != 2 && matSize != 3 && matSize != 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.OrthoProjection(): "
- "can only return a 2x2 3x3 or 4x4 matrix");
- return NULL;
- }
-
- if (PyUnicode_Check(axis)) { /* ortho projection onto cardinal plane */
- Py_ssize_t plane_len;
- const char *plane = _PyUnicode_AsStringAndSize(axis, &plane_len);
- if (matSize == 2) {
- if (plane_len == 1 && plane[0] == 'X') {
- mat[0] = 1.0f;
- }
- else if (plane_len == 1 && plane[0] == 'Y') {
- mat[3] = 1.0f;
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "Matrix.OrthoProjection(): "
- "unknown plane, expected: X, Y, not '%.200s'",
- plane);
- return NULL;
- }
- }
- else {
- if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Y') {
- mat[0] = 1.0f;
- mat[4] = 1.0f;
- }
- else if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Z') {
- mat[0] = 1.0f;
- mat[8] = 1.0f;
- }
- else if (plane_len == 2 && plane[0] == 'Y' && plane[1] == 'Z') {
- mat[4] = 1.0f;
- mat[8] = 1.0f;
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "Matrix.OrthoProjection(): "
- "unknown plane, expected: XY, XZ, YZ, not '%.200s'",
- plane);
- return NULL;
- }
- }
- }
- else {
- /* arbitrary plane */
-
- int vec_size = (matSize == 2 ? 2 : 3);
- float tvec[4];
-
- if (mathutils_array_parse(tvec, vec_size, vec_size, axis,
- "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1)
- {
- return NULL;
- }
-
- /* normalize arbitrary axis */
- for (x = 0; x < vec_size; x++) {
- norm += tvec[x] * tvec[x];
- }
- norm = sqrtf(norm);
- for (x = 0; x < vec_size; x++) {
- tvec[x] /= norm;
- }
- if (matSize == 2) {
- mat[0] = 1 - (tvec[0] * tvec[0]);
- mat[1] = - (tvec[0] * tvec[1]);
- mat[2] = - (tvec[0] * tvec[1]);
- mat[3] = 1 - (tvec[1] * tvec[1]);
- }
- else if (matSize > 2) {
- mat[0] = 1 - (tvec[0] * tvec[0]);
- mat[1] = - (tvec[0] * tvec[1]);
- mat[2] = - (tvec[0] * tvec[2]);
- mat[3] = - (tvec[0] * tvec[1]);
- mat[4] = 1 - (tvec[1] * tvec[1]);
- mat[5] = - (tvec[1] * tvec[2]);
- mat[6] = - (tvec[0] * tvec[2]);
- mat[7] = - (tvec[1] * tvec[2]);
- mat[8] = 1 - (tvec[2] * tvec[2]);
- }
- }
- if (matSize == 4) {
- matrix_3x3_as_4x4(mat);
- }
- /* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
+ PyObject *axis;
+
+ 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,
+ };
+
+ if (!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) {
+ return NULL;
+ }
+ if (matSize != 2 && matSize != 3 && matSize != 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.OrthoProjection(): "
+ "can only return a 2x2 3x3 or 4x4 matrix");
+ return NULL;
+ }
+
+ if (PyUnicode_Check(axis)) { /* ortho projection onto cardinal plane */
+ Py_ssize_t plane_len;
+ const char *plane = _PyUnicode_AsStringAndSize(axis, &plane_len);
+ if (matSize == 2) {
+ if (plane_len == 1 && plane[0] == 'X') {
+ mat[0] = 1.0f;
+ }
+ else if (plane_len == 1 && plane[0] == 'Y') {
+ mat[3] = 1.0f;
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "Matrix.OrthoProjection(): "
+ "unknown plane, expected: X, Y, not '%.200s'",
+ plane);
+ return NULL;
+ }
+ }
+ else {
+ if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Y') {
+ mat[0] = 1.0f;
+ mat[4] = 1.0f;
+ }
+ else if (plane_len == 2 && plane[0] == 'X' && plane[1] == 'Z') {
+ mat[0] = 1.0f;
+ mat[8] = 1.0f;
+ }
+ else if (plane_len == 2 && plane[0] == 'Y' && plane[1] == 'Z') {
+ mat[4] = 1.0f;
+ mat[8] = 1.0f;
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "Matrix.OrthoProjection(): "
+ "unknown plane, expected: XY, XZ, YZ, not '%.200s'",
+ plane);
+ return NULL;
+ }
+ }
+ }
+ else {
+ /* arbitrary plane */
+
+ int vec_size = (matSize == 2 ? 2 : 3);
+ float tvec[4];
+
+ if (mathutils_array_parse(tvec,
+ vec_size,
+ vec_size,
+ axis,
+ "Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) {
+ return NULL;
+ }
+
+ /* normalize arbitrary axis */
+ for (x = 0; x < vec_size; x++) {
+ norm += tvec[x] * tvec[x];
+ }
+ norm = sqrtf(norm);
+ for (x = 0; x < vec_size; x++) {
+ tvec[x] /= norm;
+ }
+ if (matSize == 2) {
+ mat[0] = 1 - (tvec[0] * tvec[0]);
+ mat[1] = -(tvec[0] * tvec[1]);
+ mat[2] = -(tvec[0] * tvec[1]);
+ mat[3] = 1 - (tvec[1] * tvec[1]);
+ }
+ else if (matSize > 2) {
+ mat[0] = 1 - (tvec[0] * tvec[0]);
+ mat[1] = -(tvec[0] * tvec[1]);
+ mat[2] = -(tvec[0] * tvec[2]);
+ mat[3] = -(tvec[0] * tvec[1]);
+ mat[4] = 1 - (tvec[1] * tvec[1]);
+ mat[5] = -(tvec[1] * tvec[2]);
+ mat[6] = -(tvec[0] * tvec[2]);
+ mat[7] = -(tvec[1] * tvec[2]);
+ mat[8] = 1 - (tvec[2] * tvec[2]);
+ }
+ }
+ if (matSize == 4) {
+ matrix_3x3_as_4x4(mat);
+ }
+ /* pass to matrix creation */
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Matrix_Shear_doc,
-".. classmethod:: Shear(plane, size, factor)\n"
-"\n"
-" Create a matrix to represent an shear transformation.\n"
-"\n"
-" :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
-" where a single axis is for a 2D matrix only.\n"
-" :type plane: string\n"
-" :arg size: The size of the shear matrix to construct [2, 4].\n"
-" :type size: int\n"
-" :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix\n"
-" pass a pair of floats corresponding with the *plane* axis.\n"
-" :type factor: float or float pair\n"
-" :return: A new shear matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. classmethod:: Shear(plane, size, factor)\n"
+ "\n"
+ " Create a matrix to represent an shear transformation.\n"
+ "\n"
+ " :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'],\n"
+ " where a single axis is for a 2D matrix only.\n"
+ " :type plane: string\n"
+ " :arg size: The size of the shear matrix to construct [2, 4].\n"
+ " :type size: int\n"
+ " :arg factor: The factor of shear to apply. For a 3 or 4 *size* matrix\n"
+ " pass a pair of floats corresponding with the *plane* axis.\n"
+ " :type factor: float or float pair\n"
+ " :return: A new shear matrix.\n"
+ " :rtype: :class:`Matrix`\n");
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,
- };
-
- if (!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) {
- return NULL;
- }
- if (matSize != 2 && matSize != 3 && matSize != 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Shear(): "
- "can only return a 2x2 3x3 or 4x4 matrix");
- return NULL;
- }
-
- if (matSize == 2) {
- float const factor = PyFloat_AsDouble(fac);
-
- if (factor == -1.0f && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "Matrix.Shear(): "
- "the factor to be a float");
- return NULL;
- }
-
- /* unit */
- mat[0] = 1.0f;
- mat[3] = 1.0f;
-
- if (STREQ(plane, "X")) {
- mat[2] = factor;
- }
- else if (STREQ(plane, "Y")) {
- mat[1] = factor;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Shear(): "
- "expected: X, Y or wrong matrix size for shearing plane");
- return NULL;
- }
- }
- else {
- /* 3 or 4, apply as 3x3, resize later if needed */
- float factor[2];
-
- if (mathutils_array_parse(factor, 2, 2, fac, "Matrix.Shear()") == -1) {
- return NULL;
- }
-
- /* unit */
- mat[0] = 1.0f;
- mat[4] = 1.0f;
- mat[8] = 1.0f;
-
- if (STREQ(plane, "XY")) {
- mat[6] = factor[0];
- mat[7] = factor[1];
- }
- else if (STREQ(plane, "XZ")) {
- mat[3] = factor[0];
- mat[5] = factor[1];
- }
- else if (STREQ(plane, "YZ")) {
- mat[1] = factor[0];
- mat[2] = factor[1];
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.Shear(): "
- "expected: X, Y, XY, XZ, YZ");
- return NULL;
- }
- }
-
- if (matSize == 4) {
- matrix_3x3_as_4x4(mat);
- }
- /* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
+ 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,
+ };
+
+ if (!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) {
+ return NULL;
+ }
+ if (matSize != 2 && matSize != 3 && matSize != 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Shear(): "
+ "can only return a 2x2 3x3 or 4x4 matrix");
+ return NULL;
+ }
+
+ if (matSize == 2) {
+ float const factor = PyFloat_AsDouble(fac);
+
+ if (factor == -1.0f && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix.Shear(): "
+ "the factor to be a float");
+ return NULL;
+ }
+
+ /* unit */
+ mat[0] = 1.0f;
+ mat[3] = 1.0f;
+
+ if (STREQ(plane, "X")) {
+ mat[2] = factor;
+ }
+ else if (STREQ(plane, "Y")) {
+ mat[1] = factor;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Shear(): "
+ "expected: X, Y or wrong matrix size for shearing plane");
+ return NULL;
+ }
+ }
+ else {
+ /* 3 or 4, apply as 3x3, resize later if needed */
+ float factor[2];
+
+ if (mathutils_array_parse(factor, 2, 2, fac, "Matrix.Shear()") == -1) {
+ return NULL;
+ }
+
+ /* unit */
+ mat[0] = 1.0f;
+ mat[4] = 1.0f;
+ mat[8] = 1.0f;
+
+ if (STREQ(plane, "XY")) {
+ mat[6] = factor[0];
+ mat[7] = factor[1];
+ }
+ else if (STREQ(plane, "XZ")) {
+ mat[3] = factor[0];
+ mat[5] = factor[1];
+ }
+ else if (STREQ(plane, "YZ")) {
+ mat[1] = factor[0];
+ mat[2] = factor[1];
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.Shear(): "
+ "expected: X, Y, XY, XZ, YZ");
+ return NULL;
+ }
+ }
+
+ if (matSize == 4) {
+ matrix_3x3_as_4x4(mat);
+ }
+ /* pass to matrix creation */
+ return Matrix_CreatePyObject(mat, matSize, matSize, (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));
+ 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->num_col == mat_src->num_col) &&
- (mat_dst->num_row == mat_src->num_row));
- BLI_assert(mat_dst != mat_src);
+ BLI_assert((mat_dst->num_col == mat_src->num_col) && (mat_dst->num_row == mat_src->num_row));
+ BLI_assert(mat_dst != mat_src);
- memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row));
+ memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row));
}
/* transposes memory layout, rol/col's don't have to match */
static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *mat_src)
{
- unsigned short col, row;
- unsigned int i = 0;
+ unsigned short col, row;
+ unsigned int i = 0;
- for (row = 0; row < mat_src->num_row; row++) {
- for (col = 0; col < mat_src->num_col; col++) {
- mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col);
- }
- }
+ for (row = 0; row < mat_src->num_row; row++) {
+ for (col = 0; col < mat_src->num_col; 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->num_col == 2) {
- return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1),
- MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1));
- }
- else if (self->num_col == 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));
- }
- else {
- return determinant_m4((float (*)[4])self->matrix);
- }
+ if (self->num_col == 2) {
+ return determinant_m2(MATRIX_ITEM(self, 0, 0),
+ MATRIX_ITEM(self, 0, 1),
+ MATRIX_ITEM(self, 1, 0),
+ MATRIX_ITEM(self, 1, 1));
+ }
+ else if (self->num_col == 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));
+ }
+ else {
+ return determinant_m4((float(*)[4])self->matrix);
+ }
}
static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const unsigned short dim)
{
- /* calculate the classical adjoint */
- switch (dim) {
- case 2:
- {
- adjoint_m2_m2((float (*)[2])mat_dst, (float (*)[2])mat_src);
- break;
- }
- case 3:
- {
- adjoint_m3_m3((float (*)[3])mat_dst, (float (*)[3])mat_src);
- break;
- }
- case 4:
- {
- adjoint_m4_m4((float (*)[4])mat_dst, (float (*)[4])mat_src);
- break;
- }
- default:
- BLI_assert(0);
- }
-}
-
-static void matrix_invert_with_det_n_internal(float *mat_dst, const float *mat_src, const float det, const unsigned short dim)
-{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- unsigned short 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++) { /* num_col */
- for (j = 0; j < dim; j++) { /* num_row */
- mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det;
- }
- }
+ /* calculate the classical adjoint */
+ switch (dim) {
+ case 2: {
+ adjoint_m2_m2((float(*)[2])mat_dst, (float(*)[2])mat_src);
+ break;
+ }
+ case 3: {
+ adjoint_m3_m3((float(*)[3])mat_dst, (float(*)[3])mat_src);
+ break;
+ }
+ case 4: {
+ adjoint_m4_m4((float(*)[4])mat_dst, (float(*)[4])mat_src);
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
+}
+
+static void matrix_invert_with_det_n_internal(float *mat_dst,
+ const float *mat_src,
+ const float det,
+ const unsigned short dim)
+{
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ unsigned short 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++) { /* num_col */
+ for (j = 0; j < dim; j++) { /* num_row */
+ mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det;
+ }
+ }
}
/**
@@ -997,17 +1045,17 @@ static void matrix_invert_with_det_n_internal(float *mat_dst, const float *mat_s
*/
static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
{
- float det;
- BLI_assert(self->num_col == self->num_row);
- det = matrix_determinant_internal(self);
+ float det;
+ BLI_assert(self->num_col == self->num_row);
+ det = matrix_determinant_internal(self);
- if (det != 0.0f) {
- matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col);
- return true;
- }
- else {
- return false;
- }
+ if (det != 0.0f) {
+ matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col);
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -1016,358 +1064,347 @@ static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
*/
static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
{
- float det;
- float *in_mat = self->matrix;
- BLI_assert(self->num_col == self->num_row);
- 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->num_col) {
- case 2:
- {
- float (*mat)[2] = (float (*)[2])in_mat;
-
- if (in_mat != self->matrix) {
- copy_m2_m2(mat, (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, (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, (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(0);
- }
- }
-
- matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->num_col);
+ float det;
+ float *in_mat = self->matrix;
+ BLI_assert(self->num_col == self->num_row);
+ 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->num_col) {
+ case 2: {
+ float(*mat)[2] = (float(*)[2])in_mat;
+
+ if (in_mat != self->matrix) {
+ copy_m2_m2(mat, (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, (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, (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(0);
+ }
+ }
+
+ matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->num_col);
}
-
/*-----------------------------METHODS----------------------------*/
PyDoc_STRVAR(Matrix_to_quaternion_doc,
-".. method:: to_quaternion()\n"
-"\n"
-" Return a quaternion representation of the rotation matrix.\n"
-"\n"
-" :return: Quaternion representation of the rotation matrix.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. method:: to_quaternion()\n"
+ "\n"
+ " Return a quaternion representation of the rotation matrix.\n"
+ "\n"
+ " :return: Quaternion representation of the rotation matrix.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Matrix_to_quaternion(MatrixObject *self)
{
- float quat[4];
+ float quat[4];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- /* must be 3-4 cols, 3-4 rows, square matrix */
- if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_quat(): "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
- if (self->num_row == 3) {
- mat3_to_quat(quat, (float (*)[3])self->matrix);
- }
- else {
- mat4_to_quat(quat, (float (*)[4])self->matrix);
- }
+ /* must be 3-4 cols, 3-4 rows, square matrix */
+ if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.to_quat(): "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
+ }
+ if (self->num_row == 3) {
+ mat3_to_quat(quat, (float(*)[3])self->matrix);
+ }
+ else {
+ mat4_to_quat(quat, (float(*)[4])self->matrix);
+ }
- return Quaternion_CreatePyObject(quat, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
/*---------------------------matrix.toEuler() --------------------*/
PyDoc_STRVAR(Matrix_to_euler_doc,
-".. method:: to_euler(order, euler_compat)\n"
-"\n"
-" Return an Euler representation of the rotation matrix\n"
-" (3x3 or 4x4 matrix only).\n"
-"\n"
-" :arg order: Optional rotation order argument in\n"
-" ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
-" :type order: string\n"
-" :arg euler_compat: Optional euler argument the new euler will be made\n"
-" compatible with (no axis flipping between them).\n"
-" Useful for converting a series of matrices to animation curves.\n"
-" :type euler_compat: :class:`Euler`\n"
-" :return: Euler representation of the matrix.\n"
-" :rtype: :class:`Euler`\n"
-);
+ ".. method:: to_euler(order, euler_compat)\n"
+ "\n"
+ " Return an Euler representation of the rotation matrix\n"
+ " (3x3 or 4x4 matrix only).\n"
+ "\n"
+ " :arg order: Optional rotation order argument in\n"
+ " ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
+ " :type order: string\n"
+ " :arg euler_compat: Optional euler argument the new euler will be made\n"
+ " compatible with (no axis flipping between them).\n"
+ " Useful for converting a series of matrices to animation curves.\n"
+ " :type euler_compat: :class:`Euler`\n"
+ " :return: Euler representation of the matrix.\n"
+ " :rtype: :class:`Euler`\n");
static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
{
- const char *order_str = NULL;
- short order = EULER_ORDER_XYZ;
- float eul[3], eul_compatf[3];
- EulerObject *eul_compat = NULL;
-
- float mat[3][3];
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) {
- return NULL;
- }
-
- if (eul_compat) {
- if (BaseMath_ReadCallback(eul_compat) == -1) {
- return NULL;
- }
-
- copy_v3_v3(eul_compatf, eul_compat->eul);
- }
-
- /*must be 3-4 cols, 3-4 rows, square matrix */
- if (self->num_row == 3 && self->num_col == 3) {
- copy_m3_m3(mat, (float (*)[3])self->matrix);
- }
- else if (self->num_row == 4 && self->num_col == 4) {
- copy_m3_m4(mat, (float (*)[4])self->matrix);
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_euler(): "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
-
- if (order_str) {
- order = euler_order_from_string(order_str, "Matrix.to_euler()");
-
- if (order == -1) {
- return NULL;
- }
- }
-
- normalize_m3(mat);
-
- if (eul_compat) {
- if (order == 1) {
- mat3_normalized_to_compatible_eul(eul, eul_compatf, mat);
- }
- else {
- mat3_normalized_to_compatible_eulO(eul, eul_compatf, order, mat);
- }
- }
- else {
- if (order == 1) {
- mat3_normalized_to_eul(eul, mat);
- }
- else {
- mat3_normalized_to_eulO(eul, order, mat);
- }
- }
-
- return Euler_CreatePyObject(eul, order, NULL);
+ const char *order_str = NULL;
+ short order = EULER_ORDER_XYZ;
+ float eul[3], eul_compatf[3];
+ EulerObject *eul_compat = NULL;
+
+ float mat[3][3];
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) {
+ return NULL;
+ }
+
+ if (eul_compat) {
+ if (BaseMath_ReadCallback(eul_compat) == -1) {
+ return NULL;
+ }
+
+ copy_v3_v3(eul_compatf, eul_compat->eul);
+ }
+
+ /*must be 3-4 cols, 3-4 rows, square matrix */
+ if (self->num_row == 3 && self->num_col == 3) {
+ copy_m3_m3(mat, (float(*)[3])self->matrix);
+ }
+ else if (self->num_row == 4 && self->num_col == 4) {
+ copy_m3_m4(mat, (float(*)[4])self->matrix);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.to_euler(): "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
+ }
+
+ if (order_str) {
+ order = euler_order_from_string(order_str, "Matrix.to_euler()");
+
+ if (order == -1) {
+ return NULL;
+ }
+ }
+
+ normalize_m3(mat);
+
+ if (eul_compat) {
+ if (order == 1) {
+ mat3_normalized_to_compatible_eul(eul, eul_compatf, mat);
+ }
+ else {
+ mat3_normalized_to_compatible_eulO(eul, eul_compatf, order, mat);
+ }
+ }
+ else {
+ if (order == 1) {
+ mat3_normalized_to_eul(eul, mat);
+ }
+ else {
+ mat3_normalized_to_eulO(eul, order, mat);
+ }
+ }
+
+ return Euler_CreatePyObject(eul, order, NULL);
}
PyDoc_STRVAR(Matrix_resize_4x4_doc,
-".. method:: resize_4x4()\n"
-"\n"
-" Resize the matrix to 4x4.\n"
-);
+ ".. method:: resize_4x4()\n"
+ "\n"
+ " Resize the matrix to 4x4.\n");
static PyObject *Matrix_resize_4x4(MatrixObject *self)
{
- float mat[4][4];
- int col;
+ float mat[4][4];
+ int col;
- if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.resize_4x4(): "
- "cannot resize wrapped data - make a copy and resize that");
- return NULL;
- }
- if (self->cb_user) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.resize_4x4(): "
- "cannot resize owned data - make a copy and resize that");
- return NULL;
- }
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.resize_4x4(): "
+ "cannot resize wrapped data - make a copy and resize that");
+ return NULL;
+ }
+ if (self->cb_user) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.resize_4x4(): "
+ "cannot resize owned data - make a copy and resize that");
+ return NULL;
+ }
- self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * (MATRIX_MAX_DIM * MATRIX_MAX_DIM)));
- if (self->matrix == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Matrix.resize_4x4(): "
- "problem allocating pointer space");
- return NULL;
- }
+ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * (MATRIX_MAX_DIM * MATRIX_MAX_DIM)));
+ if (self->matrix == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Matrix.resize_4x4(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- unit_m4(mat);
+ unit_m4(mat);
- for (col = 0; col < self->num_col; col++) {
- memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float));
- }
+ for (col = 0; col < self->num_col; col++) {
+ memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float));
+ }
- copy_m4_m4((float (*)[4])self->matrix, (float (*)[4])mat);
+ copy_m4_m4((float(*)[4])self->matrix, (float(*)[4])mat);
- self->num_col = 4;
- self->num_row = 4;
+ self->num_col = 4;
+ self->num_row = 4;
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_to_4x4_doc,
-".. method:: to_4x4()\n"
-"\n"
-" Return a 4x4 copy of this matrix.\n"
-"\n"
-" :return: a new matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: to_4x4()\n"
+ "\n"
+ " Return a 4x4 copy of this matrix.\n"
+ "\n"
+ " :return: a new matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_to_4x4(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (self->num_row == 4 && self->num_col == 4) {
- return Matrix_CreatePyObject(self->matrix, 4, 4, Py_TYPE(self));
- }
- else if (self->num_row == 3 && self->num_col == 3) {
- float mat[4][4];
- copy_m4_m3(mat, (float (*)[3])self->matrix);
- return Matrix_CreatePyObject((float *)mat, 4, 4, Py_TYPE(self));
- }
- /* TODO, 2x2 matrix */
+ if (self->num_row == 4 && self->num_col == 4) {
+ return Matrix_CreatePyObject(self->matrix, 4, 4, Py_TYPE(self));
+ }
+ else if (self->num_row == 3 && self->num_col == 3) {
+ float mat[4][4];
+ copy_m4_m3(mat, (float(*)[3])self->matrix);
+ return Matrix_CreatePyObject((float *)mat, 4, 4, Py_TYPE(self));
+ }
+ /* TODO, 2x2 matrix */
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_4x4(): "
- "inappropriate matrix size");
- return NULL;
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.to_4x4(): "
+ "inappropriate matrix size");
+ return NULL;
}
PyDoc_STRVAR(Matrix_to_3x3_doc,
-".. method:: to_3x3()\n"
-"\n"
-" Return a 3x3 copy of this matrix.\n"
-"\n"
-" :return: a new matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: to_3x3()\n"
+ "\n"
+ " Return a 3x3 copy of this matrix.\n"
+ "\n"
+ " :return: a new matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_to_3x3(MatrixObject *self)
{
- float mat[3][3];
+ float mat[3][3];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_3x3(): inappropriate matrix size");
- return NULL;
- }
+ if ((self->num_row < 3) || (self->num_col < 3)) {
+ PyErr_SetString(PyExc_ValueError, "Matrix.to_3x3(): inappropriate matrix size");
+ return NULL;
+ }
- matrix_as_3x3(mat, self);
+ matrix_as_3x3(mat, self);
- return Matrix_CreatePyObject((float *)mat, 3, 3, Py_TYPE(self));
+ return Matrix_CreatePyObject((float *)mat, 3, 3, Py_TYPE(self));
}
PyDoc_STRVAR(Matrix_to_translation_doc,
-".. method:: to_translation()\n"
-"\n"
-" Return the translation part of a 4 row matrix.\n"
-"\n"
-" :return: Return the translation of a matrix.\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: to_translation()\n"
+ "\n"
+ " Return the translation part of a 4 row matrix.\n"
+ "\n"
+ " :return: Return the translation of a matrix.\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Matrix_to_translation(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if ((self->num_row < 3) || self->num_col < 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_translation(): "
- "inappropriate matrix size");
- return NULL;
- }
+ if ((self->num_row < 3) || self->num_col < 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.to_translation(): "
+ "inappropriate matrix size");
+ return NULL;
+ }
- return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, NULL);
+ return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, NULL);
}
PyDoc_STRVAR(Matrix_to_scale_doc,
-".. method:: to_scale()\n"
-"\n"
-" Return the scale part of a 3x3 or 4x4 matrix.\n"
-"\n"
-" :return: Return the scale of a matrix.\n"
-" :rtype: :class:`Vector`\n"
-"\n"
-" .. note:: This method does not return a negative scale on any axis because it is not possible to obtain this data from the matrix alone.\n"
-);
+ ".. method:: to_scale()\n"
+ "\n"
+ " Return the scale part of a 3x3 or 4x4 matrix.\n"
+ "\n"
+ " :return: Return the scale of a matrix.\n"
+ " :rtype: :class:`Vector`\n"
+ "\n"
+ " .. note:: This method does not return a negative scale on any axis because it is "
+ "not possible to obtain this data from the matrix alone.\n");
static PyObject *Matrix_to_scale(MatrixObject *self)
{
- float rot[3][3];
- float mat[3][3];
- float size[3];
+ float rot[3][3];
+ float mat[3][3];
+ float size[3];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- /*must be 3-4 cols, 3-4 rows, square matrix */
- if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.to_scale(): "
- "inappropriate matrix size, 3x3 minimum size");
- return NULL;
- }
+ /*must be 3-4 cols, 3-4 rows, square matrix */
+ if ((self->num_row < 3) || (self->num_col < 3)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.to_scale(): "
+ "inappropriate matrix size, 3x3 minimum size");
+ return NULL;
+ }
- matrix_as_3x3(mat, self);
+ matrix_as_3x3(mat, self);
- /* compatible mat4_to_loc_rot_size */
- mat3_to_rot_size(rot, size, mat);
+ /* compatible mat4_to_loc_rot_size */
+ mat3_to_rot_size(rot, size, mat);
- return Vector_CreatePyObject(size, 3, NULL);
+ return Vector_CreatePyObject(size, 3, NULL);
}
/*---------------------------matrix.invert() ---------------------*/
@@ -1375,774 +1412,777 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
/* re-usable checks for invert */
static bool matrix_invert_is_compat(const MatrixObject *self)
{
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.invert(ed): "
- "only square matrices are supported");
- return false;
- }
- else {
- return true;
- }
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "only square matrices are supported");
+ return false;
+ }
+ else {
+ return true;
+ }
}
static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, bool check_type)
{
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- return true;
- case 1:
- if (check_type) {
- const MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
- if (!MatrixObject_Check(fallback)) {
- PyErr_SetString(PyExc_TypeError,
- "Matrix.invert: "
- "expects a matrix argument or nothing");
- return false;
- }
-
- if ((self->num_col != fallback->num_col) ||
- (self->num_row != fallback->num_row))
- {
- PyErr_SetString(PyExc_TypeError,
- "Matrix.invert: "
- "matrix argument has different dimensions");
- return false;
- }
- }
-
- return true;
- default:
- PyErr_SetString(PyExc_ValueError,
- "Matrix.invert(ed): "
- "takes at most one argument");
- return false;
- }
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ return true;
+ case 1:
+ if (check_type) {
+ const MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
+ if (!MatrixObject_Check(fallback)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix.invert: "
+ "expects a matrix argument or nothing");
+ return false;
+ }
+
+ if ((self->num_col != fallback->num_col) || (self->num_row != fallback->num_row)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Matrix.invert: "
+ "matrix argument has different dimensions");
+ return false;
+ }
+ }
+
+ return true;
+ default:
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "takes at most one argument");
+ return false;
+ }
}
static void matrix_invert_raise_degenerate(void)
{
- PyErr_SetString(PyExc_ValueError,
- "Matrix.invert(ed): "
- "matrix does not have an inverse");
-}
-
-PyDoc_STRVAR(Matrix_invert_doc,
-".. method:: invert(fallback=None)\n"
-"\n"
-" Set the matrix to its inverse.\n"
-"\n"
-" :arg fallback: Set the matrix to this value when the inverse cannot be calculated\n"
-" (instead of raising a :exc:`ValueError` exception).\n"
-" :type fallback: :class:`Matrix`\n"
-"\n"
-" .. seealso:: `Inverse matrix <https://en.wikipedia.org/wiki/Inverse_matrix>` on Wikipedia.\n"
-);
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.invert(ed): "
+ "matrix does not have an inverse");
+}
+
+PyDoc_STRVAR(
+ Matrix_invert_doc,
+ ".. method:: invert(fallback=None)\n"
+ "\n"
+ " Set the matrix to its inverse.\n"
+ "\n"
+ " :arg fallback: Set the matrix to this value when the inverse cannot be calculated\n"
+ " (instead of raising a :exc:`ValueError` exception).\n"
+ " :type fallback: :class:`Matrix`\n"
+ "\n"
+ " .. seealso:: `Inverse matrix <https://en.wikipedia.org/wiki/Inverse_matrix>` on "
+ "Wikipedia.\n");
static PyObject *Matrix_invert(MatrixObject *self, PyObject *args)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (matrix_invert_is_compat(self) == false) {
- return NULL;
- }
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
- if (matrix_invert_args_check(self, args, true) == false) {
- return NULL;
- }
+ if (matrix_invert_args_check(self, args, true) == false) {
+ return NULL;
+ }
- if (matrix_invert_internal(self, self->matrix)) {
- /* pass */
- }
- else {
- if (PyTuple_GET_SIZE(args) == 1) {
- MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
+ if (matrix_invert_internal(self, self->matrix)) {
+ /* pass */
+ }
+ else {
+ if (PyTuple_GET_SIZE(args) == 1) {
+ MatrixObject *fallback = (MatrixObject *)PyTuple_GET_ITEM(args, 0);
- if (BaseMath_ReadCallback(fallback) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(fallback) == -1) {
+ return NULL;
+ }
- if (self != fallback) {
- matrix_copy(self, fallback);
- }
- }
- else {
- matrix_invert_raise_degenerate();
- return NULL;
- }
- }
+ if (self != fallback) {
+ matrix_copy(self, fallback);
+ }
+ }
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
+ }
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_inverted_doc,
-".. method:: inverted(fallback=None)\n"
-"\n"
-" Return an inverted copy of the matrix.\n"
-"\n"
-" :arg fallback: return this when the inverse can't be calculated\n"
-" (instead of raising a :exc:`ValueError`).\n"
-" :type fallback: any\n"
-" :return: the inverted matrix or fallback when given.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: inverted(fallback=None)\n"
+ "\n"
+ " Return an inverted copy of the matrix.\n"
+ "\n"
+ " :arg fallback: return this when the inverse can't be calculated\n"
+ " (instead of raising a :exc:`ValueError`).\n"
+ " :type fallback: any\n"
+ " :return: the inverted matrix or fallback when given.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_inverted(MatrixObject *self, PyObject *args)
{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (matrix_invert_args_check(self, args, false) == false) {
- return NULL;
- }
+ if (matrix_invert_args_check(self, args, false) == false) {
+ return NULL;
+ }
- if (matrix_invert_is_compat(self) == false) {
- return NULL;
- }
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
- if (matrix_invert_internal(self, mat)) {
- /* pass */
- }
- else {
- if (PyTuple_GET_SIZE(args) == 1) {
- PyObject *fallback = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(fallback);
- return fallback;
- }
- else {
- matrix_invert_raise_degenerate();
- return NULL;
- }
- }
+ if (matrix_invert_internal(self, mat)) {
+ /* pass */
+ }
+ else {
+ if (PyTuple_GET_SIZE(args) == 1) {
+ PyObject *fallback = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
+ }
- return Matrix_copy_notest(self, mat);
+ return Matrix_copy_notest(self, mat);
}
static PyObject *Matrix_inverted_noargs(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (matrix_invert_is_compat(self) == false) {
- return NULL;
- }
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
- if (matrix_invert_internal(self, self->matrix)) {
- /* pass */
- }
- else {
- matrix_invert_raise_degenerate();
- return NULL;
- }
+ if (matrix_invert_internal(self, self->matrix)) {
+ /* pass */
+ }
+ else {
+ matrix_invert_raise_degenerate();
+ return NULL;
+ }
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_invert_safe_doc,
-".. method:: invert_safe()\n"
-"\n"
-" Set the matrix to its inverse, will never error.\n"
-" If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, to get an invertible one.\n"
-" If tweaked matrix is still degenerated, set to the identity matrix instead.\n"
-"\n"
-" .. seealso:: `Inverse Matrix <https://en.wikipedia.org/wiki/Inverse_matrix>` on Wikipedia.\n"
-);
+ ".. method:: invert_safe()\n"
+ "\n"
+ " Set the matrix to its inverse, will never error.\n"
+ " If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, "
+ "to get an invertible one.\n"
+ " If tweaked matrix is still degenerated, set to the identity matrix instead.\n"
+ "\n"
+ " .. seealso:: `Inverse Matrix <https://en.wikipedia.org/wiki/Inverse_matrix>` on "
+ "Wikipedia.\n");
static PyObject *Matrix_invert_safe(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (matrix_invert_is_compat(self) == false) {
- return NULL;
- }
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
- matrix_invert_safe_internal(self, self->matrix);
+ matrix_invert_safe_internal(self, self->matrix);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_inverted_safe_doc,
-".. method:: inverted_safe()\n"
-"\n"
-" Return an inverted copy of the matrix, will never error.\n"
-" If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, to get an invertible one.\n"
-" If tweaked matrix is still degenerated, return the identity matrix instead.\n"
-"\n"
-" :return: the inverted matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: inverted_safe()\n"
+ "\n"
+ " Return an inverted copy of the matrix, will never error.\n"
+ " If degenerated (e.g. zero scale on an axis), add some epsilon to its diagonal, "
+ "to get an invertible one.\n"
+ " If tweaked matrix is still degenerated, return the identity matrix instead.\n"
+ "\n"
+ " :return: the inverted matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_inverted_safe(MatrixObject *self)
{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (matrix_invert_is_compat(self) == false) {
- return NULL;
- }
+ if (matrix_invert_is_compat(self) == false) {
+ return NULL;
+ }
- matrix_invert_safe_internal(self, mat);
+ matrix_invert_safe_internal(self, mat);
- return Matrix_copy_notest(self, mat);
+ return Matrix_copy_notest(self, mat);
}
/*---------------------------matrix.adjugate() ---------------------*/
-PyDoc_STRVAR(Matrix_adjugate_doc,
-".. method:: adjugate()\n"
-"\n"
-" Set the matrix to its adjugate.\n"
-"\n"
-" .. note:: When the matrix cannot be adjugated a :exc:`ValueError` exception is raised.\n"
-"\n"
-" .. seealso:: `Adjugate matrix <https://en.wikipedia.org/wiki/Adjugate_matrix>` on Wikipedia.\n"
-);
+PyDoc_STRVAR(
+ Matrix_adjugate_doc,
+ ".. method:: adjugate()\n"
+ "\n"
+ " Set the matrix to its adjugate.\n"
+ "\n"
+ " .. note:: When the matrix cannot be adjugated a :exc:`ValueError` exception is raised.\n"
+ "\n"
+ " .. seealso:: `Adjugate matrix <https://en.wikipedia.org/wiki/Adjugate_matrix>` on "
+ "Wikipedia.\n");
static PyObject *Matrix_adjugate(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
-
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.adjugate(d): "
- "only square matrices are supported");
- return NULL;
- }
-
- /* calculate the classical adjoint */
- if (self->num_col <= 4) {
- adjoint_matrix_n(self->matrix, self->matrix, self->num_col);
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "Matrix adjugate(d): size (%d) unsupported",
- (int)self->num_col);
- return NULL;
- }
-
-
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
-}
-
-PyDoc_STRVAR(Matrix_adjugated_doc,
-".. method:: adjugated()\n"
-"\n"
-" Return an adjugated copy of the matrix.\n"
-"\n"
-" :return: the adjugated matrix.\n"
-" :rtype: :class:`Matrix`\n"
-"\n"
-" .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n"
-);
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
+
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.adjugate(d): "
+ "only square matrices are supported");
+ return NULL;
+ }
+
+ /* calculate the classical adjoint */
+ if (self->num_col <= 4) {
+ adjoint_matrix_n(self->matrix, self->matrix, self->num_col);
+ }
+ else {
+ PyErr_Format(
+ PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->num_col);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(
+ Matrix_adjugated_doc,
+ ".. method:: adjugated()\n"
+ "\n"
+ " Return an adjugated copy of the matrix.\n"
+ "\n"
+ " :return: the adjugated matrix.\n"
+ " :rtype: :class:`Matrix`\n"
+ "\n"
+ " .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n");
static PyObject *Matrix_adjugated(MatrixObject *self)
{
- return matrix__apply_to_copy((PyNoArgsFunction)Matrix_adjugate, self);
+ return matrix__apply_to_copy((PyNoArgsFunction)Matrix_adjugate, self);
}
-PyDoc_STRVAR(Matrix_rotate_doc,
-".. method:: rotate(other)\n"
-"\n"
-" Rotates the matrix by another mathutils value.\n"
-"\n"
-" :arg other: rotation component of mathutils value\n"
-" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
-"\n"
-" .. note:: If any of the columns are not unit length this may not have desired results.\n"
-);
+PyDoc_STRVAR(
+ Matrix_rotate_doc,
+ ".. method:: rotate(other)\n"
+ "\n"
+ " Rotates the matrix by another mathutils value.\n"
+ "\n"
+ " :arg other: rotation component of mathutils value\n"
+ " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
+ "\n"
+ " .. note:: If any of the columns are not unit length this may not have desired results.\n");
static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
{
- float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
+ float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1) {
- return NULL;
- }
+ if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1) {
+ return NULL;
+ }
- if (self->num_row != 3 || self->num_col != 3) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.rotate(): "
- "must have 3x3 dimensions");
- return NULL;
- }
+ if (self->num_row != 3 || self->num_col != 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.rotate(): "
+ "must have 3x3 dimensions");
+ return NULL;
+ }
- matrix_as_3x3(self_rmat, self);
- mul_m3_m3m3(rmat, other_rmat, self_rmat);
+ matrix_as_3x3(self_rmat, self);
+ mul_m3_m3m3(rmat, other_rmat, self_rmat);
- copy_m3_m3((float (*)[3])(self->matrix), rmat);
+ copy_m3_m3((float(*)[3])(self->matrix), rmat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
/*---------------------------matrix.decompose() ---------------------*/
PyDoc_STRVAR(Matrix_decompose_doc,
-".. method:: decompose()\n"
-"\n"
-" Return the translation, rotation, and scale components of this matrix.\n"
-"\n"
-" :return: tuple of translation, rotation, and scale\n"
-" :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)"
-);
+ ".. method:: decompose()\n"
+ "\n"
+ " Return the translation, rotation, and scale components of this matrix.\n"
+ "\n"
+ " :return: tuple of translation, rotation, and scale\n"
+ " :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)");
static PyObject *Matrix_decompose(MatrixObject *self)
{
- PyObject *ret;
- float loc[3];
- float rot[3][3];
- float quat[4];
- float size[3];
+ PyObject *ret;
+ float loc[3];
+ float rot[3][3];
+ float quat[4];
+ float size[3];
- if (self->num_row != 4 || self->num_col != 4) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.decompose(): "
- "inappropriate matrix size - expects 4x4 matrix");
- return NULL;
- }
+ if (self->num_row != 4 || self->num_col != 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.decompose(): "
+ "inappropriate matrix size - expects 4x4 matrix");
+ return NULL;
+ }
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->matrix);
- mat3_to_quat(quat, rot);
+ mat4_to_loc_rot_size(loc, rot, size, (float(*)[4])self->matrix);
+ mat3_to_quat(quat, rot);
- ret = PyTuple_New(3);
- PyTuple_SET_ITEMS(ret,
- Vector_CreatePyObject(loc, 3, NULL),
- Quaternion_CreatePyObject(quat, NULL),
- Vector_CreatePyObject(size, 3, NULL));
- return ret;
+ ret = PyTuple_New(3);
+ PyTuple_SET_ITEMS(ret,
+ Vector_CreatePyObject(loc, 3, NULL),
+ Quaternion_CreatePyObject(quat, NULL),
+ Vector_CreatePyObject(size, 3, NULL));
+ return ret;
}
-
-
PyDoc_STRVAR(Matrix_lerp_doc,
-".. function:: lerp(other, factor)\n"
-"\n"
-" Returns the interpolation of two matrices. Uses polar decomposition, see"
-" \"Matrix Animation and Polar Decomposition\", Shoemake and Duff, 1992.\n"
-"\n"
-" :arg other: value to interpolate with.\n"
-" :type other: :class:`Matrix`\n"
-" :arg factor: The interpolation value in [0.0, 1.0].\n"
-" :type factor: float\n"
-" :return: The interpolated matrix.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. function:: lerp(other, factor)\n"
+ "\n"
+ " Returns the interpolation of two matrices. Uses polar decomposition, see"
+ " \"Matrix Animation and Polar Decomposition\", Shoemake and Duff, 1992.\n"
+ "\n"
+ " :arg other: value to interpolate with.\n"
+ " :type other: :class:`Matrix`\n"
+ " :arg factor: The interpolation value in [0.0, 1.0].\n"
+ " :type factor: float\n"
+ " :return: The interpolated matrix.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
{
- MatrixObject *mat2 = NULL;
- float fac, mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ MatrixObject *mat2 = NULL;
+ float fac, mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if (!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) {
+ return NULL;
+ }
- if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.lerp(): "
- "expects both matrix objects of the same dimensions");
- return NULL;
- }
+ if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.lerp(): "
+ "expects both matrix objects of the same dimensions");
+ return NULL;
+ }
- if (BaseMath_ReadCallback(self) == -1 || BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1 || BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
- /* TODO, different sized matrix */
- if (self->num_col == 4 && self->num_row == 4) {
+ /* TODO, different sized matrix */
+ if (self->num_col == 4 && self->num_row == 4) {
#ifdef MATH_STANDALONE
- blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac);
+ blend_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac);
#else
- interp_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac);
+ interp_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac);
#endif
- }
- else if (self->num_col == 3 && self->num_row == 3) {
+ }
+ else if (self->num_col == 3 && self->num_row == 3) {
#ifdef MATH_STANDALONE
- blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac);
+ blend_m3_m3m3((float(*)[3])mat, (float(*)[3])self->matrix, (float(*)[3])mat2->matrix, fac);
#else
- interp_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac);
+ interp_m3_m3m3((float(*)[3])mat, (float(*)[3])self->matrix, (float(*)[3])mat2->matrix, fac);
#endif
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.lerp(): "
- "only 3x3 and 4x4 matrices supported");
- return NULL;
- }
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.lerp(): "
+ "only 3x3 and 4x4 matrices supported");
+ return NULL;
+ }
- return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self));
+ return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self));
}
/*---------------------------matrix.determinant() ----------------*/
-PyDoc_STRVAR(Matrix_determinant_doc,
-".. method:: determinant()\n"
-"\n"
-" Return the determinant of a matrix.\n"
-"\n"
-" :return: Return the determinant of a matrix.\n"
-" :rtype: float\n"
-"\n"
-" .. seealso:: `Determinant <https://en.wikipedia.org/wiki/Determinant>` on Wikipedia.\n"
-);
+PyDoc_STRVAR(
+ Matrix_determinant_doc,
+ ".. method:: determinant()\n"
+ "\n"
+ " Return the determinant of a matrix.\n"
+ "\n"
+ " :return: Return the determinant of a matrix.\n"
+ " :rtype: float\n"
+ "\n"
+ " .. seealso:: `Determinant <https://en.wikipedia.org/wiki/Determinant>` on Wikipedia.\n");
static PyObject *Matrix_determinant(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.determinant(): "
- "only square matrices are supported");
- return NULL;
- }
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.determinant(): "
+ "only square matrices are supported");
+ return NULL;
+ }
- return PyFloat_FromDouble((double)matrix_determinant_internal(self));
+ return PyFloat_FromDouble((double)matrix_determinant_internal(self));
}
/*---------------------------matrix.transpose() ------------------*/
-PyDoc_STRVAR(Matrix_transpose_doc,
-".. method:: transpose()\n"
-"\n"
-" Set the matrix to its transpose.\n"
-"\n"
-" .. seealso:: `Transpose <https://en.wikipedia.org/wiki/Transpose>` on Wikipedia.\n"
-);
+PyDoc_STRVAR(
+ Matrix_transpose_doc,
+ ".. method:: transpose()\n"
+ "\n"
+ " Set the matrix to its transpose.\n"
+ "\n"
+ " .. seealso:: `Transpose <https://en.wikipedia.org/wiki/Transpose>` on Wikipedia.\n");
static PyObject *Matrix_transpose(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
-
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.transpose(d): "
- "only square matrices are supported");
- return NULL;
- }
-
- if (self->num_col == 2) {
- const float t = MATRIX_ITEM(self, 1, 0);
- MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1);
- MATRIX_ITEM(self, 0, 1) = t;
- }
- else if (self->num_col == 3) {
- transpose_m3((float (*)[3])self->matrix);
- }
- else {
- transpose_m4((float (*)[4])self->matrix);
- }
-
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
+
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.transpose(d): "
+ "only square matrices are supported");
+ return NULL;
+ }
+
+ if (self->num_col == 2) {
+ const float t = MATRIX_ITEM(self, 1, 0);
+ MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1);
+ MATRIX_ITEM(self, 0, 1) = t;
+ }
+ else if (self->num_col == 3) {
+ transpose_m3((float(*)[3])self->matrix);
+ }
+ else {
+ transpose_m4((float(*)[4])self->matrix);
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_transposed_doc,
-".. method:: transposed()\n"
-"\n"
-" Return a new, transposed matrix.\n"
-"\n"
-" :return: a transposed matrix\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: transposed()\n"
+ "\n"
+ " Return a new, transposed matrix.\n"
+ "\n"
+ " :return: a transposed matrix\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_transposed(MatrixObject *self)
{
- return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self);
+ return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self);
}
/*---------------------------matrix.normalize() ------------------*/
PyDoc_STRVAR(Matrix_normalize_doc,
-".. method:: normalize()\n"
-"\n"
-" Normalize each of the matrix columns.\n"
-);
+ ".. method:: normalize()\n"
+ "\n"
+ " Normalize each of the matrix columns.\n");
static PyObject *Matrix_normalize(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
-
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.normalize(): "
- "only square matrices are supported");
- return NULL;
- }
-
- if (self->num_col == 3) {
- normalize_m3((float (*)[3])self->matrix);
- }
- else if (self->num_col == 4) {
- normalize_m4((float (*)[4])self->matrix);
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.normalize(): "
- "can only use a 3x3 or 4x4 matrix");
- }
-
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
+
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "only square matrices are supported");
+ return NULL;
+ }
+
+ if (self->num_col == 3) {
+ normalize_m3((float(*)[3])self->matrix);
+ }
+ else if (self->num_col == 4) {
+ normalize_m4((float(*)[4])self->matrix);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "can only use a 3x3 or 4x4 matrix");
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Matrix_normalized_doc,
-".. method:: normalized()\n"
-"\n"
-" Return a column normalized matrix\n"
-"\n"
-" :return: a column normalized matrix\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: normalized()\n"
+ "\n"
+ " Return a column normalized matrix\n"
+ "\n"
+ " :return: a column normalized matrix\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_normalized(MatrixObject *self)
{
- return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self);
+ return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self);
}
/*---------------------------matrix.zero() -----------------------*/
PyDoc_STRVAR(Matrix_zero_doc,
-".. method:: zero()\n"
-"\n"
-" Set all the matrix values to zero.\n"
-"\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: zero()\n"
+ "\n"
+ " Set all the matrix values to zero.\n"
+ "\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_zero(MatrixObject *self)
{
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return NULL;
- }
-
- copy_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f);
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (BaseMath_WriteCallback(self) == -1) {
- return NULL;
- }
+ copy_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f);
- Py_RETURN_NONE;
+ if (BaseMath_WriteCallback(self) == -1) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
}
/*---------------------------matrix.identity(() ------------------*/
static void matrix_identity_internal(MatrixObject *self)
{
- BLI_assert((self->num_col == self->num_row) && (self->num_row <= 4));
+ BLI_assert((self->num_col == self->num_row) && (self->num_row <= 4));
- if (self->num_col == 2) {
- unit_m2((float (*)[2])self->matrix);
- }
- else if (self->num_col == 3) {
- unit_m3((float (*)[3])self->matrix);
- }
- else {
- unit_m4((float (*)[4])self->matrix);
- }
+ if (self->num_col == 2) {
+ unit_m2((float(*)[2])self->matrix);
+ }
+ else if (self->num_col == 3) {
+ unit_m3((float(*)[3])self->matrix);
+ }
+ else {
+ unit_m4((float(*)[4])self->matrix);
+ }
}
PyDoc_STRVAR(Matrix_identity_doc,
-".. method:: identity()\n"
-"\n"
-" Set the matrix to the identity matrix.\n"
-"\n"
-" .. note:: An object with a location and rotation of zero, and a scale of one\n"
-" will have an identity matrix.\n"
-"\n"
-" .. seealso:: `Identity matrix <https://en.wikipedia.org/wiki/Identity_matrix>` on Wikipedia.\n"
-);
+ ".. method:: identity()\n"
+ "\n"
+ " Set the matrix to the identity matrix.\n"
+ "\n"
+ " .. note:: An object with a location and rotation of zero, and a scale of one\n"
+ " will have an identity matrix.\n"
+ "\n"
+ " .. seealso:: `Identity matrix <https://en.wikipedia.org/wiki/Identity_matrix>` "
+ "on Wikipedia.\n");
static PyObject *Matrix_identity(MatrixObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix.identity(): "
- "only square matrices are supported");
- return NULL;
- }
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.identity(): "
+ "only square matrices are supported");
+ return NULL;
+ }
- matrix_identity_internal(self);
+ matrix_identity_internal(self);
- if (BaseMath_WriteCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return NULL;
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
/*---------------------------Matrix.copy() ------------------*/
static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix)
{
- return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_TYPE(self));
+ return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_TYPE(self));
}
PyDoc_STRVAR(Matrix_copy_doc,
-".. method:: copy()\n"
-"\n"
-" Returns a copy of this matrix.\n"
-"\n"
-" :return: an instance of itself\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: copy()\n"
+ "\n"
+ " Returns a copy of this matrix.\n"
+ "\n"
+ " :return: an instance of itself\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Matrix_copy(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Matrix_copy_notest(self, self->matrix);
+ return Matrix_copy_notest(self, self->matrix);
}
static PyObject *Matrix_deepcopy(MatrixObject *self, PyObject *args)
{
- if (!PyC_CheckArgs_DeepCopy(args)) {
- return NULL;
- }
- return Matrix_copy(self);
+ if (!PyC_CheckArgs_DeepCopy(args)) {
+ return NULL;
+ }
+ return Matrix_copy(self);
}
/*----------------------------print object (internal)-------------*/
/* print the object to screen */
static PyObject *Matrix_repr(MatrixObject *self)
{
- int col, row;
- PyObject *rows[MATRIX_MAX_DIM] = {NULL};
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- for (row = 0; row < self->num_row; row++) {
- rows[row] = PyTuple_New(self->num_col);
- for (col = 0; col < self->num_col; col++) {
- PyTuple_SET_ITEM(rows[row], col, PyFloat_FromDouble(MATRIX_ITEM(self, row, col)));
- }
- }
- switch (self->num_row) {
- case 2: return PyUnicode_FromFormat("Matrix((%R,\n"
- " %R))", rows[0], rows[1]);
-
- case 3: return PyUnicode_FromFormat("Matrix((%R,\n"
- " %R,\n"
- " %R))", rows[0], rows[1], rows[2]);
-
- case 4: return PyUnicode_FromFormat("Matrix((%R,\n"
- " %R,\n"
- " %R,\n"
- " %R))", rows[0], rows[1], rows[2], rows[3]);
- }
-
- Py_FatalError("Matrix(): invalid row size!");
- return NULL;
+ int col, row;
+ PyObject *rows[MATRIX_MAX_DIM] = {NULL};
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ for (row = 0; row < self->num_row; row++) {
+ rows[row] = PyTuple_New(self->num_col);
+ for (col = 0; col < self->num_col; col++) {
+ PyTuple_SET_ITEM(rows[row], col, PyFloat_FromDouble(MATRIX_ITEM(self, row, col)));
+ }
+ }
+ switch (self->num_row) {
+ case 2:
+ return PyUnicode_FromFormat(
+ "Matrix((%R,\n"
+ " %R))",
+ rows[0],
+ rows[1]);
+
+ case 3:
+ return PyUnicode_FromFormat(
+ "Matrix((%R,\n"
+ " %R,\n"
+ " %R))",
+ rows[0],
+ rows[1],
+ rows[2]);
+
+ case 4:
+ return PyUnicode_FromFormat(
+ "Matrix((%R,\n"
+ " %R,\n"
+ " %R,\n"
+ " %R))",
+ rows[0],
+ rows[1],
+ rows[2],
+ rows[3]);
+ }
+
+ Py_FatalError("Matrix(): invalid row size!");
+ return NULL;
}
#ifndef MATH_STANDALONE
static PyObject *Matrix_str(MatrixObject *self)
{
- DynStr *ds;
+ DynStr *ds;
- int maxsize[MATRIX_MAX_DIM];
- int row, col;
+ int maxsize[MATRIX_MAX_DIM];
+ int row, col;
- char dummy_buf[64];
+ char dummy_buf[64];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- ds = BLI_dynstr_new();
+ ds = BLI_dynstr_new();
- /* First determine the maximum width for each column */
- for (col = 0; col < self->num_col; col++) {
- maxsize[col] = 0;
- for (row = 0; row < self->num_row; row++) {
- int size = BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
- maxsize[col] = max_ii(maxsize[col], size);
- }
- }
+ /* First determine the maximum width for each column */
+ for (col = 0; col < self->num_col; col++) {
+ maxsize[col] = 0;
+ for (row = 0; row < self->num_row; row++) {
+ int size = BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
+ maxsize[col] = max_ii(maxsize[col], size);
+ }
+ }
- /* Now write the unicode string to be printed */
- BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col);
- for (row = 0; row < self->num_row; row++) {
- for (col = 0; col < self->num_col; col++) {
- BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col));
- }
- BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n (" : ")");
- }
- BLI_dynstr_append(ds, ">");
+ /* Now write the unicode string to be printed */
+ BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col);
+ for (row = 0; row < self->num_row; row++) {
+ for (col = 0; col < self->num_col; col++) {
+ BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col));
+ }
+ BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n (" : ")");
+ }
+ BLI_dynstr_append(ds, ">");
- return mathutils_dynstr_to_py(ds); /* frees ds */
+ return mathutils_dynstr_to_py(ds); /* frees ds */
}
#endif
static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
{
- PyObject *res;
- int ok = -1; /* zero is true */
-
- if (MatrixObject_Check(a) && MatrixObject_Check(b)) {
- MatrixObject *matA = (MatrixObject *)a;
- MatrixObject *matB = (MatrixObject *)b;
-
- if (BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1) {
- return NULL;
- }
-
- ok = ((matA->num_row == matB->num_row) &&
- (matA->num_col == matB->num_col) &&
- EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1)
- ) ? 0 : -1;
- }
-
- switch (op) {
- case Py_NE:
- ok = !ok;
- ATTR_FALLTHROUGH;
- case Py_EQ:
- res = ok ? Py_False : Py_True;
- break;
-
- case Py_LT:
- case Py_LE:
- case Py_GT:
- case Py_GE:
- res = Py_NotImplemented;
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
-
- return Py_INCREF_RET(res);
+ PyObject *res;
+ int ok = -1; /* zero is true */
+
+ if (MatrixObject_Check(a) && MatrixObject_Check(b)) {
+ MatrixObject *matA = (MatrixObject *)a;
+ MatrixObject *matB = (MatrixObject *)b;
+
+ if (BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1) {
+ return NULL;
+ }
+
+ ok = ((matA->num_row == matB->num_row) && (matA->num_col == matB->num_col) &&
+ EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1)) ?
+ 0 :
+ -1;
+ }
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok;
+ ATTR_FALLTHROUGH;
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ return Py_INCREF_RET(res);
}
static Py_hash_t Matrix_hash(MatrixObject *self)
{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- if (BaseMathObject_Prepare_ForHash(self) == -1) {
- return -1;
- }
+ if (BaseMathObject_Prepare_ForHash(self) == -1) {
+ return -1;
+ }
- matrix_transpose_internal(mat, self);
+ matrix_transpose_internal(mat, self);
- return mathutils_array_hash(mat, self->num_row * self->num_col);
+ return mathutils_array_hash(mat, self->num_row * self->num_col);
}
/*---------------------SEQUENCE PROTOCOLS------------------------
@@ -2150,39 +2190,41 @@ static Py_hash_t Matrix_hash(MatrixObject *self)
* sequence length */
static int Matrix_len(MatrixObject *self)
{
- return self->num_row;
+ return self->num_row;
}
/*----------------------------object[]---------------------------
* sequence accessor (get)
* 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) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (row < 0 || row >= self->num_row) {
- PyErr_SetString(PyExc_IndexError,
- "matrix[attribute]: "
- "array index out of range");
- return NULL;
- }
- return Vector_CreatePyObject_cb((PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, row);
+ if (row < 0 || row >= self->num_row) {
+ PyErr_SetString(PyExc_IndexError,
+ "matrix[attribute]: "
+ "array index out of range");
+ return NULL;
+ }
+ return Vector_CreatePyObject_cb(
+ (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, row);
}
/* same but column access */
static PyObject *Matrix_item_col(MatrixObject *self, int col)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (col < 0 || col >= self->num_col) {
- PyErr_SetString(PyExc_IndexError,
- "matrix[attribute]: "
- "array index out of range");
- return NULL;
- }
- return Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_col_cb_index, col);
+ if (col < 0 || col >= self->num_col) {
+ PyErr_SetString(PyExc_IndexError,
+ "matrix[attribute]: "
+ "array index out of range");
+ return NULL;
+ }
+ return Vector_CreatePyObject_cb(
+ (PyObject *)self, self->num_row, mathutils_matrix_col_cb_index, col);
}
/*----------------------------object[]-------------------------
@@ -2190,994 +2232,1031 @@ static PyObject *Matrix_item_col(MatrixObject *self, int col)
static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
{
- int col;
- float vec[MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ int col;
+ float vec[MATRIX_MAX_DIM];
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- if (row >= self->num_row || row < 0) {
- PyErr_SetString(PyExc_IndexError,
- "matrix[attribute] = x: bad row");
- return -1;
- }
+ if (row >= self->num_row || row < 0) {
+ PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad row");
+ return -1;
+ }
- if (mathutils_array_parse(vec, self->num_col, self->num_col, value, "matrix[i] = value assignment") == -1) {
- return -1;
- }
+ if (mathutils_array_parse(
+ vec, self->num_col, self->num_col, value, "matrix[i] = value assignment") == -1) {
+ return -1;
+ }
- /* Since we are assigning a row we cannot memcpy */
- for (col = 0; col < self->num_col; col++) {
- MATRIX_ITEM(self, row, col) = vec[col];
- }
+ /* Since we are assigning a row we cannot memcpy */
+ for (col = 0; col < self->num_col; col++) {
+ MATRIX_ITEM(self, row, col) = vec[col];
+ }
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
{
- int row;
- float vec[MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ int row;
+ float vec[MATRIX_MAX_DIM];
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- if (col >= self->num_col || col < 0) {
- PyErr_SetString(PyExc_IndexError,
- "matrix[attribute] = x: bad col");
- return -1;
- }
+ if (col >= self->num_col || col < 0) {
+ PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad col");
+ return -1;
+ }
- if (mathutils_array_parse(vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") == -1) {
- return -1;
- }
+ if (mathutils_array_parse(
+ vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") == -1) {
+ return -1;
+ }
- /* Since we are assigning a row we cannot memcpy */
- for (row = 0; row < self->num_row; row++) {
- MATRIX_ITEM(self, row, col) = vec[row];
- }
+ /* Since we are assigning a row we cannot memcpy */
+ for (row = 0; row < self->num_row; row++) {
+ MATRIX_ITEM(self, row, col) = vec[row];
+ }
- (void)BaseMath_WriteCallback(self);
- return 0;
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
-
/*----------------------------object[z:y]------------------------
* sequence slice (get)*/
static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
+ PyObject *tuple;
+ int count;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- CLAMP(begin, 0, self->num_row);
- CLAMP(end, 0, self->num_row);
- begin = MIN2(begin, end);
+ CLAMP(begin, 0, self->num_row);
+ CLAMP(end, 0, self->num_row);
+ begin = MIN2(begin, end);
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin,
- Vector_CreatePyObject_cb((PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, count));
- }
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple,
+ count - begin,
+ Vector_CreatePyObject_cb(
+ (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, count));
+ }
- return tuple;
+ return tuple;
}
/*----------------------------object[z:y]------------------------
* sequence slice (set)*/
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value)
{
- PyObject *value_fast;
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- CLAMP(begin, 0, self->num_row);
- CLAMP(end, 0, self->num_row);
- begin = MIN2(begin, end);
-
- /* non list/tuple cases */
- if (!(value_fast = PySequence_Fast(value, "matrix[begin:end] = value"))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
- else {
- PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
- const int size = end - begin;
- int row, col;
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- float vec[4];
-
- if (PySequence_Fast_GET_SIZE(value_fast) != size) {
- Py_DECREF(value_fast);
- PyErr_SetString(PyExc_ValueError,
- "matrix[begin:end] = []: "
- "size mismatch in slice assignment");
- return -1;
- }
-
- memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float));
-
- /* parse sub items */
- for (row = begin; row < end; row++) {
- /* parse each sub sequence */
- PyObject *item = value_fast_items[row - begin];
-
- if (mathutils_array_parse(vec, self->num_col, self->num_col, item,
- "matrix[begin:end] = value assignment") == -1)
- {
- Py_DECREF(value_fast);
- return -1;
- }
-
- for (col = 0; col < self->num_col; col++) {
- mat[col * self->num_row + row] = vec[col];
- }
- }
-
- Py_DECREF(value_fast);
-
- /*parsed well - now set in matrix*/
- memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float));
-
- (void)BaseMath_WriteCallback(self);
- return 0;
- }
+ PyObject *value_fast;
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ CLAMP(begin, 0, self->num_row);
+ CLAMP(end, 0, self->num_row);
+ begin = MIN2(begin, end);
+
+ /* non list/tuple cases */
+ if (!(value_fast = PySequence_Fast(value, "matrix[begin:end] = value"))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
+ else {
+ PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
+ const int size = end - begin;
+ int row, col;
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ float vec[4];
+
+ if (PySequence_Fast_GET_SIZE(value_fast) != size) {
+ Py_DECREF(value_fast);
+ PyErr_SetString(PyExc_ValueError,
+ "matrix[begin:end] = []: "
+ "size mismatch in slice assignment");
+ return -1;
+ }
+
+ memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float));
+
+ /* parse sub items */
+ for (row = begin; row < end; row++) {
+ /* parse each sub sequence */
+ PyObject *item = value_fast_items[row - begin];
+
+ if (mathutils_array_parse(
+ vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") ==
+ -1) {
+ Py_DECREF(value_fast);
+ return -1;
+ }
+
+ for (col = 0; col < self->num_col; col++) {
+ mat[col * self->num_row + row] = vec[col];
+ }
+ }
+
+ Py_DECREF(value_fast);
+
+ /*parsed well - now set in matrix*/
+ memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float));
+
+ (void)BaseMath_WriteCallback(self);
+ return 0;
+ }
}
/*------------------------NUMERIC PROTOCOLS----------------------
*------------------------obj + obj------------------------------*/
static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- MatrixObject *mat1 = NULL, *mat2 = NULL;
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- mat1 = (MatrixObject *)m1;
- mat2 = (MatrixObject *)m2;
+ mat1 = (MatrixObject *)m1;
+ mat2 = (MatrixObject *)m2;
- if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
- PyErr_Format(PyExc_TypeError,
- "Matrix addition: (%s + %s) "
- "invalid type for this operation",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
- }
+ if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Matrix addition: (%s + %s) "
+ "invalid type for this operation",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
+ }
- if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
- if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix addition: "
- "matrices must have the same dimensions for this operation");
- return NULL;
- }
+ if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix addition: "
+ "matrices must have the same dimensions for this operation");
+ return NULL;
+ }
- add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
* subtraction */
static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
{
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- MatrixObject *mat1 = NULL, *mat2 = NULL;
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- mat1 = (MatrixObject *)m1;
- mat2 = (MatrixObject *)m2;
+ mat1 = (MatrixObject *)m1;
+ mat2 = (MatrixObject *)m2;
- if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
- PyErr_Format(PyExc_TypeError,
- "Matrix subtraction: (%s - %s) "
- "invalid type for this operation",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
- }
+ if (!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Matrix subtraction: (%s - %s) "
+ "invalid type for this operation",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
+ }
- if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
- if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "Matrix addition: "
- "matrices must have the same dimensions for this operation");
- return NULL;
- }
+ if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix addition: "
+ "matrices must have the same dimensions for this operation");
+ return NULL;
+ }
- sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
* element-wise multiplication */
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
- float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
- return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat));
+ float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
+ return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat));
}
static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
{
- float scalar;
+ float scalar;
- MatrixObject *mat1 = NULL, *mat2 = NULL;
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- if (MatrixObject_Check(m1)) {
- mat1 = (MatrixObject *)m1;
- if (BaseMath_ReadCallback(mat1) == -1) {
- return NULL;
- }
- }
- if (MatrixObject_Check(m2)) {
- mat2 = (MatrixObject *)m2;
- if (BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
- }
+ if (MatrixObject_Check(m1)) {
+ mat1 = (MatrixObject *)m1;
+ if (BaseMath_ReadCallback(mat1) == -1) {
+ return NULL;
+ }
+ }
+ if (MatrixObject_Check(m2)) {
+ mat2 = (MatrixObject *)m2;
+ if (BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
+ }
- if (mat1 && mat2) {
+ if (mat1 && mat2) {
#ifdef USE_MATHUTILS_ELEM_MUL
- /* MATRIX * MATRIX */
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ /* MATRIX * MATRIX */
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
- PyErr_SetString(PyExc_ValueError,
- "matrix1 * matrix2: matrix1 number of rows/columns "
- "and the matrix2 number of rows/columns must be the same");
- return NULL;
- }
+ if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
+ PyErr_SetString(PyExc_ValueError,
+ "matrix1 * matrix2: matrix1 number of rows/columns "
+ "and the matrix2 number of rows/columns must be the same");
+ return NULL;
+ }
- mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
#endif
- }
- else if (mat2) {
- /*FLOAT/INT * MATRIX */
- if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) {
- return matrix_mul_float(mat2, scalar);
- }
- }
- else if (mat1) {
- /* MATRIX * FLOAT/INT */
- if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) {
- return matrix_mul_float(mat1, scalar);
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
+ }
+ else if (mat2) {
+ /*FLOAT/INT * MATRIX */
+ if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) {
+ return matrix_mul_float(mat2, scalar);
+ }
+ }
+ else if (mat1) {
+ /* MATRIX * FLOAT/INT */
+ if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) {
+ return matrix_mul_float(mat1, scalar);
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
}
/*------------------------obj *= obj------------------------------
* Inplace element-wise multiplication */
static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
{
- float scalar;
+ float scalar;
- MatrixObject *mat1 = NULL, *mat2 = NULL;
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
- if (MatrixObject_Check(m1)) {
- mat1 = (MatrixObject *)m1;
- if (BaseMath_ReadCallback(mat1) == -1) {
- return NULL;
- }
- }
- if (MatrixObject_Check(m2)) {
- mat2 = (MatrixObject *)m2;
- if (BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
- }
+ if (MatrixObject_Check(m1)) {
+ mat1 = (MatrixObject *)m1;
+ if (BaseMath_ReadCallback(mat1) == -1) {
+ return NULL;
+ }
+ }
+ if (MatrixObject_Check(m2)) {
+ mat2 = (MatrixObject *)m2;
+ if (BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
+ }
- if (mat1 && mat2) {
+ if (mat1 && mat2) {
#ifdef USE_MATHUTILS_ELEM_MUL
- /* MATRIX *= MATRIX */
- if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
- PyErr_SetString(PyExc_ValueError,
- "matrix1 *= matrix2: matrix1 number of rows/columns "
- "and the matrix2 number of rows/columns must be the same");
- return NULL;
- }
-
- mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ /* MATRIX *= MATRIX */
+ if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
+ PyErr_SetString(PyExc_ValueError,
+ "matrix1 *= matrix2: matrix1 number of rows/columns "
+ "and the matrix2 number of rows/columns must be the same");
+ return NULL;
+ }
+
+ mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
#else
- PyErr_Format(PyExc_TypeError,
- "Inplace element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "Inplace element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
#endif
- }
- else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) {
- /* MATRIX *= FLOAT/INT */
- mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Inplace element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(mat1);
- Py_INCREF(m1);
- return m1;
+ }
+ else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) {
+ /* MATRIX *= FLOAT/INT */
+ mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Inplace element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(mat1);
+ Py_INCREF(m1);
+ return m1;
}
/*------------------------obj @ obj------------------------------
* matrix multiplication */
static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
{
- int vec_size;
-
- MatrixObject *mat1 = NULL, *mat2 = NULL;
-
- if (MatrixObject_Check(m1)) {
- mat1 = (MatrixObject *)m1;
- if (BaseMath_ReadCallback(mat1) == -1) {
- return NULL;
- }
- }
- if (MatrixObject_Check(m2)) {
- mat2 = (MatrixObject *)m2;
- if (BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
- }
-
- if (mat1 && mat2) {
- /* MATRIX @ MATRIX */
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
-
- int col, row, item;
-
- if (mat1->num_col != mat2->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "matrix1 * matrix2: matrix1 number of columns "
- "and the matrix2 number of rows must be the same");
- return NULL;
- }
-
- for (col = 0; col < mat2->num_col; col++) {
- for (row = 0; row < mat1->num_row; row++) {
- double dot = 0.0f;
- for (item = 0; item < mat1->num_col; item++) {
- dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
- }
- mat[(col * mat1->num_row) + row] = (float)dot;
- }
- }
-
- return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
- }
- else if (mat1) {
- /* MATRIX @ VECTOR */
- if (VectorObject_Check(m2)) {
- VectorObject *vec2 = (VectorObject *)m2;
- float tvec[MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
- if (column_vector_multiplication(tvec, vec2, mat1) == -1) {
- return NULL;
- }
-
- if (mat1->num_col == 4 && vec2->size == 3) {
- vec_size = 3;
- }
- else {
- vec_size = mat1->num_row;
- }
-
- return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2));
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Matrix multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
+ int vec_size;
+
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
+
+ if (MatrixObject_Check(m1)) {
+ mat1 = (MatrixObject *)m1;
+ if (BaseMath_ReadCallback(mat1) == -1) {
+ return NULL;
+ }
+ }
+ if (MatrixObject_Check(m2)) {
+ mat2 = (MatrixObject *)m2;
+ if (BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (mat1 && mat2) {
+ /* MATRIX @ MATRIX */
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+
+ int col, row, item;
+
+ if (mat1->num_col != mat2->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "matrix1 * matrix2: matrix1 number of columns "
+ "and the matrix2 number of rows must be the same");
+ return NULL;
+ }
+
+ for (col = 0; col < mat2->num_col; col++) {
+ for (row = 0; row < mat1->num_row; row++) {
+ double dot = 0.0f;
+ for (item = 0; item < mat1->num_col; item++) {
+ dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
+ }
+ mat[(col * mat1->num_row) + row] = (float)dot;
+ }
+ }
+
+ return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
+ }
+ else if (mat1) {
+ /* MATRIX @ VECTOR */
+ if (VectorObject_Check(m2)) {
+ VectorObject *vec2 = (VectorObject *)m2;
+ float tvec[MATRIX_MAX_DIM];
+ if (BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+ if (column_vector_multiplication(tvec, vec2, mat1) == -1) {
+ return NULL;
+ }
+
+ if (mat1->num_col == 4 && vec2->size == 3) {
+ vec_size = 3;
+ }
+ else {
+ vec_size = mat1->num_row;
+ }
+
+ return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2));
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Matrix multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
}
/*------------------------obj @= obj------------------------------
* inplace matrix multiplication */
static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2)
{
- MatrixObject *mat1 = NULL, *mat2 = NULL;
-
- if (MatrixObject_Check(m1)) {
- mat1 = (MatrixObject *)m1;
- if (BaseMath_ReadCallback(mat1) == -1) {
- return NULL;
- }
- }
- if (MatrixObject_Check(m2)) {
- mat2 = (MatrixObject *)m2;
- if (BaseMath_ReadCallback(mat2) == -1) {
- return NULL;
- }
- }
-
- if (mat1 && mat2) {
- /* MATRIX @= MATRIX */
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- int col, row, item;
-
- if (mat1->num_col != mat2->num_row) {
- PyErr_SetString(PyExc_ValueError,
- "matrix1 * matrix2: matrix1 number of columns "
- "and the matrix2 number of rows must be the same");
- return NULL;
- }
-
- for (col = 0; col < mat2->num_col; col++) {
- for (row = 0; row < mat1->num_row; row++) {
- double dot = 0.0f;
- for (item = 0; item < mat1->num_col; item++) {
- dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
- }
- /* store in new matrix as overwriting original at this point will cause
- * subsequent iterations to use incorrect values */
- mat[(col * mat1->num_row) + row] = (float)dot;
- }
- }
-
- /* copy matrix back */
- memcpy(mat1->matrix, mat, (mat1->num_row * mat1->num_col) * sizeof(float));
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Inplace matrix multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(mat1);
- Py_INCREF(m1);
- return m1;
+ MatrixObject *mat1 = NULL, *mat2 = NULL;
+
+ if (MatrixObject_Check(m1)) {
+ mat1 = (MatrixObject *)m1;
+ if (BaseMath_ReadCallback(mat1) == -1) {
+ return NULL;
+ }
+ }
+ if (MatrixObject_Check(m2)) {
+ mat2 = (MatrixObject *)m2;
+ if (BaseMath_ReadCallback(mat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (mat1 && mat2) {
+ /* MATRIX @= MATRIX */
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ int col, row, item;
+
+ if (mat1->num_col != mat2->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "matrix1 * matrix2: matrix1 number of columns "
+ "and the matrix2 number of rows must be the same");
+ return NULL;
+ }
+
+ for (col = 0; col < mat2->num_col; col++) {
+ for (row = 0; row < mat1->num_row; row++) {
+ double dot = 0.0f;
+ for (item = 0; item < mat1->num_col; item++) {
+ dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
+ }
+ /* store in new matrix as overwriting original at this point will cause
+ * subsequent iterations to use incorrect values */
+ mat[(col * mat1->num_row) + row] = (float)dot;
+ }
+ }
+
+ /* copy matrix back */
+ memcpy(mat1->matrix, mat, (mat1->num_row * mat1->num_col) * sizeof(float));
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Inplace matrix multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(m1)->tp_name,
+ Py_TYPE(m2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(mat1);
+ Py_INCREF(m1);
+ 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 */
+ (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->num_row;
- }
- return Matrix_item_row(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return Matrix_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with matrices");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "matrix indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ 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->num_row;
+ }
+ return Matrix_item_row(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return Matrix_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
+ return NULL;
+ }
+ }
+ else {
+ 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->num_row;
- }
- return Matrix_ass_item_row(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
-
- if (step == 1) {
- return Matrix_ass_slice(self, start, stop, value);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with matrices");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "matrix indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ 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->num_row;
+ }
+ return Matrix_ass_item_row(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Matrix_ass_slice(self, start, stop, value);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
static PyMappingMethods Matrix_AsMapping = {
- (lenfunc)Matrix_len,
- (binaryfunc)Matrix_subscript,
- (objobjargproc)Matrix_ass_subscript,
+ (lenfunc)Matrix_len,
+ (binaryfunc)Matrix_subscript,
+ (objobjargproc)Matrix_ass_subscript,
};
-
static PyNumberMethods Matrix_NumMethods = {
- (binaryfunc) Matrix_add, /*nb_add*/
- (binaryfunc) Matrix_sub, /*nb_subtract*/
- (binaryfunc) Matrix_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc) 0, /*nb_negative*/
- (unaryfunc) 0, /*tp_positive*/
- (unaryfunc) 0, /*tp_absolute*/
- (inquiry) 0, /*tp_bool*/
- (unaryfunc) Matrix_inverted_noargs, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)0, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- 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 */
+ (binaryfunc)Matrix_add, /*nb_add*/
+ (binaryfunc)Matrix_sub, /*nb_subtract*/
+ (binaryfunc)Matrix_mul, /*nb_multiply*/
+ NULL, /*nb_remainder*/
+ NULL, /*nb_divmod*/
+ NULL, /*nb_power*/
+ (unaryfunc)0, /*nb_negative*/
+ (unaryfunc)0, /*tp_positive*/
+ (unaryfunc)0, /*tp_absolute*/
+ (inquiry)0, /*tp_bool*/
+ (unaryfunc)Matrix_inverted_noargs, /*nb_invert*/
+ NULL, /*nb_lshift*/
+ (binaryfunc)0, /*nb_rshift*/
+ NULL, /*nb_and*/
+ NULL, /*nb_xor*/
+ NULL, /*nb_or*/
+ 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 */
};
-PyDoc_STRVAR(Matrix_translation_doc,
-"The translation component of the matrix.\n\n:type: Vector"
-);
+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))
{
- PyObject *ret;
+ PyObject *ret;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- /*must be 4x4 square matrix*/
- if (self->num_row != 4 || self->num_col != 4) {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.translation: "
- "inappropriate matrix size, must be 4x4");
- return NULL;
- }
+ /*must be 4x4 square matrix*/
+ if (self->num_row != 4 || self->num_col != 4) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.translation: "
+ "inappropriate matrix size, must be 4x4");
+ return NULL;
+ }
- ret = (PyObject *)Vector_CreatePyObject_cb((PyObject *)self, 3, mathutils_matrix_translation_cb_index, 3);
+ ret = (PyObject *)Vector_CreatePyObject_cb(
+ (PyObject *)self, 3, mathutils_matrix_translation_cb_index, 3);
- return ret;
+ return ret;
}
static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNUSED(closure))
{
- float tvec[3];
+ float tvec[3];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- /*must be 4x4 square matrix*/
- if (self->num_row != 4 || self->num_col != 4) {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.translation: "
- "inappropriate matrix size, must be 4x4");
- return -1;
- }
+ /*must be 4x4 square matrix*/
+ if (self->num_row != 4 || self->num_col != 4) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.translation: "
+ "inappropriate matrix size, must be 4x4");
+ return -1;
+ }
- if ((mathutils_array_parse(tvec, 3, 3, value, "Matrix.translation")) == -1) {
- return -1;
- }
+ if ((mathutils_array_parse(tvec, 3, 3, value, "Matrix.translation")) == -1) {
+ return -1;
+ }
- copy_v3_v3(((float (*)[4])self->matrix)[3], tvec);
+ copy_v3_v3(((float(*)[4])self->matrix)[3], tvec);
- (void)BaseMath_WriteCallback(self);
+ (void)BaseMath_WriteCallback(self);
- return 0;
+ return 0;
}
PyDoc_STRVAR(Matrix_row_doc,
-"Access the matrix by rows (default), (read-only).\n\n:type: Matrix Access"
-);
+ "Access the matrix by rows (default), (read-only).\n\n:type: Matrix Access");
static PyObject *Matrix_row_get(MatrixObject *self, void *UNUSED(closure))
{
- return MatrixAccess_CreatePyObject(self, MAT_ACCESS_ROW);
+ return MatrixAccess_CreatePyObject(self, MAT_ACCESS_ROW);
}
-PyDoc_STRVAR(Matrix_col_doc,
-"Access the matrix by columns, 3x3 and 4x4 only, (read-only).\n\n:type: Matrix Access"
-);
+PyDoc_STRVAR(
+ Matrix_col_doc,
+ "Access the matrix by columns, 3x3 and 4x4 only, (read-only).\n\n:type: Matrix Access");
static PyObject *Matrix_col_get(MatrixObject *self, void *UNUSED(closure))
{
- return MatrixAccess_CreatePyObject(self, MAT_ACCESS_COL);
+ return MatrixAccess_CreatePyObject(self, MAT_ACCESS_COL);
}
PyDoc_STRVAR(Matrix_median_scale_doc,
-"The average scale applied to each axis (read-only).\n\n:type: float"
-);
+ "The average scale applied to each axis (read-only).\n\n:type: float");
static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure))
{
- float mat[3][3];
+ float mat[3][3];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- /*must be 3-4 cols, 3-4 rows, square matrix*/
- if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.median_scale: "
- "inappropriate matrix size, 3x3 minimum");
- return NULL;
- }
+ /*must be 3-4 cols, 3-4 rows, square matrix*/
+ if ((self->num_row < 3) || (self->num_col < 3)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.median_scale: "
+ "inappropriate matrix size, 3x3 minimum");
+ return NULL;
+ }
- matrix_as_3x3(mat, self);
+ matrix_as_3x3(mat, self);
- return PyFloat_FromDouble(mat3_to_scale(mat));
+ return PyFloat_FromDouble(mat3_to_scale(mat));
}
PyDoc_STRVAR(Matrix_is_negative_doc,
-"True if this matrix results in a negative scale, 3x3 and 4x4 only, (read-only).\n\n:type: bool"
-);
+ "True if this matrix results in a negative scale, 3x3 and 4x4 only, "
+ "(read-only).\n\n:type: bool");
static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- /*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->num_row == 4 && self->num_col == 4) {
- return PyBool_FromLong(is_negative_m4((float (*)[4])self->matrix));
- }
- else if (self->num_row == 3 && self->num_col == 3) {
- return PyBool_FromLong(is_negative_m3((float (*)[3])self->matrix));
- }
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_negative: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ /*must be 3-4 cols, 3-4 rows, square matrix*/
+ if (self->num_row == 4 && self->num_col == 4) {
+ return PyBool_FromLong(is_negative_m4((float(*)[4])self->matrix));
+ }
+ else if (self->num_row == 3 && self->num_col == 3) {
+ return PyBool_FromLong(is_negative_m3((float(*)[3])self->matrix));
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_negative: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
+ }
}
PyDoc_STRVAR(Matrix_is_orthogonal_doc,
-"True if this matrix is orthogonal, 3x3 and 4x4 only, (read-only).\n\n:type: bool"
-);
+ "True if this matrix is orthogonal, 3x3 and 4x4 only, (read-only).\n\n:type: bool");
static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- /*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->num_row == 4 && self->num_col == 4) {
- return PyBool_FromLong(is_orthonormal_m4((float (*)[4])self->matrix));
- }
- else if (self->num_row == 3 && self->num_col == 3) {
- return PyBool_FromLong(is_orthonormal_m3((float (*)[3])self->matrix));
- }
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_orthogonal: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ /*must be 3-4 cols, 3-4 rows, square matrix*/
+ if (self->num_row == 4 && self->num_col == 4) {
+ return PyBool_FromLong(is_orthonormal_m4((float(*)[4])self->matrix));
+ }
+ else if (self->num_row == 3 && self->num_col == 3) {
+ return PyBool_FromLong(is_orthonormal_m3((float(*)[3])self->matrix));
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_orthogonal: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
+ }
}
PyDoc_STRVAR(Matrix_is_orthogonal_axis_vectors_doc,
-"True if this matrix has got orthogonal axis vectors, 3x3 and 4x4 only, (read-only).\n\n:type: bool"
-);
+ "True if this matrix has got orthogonal axis vectors, 3x3 and 4x4 only, "
+ "(read-only).\n\n:type: bool");
static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- /*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->num_row == 4 && self->num_col == 4) {
- return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->matrix));
- }
- else if (self->num_row == 3 && self->num_col == 3) {
- return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->matrix));
- }
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_orthogonal_axis_vectors: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ /*must be 3-4 cols, 3-4 rows, square matrix*/
+ if (self->num_row == 4 && self->num_col == 4) {
+ return PyBool_FromLong(is_orthogonal_m4((float(*)[4])self->matrix));
+ }
+ else if (self->num_row == 3 && self->num_col == 3) {
+ return PyBool_FromLong(is_orthogonal_m3((float(*)[3])self->matrix));
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_orthogonal_axis_vectors: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
+ }
}
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters[] = {
- {(char *)"median_scale", (getter)Matrix_median_scale_get, (setter)NULL, Matrix_median_scale_doc, NULL},
- {(char *)"translation", (getter)Matrix_translation_get, (setter)Matrix_translation_set, Matrix_translation_doc, NULL},
- {(char *)"row", (getter)Matrix_row_get, (setter)NULL, Matrix_row_doc, NULL},
- {(char *)"col", (getter)Matrix_col_get, (setter)NULL, Matrix_col_doc, NULL},
- {(char *)"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, Matrix_is_negative_doc, NULL},
- {(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, Matrix_is_orthogonal_doc, NULL},
- {(char *)"is_orthogonal_axis_vectors", (getter)Matrix_is_orthogonal_axis_vectors_get, (setter)NULL, Matrix_is_orthogonal_axis_vectors_doc, NULL},
- {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
- {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
- {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {(char *)"median_scale",
+ (getter)Matrix_median_scale_get,
+ (setter)NULL,
+ Matrix_median_scale_doc,
+ NULL},
+ {(char *)"translation",
+ (getter)Matrix_translation_get,
+ (setter)Matrix_translation_set,
+ Matrix_translation_doc,
+ NULL},
+ {(char *)"row", (getter)Matrix_row_get, (setter)NULL, Matrix_row_doc, NULL},
+ {(char *)"col", (getter)Matrix_col_get, (setter)NULL, Matrix_col_doc, NULL},
+ {(char *)"is_negative",
+ (getter)Matrix_is_negative_get,
+ (setter)NULL,
+ Matrix_is_negative_doc,
+ NULL},
+ {(char *)"is_orthogonal",
+ (getter)Matrix_is_orthogonal_get,
+ (setter)NULL,
+ Matrix_is_orthogonal_doc,
+ NULL},
+ {(char *)"is_orthogonal_axis_vectors",
+ (getter)Matrix_is_orthogonal_axis_vectors_get,
+ (setter)NULL,
+ Matrix_is_orthogonal_axis_vectors_doc,
+ NULL},
+ {(char *)"is_wrapped",
+ (getter)BaseMathObject_is_wrapped_get,
+ (setter)NULL,
+ BaseMathObject_is_wrapped_doc,
+ NULL},
+ {(char *)"is_frozen",
+ (getter)BaseMathObject_is_frozen_get,
+ (setter)NULL,
+ BaseMathObject_is_frozen_doc,
+ NULL},
+ {(char *)"owner",
+ (getter)BaseMathObject_owner_get,
+ (setter)NULL,
+ BaseMathObject_owner_doc,
+ NULL},
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/*-----------------------METHOD DEFINITIONS ----------------------*/
static struct PyMethodDef Matrix_methods[] = {
- /* derived values */
- {"determinant", (PyCFunction) Matrix_determinant, METH_NOARGS, Matrix_determinant_doc},
- {"decompose", (PyCFunction) Matrix_decompose, METH_NOARGS, Matrix_decompose_doc},
-
- /* in place only */
- {"zero", (PyCFunction) Matrix_zero, METH_NOARGS, Matrix_zero_doc},
- {"identity", (PyCFunction) Matrix_identity, METH_NOARGS, Matrix_identity_doc},
-
- /* operate on original or copy */
- {"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc},
- {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
- {"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
- {"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
- {"invert", (PyCFunction) Matrix_invert, METH_VARARGS, Matrix_invert_doc},
- {"inverted", (PyCFunction) Matrix_inverted, METH_VARARGS, Matrix_inverted_doc},
- {"invert_safe", (PyCFunction) Matrix_invert_safe, METH_NOARGS, Matrix_invert_safe_doc},
- {"inverted_safe", (PyCFunction) Matrix_inverted_safe, METH_NOARGS, Matrix_inverted_safe_doc},
- {"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
- {"adjugated", (PyCFunction) Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc},
- {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
- /* TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc}, */
- {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc},
- {"resize_4x4", (PyCFunction) Matrix_resize_4x4, METH_NOARGS, Matrix_resize_4x4_doc},
- {"rotate", (PyCFunction) Matrix_rotate, METH_O, Matrix_rotate_doc},
-
- /* return converted representation */
- {"to_euler", (PyCFunction) Matrix_to_euler, METH_VARARGS, Matrix_to_euler_doc},
- {"to_quaternion", (PyCFunction) Matrix_to_quaternion, METH_NOARGS, Matrix_to_quaternion_doc},
- {"to_scale", (PyCFunction) Matrix_to_scale, METH_NOARGS, Matrix_to_scale_doc},
- {"to_translation", (PyCFunction) Matrix_to_translation, METH_NOARGS, Matrix_to_translation_doc},
-
- /* operation between 2 or more types */
- {"lerp", (PyCFunction) Matrix_lerp, METH_VARARGS, Matrix_lerp_doc},
- {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
- {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
- {"__deepcopy__", (PyCFunction) Matrix_deepcopy, METH_VARARGS, Matrix_copy_doc},
-
- /* base-math methods */
- {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
-
- /* class methods */
- {"Identity", (PyCFunction) C_Matrix_Identity, METH_VARARGS | METH_CLASS, C_Matrix_Identity_doc},
- {"Rotation", (PyCFunction) C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc},
- {"Scale", (PyCFunction) C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc},
- {"Shear", (PyCFunction) C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc},
- {"Translation", (PyCFunction) C_Matrix_Translation, METH_O | METH_CLASS, C_Matrix_Translation_doc},
- {"OrthoProjection", (PyCFunction) C_Matrix_OrthoProjection, METH_VARARGS | METH_CLASS, C_Matrix_OrthoProjection_doc},
- {NULL, NULL, 0, NULL},
+ /* derived values */
+ {"determinant", (PyCFunction)Matrix_determinant, METH_NOARGS, Matrix_determinant_doc},
+ {"decompose", (PyCFunction)Matrix_decompose, METH_NOARGS, Matrix_decompose_doc},
+
+ /* in place only */
+ {"zero", (PyCFunction)Matrix_zero, METH_NOARGS, Matrix_zero_doc},
+ {"identity", (PyCFunction)Matrix_identity, METH_NOARGS, Matrix_identity_doc},
+
+ /* operate on original or copy */
+ {"transpose", (PyCFunction)Matrix_transpose, METH_NOARGS, Matrix_transpose_doc},
+ {"transposed", (PyCFunction)Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
+ {"normalize", (PyCFunction)Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
+ {"normalized", (PyCFunction)Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
+ {"invert", (PyCFunction)Matrix_invert, METH_VARARGS, Matrix_invert_doc},
+ {"inverted", (PyCFunction)Matrix_inverted, METH_VARARGS, Matrix_inverted_doc},
+ {"invert_safe", (PyCFunction)Matrix_invert_safe, METH_NOARGS, Matrix_invert_safe_doc},
+ {"inverted_safe", (PyCFunction)Matrix_inverted_safe, METH_NOARGS, Matrix_inverted_safe_doc},
+ {"adjugate", (PyCFunction)Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
+ {"adjugated", (PyCFunction)Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc},
+ {"to_3x3", (PyCFunction)Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
+ /* TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc}, */
+ {"to_4x4", (PyCFunction)Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc},
+ {"resize_4x4", (PyCFunction)Matrix_resize_4x4, METH_NOARGS, Matrix_resize_4x4_doc},
+ {"rotate", (PyCFunction)Matrix_rotate, METH_O, Matrix_rotate_doc},
+
+ /* return converted representation */
+ {"to_euler", (PyCFunction)Matrix_to_euler, METH_VARARGS, Matrix_to_euler_doc},
+ {"to_quaternion", (PyCFunction)Matrix_to_quaternion, METH_NOARGS, Matrix_to_quaternion_doc},
+ {"to_scale", (PyCFunction)Matrix_to_scale, METH_NOARGS, Matrix_to_scale_doc},
+ {"to_translation", (PyCFunction)Matrix_to_translation, METH_NOARGS, Matrix_to_translation_doc},
+
+ /* operation between 2 or more types */
+ {"lerp", (PyCFunction)Matrix_lerp, METH_VARARGS, Matrix_lerp_doc},
+ {"copy", (PyCFunction)Matrix_copy, METH_NOARGS, Matrix_copy_doc},
+ {"__copy__", (PyCFunction)Matrix_copy, METH_NOARGS, Matrix_copy_doc},
+ {"__deepcopy__", (PyCFunction)Matrix_deepcopy, METH_VARARGS, Matrix_copy_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
+ /* class methods */
+ {"Identity", (PyCFunction)C_Matrix_Identity, METH_VARARGS | METH_CLASS, C_Matrix_Identity_doc},
+ {"Rotation", (PyCFunction)C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc},
+ {"Scale", (PyCFunction)C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc},
+ {"Shear", (PyCFunction)C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc},
+ {"Translation",
+ (PyCFunction)C_Matrix_Translation,
+ METH_O | METH_CLASS,
+ C_Matrix_Translation_doc},
+ {"OrthoProjection",
+ (PyCFunction)C_Matrix_OrthoProjection,
+ METH_VARARGS | METH_CLASS,
+ C_Matrix_OrthoProjection_doc},
+ {NULL, NULL, 0, NULL},
};
/*------------------PY_OBECT DEFINITION--------------------------*/
-PyDoc_STRVAR(matrix_doc,
-".. class:: Matrix([rows])\n"
-"\n"
-" This object gives access to Matrices in Blender, supporting square and rectangular\n"
-" matrices from 2x2 up to 4x4.\n"
-"\n"
-" :param rows: Sequence of rows.\n"
-" When omitted, a 4x4 identity matrix is constructed.\n"
-" :type rows: 2d number sequence\n"
-);
+PyDoc_STRVAR(
+ matrix_doc,
+ ".. class:: Matrix([rows])\n"
+ "\n"
+ " This object gives access to Matrices in Blender, supporting square and rectangular\n"
+ " matrices from 2x2 up to 4x4.\n"
+ "\n"
+ " :param rows: Sequence of rows.\n"
+ " When omitted, a 4x4 identity matrix is constructed.\n"
+ " :type rows: 2d number sequence\n");
PyTypeObject matrix_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "Matrix", /*tp_name*/
- sizeof(MatrixObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)BaseMathObject_dealloc, /*tp_dealloc*/
- NULL, /*tp_print*/
- NULL, /*tp_getattr*/
- NULL, /*tp_setattr*/
- NULL, /*tp_compare*/
- (reprfunc) Matrix_repr, /*tp_repr*/
- &Matrix_NumMethods, /*tp_as_number*/
- &Matrix_SeqMethods, /*tp_as_sequence*/
- &Matrix_AsMapping, /*tp_as_mapping*/
- (hashfunc)Matrix_hash, /*tp_hash*/
- NULL, /*tp_call*/
+ PyVarObject_HEAD_INIT(NULL, 0) "Matrix", /*tp_name*/
+ sizeof(MatrixObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)BaseMathObject_dealloc, /*tp_dealloc*/
+ NULL, /*tp_print*/
+ NULL, /*tp_getattr*/
+ NULL, /*tp_setattr*/
+ NULL, /*tp_compare*/
+ (reprfunc)Matrix_repr, /*tp_repr*/
+ &Matrix_NumMethods, /*tp_as_number*/
+ &Matrix_SeqMethods, /*tp_as_sequence*/
+ &Matrix_AsMapping, /*tp_as_mapping*/
+ (hashfunc)Matrix_hash, /*tp_hash*/
+ NULL, /*tp_call*/
#ifndef MATH_STANDALONE
- (reprfunc) Matrix_str, /*tp_str*/
+ (reprfunc)Matrix_str, /*tp_str*/
#else
- NULL, /*tp_str*/
+ NULL, /*tp_str*/
#endif
- NULL, /*tp_getattro*/
- NULL, /*tp_setattro*/
- NULL, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- matrix_doc, /*tp_doc*/
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /*tp_clear*/
- (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- NULL, /*tp_iter*/
- NULL, /*tp_iternext*/
- Matrix_methods, /*tp_methods*/
- NULL, /*tp_members*/
- Matrix_getseters, /*tp_getset*/
- NULL, /*tp_base*/
- NULL, /*tp_dict*/
- NULL, /*tp_descr_get*/
- NULL, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- NULL, /*tp_init*/
- NULL, /*tp_alloc*/
- Matrix_new, /*tp_new*/
- NULL, /*tp_free*/
- NULL, /*tp_is_gc*/
- NULL, /*tp_bases*/
- NULL, /*tp_mro*/
- NULL, /*tp_cache*/
- NULL, /*tp_subclasses*/
- NULL, /*tp_weaklist*/
- NULL, /*tp_del*/
+ NULL, /*tp_getattro*/
+ NULL, /*tp_setattro*/
+ NULL, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ matrix_doc, /*tp_doc*/
+ (traverseproc)BaseMathObject_traverse, /* tp_traverse */
+ (inquiry)BaseMathObject_clear, /*tp_clear*/
+ (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ NULL, /*tp_iter*/
+ NULL, /*tp_iternext*/
+ Matrix_methods, /*tp_methods*/
+ NULL, /*tp_members*/
+ Matrix_getseters, /*tp_getset*/
+ NULL, /*tp_base*/
+ NULL, /*tp_dict*/
+ NULL, /*tp_descr_get*/
+ NULL, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ NULL, /*tp_init*/
+ NULL, /*tp_alloc*/
+ Matrix_new, /*tp_new*/
+ NULL, /*tp_free*/
+ NULL, /*tp_is_gc*/
+ NULL, /*tp_bases*/
+ NULL, /*tp_mro*/
+ NULL, /*tp_cache*/
+ NULL, /*tp_subclasses*/
+ NULL, /*tp_weaklist*/
+ NULL, /*tp_del*/
};
-PyObject *Matrix_CreatePyObject(
- const float *mat,
- const unsigned short num_col, const unsigned short num_row,
- PyTypeObject *base_type)
-{
- MatrixObject *self;
- float *mat_alloc;
-
- /* matrix objects can be any 2-4row x 2-4col matrix */
- if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
- PyErr_SetString(PyExc_RuntimeError,
- "Matrix(): "
- "row and column sizes must be between 2 and 4");
- return NULL;
- }
-
- mat_alloc = PyMem_Malloc(num_col * num_row * sizeof(float));
- if (UNLIKELY(mat_alloc == NULL)) {
- PyErr_SetString(PyExc_MemoryError,
- "Matrix(): "
- "problem allocating data");
- return NULL;
- }
-
- self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
- if (self) {
- self->matrix = mat_alloc;
- self->num_col = num_col;
- self->num_row = num_row;
-
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- if (mat) { /*if a float array passed*/
- memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
- }
- else if (num_col == num_row) {
- /* or if no arguments are passed return identity matrix for square matrices */
- matrix_identity_internal(self);
- }
- else {
- /* otherwise zero everything */
- memset(self->matrix, 0, num_col * num_row * sizeof(float));
- }
- self->flag = BASE_MATH_FLAG_DEFAULT;
- }
- else {
- PyMem_Free(mat_alloc);
- }
-
- return (PyObject *)self;
-}
-
-PyObject *Matrix_CreatePyObject_wrap(
- float *mat,
- const unsigned short num_col, const unsigned short num_row,
- PyTypeObject *base_type)
-{
- MatrixObject *self;
-
- /* matrix objects can be any 2-4row x 2-4col matrix */
- if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
- PyErr_SetString(PyExc_RuntimeError,
- "Matrix(): "
- "row and column sizes must be between 2 and 4");
- return NULL;
- }
-
- self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
- if (self) {
- self->num_col = num_col;
- self->num_row = num_row;
-
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- self->matrix = mat;
- self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
- }
- return (PyObject *) self;
+PyObject *Matrix_CreatePyObject(const float *mat,
+ const unsigned short num_col,
+ const unsigned short num_row,
+ PyTypeObject *base_type)
+{
+ MatrixObject *self;
+ float *mat_alloc;
+
+ /* matrix objects can be any 2-4row x 2-4col matrix */
+ if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Matrix(): "
+ "row and column sizes must be between 2 and 4");
+ return NULL;
+ }
+
+ mat_alloc = PyMem_Malloc(num_col * num_row * sizeof(float));
+ if (UNLIKELY(mat_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Matrix(): "
+ "problem allocating data");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
+ if (self) {
+ self->matrix = mat_alloc;
+ self->num_col = num_col;
+ self->num_row = num_row;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ if (mat) { /*if a float array passed*/
+ memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
+ }
+ else if (num_col == num_row) {
+ /* or if no arguments are passed return identity matrix for square matrices */
+ matrix_identity_internal(self);
+ }
+ else {
+ /* otherwise zero everything */
+ memset(self->matrix, 0, num_col * num_row * sizeof(float));
+ }
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(mat_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Matrix_CreatePyObject_wrap(float *mat,
+ const unsigned short num_col,
+ const unsigned short num_row,
+ PyTypeObject *base_type)
+{
+ MatrixObject *self;
+
+ /* matrix objects can be any 2-4row x 2-4col matrix */
+ if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Matrix(): "
+ "row and column sizes must be between 2 and 4");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
+ if (self) {
+ self->num_col = num_col;
+ self->num_row = num_row;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ self->matrix = mat;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+ }
+ return (PyObject *)self;
}
PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user,
- const unsigned short num_col, const unsigned short num_row,
- unsigned char cb_type, unsigned char cb_subtype)
-{
- MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL);
- if (self) {
- Py_INCREF(cb_user);
- self->cb_user = cb_user;
- self->cb_type = cb_type;
- self->cb_subtype = cb_subtype;
- PyObject_GC_Track(self);
- }
- return (PyObject *) self;
+ const unsigned short num_col,
+ const unsigned short num_row,
+ unsigned char cb_type,
+ unsigned char cb_subtype)
+{
+ MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL);
+ if (self) {
+ Py_INCREF(cb_user);
+ self->cb_user = cb_user;
+ self->cb_type = cb_type;
+ self->cb_subtype = cb_subtype;
+ PyObject_GC_Track(self);
+ }
+ return (PyObject *)self;
}
/**
@@ -3185,288 +3264,278 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user,
*/
static bool Matrix_ParseCheck(MatrixObject *pymat)
{
- if (!MatrixObject_Check(pymat)) {
- PyErr_Format(PyExc_TypeError,
- "expected a mathutils.Matrix, not a %.200s",
- Py_TYPE(pymat)->tp_name);
- return 0;
- }
- /* sets error */
- if (BaseMath_ReadCallback(pymat) == -1) {
- return 0;
- }
- return 1;
+ if (!MatrixObject_Check(pymat)) {
+ PyErr_Format(
+ PyExc_TypeError, "expected a mathutils.Matrix, not a %.200s", Py_TYPE(pymat)->tp_name);
+ return 0;
+ }
+ /* sets error */
+ if (BaseMath_ReadCallback(pymat) == -1) {
+ return 0;
+ }
+ return 1;
}
int Matrix_ParseAny(PyObject *o, void *p)
{
- MatrixObject **pymat_p = p;
- MatrixObject *pymat = (MatrixObject *)o;
+ MatrixObject **pymat_p = p;
+ MatrixObject *pymat = (MatrixObject *)o;
- if (!Matrix_ParseCheck(pymat)) {
- return 0;
- }
- *pymat_p = pymat;
- return 1;
+ if (!Matrix_ParseCheck(pymat)) {
+ return 0;
+ }
+ *pymat_p = pymat;
+ return 1;
}
int Matrix_Parse3x3(PyObject *o, void *p)
{
- MatrixObject **pymat_p = p;
- MatrixObject *pymat = (MatrixObject *)o;
+ MatrixObject **pymat_p = p;
+ MatrixObject *pymat = (MatrixObject *)o;
- if (!Matrix_ParseCheck(pymat)) {
- return 0;
- }
- if ((pymat->num_col != 3) ||
- (pymat->num_row != 3))
- {
- PyErr_SetString(PyExc_ValueError, "matrix must be 3x3");
- return 0;
- }
+ if (!Matrix_ParseCheck(pymat)) {
+ return 0;
+ }
+ if ((pymat->num_col != 3) || (pymat->num_row != 3)) {
+ PyErr_SetString(PyExc_ValueError, "matrix must be 3x3");
+ return 0;
+ }
- *pymat_p = pymat;
- return 1;
+ *pymat_p = pymat;
+ return 1;
}
int Matrix_Parse4x4(PyObject *o, void *p)
{
- MatrixObject **pymat_p = p;
- MatrixObject *pymat = (MatrixObject *)o;
+ MatrixObject **pymat_p = p;
+ MatrixObject *pymat = (MatrixObject *)o;
- if (!Matrix_ParseCheck(pymat)) {
- return 0;
- }
- if ((pymat->num_col != 4) ||
- (pymat->num_row != 4))
- {
- PyErr_SetString(PyExc_ValueError, "matrix must be 4x4");
- return 0;
- }
+ if (!Matrix_ParseCheck(pymat)) {
+ return 0;
+ }
+ if ((pymat->num_col != 4) || (pymat->num_row != 4)) {
+ PyErr_SetString(PyExc_ValueError, "matrix must be 4x4");
+ return 0;
+ }
- *pymat_p = pymat;
- return 1;
+ *pymat_p = pymat;
+ return 1;
}
/* ----------------------------------------------------------------------------
* special type for alternate access */
typedef struct {
- PyObject_HEAD /* required python macro */
- MatrixObject *matrix_user;
- eMatrixAccess_t type;
+ PyObject_HEAD /* required python macro */
+ MatrixObject *matrix_user;
+ eMatrixAccess_t type;
} MatrixAccessObject;
static int MatrixAccess_traverse(MatrixAccessObject *self, visitproc visit, void *arg)
{
- Py_VISIT(self->matrix_user);
- return 0;
+ Py_VISIT(self->matrix_user);
+ return 0;
}
static int MatrixAccess_clear(MatrixAccessObject *self)
{
- Py_CLEAR(self->matrix_user);
- return 0;
+ Py_CLEAR(self->matrix_user);
+ return 0;
}
static void MatrixAccess_dealloc(MatrixAccessObject *self)
{
- if (self->matrix_user) {
- PyObject_GC_UnTrack(self);
- MatrixAccess_clear(self);
- }
+ if (self->matrix_user) {
+ PyObject_GC_UnTrack(self);
+ MatrixAccess_clear(self);
+ }
- Py_TYPE(self)->tp_free(self);
+ Py_TYPE(self)->tp_free(self);
}
/* sequence access */
static int MatrixAccess_len(MatrixAccessObject *self)
{
- return (self->type == MAT_ACCESS_ROW) ?
- self->matrix_user->num_row :
- self->matrix_user->num_col;
+ return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->num_row : self->matrix_user->num_col;
}
static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
+ PyObject *tuple;
+ int count;
- /* row/col access */
- MatrixObject *matrix_user = self->matrix_user;
- int matrix_access_len;
- PyObject *(*Matrix_item_new)(MatrixObject *, int);
+ /* row/col access */
+ MatrixObject *matrix_user = self->matrix_user;
+ int matrix_access_len;
+ PyObject *(*Matrix_item_new)(MatrixObject *, int);
- if (self->type == MAT_ACCESS_ROW) {
- matrix_access_len = matrix_user->num_row;
- Matrix_item_new = Matrix_item_row;
- }
- else { /* MAT_ACCESS_ROW */
- matrix_access_len = matrix_user->num_col;
- Matrix_item_new = Matrix_item_col;
- }
+ if (self->type == MAT_ACCESS_ROW) {
+ matrix_access_len = matrix_user->num_row;
+ Matrix_item_new = Matrix_item_row;
+ }
+ else { /* MAT_ACCESS_ROW */
+ matrix_access_len = matrix_user->num_col;
+ Matrix_item_new = Matrix_item_col;
+ }
- CLAMP(begin, 0, matrix_access_len);
- if (end < 0) {
- end = (matrix_access_len + 1) + end;
- }
- CLAMP(end, 0, matrix_access_len);
- begin = MIN2(begin, end);
+ CLAMP(begin, 0, matrix_access_len);
+ if (end < 0) {
+ end = (matrix_access_len + 1) + end;
+ }
+ CLAMP(end, 0, matrix_access_len);
+ begin = MIN2(begin, end);
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count));
- }
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count));
+ }
- return tuple;
+ return tuple;
}
static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item)
{
- MatrixObject *matrix_user = self->matrix_user;
-
- if (PyIndex_Check(item)) {
- Py_ssize_t i;
- i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred()) {
- return NULL;
- }
- if (self->type == MAT_ACCESS_ROW) {
- if (i < 0) {
- i += matrix_user->num_row;
- }
- return Matrix_item_row(matrix_user, i);
- }
- else { /* MAT_ACCESS_ROW */
- if (i < 0) {
- i += matrix_user->num_col;
- }
- return Matrix_item_col(matrix_user, i);
- }
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return MatrixAccess_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with matrix accessors");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "matrix indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ MatrixObject *matrix_user = self->matrix_user;
+
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i;
+ i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (self->type == MAT_ACCESS_ROW) {
+ if (i < 0) {
+ i += matrix_user->num_row;
+ }
+ return Matrix_item_row(matrix_user, i);
+ }
+ else { /* MAT_ACCESS_ROW */
+ if (i < 0) {
+ i += matrix_user->num_col;
+ }
+ return Matrix_item_col(matrix_user, i);
+ }
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) <
+ 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return MatrixAccess_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrix accessors");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
+ }
}
static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, PyObject *value)
{
- MatrixObject *matrix_user = self->matrix_user;
-
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred()) {
- return -1;
- }
-
- if (self->type == MAT_ACCESS_ROW) {
- if (i < 0) {
- i += matrix_user->num_row;
- }
- return Matrix_ass_item_row(matrix_user, i, value);
- }
- else { /* MAT_ACCESS_ROW */
- if (i < 0) {
- i += matrix_user->num_col;
- }
- return Matrix_ass_item_col(matrix_user, i, value);
- }
-
- }
- /* TODO, slice */
- else {
- PyErr_Format(PyExc_TypeError,
- "matrix indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ MatrixObject *matrix_user = self->matrix_user;
+
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+
+ if (self->type == MAT_ACCESS_ROW) {
+ if (i < 0) {
+ i += matrix_user->num_row;
+ }
+ return Matrix_ass_item_row(matrix_user, i, value);
+ }
+ else { /* MAT_ACCESS_ROW */
+ if (i < 0) {
+ i += matrix_user->num_col;
+ }
+ return Matrix_ass_item_col(matrix_user, i, value);
+ }
+ }
+ /* TODO, slice */
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
{
- /* Try get values from a collection */
- PyObject *ret;
- PyObject *iter = NULL;
- ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM);
+ /* 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 */
- if (ret) {
- iter = PyObject_GetIter(ret);
- Py_DECREF(ret);
- }
+ /* 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);
+ }
- return iter;
+ return iter;
}
static PyMappingMethods MatrixAccess_AsMapping = {
- (lenfunc)MatrixAccess_len,
- (binaryfunc)MatrixAccess_subscript,
- (objobjargproc) MatrixAccess_ass_subscript,
+ (lenfunc)MatrixAccess_len,
+ (binaryfunc)MatrixAccess_subscript,
+ (objobjargproc)MatrixAccess_ass_subscript,
};
PyTypeObject matrix_access_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "MatrixAccess", /*tp_name*/
- sizeof(MatrixAccessObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)MatrixAccess_dealloc, /*tp_dealloc*/
- NULL, /*tp_print*/
- NULL, /*tp_getattr*/
- NULL, /*tp_setattr*/
- NULL, /*tp_compare*/
- NULL, /*tp_repr*/
- NULL, /*tp_as_number*/
- NULL /*&MatrixAccess_SeqMethods*/ /* TODO */, /*tp_as_sequence*/
- &MatrixAccess_AsMapping, /*tp_as_mapping*/
- NULL, /*tp_hash*/
- NULL, /*tp_call*/
- NULL, /*tp_str*/
- NULL, /*tp_getattro*/
- NULL, /*tp_setattro*/
- NULL, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- NULL, /*tp_doc*/
- (traverseproc)MatrixAccess_traverse,/*tp_traverse*/
- (inquiry)MatrixAccess_clear, /*tp_clear*/
- NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
+ PyVarObject_HEAD_INIT(NULL, 0) "MatrixAccess", /*tp_name*/
+ sizeof(MatrixAccessObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)MatrixAccess_dealloc, /*tp_dealloc*/
+ NULL, /*tp_print*/
+ NULL, /*tp_getattr*/
+ NULL, /*tp_setattr*/
+ NULL, /*tp_compare*/
+ NULL, /*tp_repr*/
+ NULL, /*tp_as_number*/
+ NULL /*&MatrixAccess_SeqMethods*/ /* TODO */, /*tp_as_sequence*/
+ &MatrixAccess_AsMapping, /*tp_as_mapping*/
+ NULL, /*tp_hash*/
+ NULL, /*tp_call*/
+ NULL, /*tp_str*/
+ NULL, /*tp_getattro*/
+ NULL, /*tp_setattro*/
+ NULL, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ NULL, /*tp_doc*/
+ (traverseproc)MatrixAccess_traverse, /*tp_traverse*/
+ (inquiry)MatrixAccess_clear, /*tp_clear*/
+ NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
};
static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type)
{
- MatrixAccessObject *matrix_access = (MatrixAccessObject *)PyObject_GC_New(MatrixObject, &matrix_access_Type);
+ MatrixAccessObject *matrix_access = (MatrixAccessObject *)PyObject_GC_New(MatrixObject,
+ &matrix_access_Type);
- matrix_access->matrix_user = matrix;
- Py_INCREF(matrix);
+ matrix_access->matrix_user = matrix;
+ Py_INCREF(matrix);
- matrix_access->type = type;
+ matrix_access->type = type;
- return (PyObject *)matrix_access;
+ return (PyObject *)matrix_access;
}
/* end special access
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index 0f47472c8fd..3b42e22a787 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#ifndef __MATHUTILS_MATRIX_H__
#define __MATHUTILS_MATRIX_H__
@@ -33,23 +32,25 @@ extern PyTypeObject matrix_access_Type;
/* matrix[row][col] == MATRIX_ITEM_INDEX(matrix, row, col) */
#ifdef DEBUG
-# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col))
+# define MATRIX_ITEM_ASSERT(_mat, _row, _col) \
+ (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col))
#else
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0
#endif
#define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col) (((_totrow) * (_col)) + (_row))
-#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->num_row * (_col)) + (_row)))
-#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col))
-#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->matrix [MATRIX_ITEM_INDEX(_mat, _row, _col)])
+#define MATRIX_ITEM_INDEX(_mat, _row, _col) \
+ (MATRIX_ITEM_ASSERT(_mat, _row, _col), (((_mat)->num_row * (_col)) + (_row)))
+#define MATRIX_ITEM_PTR(_mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col))
+#define MATRIX_ITEM(_mat, _row, _col) ((_mat)->matrix[MATRIX_ITEM_INDEX(_mat, _row, _col)])
#define MATRIX_COL_INDEX(_mat, _col) (MATRIX_ITEM_INDEX(_mat, 0, _col))
-#define MATRIX_COL_PTR( _mat, _col) ((_mat)->matrix + MATRIX_COL_INDEX(_mat, _col))
+#define MATRIX_COL_PTR(_mat, _col) ((_mat)->matrix + MATRIX_COL_INDEX(_mat, _col))
typedef struct {
- BASE_MATH_MEMBERS(matrix);
- unsigned short num_col;
- unsigned short num_row;
+ BASE_MATH_MEMBERS(matrix);
+ unsigned short num_col;
+ unsigned short num_row;
} MatrixObject;
/* struct data contains a pointer to the actual data that the
@@ -58,21 +59,20 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Matrix_CreatePyObject(
- const float *mat,
- const unsigned short num_col, const unsigned short num_row,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Matrix_CreatePyObject_wrap(
- float *mat,
- const unsigned short num_col, const unsigned short num_row,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-PyObject *Matrix_CreatePyObject_cb(
- PyObject *user,
- const unsigned short num_col, const unsigned short num_row,
- unsigned char cb_type, unsigned char cb_subtype
- ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Matrix_CreatePyObject(const float *mat,
+ const unsigned short num_col,
+ const unsigned short num_row,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
+PyObject *Matrix_CreatePyObject_wrap(float *mat,
+ const unsigned short num_col,
+ const unsigned short num_row,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+PyObject *Matrix_CreatePyObject_cb(PyObject *user,
+ const unsigned short num_col,
+ const unsigned short num_row,
+ unsigned char cb_type,
+ unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
/* PyArg_ParseTuple's "O&" formatting helpers. */
int Matrix_ParseAny(PyObject *o, void *p);
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 422a1ff28fa..86da4511a2e 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -36,7 +35,7 @@
#define QUAT_SIZE 4
static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self);
-static void quat__axis_angle_sanitize(float axis[3], float *angle);
+static void quat__axis_angle_sanitize(float axis[3], float *angle);
static PyObject *Quaternion_copy(QuaternionObject *self);
static PyObject *Quaternion_deepcopy(QuaternionObject *self, PyObject *args);
@@ -45,569 +44,556 @@ static PyObject *Quaternion_deepcopy(QuaternionObject *self, PyObject *args);
/* note: BaseMath_ReadCallback must be called beforehand */
static PyObject *Quaternion_to_tuple_ext(QuaternionObject *self, int ndigits)
{
- PyObject *ret;
- int i;
-
- ret = PyTuple_New(QUAT_SIZE);
-
- if (ndigits >= 0) {
- for (i = 0; i < QUAT_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->quat[i], ndigits)));
- }
- }
- else {
- for (i = 0; i < QUAT_SIZE; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->quat[i]));
- }
- }
-
- return ret;
+ PyObject *ret;
+ int i;
+
+ ret = PyTuple_New(QUAT_SIZE);
+
+ if (ndigits >= 0) {
+ for (i = 0; i < QUAT_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->quat[i], ndigits)));
+ }
+ }
+ else {
+ for (i = 0; i < QUAT_SIZE; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->quat[i]));
+ }
+ }
+
+ return ret;
}
PyDoc_STRVAR(Quaternion_to_euler_doc,
-".. method:: to_euler(order, euler_compat)\n"
-"\n"
-" Return Euler representation of the quaternion.\n"
-"\n"
-" :arg order: Optional rotation order argument in\n"
-" ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
-" :type order: string\n"
-" :arg euler_compat: Optional euler argument the new euler will be made\n"
-" compatible with (no axis flipping between them).\n"
-" Useful for converting a series of matrices to animation curves.\n"
-" :type euler_compat: :class:`Euler`\n"
-" :return: Euler representation of the quaternion.\n"
-" :rtype: :class:`Euler`\n"
-);
+ ".. method:: to_euler(order, euler_compat)\n"
+ "\n"
+ " Return Euler representation of the quaternion.\n"
+ "\n"
+ " :arg order: Optional rotation order argument in\n"
+ " ['XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'].\n"
+ " :type order: string\n"
+ " :arg euler_compat: Optional euler argument the new euler will be made\n"
+ " compatible with (no axis flipping between them).\n"
+ " Useful for converting a series of matrices to animation curves.\n"
+ " :type euler_compat: :class:`Euler`\n"
+ " :return: Euler representation of the quaternion.\n"
+ " :rtype: :class:`Euler`\n");
static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
{
- float tquat[4];
- float eul[3];
- const char *order_str = NULL;
- short order = EULER_ORDER_XYZ;
- EulerObject *eul_compat = NULL;
-
- if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) {
- return NULL;
- }
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (order_str) {
- order = euler_order_from_string(order_str, "Matrix.to_euler()");
-
- if (order == -1) {
- return NULL;
- }
- }
-
- normalize_qt_qt(tquat, self->quat);
-
- if (eul_compat) {
- if (BaseMath_ReadCallback(eul_compat) == -1) {
- return NULL;
- }
-
- if (order == EULER_ORDER_XYZ) {
- quat_to_compatible_eul(eul, eul_compat->eul, tquat);
- }
- else {
- quat_to_compatible_eulO(eul, eul_compat->eul, order, tquat);
- }
- }
- else {
- if (order == EULER_ORDER_XYZ) {
- quat_to_eul(eul, tquat);
- }
- else {
- quat_to_eulO(eul, order, tquat);
- }
- }
-
- return Euler_CreatePyObject(eul, order, NULL);
+ float tquat[4];
+ float eul[3];
+ const char *order_str = NULL;
+ short order = EULER_ORDER_XYZ;
+ EulerObject *eul_compat = NULL;
+
+ if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat)) {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (order_str) {
+ order = euler_order_from_string(order_str, "Matrix.to_euler()");
+
+ if (order == -1) {
+ return NULL;
+ }
+ }
+
+ normalize_qt_qt(tquat, self->quat);
+
+ if (eul_compat) {
+ if (BaseMath_ReadCallback(eul_compat) == -1) {
+ return NULL;
+ }
+
+ if (order == EULER_ORDER_XYZ) {
+ quat_to_compatible_eul(eul, eul_compat->eul, tquat);
+ }
+ else {
+ quat_to_compatible_eulO(eul, eul_compat->eul, order, tquat);
+ }
+ }
+ else {
+ if (order == EULER_ORDER_XYZ) {
+ quat_to_eul(eul, tquat);
+ }
+ else {
+ quat_to_eulO(eul, order, tquat);
+ }
+ }
+
+ return Euler_CreatePyObject(eul, order, NULL);
}
PyDoc_STRVAR(Quaternion_to_matrix_doc,
-".. method:: to_matrix()\n"
-"\n"
-" Return a matrix representation of the quaternion.\n"
-"\n"
-" :return: A 3x3 rotation matrix representation of the quaternion.\n"
-" :rtype: :class:`Matrix`\n"
-);
+ ".. method:: to_matrix()\n"
+ "\n"
+ " Return a matrix representation of the quaternion.\n"
+ "\n"
+ " :return: A 3x3 rotation matrix representation of the quaternion.\n"
+ " :rtype: :class:`Matrix`\n");
static PyObject *Quaternion_to_matrix(QuaternionObject *self)
{
- float mat[9]; /* all values are set */
+ float mat[9]; /* all values are set */
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- quat_to_mat3((float (*)[3])mat, self->quat);
- return Matrix_CreatePyObject(mat, 3, 3, NULL);
+ quat_to_mat3((float(*)[3])mat, self->quat);
+ return Matrix_CreatePyObject(mat, 3, 3, NULL);
}
PyDoc_STRVAR(Quaternion_to_axis_angle_doc,
-".. method:: to_axis_angle()\n"
-"\n"
-" Return the axis, angle representation of the quaternion.\n"
-"\n"
-" :return: axis, angle.\n"
-" :rtype: (:class:`Vector`, float) pair\n"
-);
+ ".. method:: to_axis_angle()\n"
+ "\n"
+ " Return the axis, angle representation of the quaternion.\n"
+ "\n"
+ " :return: axis, angle.\n"
+ " :rtype: (:class:`Vector`, float) pair\n");
static PyObject *Quaternion_to_axis_angle(QuaternionObject *self)
{
- PyObject *ret;
+ PyObject *ret;
- float tquat[4];
+ float tquat[4];
- float axis[3];
- float angle;
+ float axis[3];
+ float angle;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- normalize_qt_qt(tquat, self->quat);
- quat_to_axis_angle(axis, &angle, tquat);
+ normalize_qt_qt(tquat, self->quat);
+ quat_to_axis_angle(axis, &angle, tquat);
- quat__axis_angle_sanitize(axis, &angle);
+ quat__axis_angle_sanitize(axis, &angle);
- ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret,
- Vector_CreatePyObject(axis, 3, NULL),
- PyFloat_FromDouble(angle));
- return ret;
+ ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(axis, 3, NULL), PyFloat_FromDouble(angle));
+ return ret;
}
-PyDoc_STRVAR(Quaternion_to_exponential_map_doc,
-".. method:: to_exponential_map()\n"
-"\n"
-" Return the exponential map representation of the quaternion.\n"
-"\n"
-" This representation consist of the rotation axis multiplied by the rotation angle."
-" Such a representation is useful for interpolation between multiple orientations.\n"
-"\n"
-" :return: exponential map.\n"
-" :rtype: :class:`Vector` of size 3\n"
-"\n"
-" To convert back to a quaternion, pass it to the :class:`Quaternion` constructor.\n"
-);
+PyDoc_STRVAR(
+ Quaternion_to_exponential_map_doc,
+ ".. method:: to_exponential_map()\n"
+ "\n"
+ " Return the exponential map representation of the quaternion.\n"
+ "\n"
+ " This representation consist of the rotation axis multiplied by the rotation angle."
+ " Such a representation is useful for interpolation between multiple orientations.\n"
+ "\n"
+ " :return: exponential map.\n"
+ " :rtype: :class:`Vector` of size 3\n"
+ "\n"
+ " To convert back to a quaternion, pass it to the :class:`Quaternion` constructor.\n");
static PyObject *Quaternion_to_exponential_map(QuaternionObject *self)
{
- float expmap[3];
+ float expmap[3];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- quat_to_expmap(expmap, self->quat);
- return Vector_CreatePyObject(expmap, 3, NULL);
+ quat_to_expmap(expmap, self->quat);
+ return Vector_CreatePyObject(expmap, 3, NULL);
}
PyDoc_STRVAR(Quaternion_cross_doc,
-".. method:: cross(other)\n"
-"\n"
-" Return the cross product of this quaternion and another.\n"
-"\n"
-" :arg other: The other quaternion to perform the cross product with.\n"
-" :type other: :class:`Quaternion`\n"
-" :return: The cross product.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. method:: cross(other)\n"
+ "\n"
+ " Return the cross product of this quaternion and another.\n"
+ "\n"
+ " :arg other: The other quaternion to perform the cross product with.\n"
+ " :type other: :class:`Quaternion`\n"
+ " :return: The cross product.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value)
{
- float quat[QUAT_SIZE], tquat[QUAT_SIZE];
+ float quat[QUAT_SIZE], tquat[QUAT_SIZE];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
- "Quaternion.cross(other), invalid 'other' arg") == -1)
- {
- return NULL;
- }
+ if (mathutils_array_parse(
+ tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.cross(other), invalid 'other' arg") ==
+ -1) {
+ return NULL;
+ }
- mul_qt_qtqt(quat, self->quat, tquat);
- return Quaternion_CreatePyObject(quat, Py_TYPE(self));
+ mul_qt_qtqt(quat, self->quat, tquat);
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_dot_doc,
-".. method:: dot(other)\n"
-"\n"
-" Return the dot product of this quaternion and another.\n"
-"\n"
-" :arg other: The other quaternion to perform the dot product with.\n"
-" :type other: :class:`Quaternion`\n"
-" :return: The dot product.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. method:: dot(other)\n"
+ "\n"
+ " Return the dot product of this quaternion and another.\n"
+ "\n"
+ " :arg other: The other quaternion to perform the dot product with.\n"
+ " :type other: :class:`Quaternion`\n"
+ " :return: The dot product.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_dot(QuaternionObject *self, PyObject *value)
{
- float tquat[QUAT_SIZE];
+ float tquat[QUAT_SIZE];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
- "Quaternion.dot(other), invalid 'other' arg") == -1)
- {
- return NULL;
- }
+ if (mathutils_array_parse(
+ tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.dot(other), invalid 'other' arg") ==
+ -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(dot_qtqt(self->quat, tquat));
+ return PyFloat_FromDouble(dot_qtqt(self->quat, tquat));
}
PyDoc_STRVAR(Quaternion_rotation_difference_doc,
-".. function:: rotation_difference(other)\n"
-"\n"
-" Returns a quaternion representing the rotational difference.\n"
-"\n"
-" :arg other: second quaternion.\n"
-" :type other: :class:`Quaternion`\n"
-" :return: the rotational difference between the two quat rotations.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: rotation_difference(other)\n"
+ "\n"
+ " Returns a quaternion representing the rotational difference.\n"
+ "\n"
+ " :arg other: second quaternion.\n"
+ " :type other: :class:`Quaternion`\n"
+ " :return: the rotational difference between the two quat rotations.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject *value)
{
- float tquat[QUAT_SIZE], quat[QUAT_SIZE];
+ float tquat[QUAT_SIZE], quat[QUAT_SIZE];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
- "Quaternion.difference(other), invalid 'other' arg") == -1)
- {
- return NULL;
- }
+ if (mathutils_array_parse(tquat,
+ QUAT_SIZE,
+ QUAT_SIZE,
+ value,
+ "Quaternion.difference(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
- rotation_between_quats_to_quat(quat, self->quat, tquat);
+ rotation_between_quats_to_quat(quat, self->quat, tquat);
- return Quaternion_CreatePyObject(quat, Py_TYPE(self));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_slerp_doc,
-".. function:: slerp(other, factor)\n"
-"\n"
-" Returns the interpolation of two quaternions.\n"
-"\n"
-" :arg other: value to interpolate with.\n"
-" :type other: :class:`Quaternion`\n"
-" :arg factor: The interpolation value in [0.0, 1.0].\n"
-" :type factor: float\n"
-" :return: The interpolated rotation.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: slerp(other, factor)\n"
+ "\n"
+ " Returns the interpolation of two quaternions.\n"
+ "\n"
+ " :arg other: value to interpolate with.\n"
+ " :type other: :class:`Quaternion`\n"
+ " :arg factor: The interpolation value in [0.0, 1.0].\n"
+ " :type factor: float\n"
+ " :return: The interpolated rotation.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
{
- PyObject *value;
- float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac;
-
- if (!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) {
- PyErr_SetString(PyExc_TypeError,
- "quat.slerp(): "
- "expected Quaternion types and float");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
- "Quaternion.slerp(other), invalid 'other' arg") == -1)
- {
- return NULL;
- }
-
- if (fac > 1.0f || fac < 0.0f) {
- PyErr_SetString(PyExc_ValueError,
- "quat.slerp(): "
- "interpolation factor must be between 0.0 and 1.0");
- return NULL;
- }
-
- interp_qt_qtqt(quat, self->quat, tquat, fac);
-
- return Quaternion_CreatePyObject(quat, Py_TYPE(self));
+ PyObject *value;
+ float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac;
+
+ if (!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) {
+ PyErr_SetString(PyExc_TypeError,
+ "quat.slerp(): "
+ "expected Quaternion types and float");
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(
+ tquat, QUAT_SIZE, QUAT_SIZE, value, "Quaternion.slerp(other), invalid 'other' arg") ==
+ -1) {
+ return NULL;
+ }
+
+ if (fac > 1.0f || fac < 0.0f) {
+ PyErr_SetString(PyExc_ValueError,
+ "quat.slerp(): "
+ "interpolation factor must be between 0.0 and 1.0");
+ return NULL;
+ }
+
+ interp_qt_qtqt(quat, self->quat, tquat, fac);
+
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_rotate_doc,
-".. method:: rotate(other)\n"
-"\n"
-" Rotates the quaternion by another mathutils value.\n"
-"\n"
-" :arg other: rotation component of mathutils value\n"
-" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
-);
+ ".. method:: rotate(other)\n"
+ "\n"
+ " Rotates the quaternion by another mathutils value.\n"
+ "\n"
+ " :arg other: rotation component of mathutils value\n"
+ " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
{
- float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
- float tquat[4], length;
+ float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
+ float tquat[4], length;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (mathutils_any_to_rotmat(other_rmat, value, "Quaternion.rotate(value)") == -1) {
- return NULL;
- }
+ if (mathutils_any_to_rotmat(other_rmat, value, "Quaternion.rotate(value)") == -1) {
+ return NULL;
+ }
- length = normalize_qt_qt(tquat, self->quat);
- quat_to_mat3(self_rmat, tquat);
- mul_m3_m3m3(rmat, other_rmat, self_rmat);
+ length = normalize_qt_qt(tquat, self->quat);
+ quat_to_mat3(self_rmat, tquat);
+ mul_m3_m3m3(rmat, other_rmat, self_rmat);
- mat3_to_quat(self->quat, rmat);
- mul_qt_fl(self->quat, length); /* maintain length after rotating */
+ mat3_to_quat(self->quat, rmat);
+ mul_qt_fl(self->quat, length); /* maintain length after rotating */
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
/* ----------------------------Quaternion.normalize()---------------- */
/* Normalize the quaternion. This may change the angle as well as the
* rotation axis, as all of (w, x, y, z) are scaled. */
PyDoc_STRVAR(Quaternion_normalize_doc,
-".. function:: normalize()\n"
-"\n"
-" Normalize the quaternion.\n"
-);
+ ".. function:: normalize()\n"
+ "\n"
+ " Normalize the quaternion.\n");
static PyObject *Quaternion_normalize(QuaternionObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- normalize_qt(self->quat);
+ normalize_qt(self->quat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Quaternion_normalized_doc,
-".. function:: normalized()\n"
-"\n"
-" Return a new normalized quaternion.\n"
-"\n"
-" :return: a normalized copy.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: normalized()\n"
+ "\n"
+ " Return a new normalized quaternion.\n"
+ "\n"
+ " :return: a normalized copy.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_normalized(QuaternionObject *self)
{
- return quat__apply_to_copy((PyNoArgsFunction)Quaternion_normalize, self);
+ return quat__apply_to_copy((PyNoArgsFunction)Quaternion_normalize, self);
}
PyDoc_STRVAR(Quaternion_invert_doc,
-".. function:: invert()\n"
-"\n"
-" Set the quaternion to its inverse.\n"
-);
+ ".. function:: invert()\n"
+ "\n"
+ " Set the quaternion to its inverse.\n");
static PyObject *Quaternion_invert(QuaternionObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- invert_qt(self->quat);
+ invert_qt(self->quat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Quaternion_inverted_doc,
-".. function:: inverted()\n"
-"\n"
-" Return a new, inverted quaternion.\n"
-"\n"
-" :return: the inverted value.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: inverted()\n"
+ "\n"
+ " Return a new, inverted quaternion.\n"
+ "\n"
+ " :return: the inverted value.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_inverted(QuaternionObject *self)
{
- return quat__apply_to_copy((PyNoArgsFunction)Quaternion_invert, self);
+ return quat__apply_to_copy((PyNoArgsFunction)Quaternion_invert, self);
}
PyDoc_STRVAR(Quaternion_identity_doc,
-".. function:: identity()\n"
-"\n"
-" Set the quaternion to an identity quaternion.\n"
-"\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: identity()\n"
+ "\n"
+ " Set the quaternion to an identity quaternion.\n"
+ "\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_identity(QuaternionObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- unit_qt(self->quat);
+ unit_qt(self->quat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Quaternion_negate_doc,
-".. function:: negate()\n"
-"\n"
-" Set the quaternion to its negative.\n"
-"\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: negate()\n"
+ "\n"
+ " Set the quaternion to its negative.\n"
+ "\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_negate(QuaternionObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- mul_qt_fl(self->quat, -1.0f);
+ mul_qt_fl(self->quat, -1.0f);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Quaternion_conjugate_doc,
-".. function:: conjugate()\n"
-"\n"
-" Set the quaternion to its conjugate (negate x, y, z).\n"
-);
+ ".. function:: conjugate()\n"
+ "\n"
+ " Set the quaternion to its conjugate (negate x, y, z).\n");
static PyObject *Quaternion_conjugate(QuaternionObject *self)
{
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- conjugate_qt(self->quat);
+ conjugate_qt(self->quat);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Quaternion_conjugated_doc,
-".. function:: conjugated()\n"
-"\n"
-" Return a new conjugated quaternion.\n"
-"\n"
-" :return: a new quaternion.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. function:: conjugated()\n"
+ "\n"
+ " Return a new conjugated quaternion.\n"
+ "\n"
+ " :return: a new quaternion.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Quaternion_conjugated(QuaternionObject *self)
{
- return quat__apply_to_copy((PyNoArgsFunction)Quaternion_conjugate, self);
+ return quat__apply_to_copy((PyNoArgsFunction)Quaternion_conjugate, self);
}
PyDoc_STRVAR(Quaternion_copy_doc,
-".. function:: copy()\n"
-"\n"
-" Returns a copy of this quaternion.\n"
-"\n"
-" :return: A copy of the quaternion.\n"
-" :rtype: :class:`Quaternion`\n"
-"\n"
-" .. note:: use this to get a copy of a wrapped quaternion with\n"
-" no reference to the original data.\n"
-);
+ ".. function:: copy()\n"
+ "\n"
+ " Returns a copy of this quaternion.\n"
+ "\n"
+ " :return: A copy of the quaternion.\n"
+ " :rtype: :class:`Quaternion`\n"
+ "\n"
+ " .. note:: use this to get a copy of a wrapped quaternion with\n"
+ " no reference to the original data.\n");
static PyObject *Quaternion_copy(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Quaternion_CreatePyObject(self->quat, Py_TYPE(self));
+ return Quaternion_CreatePyObject(self->quat, Py_TYPE(self));
}
static PyObject *Quaternion_deepcopy(QuaternionObject *self, PyObject *args)
{
- if (!PyC_CheckArgs_DeepCopy(args)) {
- return NULL;
- }
- return Quaternion_copy(self);
+ if (!PyC_CheckArgs_DeepCopy(args)) {
+ return NULL;
+ }
+ return Quaternion_copy(self);
}
/* print the object to screen */
static PyObject *Quaternion_repr(QuaternionObject *self)
{
- PyObject *ret, *tuple;
+ PyObject *ret, *tuple;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- tuple = Quaternion_to_tuple_ext(self, -1);
+ tuple = Quaternion_to_tuple_ext(self, -1);
- ret = PyUnicode_FromFormat("Quaternion(%R)", tuple);
+ ret = PyUnicode_FromFormat("Quaternion(%R)", tuple);
- Py_DECREF(tuple);
- return ret;
+ Py_DECREF(tuple);
+ return ret;
}
#ifndef MATH_STANDALONE
static PyObject *Quaternion_str(QuaternionObject *self)
{
- DynStr *ds;
+ DynStr *ds;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- ds = BLI_dynstr_new();
+ ds = BLI_dynstr_new();
- BLI_dynstr_appendf(ds, "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
- self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
+ BLI_dynstr_appendf(ds,
+ "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
+ self->quat[0],
+ self->quat[1],
+ self->quat[2],
+ self->quat[3]);
- return mathutils_dynstr_to_py(ds); /* frees ds */
+ return mathutils_dynstr_to_py(ds); /* frees ds */
}
#endif
static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
{
- PyObject *res;
- int ok = -1; /* zero is true */
-
- if (QuaternionObject_Check(a) && QuaternionObject_Check(b)) {
- QuaternionObject *quatA = (QuaternionObject *)a;
- QuaternionObject *quatB = (QuaternionObject *)b;
-
- if (BaseMath_ReadCallback(quatA) == -1 || BaseMath_ReadCallback(quatB) == -1) {
- return NULL;
- }
-
- ok = (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1;
- }
-
- switch (op) {
- case Py_NE:
- ok = !ok;
- ATTR_FALLTHROUGH;
- case Py_EQ:
- res = ok ? Py_False : Py_True;
- break;
-
- case Py_LT:
- case Py_LE:
- case Py_GT:
- case Py_GE:
- res = Py_NotImplemented;
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
-
- return Py_INCREF_RET(res);
+ PyObject *res;
+ int ok = -1; /* zero is true */
+
+ if (QuaternionObject_Check(a) && QuaternionObject_Check(b)) {
+ QuaternionObject *quatA = (QuaternionObject *)a;
+ QuaternionObject *quatB = (QuaternionObject *)b;
+
+ if (BaseMath_ReadCallback(quatA) == -1 || BaseMath_ReadCallback(quatB) == -1) {
+ return NULL;
+ }
+
+ ok = (EXPP_VectorsAreEqual(quatA->quat, quatB->quat, QUAT_SIZE, 1)) ? 0 : -1;
+ }
+
+ switch (op) {
+ case Py_NE:
+ ok = !ok;
+ ATTR_FALLTHROUGH;
+ case Py_EQ:
+ res = ok ? Py_False : Py_True;
+ break;
+
+ case Py_LT:
+ case Py_LE:
+ case Py_GT:
+ case Py_GE:
+ res = Py_NotImplemented;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ return Py_INCREF_RET(res);
}
static Py_hash_t Quaternion_hash(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- if (BaseMathObject_Prepare_ForHash(self) == -1) {
- return -1;
- }
+ if (BaseMathObject_Prepare_ForHash(self) == -1) {
+ return -1;
+ }
- return mathutils_array_hash(self->quat, QUAT_SIZE);
+ return mathutils_array_hash(self->quat, QUAT_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -615,206 +601,202 @@ static Py_hash_t Quaternion_hash(QuaternionObject *self)
/* sequence length */
static int Quaternion_len(QuaternionObject *UNUSED(self))
{
- return QUAT_SIZE;
+ return QUAT_SIZE;
}
/* ----------------------------object[]--------------------------- */
/* sequence accessor (get) */
static PyObject *Quaternion_item(QuaternionObject *self, int i)
{
- if (i < 0) {
- i = QUAT_SIZE - i;
- }
-
- if (i < 0 || i >= QUAT_SIZE) {
- PyErr_SetString(PyExc_IndexError,
- "quaternion[attribute]: "
- "array index out of range");
- return NULL;
- }
-
- if (BaseMath_ReadIndexCallback(self, i) == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(self->quat[i]);
-
+ if (i < 0) {
+ i = QUAT_SIZE - i;
+ }
+
+ if (i < 0 || i >= QUAT_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "quaternion[attribute]: "
+ "array index out of range");
+ return NULL;
+ }
+
+ if (BaseMath_ReadIndexCallback(self, i) == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(self->quat[i]);
}
/* ----------------------------object[]------------------------- */
/* sequence accessor (set) */
static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
{
- float f;
-
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
-
- f = (float)PyFloat_AsDouble(ob);
-
- if (f == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "quaternion[index] = x: "
- "assigned value not a number");
- return -1;
- }
-
- if (i < 0) {
- i = QUAT_SIZE - i;
- }
-
- if (i < 0 || i >= QUAT_SIZE) {
- PyErr_SetString(PyExc_IndexError,
- "quaternion[attribute] = x: "
- "array assignment index out of range");
- return -1;
- }
- self->quat[i] = f;
-
- if (BaseMath_WriteIndexCallback(self, i) == -1) {
- return -1;
- }
-
- return 0;
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ f = (float)PyFloat_AsDouble(ob);
+
+ if (f == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "quaternion[index] = x: "
+ "assigned value not a number");
+ return -1;
+ }
+
+ if (i < 0) {
+ i = QUAT_SIZE - i;
+ }
+
+ if (i < 0 || i >= QUAT_SIZE) {
+ PyErr_SetString(PyExc_IndexError,
+ "quaternion[attribute] = x: "
+ "array assignment index out of range");
+ return -1;
+ }
+ self->quat[i] = f;
+
+ if (BaseMath_WriteIndexCallback(self, i) == -1) {
+ return -1;
+ }
+
+ return 0;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (get) */
static PyObject *Quaternion_slice(QuaternionObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- CLAMP(begin, 0, QUAT_SIZE);
- if (end < 0) {
- end = (QUAT_SIZE + 1) + end;
- }
- CLAMP(end, 0, QUAT_SIZE);
- begin = MIN2(begin, end);
-
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->quat[count]));
- }
-
- return tuple;
+ PyObject *tuple;
+ int count;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ CLAMP(begin, 0, QUAT_SIZE);
+ if (end < 0) {
+ end = (QUAT_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, QUAT_SIZE);
+ begin = MIN2(begin, end);
+
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->quat[count]));
+ }
+
+ return tuple;
}
/* ----------------------------object[z:y]------------------------ */
/* sequence slice (set) */
static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyObject *seq)
{
- int i, size;
- float quat[QUAT_SIZE];
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- CLAMP(begin, 0, QUAT_SIZE);
- if (end < 0) {
- end = (QUAT_SIZE + 1) + end;
- }
- CLAMP(end, 0, QUAT_SIZE);
- begin = MIN2(begin, end);
-
- if ((size = mathutils_array_parse(quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1) {
- return -1;
- }
-
- if (size != (end - begin)) {
- PyErr_SetString(PyExc_ValueError,
- "quaternion[begin:end] = []: "
- "size mismatch in slice assignment");
- return -1;
- }
-
- /* parsed well - now set in vector */
- for (i = 0; i < size; i++) {
- self->quat[begin + i] = quat[i];
- }
-
- (void)BaseMath_WriteCallback(self);
- return 0;
+ int i, size;
+ float quat[QUAT_SIZE];
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ CLAMP(begin, 0, QUAT_SIZE);
+ if (end < 0) {
+ end = (QUAT_SIZE + 1) + end;
+ }
+ CLAMP(end, 0, QUAT_SIZE);
+ begin = MIN2(begin, end);
+
+ if ((size = mathutils_array_parse(
+ quat, 0, QUAT_SIZE, seq, "mathutils.Quaternion[begin:end] = []")) == -1) {
+ return -1;
+ }
+
+ if (size != (end - begin)) {
+ PyErr_SetString(PyExc_ValueError,
+ "quaternion[begin:end] = []: "
+ "size mismatch in slice assignment");
+ return -1;
+ }
+
+ /* parsed well - now set in vector */
+ for (i = 0; i < size; i++) {
+ self->quat[begin + i] = quat[i];
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
-
static PyObject *Quaternion_subscript(QuaternionObject *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 += QUAT_SIZE;
- }
- return Quaternion_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return Quaternion_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with quaternions");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "quaternion indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ 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 += QUAT_SIZE;
+ }
+ return Quaternion_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return Quaternion_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternions");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "quaternion indices must be integers, not %.200s",
+ Py_TYPE(item)->tp_name);
+ return NULL;
+ }
}
-
static int Quaternion_ass_subscript(QuaternionObject *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 += QUAT_SIZE;
- }
- return Quaternion_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
-
- if (step == 1) {
- return Quaternion_ass_slice(self, start, stop, value);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with quaternion");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "quaternion indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ 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 += QUAT_SIZE;
+ }
+ return Quaternion_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Quaternion_ass_slice(self, start, stop, value);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternion");
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "quaternion indices must be integers, not %.200s",
+ Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
/* ------------------------NUMERIC PROTOCOLS---------------------- */
@@ -822,757 +804,793 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb
/* addition */
static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
{
- float quat[QUAT_SIZE];
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
- PyErr_Format(PyExc_TypeError,
- "Quaternion addition: (%s + %s) "
- "invalid type for this operation",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
- }
- quat1 = (QuaternionObject *)q1;
- quat2 = (QuaternionObject *)q2;
-
- if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
-
- add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
- return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
+ float quat[QUAT_SIZE];
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Quaternion addition: (%s + %s) "
+ "invalid type for this operation",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
+ }
+ quat1 = (QuaternionObject *)q1;
+ quat2 = (QuaternionObject *)q2;
+
+ if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+
+ add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
/* ------------------------obj - obj------------------------------ */
/* subtraction */
static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
{
- int x;
- float quat[QUAT_SIZE];
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
- PyErr_Format(PyExc_TypeError,
- "Quaternion subtraction: (%s - %s) "
- "invalid type for this operation",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
- }
-
- quat1 = (QuaternionObject *)q1;
- quat2 = (QuaternionObject *)q2;
-
- if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
-
- for (x = 0; x < QUAT_SIZE; x++) {
- quat[x] = quat1->quat[x] - quat2->quat[x];
- }
-
- return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
+ int x;
+ float quat[QUAT_SIZE];
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
+ PyErr_Format(PyExc_TypeError,
+ "Quaternion subtraction: (%s - %s) "
+ "invalid type for this operation",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
+ }
+
+ quat1 = (QuaternionObject *)q1;
+ quat2 = (QuaternionObject *)q2;
+
+ if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+
+ for (x = 0; x < QUAT_SIZE; x++) {
+ quat[x] = quat1->quat[x] - quat2->quat[x];
+ }
+
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
{
- float tquat[4];
- copy_qt_qt(tquat, quat->quat);
- mul_qt_fl(tquat, scalar);
- return Quaternion_CreatePyObject(tquat, Py_TYPE(quat));
+ float tquat[4];
+ copy_qt_qt(tquat, quat->quat);
+ mul_qt_fl(tquat, scalar);
+ return Quaternion_CreatePyObject(tquat, Py_TYPE(quat));
}
/*------------------------obj * obj------------------------------
* multiplication */
static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
{
- float scalar;
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (QuaternionObject_Check(q1)) {
- quat1 = (QuaternionObject *)q1;
- if (BaseMath_ReadCallback(quat1) == -1) {
- return NULL;
- }
- }
- if (QuaternionObject_Check(q2)) {
- quat2 = (QuaternionObject *)q2;
- if (BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
- }
-
- if (quat1 && quat2) { /* QUAT * QUAT (element-wise product) */
+ float scalar;
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (QuaternionObject_Check(q1)) {
+ quat1 = (QuaternionObject *)q1;
+ if (BaseMath_ReadCallback(quat1) == -1) {
+ return NULL;
+ }
+ }
+ if (QuaternionObject_Check(q2)) {
+ quat2 = (QuaternionObject *)q2;
+ if (BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (quat1 && quat2) { /* QUAT * QUAT (element-wise product) */
#ifdef USE_MATHUTILS_ELEM_MUL
- float quat[QUAT_SIZE];
- mul_vn_vnvn(quat, quat1->quat, quat2->quat, QUAT_SIZE);
- return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
+ float quat[QUAT_SIZE];
+ mul_vn_vnvn(quat, quat1->quat, quat2->quat, QUAT_SIZE);
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
#endif
- }
- /* the only case this can happen (for a supported type is "FLOAT * QUAT") */
- else if (quat2) { /* FLOAT * QUAT */
- if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
- return quat_mul_float(quat2, scalar);
- }
- }
- else if (quat1) { /* QUAT * FLOAT */
- if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
- return quat_mul_float(quat1, scalar);
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
+ }
+ /* the only case this can happen (for a supported type is "FLOAT * QUAT") */
+ else if (quat2) { /* FLOAT * QUAT */
+ if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
+ return quat_mul_float(quat2, scalar);
+ }
+ }
+ else if (quat1) { /* QUAT * FLOAT */
+ if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
+ return quat_mul_float(quat1, scalar);
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
}
/*------------------------obj *= obj------------------------------
* inplace multiplication */
static PyObject *Quaternion_imul(PyObject *q1, PyObject *q2)
{
- float scalar;
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (QuaternionObject_Check(q1)) {
- quat1 = (QuaternionObject *)q1;
- if (BaseMath_ReadCallback(quat1) == -1) {
- return NULL;
- }
- }
- if (QuaternionObject_Check(q2)) {
- quat2 = (QuaternionObject *)q2;
- if (BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
- }
-
- if (quat1 && quat2) { /* QUAT *= QUAT (inplace element-wise product) */
+ float scalar;
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (QuaternionObject_Check(q1)) {
+ quat1 = (QuaternionObject *)q1;
+ if (BaseMath_ReadCallback(quat1) == -1) {
+ return NULL;
+ }
+ }
+ if (QuaternionObject_Check(q2)) {
+ quat2 = (QuaternionObject *)q2;
+ if (BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (quat1 && quat2) { /* QUAT *= QUAT (inplace element-wise product) */
#ifdef USE_MATHUTILS_ELEM_MUL
- mul_vn_vn(quat1->quat, quat2->quat, QUAT_SIZE);
+ mul_vn_vn(quat1->quat, quat2->quat, QUAT_SIZE);
#else
- PyErr_Format(PyExc_TypeError,
- "Inplace element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "Inplace element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
#endif
- }
- else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
- /* QUAT *= FLOAT */
- mul_qt_fl(quat1->quat, scalar);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(quat1);
- Py_INCREF(q1);
- return q1;
+ }
+ else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
+ /* QUAT *= FLOAT */
+ mul_qt_fl(quat1->quat, scalar);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(quat1);
+ Py_INCREF(q1);
+ return q1;
}
/*------------------------obj @ obj------------------------------
* quaternion multiplication */
static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2)
{
- float quat[QUAT_SIZE];
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (QuaternionObject_Check(q1)) {
- quat1 = (QuaternionObject *)q1;
- if (BaseMath_ReadCallback(quat1) == -1) {
- return NULL;
- }
- }
- if (QuaternionObject_Check(q2)) {
- quat2 = (QuaternionObject *)q2;
- if (BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
- }
-
- if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */
- mul_qt_qtqt(quat, quat1->quat, quat2->quat);
- return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
- }
- else if (quat1) {
- /* QUAT @ VEC */
- if (VectorObject_Check(q2)) {
- VectorObject *vec2 = (VectorObject *)q2;
- float tvec[3];
-
- if (vec2->size != 3) {
- PyErr_SetString(PyExc_ValueError,
- "Vector multiplication: "
- "only 3D vector rotations (with quats) "
- "currently supported");
- return NULL;
- }
- if (BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
-
- copy_v3_v3(tvec, vec2->vec);
- mul_qt_v3(quat1->quat, tvec);
-
- return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec2));
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Quaternion multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
+ float quat[QUAT_SIZE];
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (QuaternionObject_Check(q1)) {
+ quat1 = (QuaternionObject *)q1;
+ if (BaseMath_ReadCallback(quat1) == -1) {
+ return NULL;
+ }
+ }
+ if (QuaternionObject_Check(q2)) {
+ quat2 = (QuaternionObject *)q2;
+ if (BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */
+ mul_qt_qtqt(quat, quat1->quat, quat2->quat);
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
+ }
+ else if (quat1) {
+ /* QUAT @ VEC */
+ if (VectorObject_Check(q2)) {
+ VectorObject *vec2 = (VectorObject *)q2;
+ float tvec[3];
+
+ if (vec2->size != 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector multiplication: "
+ "only 3D vector rotations (with quats) "
+ "currently supported");
+ return NULL;
+ }
+ if (BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+
+ copy_v3_v3(tvec, vec2->vec);
+ mul_qt_v3(quat1->quat, tvec);
+
+ return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec2));
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Quaternion multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
}
/*------------------------obj @= obj------------------------------
* inplace quaternion multiplication */
static PyObject *Quaternion_imatmul(PyObject *q1, PyObject *q2)
{
- float quat[QUAT_SIZE];
- QuaternionObject *quat1 = NULL, *quat2 = NULL;
-
- if (QuaternionObject_Check(q1)) {
- quat1 = (QuaternionObject *)q1;
- if (BaseMath_ReadCallback(quat1) == -1) {
- return NULL;
- }
- }
- if (QuaternionObject_Check(q2)) {
- quat2 = (QuaternionObject *)q2;
- if (BaseMath_ReadCallback(quat2) == -1) {
- return NULL;
- }
- }
-
- if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */
- mul_qt_qtqt(quat, quat1->quat, quat2->quat);
- copy_qt_qt(quat1->quat, quat);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Inplace quaternion multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(quat1);
- Py_INCREF(q1);
- return q1;
+ float quat[QUAT_SIZE];
+ QuaternionObject *quat1 = NULL, *quat2 = NULL;
+
+ if (QuaternionObject_Check(q1)) {
+ quat1 = (QuaternionObject *)q1;
+ if (BaseMath_ReadCallback(quat1) == -1) {
+ return NULL;
+ }
+ }
+ if (QuaternionObject_Check(q2)) {
+ quat2 = (QuaternionObject *)q2;
+ if (BaseMath_ReadCallback(quat2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */
+ mul_qt_qtqt(quat, quat1->quat, quat2->quat);
+ copy_qt_qt(quat1->quat, quat);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Inplace quaternion multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(q1)->tp_name,
+ Py_TYPE(q2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(quat1);
+ Py_INCREF(q1);
+ return q1;
}
/* -obj
* returns the negative of this object*/
static PyObject *Quaternion_neg(QuaternionObject *self)
{
- float tquat[QUAT_SIZE];
+ float tquat[QUAT_SIZE];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- negate_v4_v4(tquat, self->quat);
- return Quaternion_CreatePyObject(tquat, Py_TYPE(self));
+ negate_v4_v4(tquat, self->quat);
+ return Quaternion_CreatePyObject(tquat, Py_TYPE(self));
}
-
/* -----------------PROTOCOL DECLARATIONS-------------------------- */
static PySequenceMethods Quaternion_SeqMethods = {
- (lenfunc) Quaternion_len, /* sq_length */
- (binaryfunc) NULL, /* sq_concat */
- (ssizeargfunc) NULL, /* sq_repeat */
- (ssizeargfunc) Quaternion_item, /* sq_item */
- (ssizessizeargfunc) NULL, /* sq_slice, deprecated */
- (ssizeobjargproc) Quaternion_ass_item, /* sq_ass_item */
- (ssizessizeobjargproc) NULL, /* sq_ass_slice, deprecated */
- (objobjproc) NULL, /* sq_contains */
- (binaryfunc) NULL, /* sq_inplace_concat */
- (ssizeargfunc) NULL, /* sq_inplace_repeat */
+ (lenfunc)Quaternion_len, /* sq_length */
+ (binaryfunc)NULL, /* sq_concat */
+ (ssizeargfunc)NULL, /* sq_repeat */
+ (ssizeargfunc)Quaternion_item, /* sq_item */
+ (ssizessizeargfunc)NULL, /* sq_slice, deprecated */
+ (ssizeobjargproc)Quaternion_ass_item, /* 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 Quaternion_AsMapping = {
- (lenfunc)Quaternion_len,
- (binaryfunc)Quaternion_subscript,
- (objobjargproc)Quaternion_ass_subscript,
+ (lenfunc)Quaternion_len,
+ (binaryfunc)Quaternion_subscript,
+ (objobjargproc)Quaternion_ass_subscript,
};
static PyNumberMethods Quaternion_NumMethods = {
- (binaryfunc) Quaternion_add, /*nb_add*/
- (binaryfunc) Quaternion_sub, /*nb_subtract*/
- (binaryfunc) Quaternion_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc) Quaternion_neg, /*nb_negative*/
- (unaryfunc) Quaternion_copy,/*tp_positive*/
- (unaryfunc) 0, /*tp_absolute*/
- (inquiry) 0, /*tp_bool*/
- (unaryfunc) 0, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)0, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- NULL, /* nb_inplace_add */
- NULL, /* nb_inplace_subtract */
- (binaryfunc) Quaternion_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) Quaternion_matmul, /* nb_matrix_multiply */
- (binaryfunc) Quaternion_imatmul, /* nb_inplace_matrix_multiply */
+ (binaryfunc)Quaternion_add, /*nb_add*/
+ (binaryfunc)Quaternion_sub, /*nb_subtract*/
+ (binaryfunc)Quaternion_mul, /*nb_multiply*/
+ NULL, /*nb_remainder*/
+ NULL, /*nb_divmod*/
+ NULL, /*nb_power*/
+ (unaryfunc)Quaternion_neg, /*nb_negative*/
+ (unaryfunc)Quaternion_copy, /*tp_positive*/
+ (unaryfunc)0, /*tp_absolute*/
+ (inquiry)0, /*tp_bool*/
+ (unaryfunc)0, /*nb_invert*/
+ NULL, /*nb_lshift*/
+ (binaryfunc)0, /*nb_rshift*/
+ NULL, /*nb_and*/
+ NULL, /*nb_xor*/
+ NULL, /*nb_or*/
+ NULL, /*nb_int*/
+ NULL, /*nb_reserved*/
+ NULL, /*nb_float*/
+ NULL, /* nb_inplace_add */
+ NULL, /* nb_inplace_subtract */
+ (binaryfunc)Quaternion_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)Quaternion_matmul, /* nb_matrix_multiply */
+ (binaryfunc)Quaternion_imatmul, /* nb_inplace_matrix_multiply */
};
-PyDoc_STRVAR(Quaternion_axis_doc,
-"Quaternion axis value.\n\n:type: float"
-);
+PyDoc_STRVAR(Quaternion_axis_doc, "Quaternion axis value.\n\n:type: float");
static PyObject *Quaternion_axis_get(QuaternionObject *self, void *type)
{
- return Quaternion_item(self, POINTER_AS_INT(type));
+ return Quaternion_item(self, POINTER_AS_INT(type));
}
static int Quaternion_axis_set(QuaternionObject *self, PyObject *value, void *type)
{
- return Quaternion_ass_item(self, POINTER_AS_INT(type), value);
+ return Quaternion_ass_item(self, POINTER_AS_INT(type), value);
}
-PyDoc_STRVAR(Quaternion_magnitude_doc,
-"Size of the quaternion (read-only).\n\n:type: float"
-);
+PyDoc_STRVAR(Quaternion_magnitude_doc, "Size of the quaternion (read-only).\n\n:type: float");
static PyObject *Quaternion_magnitude_get(QuaternionObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(sqrtf(dot_qtqt(self->quat, self->quat)));
+ return PyFloat_FromDouble(sqrtf(dot_qtqt(self->quat, self->quat)));
}
-PyDoc_STRVAR(Quaternion_angle_doc,
-"Angle of the quaternion.\n\n:type: float"
-);
+PyDoc_STRVAR(Quaternion_angle_doc, "Angle of the quaternion.\n\n:type: float");
static PyObject *Quaternion_angle_get(QuaternionObject *self, void *UNUSED(closure))
{
- float tquat[4];
- float angle;
+ float tquat[4];
+ float angle;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- normalize_qt_qt(tquat, self->quat);
+ normalize_qt_qt(tquat, self->quat);
- angle = 2.0f * saacos(tquat[0]);
+ angle = 2.0f * saacos(tquat[0]);
- quat__axis_angle_sanitize(NULL, &angle);
+ quat__axis_angle_sanitize(NULL, &angle);
- return PyFloat_FromDouble(angle);
+ return PyFloat_FromDouble(angle);
}
static int Quaternion_angle_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
{
- float tquat[4];
- float len;
+ float tquat[4];
+ float len;
- float axis[3], angle_dummy;
- float angle;
+ float axis[3], angle_dummy;
+ float angle;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- len = normalize_qt_qt(tquat, self->quat);
- quat_to_axis_angle(axis, &angle_dummy, tquat);
+ len = normalize_qt_qt(tquat, self->quat);
+ quat_to_axis_angle(axis, &angle_dummy, tquat);
- angle = PyFloat_AsDouble(value);
+ angle = PyFloat_AsDouble(value);
- if (angle == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "Quaternion.angle = value: float expected");
- return -1;
- }
+ if (angle == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError, "Quaternion.angle = value: float expected");
+ return -1;
+ }
- angle = angle_wrap_rad(angle);
+ angle = angle_wrap_rad(angle);
- quat__axis_angle_sanitize(axis, &angle);
+ quat__axis_angle_sanitize(axis, &angle);
- axis_angle_to_quat(self->quat, axis, angle);
- mul_qt_fl(self->quat, len);
+ axis_angle_to_quat(self->quat, axis, angle);
+ mul_qt_fl(self->quat, len);
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
-PyDoc_STRVAR(Quaternion_axis_vector_doc,
-"Quaternion axis as a vector.\n\n:type: :class:`Vector`"
-);
+PyDoc_STRVAR(Quaternion_axis_vector_doc, "Quaternion axis as a vector.\n\n:type: :class:`Vector`");
static PyObject *Quaternion_axis_vector_get(QuaternionObject *self, void *UNUSED(closure))
{
- float tquat[4];
+ float tquat[4];
- float axis[3];
- float angle_dummy;
+ float axis[3];
+ float angle_dummy;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- normalize_qt_qt(tquat, self->quat);
- quat_to_axis_angle(axis, &angle_dummy, tquat);
+ normalize_qt_qt(tquat, self->quat);
+ quat_to_axis_angle(axis, &angle_dummy, tquat);
- quat__axis_angle_sanitize(axis, NULL);
+ quat__axis_angle_sanitize(axis, NULL);
- return Vector_CreatePyObject(axis, 3, NULL);
+ return Vector_CreatePyObject(axis, 3, NULL);
}
-static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
+static int Quaternion_axis_vector_set(QuaternionObject *self,
+ PyObject *value,
+ void *UNUSED(closure))
{
- float tquat[4];
- float len;
+ float tquat[4];
+ float len;
- float axis[3];
- float angle;
+ float axis[3];
+ float angle;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- len = normalize_qt_qt(tquat, self->quat);
- quat_to_axis_angle(axis, &angle, tquat); /* axis value is unused */
+ len = normalize_qt_qt(tquat, self->quat);
+ quat_to_axis_angle(axis, &angle, tquat); /* axis value is unused */
- if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1) {
- return -1;
- }
+ if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1) {
+ return -1;
+ }
- quat__axis_angle_sanitize(axis, &angle);
+ quat__axis_angle_sanitize(axis, &angle);
- axis_angle_to_quat(self->quat, axis, angle);
- mul_qt_fl(self->quat, len);
+ axis_angle_to_quat(self->quat, axis, angle);
+ mul_qt_fl(self->quat, len);
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
/* ----------------------------------mathutils.Quaternion() -------------- */
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *seq = NULL;
- double angle = 0.0f;
- float quat[QUAT_SIZE];
- unit_qt(quat);
-
- if (kwds && PyDict_Size(kwds)) {
- PyErr_SetString(PyExc_TypeError,
- "mathutils.Quaternion(): "
- "takes no keyword args");
- return NULL;
- }
-
- if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) {
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- break;
- case 1:
- {
- int size;
-
- if ((size = mathutils_array_parse(quat, 3, QUAT_SIZE, seq, "mathutils.Quaternion()")) == -1) {
- return NULL;
- }
-
- if (size == 4) {
- /* 4d: Quaternion (common case) */
- }
- else {
- /* 3d: Interpret as exponential map */
- BLI_assert(size == 3);
- expmap_to_quat(quat, quat);
- }
-
- break;
- }
- case 2:
- {
- float axis[3];
- if (mathutils_array_parse(axis, 3, 3, seq, "mathutils.Quaternion()") == -1) {
- return NULL;
- }
- angle = angle_wrap_rad(angle); /* clamp because of precision issues */
- axis_angle_to_quat(quat, axis, angle);
- break;
- /* PyArg_ParseTuple assures no more than 2 */
- }
- }
- return Quaternion_CreatePyObject(quat, type);
+ PyObject *seq = NULL;
+ double angle = 0.0f;
+ float quat[QUAT_SIZE];
+ unit_qt(quat);
+
+ if (kwds && PyDict_Size(kwds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "mathutils.Quaternion(): "
+ "takes no keyword args");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle)) {
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ break;
+ case 1: {
+ int size;
+
+ if ((size = mathutils_array_parse(quat, 3, QUAT_SIZE, seq, "mathutils.Quaternion()")) ==
+ -1) {
+ return NULL;
+ }
+
+ if (size == 4) {
+ /* 4d: Quaternion (common case) */
+ }
+ else {
+ /* 3d: Interpret as exponential map */
+ BLI_assert(size == 3);
+ expmap_to_quat(quat, quat);
+ }
+
+ break;
+ }
+ case 2: {
+ float axis[3];
+ if (mathutils_array_parse(axis, 3, 3, seq, "mathutils.Quaternion()") == -1) {
+ return NULL;
+ }
+ angle = angle_wrap_rad(angle); /* clamp because of precision issues */
+ axis_angle_to_quat(quat, axis, angle);
+ break;
+ /* PyArg_ParseTuple assures no more than 2 */
+ }
+ }
+ return Quaternion_CreatePyObject(quat, type);
}
static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self)
{
- PyObject *ret = Quaternion_copy(self);
- PyObject *ret_dummy = quat_func(ret);
- if (ret_dummy) {
- Py_DECREF(ret_dummy);
- return ret;
- }
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
+ PyObject *ret = Quaternion_copy(self);
+ PyObject *ret_dummy = quat_func(ret);
+ if (ret_dummy) {
+ Py_DECREF(ret_dummy);
+ return ret;
+ }
+ else { /* error */
+ Py_DECREF(ret);
+ return NULL;
+ }
}
/* axis vector suffers from precision errors, use this function to ensure */
static void quat__axis_angle_sanitize(float axis[3], float *angle)
{
- if (axis) {
- if (is_zero_v3(axis) ||
- !isfinite(axis[0]) ||
- !isfinite(axis[1]) ||
- !isfinite(axis[2]))
- {
- axis[0] = 1.0f;
- axis[1] = 0.0f;
- axis[2] = 0.0f;
- }
- else if (EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
- EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
- EXPP_FloatsAreEqual(axis[2], 0.0f, 10))
- {
- axis[0] = 1.0f;
- }
- }
-
- if (angle) {
- if (!isfinite(*angle)) {
- *angle = 0.0f;
- }
- }
+ if (axis) {
+ if (is_zero_v3(axis) || !isfinite(axis[0]) || !isfinite(axis[1]) || !isfinite(axis[2])) {
+ axis[0] = 1.0f;
+ axis[1] = 0.0f;
+ axis[2] = 0.0f;
+ }
+ else if (EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
+ EXPP_FloatsAreEqual(axis[2], 0.0f, 10)) {
+ axis[0] = 1.0f;
+ }
+ }
+
+ if (angle) {
+ if (!isfinite(*angle)) {
+ *angle = 0.0f;
+ }
+ }
}
/* -----------------------METHOD DEFINITIONS ---------------------- */
static struct PyMethodDef Quaternion_methods[] = {
- /* in place only */
- {"identity", (PyCFunction) Quaternion_identity, METH_NOARGS, Quaternion_identity_doc},
- {"negate", (PyCFunction) Quaternion_negate, METH_NOARGS, Quaternion_negate_doc},
-
- /* operate on original or copy */
- {"conjugate", (PyCFunction) Quaternion_conjugate, METH_NOARGS, Quaternion_conjugate_doc},
- {"conjugated", (PyCFunction) Quaternion_conjugated, METH_NOARGS, Quaternion_conjugated_doc},
-
- {"invert", (PyCFunction) Quaternion_invert, METH_NOARGS, Quaternion_invert_doc},
- {"inverted", (PyCFunction) Quaternion_inverted, METH_NOARGS, Quaternion_inverted_doc},
-
- {"normalize", (PyCFunction) Quaternion_normalize, METH_NOARGS, Quaternion_normalize_doc},
- {"normalized", (PyCFunction) Quaternion_normalized, METH_NOARGS, Quaternion_normalized_doc},
-
- /* return converted representation */
- {"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc},
- {"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc},
- {"to_axis_angle", (PyCFunction) Quaternion_to_axis_angle, METH_NOARGS, Quaternion_to_axis_angle_doc},
- {"to_exponential_map", (PyCFunction) Quaternion_to_exponential_map, METH_NOARGS, Quaternion_to_exponential_map_doc},
-
- /* operation between 2 or more types */
- {"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc},
- {"dot", (PyCFunction) Quaternion_dot, METH_O, Quaternion_dot_doc},
- {"rotation_difference", (PyCFunction) Quaternion_rotation_difference, METH_O, Quaternion_rotation_difference_doc},
- {"slerp", (PyCFunction) Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
- {"rotate", (PyCFunction) Quaternion_rotate, METH_O, Quaternion_rotate_doc},
-
- /* base-math methods */
- {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
-
- {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
- {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
- {"__deepcopy__", (PyCFunction) Quaternion_deepcopy, METH_VARARGS, Quaternion_copy_doc},
- {NULL, NULL, 0, NULL},
+ /* in place only */
+ {"identity", (PyCFunction)Quaternion_identity, METH_NOARGS, Quaternion_identity_doc},
+ {"negate", (PyCFunction)Quaternion_negate, METH_NOARGS, Quaternion_negate_doc},
+
+ /* operate on original or copy */
+ {"conjugate", (PyCFunction)Quaternion_conjugate, METH_NOARGS, Quaternion_conjugate_doc},
+ {"conjugated", (PyCFunction)Quaternion_conjugated, METH_NOARGS, Quaternion_conjugated_doc},
+
+ {"invert", (PyCFunction)Quaternion_invert, METH_NOARGS, Quaternion_invert_doc},
+ {"inverted", (PyCFunction)Quaternion_inverted, METH_NOARGS, Quaternion_inverted_doc},
+
+ {"normalize", (PyCFunction)Quaternion_normalize, METH_NOARGS, Quaternion_normalize_doc},
+ {"normalized", (PyCFunction)Quaternion_normalized, METH_NOARGS, Quaternion_normalized_doc},
+
+ /* return converted representation */
+ {"to_euler", (PyCFunction)Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc},
+ {"to_matrix", (PyCFunction)Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc},
+ {"to_axis_angle",
+ (PyCFunction)Quaternion_to_axis_angle,
+ METH_NOARGS,
+ Quaternion_to_axis_angle_doc},
+ {"to_exponential_map",
+ (PyCFunction)Quaternion_to_exponential_map,
+ METH_NOARGS,
+ Quaternion_to_exponential_map_doc},
+
+ /* operation between 2 or more types */
+ {"cross", (PyCFunction)Quaternion_cross, METH_O, Quaternion_cross_doc},
+ {"dot", (PyCFunction)Quaternion_dot, METH_O, Quaternion_dot_doc},
+ {"rotation_difference",
+ (PyCFunction)Quaternion_rotation_difference,
+ METH_O,
+ Quaternion_rotation_difference_doc},
+ {"slerp", (PyCFunction)Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
+ {"rotate", (PyCFunction)Quaternion_rotate, METH_O, Quaternion_rotate_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
+ {"copy", (PyCFunction)Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
+ {"__copy__", (PyCFunction)Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
+ {"__deepcopy__", (PyCFunction)Quaternion_deepcopy, METH_VARARGS, Quaternion_copy_doc},
+ {NULL, NULL, 0, NULL},
};
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Quaternion_getseters[] = {
- {(char *)"w", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)0},
- {(char *)"x", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)1},
- {(char *)"y", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)2},
- {(char *)"z", (getter)Quaternion_axis_get, (setter)Quaternion_axis_set, Quaternion_axis_doc, (void *)3},
- {(char *)"magnitude", (getter)Quaternion_magnitude_get, (setter)NULL, Quaternion_magnitude_doc, NULL},
- {(char *)"angle", (getter)Quaternion_angle_get, (setter)Quaternion_angle_set, Quaternion_angle_doc, NULL},
- {(char *)"axis", (getter)Quaternion_axis_vector_get, (setter)Quaternion_axis_vector_set, Quaternion_axis_vector_doc, NULL},
- {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
- {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
- {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {(char *)"w",
+ (getter)Quaternion_axis_get,
+ (setter)Quaternion_axis_set,
+ Quaternion_axis_doc,
+ (void *)0},
+ {(char *)"x",
+ (getter)Quaternion_axis_get,
+ (setter)Quaternion_axis_set,
+ Quaternion_axis_doc,
+ (void *)1},
+ {(char *)"y",
+ (getter)Quaternion_axis_get,
+ (setter)Quaternion_axis_set,
+ Quaternion_axis_doc,
+ (void *)2},
+ {(char *)"z",
+ (getter)Quaternion_axis_get,
+ (setter)Quaternion_axis_set,
+ Quaternion_axis_doc,
+ (void *)3},
+ {(char *)"magnitude",
+ (getter)Quaternion_magnitude_get,
+ (setter)NULL,
+ Quaternion_magnitude_doc,
+ NULL},
+ {(char *)"angle",
+ (getter)Quaternion_angle_get,
+ (setter)Quaternion_angle_set,
+ Quaternion_angle_doc,
+ NULL},
+ {(char *)"axis",
+ (getter)Quaternion_axis_vector_get,
+ (setter)Quaternion_axis_vector_set,
+ Quaternion_axis_vector_doc,
+ NULL},
+ {(char *)"is_wrapped",
+ (getter)BaseMathObject_is_wrapped_get,
+ (setter)NULL,
+ BaseMathObject_is_wrapped_doc,
+ NULL},
+ {(char *)"is_frozen",
+ (getter)BaseMathObject_is_frozen_get,
+ (setter)NULL,
+ BaseMathObject_is_frozen_doc,
+ NULL},
+ {(char *)"owner",
+ (getter)BaseMathObject_owner_get,
+ (setter)NULL,
+ BaseMathObject_owner_doc,
+ NULL},
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
PyDoc_STRVAR(quaternion_doc,
-".. class:: Quaternion([seq, [angle]])\n"
-"\n"
-" This object gives access to Quaternions in Blender.\n"
-"\n"
-" :param seq: size 3 or 4\n"
-" :type seq: :class:`Vector`\n"
-" :param angle: rotation angle, in radians\n"
-" :type angle: float\n"
-"\n"
-" The constructor takes arguments in various forms:\n"
-"\n"
-" (), *no args*\n"
-" Create an identity quaternion\n"
-" (*wxyz*)\n"
-" Create a quaternion from a ``(w, x, y, z)`` vector.\n"
-" (*exponential_map*)\n"
-" Create a quaternion from a 3d exponential map vector.\n"
-"\n"
-" .. seealso:: :meth:`to_exponential_map`\n"
-" (*axis, angle*)\n"
-" Create a quaternion representing a rotation of *angle* radians over *axis*.\n"
-"\n"
-" .. seealso:: :meth:`to_axis_angle`\n"
-);
+ ".. class:: Quaternion([seq, [angle]])\n"
+ "\n"
+ " This object gives access to Quaternions in Blender.\n"
+ "\n"
+ " :param seq: size 3 or 4\n"
+ " :type seq: :class:`Vector`\n"
+ " :param angle: rotation angle, in radians\n"
+ " :type angle: float\n"
+ "\n"
+ " The constructor takes arguments in various forms:\n"
+ "\n"
+ " (), *no args*\n"
+ " Create an identity quaternion\n"
+ " (*wxyz*)\n"
+ " Create a quaternion from a ``(w, x, y, z)`` vector.\n"
+ " (*exponential_map*)\n"
+ " Create a quaternion from a 3d exponential map vector.\n"
+ "\n"
+ " .. seealso:: :meth:`to_exponential_map`\n"
+ " (*axis, angle*)\n"
+ " Create a quaternion representing a rotation of *angle* radians over *axis*.\n"
+ "\n"
+ " .. seealso:: :meth:`to_axis_angle`\n");
PyTypeObject quaternion_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "Quaternion", /* tp_name */
- sizeof(QuaternionObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)BaseMathObject_dealloc, /* tp_dealloc */
- NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- (reprfunc) Quaternion_repr, /* tp_repr */
- &Quaternion_NumMethods, /* tp_as_number */
- &Quaternion_SeqMethods, /* tp_as_sequence */
- &Quaternion_AsMapping, /* tp_as_mapping */
- (hashfunc)Quaternion_hash, /* tp_hash */
- NULL, /* tp_call */
+ PyVarObject_HEAD_INIT(NULL, 0) "Quaternion", /* tp_name */
+ sizeof(QuaternionObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)BaseMathObject_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ NULL, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ (reprfunc)Quaternion_repr, /* tp_repr */
+ &Quaternion_NumMethods, /* tp_as_number */
+ &Quaternion_SeqMethods, /* tp_as_sequence */
+ &Quaternion_AsMapping, /* tp_as_mapping */
+ (hashfunc)Quaternion_hash, /* tp_hash */
+ NULL, /* tp_call */
#ifndef MATH_STANDALONE
- (reprfunc) Quaternion_str, /* tp_str */
+ (reprfunc)Quaternion_str, /* tp_str */
#else
- NULL, /* tp_str */
+ NULL, /* tp_str */
#endif
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- quaternion_doc, /* tp_doc */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
- (inquiry)BaseMathObject_clear, /* tp_clear */
- (richcmpfunc)Quaternion_richcmpr, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- Quaternion_methods, /* tp_methods */
- NULL, /* tp_members */
- Quaternion_getseters, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- NULL, /* tp_alloc */
- Quaternion_new, /* tp_new */
- NULL, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- NULL, /* tp_del */
+ NULL, /* tp_getattro */
+ NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ quaternion_doc, /* tp_doc */
+ (traverseproc)BaseMathObject_traverse, /* tp_traverse */
+ (inquiry)BaseMathObject_clear, /* tp_clear */
+ (richcmpfunc)Quaternion_richcmpr, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ NULL, /* tp_iter */
+ NULL, /* tp_iternext */
+ Quaternion_methods, /* tp_methods */
+ NULL, /* tp_members */
+ Quaternion_getseters, /* tp_getset */
+ NULL, /* tp_base */
+ NULL, /* tp_dict */
+ NULL, /* tp_descr_get */
+ NULL, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ NULL, /* tp_init */
+ NULL, /* tp_alloc */
+ Quaternion_new, /* tp_new */
+ NULL, /* tp_free */
+ NULL, /* tp_is_gc */
+ NULL, /* tp_bases */
+ NULL, /* tp_mro */
+ NULL, /* tp_cache */
+ NULL, /* tp_subclasses */
+ NULL, /* tp_weaklist */
+ NULL, /* tp_del */
};
-PyObject *Quaternion_CreatePyObject(
- const float quat[4],
- PyTypeObject *base_type)
+PyObject *Quaternion_CreatePyObject(const float quat[4], PyTypeObject *base_type)
{
- QuaternionObject *self;
- float *quat_alloc;
-
- quat_alloc = PyMem_Malloc(QUAT_SIZE * sizeof(float));
- if (UNLIKELY(quat_alloc == NULL)) {
- PyErr_SetString(PyExc_MemoryError,
- "Quaternion(): "
- "problem allocating data");
- return NULL;
- }
-
- self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
- if (self) {
- self->quat = quat_alloc;
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- /* NEW */
- if (!quat) { /* new empty */
- unit_qt(self->quat);
- }
- else {
- copy_qt_qt(self->quat, quat);
- }
- self->flag = BASE_MATH_FLAG_DEFAULT;
- }
- else {
- PyMem_Free(quat_alloc);
- }
-
- return (PyObject *)self;
+ QuaternionObject *self;
+ float *quat_alloc;
+
+ quat_alloc = PyMem_Malloc(QUAT_SIZE * sizeof(float));
+ if (UNLIKELY(quat_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Quaternion(): "
+ "problem allocating data");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
+ if (self) {
+ self->quat = quat_alloc;
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ /* NEW */
+ if (!quat) { /* new empty */
+ unit_qt(self->quat);
+ }
+ else {
+ copy_qt_qt(self->quat, quat);
+ }
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(quat_alloc);
+ }
+
+ return (PyObject *)self;
}
-PyObject *Quaternion_CreatePyObject_wrap(
- float quat[4],
- PyTypeObject *base_type)
+PyObject *Quaternion_CreatePyObject_wrap(float quat[4], PyTypeObject *base_type)
{
- QuaternionObject *self;
-
- self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
- if (self) {
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- /* WRAP */
- self->quat = quat;
- self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
- }
- return (PyObject *) self;
+ QuaternionObject *self;
+
+ self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ /* WRAP */
+ self->quat = quat;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+ }
+ return (PyObject *)self;
}
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype)
+ unsigned char cb_type,
+ unsigned char cb_subtype)
{
- QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, NULL);
- if (self) {
- Py_INCREF(cb_user);
- self->cb_user = cb_user;
- self->cb_type = cb_type;
- self->cb_subtype = cb_subtype;
- PyObject_GC_Track(self);
- }
-
- return (PyObject *)self;
+ QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, NULL);
+ if (self) {
+ Py_INCREF(cb_user);
+ self->cb_user = cb_user;
+ self->cb_type = cb_type;
+ self->cb_subtype = cb_subtype;
+ PyObject_GC_Track(self);
+ }
+
+ return (PyObject *)self;
}
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h
index a4c55fffccc..bc6bd307ece 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.h
+++ b/source/blender/python/mathutils/mathutils_Quaternion.h
@@ -27,7 +27,7 @@ extern PyTypeObject quaternion_Type;
#define QuaternionObject_CheckExact(v) (Py_TYPE(v) == &quaternion_Type)
typedef struct {
- BASE_MATH_MEMBERS(quat);
+ BASE_MATH_MEMBERS(quat);
} QuaternionObject;
/* struct data contains a pointer to the actual data that the
@@ -36,17 +36,13 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Quaternion_CreatePyObject(
- const float quat[4],
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Quaternion_CreatePyObject_wrap(
- float quat[4],
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-PyObject *Quaternion_CreatePyObject_cb(
- PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype
- ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Quaternion_CreatePyObject(const float quat[4],
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
+PyObject *Quaternion_CreatePyObject_wrap(float quat[4],
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
+ unsigned char cb_type,
+ unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
#endif /* __MATHUTILS_QUATERNION_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 1dd578096f9..7d73f165c1e 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -44,12 +43,14 @@
* used as a sentinel: if it is unset, the axis is not valid. */
#define SWIZZLE_BITS_PER_AXIS 3
#define SWIZZLE_VALID_AXIS 0x4
-#define SWIZZLE_AXIS 0x3
+#define SWIZZLE_AXIS 0x3
static PyObject *Vector_copy(VectorObject *self);
static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args);
static PyObject *Vector_to_tuple_ext(VectorObject *self, int ndigits);
-static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat);
+static int row_vector_multiplication(float rvec[MAX_DIMENSIONS],
+ VectorObject *vec,
+ MatrixObject *mat);
/**
* Supports 2D, 3D, and 4D vector objects both int and float values
@@ -57,803 +58,780 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v
*/
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- float *vec = NULL;
- int size = 3; /* default to a 3D vector */
-
- if (kwds && PyDict_Size(kwds)) {
- PyErr_SetString(PyExc_TypeError,
- "Vector(): "
- "takes no keyword args");
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 0:
- vec = PyMem_Malloc(size * sizeof(float));
-
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- copy_vn_fl(vec, size, 0.0f);
- break;
- case 1:
- if ((size = mathutils_array_parse_alloc(&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
- return NULL;
- }
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "mathutils.Vector(): "
- "more than a single arg given");
- return NULL;
- }
- return Vector_CreatePyObject_alloc(vec, size, type);
+ float *vec = NULL;
+ int size = 3; /* default to a 3D vector */
+
+ if (kwds && PyDict_Size(kwds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector(): "
+ "takes no keyword args");
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 0:
+ vec = PyMem_Malloc(size * sizeof(float));
+
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ copy_vn_fl(vec, size, 0.0f);
+ break;
+ case 1:
+ if ((size = mathutils_array_parse_alloc(
+ &vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "mathutils.Vector(): "
+ "more than a single arg given");
+ return NULL;
+ }
+ return Vector_CreatePyObject_alloc(vec, size, type);
}
static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject *self)
{
- PyObject *ret = Vector_copy(self);
- PyObject *ret_dummy = vec_func(ret);
- if (ret_dummy) {
- Py_DECREF(ret_dummy);
- return (PyObject *)ret;
- }
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
+ PyObject *ret = Vector_copy(self);
+ PyObject *ret_dummy = vec_func(ret);
+ if (ret_dummy) {
+ Py_DECREF(ret_dummy);
+ return (PyObject *)ret;
+ }
+ else { /* error */
+ Py_DECREF(ret);
+ return NULL;
+ }
}
/*-----------------------CLASS-METHODS----------------------------*/
PyDoc_STRVAR(C_Vector_Fill_doc,
-".. classmethod:: Fill(size, fill=0.0)\n"
-"\n"
-" Create a vector of length size with all values set to fill.\n"
-"\n"
-" :arg size: The length of the vector to be created.\n"
-" :type size: int\n"
-" :arg fill: The value used to fill the vector.\n"
-" :type fill: float\n"
-);
+ ".. classmethod:: Fill(size, fill=0.0)\n"
+ "\n"
+ " Create a vector of length size with all values set to fill.\n"
+ "\n"
+ " :arg size: The length of the vector to be created.\n"
+ " :type size: int\n"
+ " :arg fill: The value used to fill the vector.\n"
+ " :type fill: float\n");
static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
{
- float *vec;
- int size;
- float fill = 0.0f;
+ float *vec;
+ int size;
+ float fill = 0.0f;
- if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) {
+ return NULL;
+ }
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
+ return NULL;
+ }
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.Fill(): "
- "problem allocating pointer space");
- return NULL;
- }
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Fill(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- copy_vn_fl(vec, size, fill);
+ copy_vn_fl(vec, size, fill);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Vector_Range_doc,
-".. classmethod:: Range(start=0, stop, step=1)\n"
-"\n"
-" Create a filled with a range of values.\n"
-"\n"
-" :arg start: The start of the range used to fill the vector.\n"
-" :type start: int\n"
-" :arg stop: The end of the range used to fill the vector.\n"
-" :type stop: int\n"
-" :arg step: The step between successive values in the vector.\n"
-" :type step: int\n"
-);
+ ".. classmethod:: Range(start=0, stop, step=1)\n"
+ "\n"
+ " Create a filled with a range of values.\n"
+ "\n"
+ " :arg start: The start of the range used to fill the vector.\n"
+ " :type start: int\n"
+ " :arg stop: The end of the range used to fill the vector.\n"
+ " :type stop: int\n"
+ " :arg step: The step between successive values in the vector.\n"
+ " :type step: int\n");
static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
{
- float *vec;
- int stop, size;
- int start = 0;
- int step = 1;
-
- if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) {
- return NULL;
- }
-
- switch (PyTuple_GET_SIZE(args)) {
- case 1:
- size = start;
- start = 0;
- break;
- case 2:
- if (start >= stop) {
- PyErr_SetString(PyExc_RuntimeError,
- "Start value is larger "
- "than the stop value");
- return NULL;
- }
-
- size = stop - start;
- break;
- default:
- if (start >= stop) {
- PyErr_SetString(PyExc_RuntimeError,
- "Start value is larger "
- "than the stop value");
- return NULL;
- }
-
- size = (stop - start);
-
- if ((size % step) != 0) {
- size += step;
- }
-
- size /= step;
-
- break;
- }
-
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector(): invalid size");
- return NULL;
- }
-
- vec = PyMem_Malloc(size * sizeof(float));
-
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.Range(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- range_vn_fl(vec, size, (float)start, (float)step);
-
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ float *vec;
+ int stop, size;
+ int start = 0;
+ int step = 1;
+
+ if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) {
+ return NULL;
+ }
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 1:
+ size = start;
+ start = 0;
+ break;
+ case 2:
+ if (start >= stop) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Start value is larger "
+ "than the stop value");
+ return NULL;
+ }
+
+ size = stop - start;
+ break;
+ default:
+ if (start >= stop) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Start value is larger "
+ "than the stop value");
+ return NULL;
+ }
+
+ size = (stop - start);
+
+ if ((size % step) != 0) {
+ size += step;
+ }
+
+ size /= step;
+
+ break;
+ }
+
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
+ return NULL;
+ }
+
+ vec = PyMem_Malloc(size * sizeof(float));
+
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Range(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ range_vn_fl(vec, size, (float)start, (float)step);
+
+ return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Vector_Linspace_doc,
-".. classmethod:: Linspace(start, stop, size)\n"
-"\n"
-" Create a vector of the specified size which is filled with linearly spaced values between start and stop values.\n"
-"\n"
-" :arg start: The start of the range used to fill the vector.\n"
-" :type start: int\n"
-" :arg stop: The end of the range used to fill the vector.\n"
-" :type stop: int\n"
-" :arg size: The size of the vector to be created.\n"
-" :type size: int\n"
-);
+ ".. classmethod:: Linspace(start, stop, size)\n"
+ "\n"
+ " Create a vector of the specified size which is filled with linearly spaced "
+ "values between start and stop values.\n"
+ "\n"
+ " :arg start: The start of the range used to fill the vector.\n"
+ " :type start: int\n"
+ " :arg stop: The end of the range used to fill the vector.\n"
+ " :type stop: int\n"
+ " :arg size: The size of the vector to be created.\n"
+ " :type size: int\n");
static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args)
{
- float *vec;
- int size;
- float start, end, step;
+ float *vec;
+ int size;
+ float start, end, step;
- if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) {
+ return NULL;
+ }
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector.Linspace(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector.Linspace(): invalid size");
+ return NULL;
+ }
- step = (end - start) / (float)(size - 1);
+ step = (end - start) / (float)(size - 1);
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.Linspace(): "
- "problem allocating pointer space");
- return NULL;
- }
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Linspace(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- range_vn_fl(vec, size, start, step);
+ range_vn_fl(vec, size, start, step);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
}
-PyDoc_STRVAR(C_Vector_Repeat_doc,
-".. classmethod:: Repeat(vector, size)\n"
-"\n"
-" Create a vector by repeating the values in vector until the required size is reached.\n"
-"\n"
-" :arg tuple: The vector to draw values from.\n"
-" :type tuple: :class:`mathutils.Vector`\n"
-" :arg size: The size of the vector to be created.\n"
-" :type size: int\n"
-);
+PyDoc_STRVAR(
+ C_Vector_Repeat_doc,
+ ".. classmethod:: Repeat(vector, size)\n"
+ "\n"
+ " Create a vector by repeating the values in vector until the required size is reached.\n"
+ "\n"
+ " :arg tuple: The vector to draw values from.\n"
+ " :type tuple: :class:`mathutils.Vector`\n"
+ " :arg size: The size of the vector to be created.\n"
+ " :type size: int\n");
static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
{
- float *vec;
- float *iter_vec = NULL;
- int i, size, value_size;
- PyObject *value;
+ float *vec;
+ float *iter_vec = NULL;
+ int i, size, value_size;
+ PyObject *value;
- if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) {
+ return NULL;
+ }
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector.Repeat(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid size");
+ return NULL;
+ }
- if ((value_size = mathutils_array_parse_alloc(&iter_vec, 2, value,
- "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1)
- {
- return NULL;
- }
+ if ((value_size = mathutils_array_parse_alloc(
+ &iter_vec, 2, value, "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1) {
+ return NULL;
+ }
- if (iter_vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.Repeat(): "
- "problem allocating pointer space");
- return NULL;
- }
+ if (iter_vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Repeat(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(size * sizeof(float));
- if (vec == NULL) {
- PyMem_Free(iter_vec);
- PyErr_SetString(PyExc_MemoryError,
- "Vector.Repeat(): "
- "problem allocating pointer space");
- return NULL;
- }
+ if (vec == NULL) {
+ PyMem_Free(iter_vec);
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.Repeat(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- i = 0;
- while (i < size) {
- vec[i] = iter_vec[i % value_size];
- i++;
- }
+ i = 0;
+ while (i < size) {
+ vec[i] = iter_vec[i % value_size];
+ i++;
+ }
- PyMem_Free(iter_vec);
+ PyMem_Free(iter_vec);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
}
/*-----------------------------METHODS---------------------------- */
PyDoc_STRVAR(Vector_zero_doc,
-".. method:: zero()\n"
-"\n"
-" Set all values to zero.\n"
-);
+ ".. method:: zero()\n"
+ "\n"
+ " Set all values to zero.\n");
static PyObject *Vector_zero(VectorObject *self)
{
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return NULL;
+ }
- copy_vn_fl(self->vec, self->size, 0.0f);
+ copy_vn_fl(self->vec, self->size, 0.0f);
- if (BaseMath_WriteCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return NULL;
+ }
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_normalize_doc,
-".. method:: normalize()\n"
-"\n"
-" Normalize the vector, making the length of the vector always 1.0.\n"
-"\n"
-" .. warning:: Normalizing a vector where all values are zero has no effect.\n"
-"\n"
-" .. note:: Normalize works for vectors of all sizes,\n"
-" however 4D Vectors w axis is left untouched.\n"
-);
+ ".. method:: normalize()\n"
+ "\n"
+ " Normalize the vector, making the length of the vector always 1.0.\n"
+ "\n"
+ " .. warning:: Normalizing a vector where all values are zero has no effect.\n"
+ "\n"
+ " .. note:: Normalize works for vectors of all sizes,\n"
+ " however 4D Vectors w axis is left untouched.\n");
static PyObject *Vector_normalize(VectorObject *self)
{
- int size = (self->size == 4 ? 3 : self->size);
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ int size = (self->size == 4 ? 3 : self->size);
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- normalize_vn(self->vec, size);
+ normalize_vn(self->vec, size);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_normalized_doc,
-".. method:: normalized()\n"
-"\n"
-" Return a new, normalized vector.\n"
-"\n"
-" :return: a normalized copy of the vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: normalized()\n"
+ "\n"
+ " Return a new, normalized vector.\n"
+ "\n"
+ " :return: a normalized copy of the vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_normalized(VectorObject *self)
{
- return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self);
+ return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self);
}
PyDoc_STRVAR(Vector_resize_doc,
-".. method:: resize(size=3)\n"
-"\n"
-" Resize the vector to have size number of elements.\n"
-);
+ ".. method:: resize(size=3)\n"
+ "\n"
+ " Resize the vector to have size number of elements.\n");
static PyObject *Vector_resize(VectorObject *self, PyObject *value)
{
- int size;
-
- if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize(): "
- "cannot resize wrapped data - only python vectors");
- return NULL;
- }
- if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize(): "
- "cannot resize a vector that has an owner");
- return NULL;
- }
-
- if ((size = PyC_Long_AsI32(value)) == -1) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize(size): "
- "expected size argument to be an integer");
- return NULL;
- }
-
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector.resize(): invalid size");
- return NULL;
- }
-
- self->vec = PyMem_Realloc(self->vec, (size * sizeof(float)));
- if (self->vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.resize(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- /* If the vector has increased in length, set all new elements to 0.0f */
- if (size > self->size) {
- copy_vn_fl(self->vec + self->size, size - self->size, 0.0f);
- }
-
- self->size = size;
- Py_RETURN_NONE;
+ int size;
+
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize(): "
+ "cannot resize wrapped data - only python vectors");
+ return NULL;
+ }
+ if (self->cb_user) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize(): "
+ "cannot resize a vector that has an owner");
+ return NULL;
+ }
+
+ if ((size = PyC_Long_AsI32(value)) == -1) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize(size): "
+ "expected size argument to be an integer");
+ return NULL;
+ }
+
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector.resize(): invalid size");
+ return NULL;
+ }
+
+ self->vec = PyMem_Realloc(self->vec, (size * sizeof(float)));
+ if (self->vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.resize(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ /* If the vector has increased in length, set all new elements to 0.0f */
+ if (size > self->size) {
+ copy_vn_fl(self->vec + self->size, size - self->size, 0.0f);
+ }
+
+ self->size = size;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_resized_doc,
-".. method:: resized(size=3)\n"
-"\n"
-" Return a resized copy of the vector with size number of elements.\n"
-"\n"
-" :return: a new vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: resized(size=3)\n"
+ "\n"
+ " Return a resized copy of the vector with size number of elements.\n"
+ "\n"
+ " :return: a new vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_resized(VectorObject *self, PyObject *value)
{
- int size;
- float *vec;
+ int size;
+ float *vec;
- if ((size = PyLong_AsLong(value)) == -1) {
- return NULL;
- }
+ if ((size = PyLong_AsLong(value)) == -1) {
+ return NULL;
+ }
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector.resized(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector.resized(): invalid size");
+ return NULL;
+ }
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.resized(): "
- "problem allocating pointer space");
- return NULL;
- }
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.resized(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- copy_vn_fl(vec, size, 0.0f);
- memcpy(vec, self->vec, self->size * sizeof(float));
+ copy_vn_fl(vec, size, 0.0f);
+ memcpy(vec, self->vec, self->size * sizeof(float));
- return Vector_CreatePyObject_alloc(vec, size, NULL);
+ return Vector_CreatePyObject_alloc(vec, size, NULL);
}
PyDoc_STRVAR(Vector_resize_2d_doc,
-".. method:: resize_2d()\n"
-"\n"
-" Resize the vector to 2D (x, y).\n"
-);
+ ".. method:: resize_2d()\n"
+ "\n"
+ " Resize the vector to 2D (x, y).\n");
static PyObject *Vector_resize_2d(VectorObject *self)
{
- if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_2d(): "
- "cannot resize wrapped data - only python vectors");
- return NULL;
- }
- if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_2d(): "
- "cannot resize a vector that has an owner");
- return NULL;
- }
-
- self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2));
- if (self->vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.resize_2d(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- self->size = 2;
- Py_RETURN_NONE;
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_2d(): "
+ "cannot resize wrapped data - only python vectors");
+ return NULL;
+ }
+ if (self->cb_user) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_2d(): "
+ "cannot resize a vector that has an owner");
+ return NULL;
+ }
+
+ self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2));
+ if (self->vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.resize_2d(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ self->size = 2;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_resize_3d_doc,
-".. method:: resize_3d()\n"
-"\n"
-" Resize the vector to 3D (x, y, z).\n"
-);
+ ".. method:: resize_3d()\n"
+ "\n"
+ " Resize the vector to 3D (x, y, z).\n");
static PyObject *Vector_resize_3d(VectorObject *self)
{
- if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_3d(): "
- "cannot resize wrapped data - only python vectors");
- return NULL;
- }
- if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_3d(): "
- "cannot resize a vector that has an owner");
- return NULL;
- }
-
- self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3));
- if (self->vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.resize_3d(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- if (self->size == 2) {
- self->vec[2] = 0.0f;
- }
-
- self->size = 3;
- Py_RETURN_NONE;
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_3d(): "
+ "cannot resize wrapped data - only python vectors");
+ return NULL;
+ }
+ if (self->cb_user) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_3d(): "
+ "cannot resize a vector that has an owner");
+ return NULL;
+ }
+
+ self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3));
+ if (self->vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.resize_3d(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ if (self->size == 2) {
+ self->vec[2] = 0.0f;
+ }
+
+ self->size = 3;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_resize_4d_doc,
-".. method:: resize_4d()\n"
-"\n"
-" Resize the vector to 4D (x, y, z, w).\n"
-);
+ ".. method:: resize_4d()\n"
+ "\n"
+ " Resize the vector to 4D (x, y, z, w).\n");
static PyObject *Vector_resize_4d(VectorObject *self)
{
- if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_4d(): "
- "cannot resize wrapped data - only python vectors");
- return NULL;
- }
- if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.resize_4d(): "
- "cannot resize a vector that has an owner");
- return NULL;
- }
-
- self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4));
- if (self->vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.resize_4d(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- if (self->size == 2) {
- self->vec[2] = 0.0f;
- self->vec[3] = 1.0f;
- }
- else if (self->size == 3) {
- self->vec[3] = 1.0f;
- }
- self->size = 4;
- Py_RETURN_NONE;
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_4d(): "
+ "cannot resize wrapped data - only python vectors");
+ return NULL;
+ }
+ if (self->cb_user) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.resize_4d(): "
+ "cannot resize a vector that has an owner");
+ return NULL;
+ }
+
+ self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4));
+ if (self->vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector.resize_4d(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ if (self->size == 2) {
+ self->vec[2] = 0.0f;
+ self->vec[3] = 1.0f;
+ }
+ else if (self->size == 3) {
+ self->vec[3] = 1.0f;
+ }
+ self->size = 4;
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_to_2d_doc,
-".. method:: to_2d()\n"
-"\n"
-" Return a 2d copy of the vector.\n"
-"\n"
-" :return: a new vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: to_2d()\n"
+ "\n"
+ " Return a 2d copy of the vector.\n"
+ "\n"
+ " :return: a new vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_to_2d(VectorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Vector_CreatePyObject(self->vec, 2, Py_TYPE(self));
+ return Vector_CreatePyObject(self->vec, 2, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_3d_doc,
-".. method:: to_3d()\n"
-"\n"
-" Return a 3d copy of the vector.\n"
-"\n"
-" :return: a new vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: to_3d()\n"
+ "\n"
+ " Return a 3d copy of the vector.\n"
+ "\n"
+ " :return: a new vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_to_3d(VectorObject *self)
{
- float tvec[3] = {0.0f};
+ float tvec[3] = {0.0f};
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3));
- return Vector_CreatePyObject(tvec, 3, Py_TYPE(self));
+ memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3));
+ return Vector_CreatePyObject(tvec, 3, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_4d_doc,
-".. method:: to_4d()\n"
-"\n"
-" Return a 4d copy of the vector.\n"
-"\n"
-" :return: a new vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: to_4d()\n"
+ "\n"
+ " Return a 4d copy of the vector.\n"
+ "\n"
+ " :return: a new vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_to_4d(VectorObject *self)
{
- float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float tvec[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4));
- return Vector_CreatePyObject(tvec, 4, Py_TYPE(self));
+ memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4));
+ return Vector_CreatePyObject(tvec, 4, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_tuple_doc,
-".. method:: to_tuple(precision=-1)\n"
-"\n"
-" Return this vector as a tuple with.\n"
-"\n"
-" :arg precision: The number to round the value to in [-1, 21].\n"
-" :type precision: int\n"
-" :return: the values of the vector rounded by *precision*\n"
-" :rtype: tuple\n"
-);
+ ".. method:: to_tuple(precision=-1)\n"
+ "\n"
+ " Return this vector as a tuple with.\n"
+ "\n"
+ " :arg precision: The number to round the value to in [-1, 21].\n"
+ " :type precision: int\n"
+ " :return: the values of the vector rounded by *precision*\n"
+ " :rtype: tuple\n");
/* note: BaseMath_ReadCallback must be called beforehand */
static PyObject *Vector_to_tuple_ext(VectorObject *self, int ndigits)
{
- PyObject *ret;
- int i;
+ PyObject *ret;
+ int i;
- ret = PyTuple_New(self->size);
+ ret = PyTuple_New(self->size);
- if (ndigits >= 0) {
- for (i = 0; i < self->size; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits)));
- }
- }
- else {
- for (i = 0; i < self->size; i++) {
- PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i]));
- }
- }
+ if (ndigits >= 0) {
+ for (i = 0; i < self->size; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits)));
+ }
+ }
+ else {
+ for (i = 0; i < self->size; i++) {
+ PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i]));
+ }
+ }
- return ret;
+ return ret;
}
static PyObject *Vector_to_tuple(VectorObject *self, PyObject *args)
{
- int ndigits = 0;
+ int ndigits = 0;
- if (!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "|i:to_tuple", &ndigits)) {
+ return NULL;
+ }
- if (ndigits > 22 || ndigits < 0) {
- PyErr_SetString(PyExc_ValueError,
- "Vector.to_tuple(ndigits): "
- "ndigits must be between 0 and 21");
- return NULL;
- }
+ if (ndigits > 22 || ndigits < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.to_tuple(ndigits): "
+ "ndigits must be between 0 and 21");
+ return NULL;
+ }
- if (PyTuple_GET_SIZE(args) == 0) {
- ndigits = -1;
- }
+ if (PyTuple_GET_SIZE(args) == 0) {
+ ndigits = -1;
+ }
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Vector_to_tuple_ext(self, ndigits);
+ return Vector_to_tuple_ext(self, ndigits);
}
PyDoc_STRVAR(Vector_to_track_quat_doc,
-".. method:: to_track_quat(track, up)\n"
-"\n"
-" Return a quaternion rotation from the vector and the track and up axis.\n"
-"\n"
-" :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
-" :type track: string\n"
-" :arg up: Up axis in ['X', 'Y', 'Z'].\n"
-" :type up: string\n"
-" :return: rotation from the vector and the track and up axis.\n"
-" :rtype: :class:`Quaternion`\n"
-);
+ ".. method:: to_track_quat(track, up)\n"
+ "\n"
+ " Return a quaternion rotation from the vector and the track and up axis.\n"
+ "\n"
+ " :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
+ " :type track: string\n"
+ " :arg up: Up axis in ['X', 'Y', 'Z'].\n"
+ " :type up: string\n"
+ " :return: rotation from the vector and the track and up axis.\n"
+ " :rtype: :class:`Quaternion`\n");
static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
{
- float vec[3], quat[4];
- const char *strack, *sup;
- short track = 2, up = 1;
-
- if (!PyArg_ParseTuple(args, "|ss:to_track_quat", &strack, &sup)) {
- return NULL;
- }
-
- if (self->size != 3) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.to_track_quat(): "
- "only for 3D vectors");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (strack) {
- const char *axis_err_msg = "only X, -X, Y, -Y, Z or -Z for track axis";
-
- if (strlen(strack) == 2) {
- if (strack[0] == '-') {
- switch (strack[1]) {
- case 'X':
- track = 3;
- break;
- case 'Y':
- track = 4;
- break;
- case 'Z':
- track = 5;
- break;
- default:
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
- else {
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
- else if (strlen(strack) == 1) {
- switch (strack[0]) {
- case '-':
- case 'X':
- track = 0;
- break;
- case 'Y':
- track = 1;
- break;
- case 'Z':
- track = 2;
- break;
- default:
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
- else {
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
-
- if (sup) {
- const char *axis_err_msg = "only X, Y or Z for up axis";
- if (strlen(sup) == 1) {
- switch (*sup) {
- case 'X':
- up = 0;
- break;
- case 'Y':
- up = 1;
- break;
- case 'Z':
- up = 2;
- break;
- default:
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
- else {
- PyErr_SetString(PyExc_ValueError, axis_err_msg);
- return NULL;
- }
- }
-
- if (track == up) {
- PyErr_SetString(PyExc_ValueError,
- "Can't have the same axis for track and up");
- return NULL;
- }
-
- /*
- * flip vector around, since vectoquat expect a vector from target to tracking object
- * and the python function expects the inverse (a vector to the target).
- */
- negate_v3_v3(vec, self->vec);
-
- vec_to_quat(quat, vec, track, up);
-
- return Quaternion_CreatePyObject(quat, NULL);
-}
-
-PyDoc_STRVAR(Vector_orthogonal_doc,
-".. method:: orthogonal()\n"
-"\n"
-" Return a perpendicular vector.\n"
-"\n"
-" :return: a new vector 90 degrees from this vector.\n"
-" :rtype: :class:`Vector`\n"
-"\n"
-" .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n"
-);
+ float vec[3], quat[4];
+ const char *strack, *sup;
+ short track = 2, up = 1;
+
+ if (!PyArg_ParseTuple(args, "|ss:to_track_quat", &strack, &sup)) {
+ return NULL;
+ }
+
+ if (self->size != 3) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.to_track_quat(): "
+ "only for 3D vectors");
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (strack) {
+ const char *axis_err_msg = "only X, -X, Y, -Y, Z or -Z for track axis";
+
+ if (strlen(strack) == 2) {
+ if (strack[0] == '-') {
+ switch (strack[1]) {
+ case 'X':
+ track = 3;
+ break;
+ case 'Y':
+ track = 4;
+ break;
+ case 'Z':
+ track = 5;
+ break;
+ default:
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+ else if (strlen(strack) == 1) {
+ switch (strack[0]) {
+ case '-':
+ case 'X':
+ track = 0;
+ break;
+ case 'Y':
+ track = 1;
+ break;
+ case 'Z':
+ track = 2;
+ break;
+ default:
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+
+ if (sup) {
+ const char *axis_err_msg = "only X, Y or Z for up axis";
+ if (strlen(sup) == 1) {
+ switch (*sup) {
+ case 'X':
+ up = 0;
+ break;
+ case 'Y':
+ up = 1;
+ break;
+ case 'Z':
+ up = 2;
+ break;
+ default:
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError, axis_err_msg);
+ return NULL;
+ }
+ }
+
+ if (track == up) {
+ PyErr_SetString(PyExc_ValueError, "Can't have the same axis for track and up");
+ return NULL;
+ }
+
+ /*
+ * flip vector around, since vectoquat expect a vector from target to tracking object
+ * and the python function expects the inverse (a vector to the target).
+ */
+ negate_v3_v3(vec, self->vec);
+
+ vec_to_quat(quat, vec, track, up);
+
+ return Quaternion_CreatePyObject(quat, NULL);
+}
+
+PyDoc_STRVAR(
+ Vector_orthogonal_doc,
+ ".. method:: orthogonal()\n"
+ "\n"
+ " Return a perpendicular vector.\n"
+ "\n"
+ " :return: a new vector 90 degrees from this vector.\n"
+ " :rtype: :class:`Vector`\n"
+ "\n"
+ " .. note:: the axis is undefined, only use when any orthogonal vector is acceptable.\n");
static PyObject *Vector_orthogonal(VectorObject *self)
{
- float vec[3];
+ float vec[3];
- if (self->size > 3) {
- PyErr_SetString(PyExc_TypeError,
- "Vector.orthogonal(): "
- "Vector must be 3D or 2D");
- return NULL;
- }
+ if (self->size > 3) {
+ PyErr_SetString(PyExc_TypeError,
+ "Vector.orthogonal(): "
+ "Vector must be 3D or 2D");
+ return NULL;
+ }
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (self->size == 3) {
- ortho_v3_v3(vec, self->vec);
- }
- else {
- ortho_v2_v2(vec, self->vec);
- }
+ if (self->size == 3) {
+ ortho_v3_v3(vec, self->vec);
+ }
+ else {
+ ortho_v2_v2(vec, self->vec);
+ }
- return Vector_CreatePyObject(vec, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, self->size, Py_TYPE(self));
}
-
/**
* Vector.reflect(mirror): return a reflected vector on the mirror normal.
* <pre>
@@ -861,541 +839,533 @@ static PyObject *Vector_orthogonal(VectorObject *self)
* </pre>
*/
PyDoc_STRVAR(Vector_reflect_doc,
-".. method:: reflect(mirror)\n"
-"\n"
-" Return the reflection vector from the *mirror* argument.\n"
-"\n"
-" :arg mirror: This vector could be a normal from the reflecting surface.\n"
-" :type mirror: :class:`Vector`\n"
-" :return: The reflected vector matching the size of this vector.\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: reflect(mirror)\n"
+ "\n"
+ " Return the reflection vector from the *mirror* argument.\n"
+ "\n"
+ " :arg mirror: This vector could be a normal from the reflecting surface.\n"
+ " :type mirror: :class:`Vector`\n"
+ " :return: The reflected vector matching the size of this vector.\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
{
- int value_size;
- float mirror[3], vec[3];
- float reflect[3] = {0.0f};
- float tvec[MAX_DIMENSIONS];
+ int value_size;
+ float mirror[3], vec[3];
+ float reflect[3] = {0.0f};
+ float tvec[MAX_DIMENSIONS];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if ((value_size = mathutils_array_parse(tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) {
- return NULL;
- }
+ if ((value_size = mathutils_array_parse(
+ tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) {
+ return NULL;
+ }
- if (self->size < 2 || self->size > 4) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D, 3D or 4D");
- return NULL;
- }
+ if (self->size < 2 || self->size > 4) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
+ return NULL;
+ }
- mirror[0] = tvec[0];
- mirror[1] = tvec[1];
- mirror[2] = (value_size > 2) ? tvec[2] : 0.0f;
+ mirror[0] = tvec[0];
+ mirror[1] = tvec[1];
+ mirror[2] = (value_size > 2) ? tvec[2] : 0.0f;
- vec[0] = self->vec[0];
- vec[1] = self->vec[1];
- vec[2] = (value_size > 2) ? self->vec[2] : 0.0f;
+ vec[0] = self->vec[0];
+ vec[1] = self->vec[1];
+ vec[2] = (value_size > 2) ? self->vec[2] : 0.0f;
- normalize_v3(mirror);
- reflect_v3_v3v3(reflect, vec, mirror);
+ normalize_v3(mirror);
+ reflect_v3_v3v3(reflect, vec, mirror);
- return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_cross_doc,
-".. method:: cross(other)\n"
-"\n"
-" Return the cross product of this vector and another.\n"
-"\n"
-" :arg other: The other vector to perform the cross product with.\n"
-" :type other: :class:`Vector`\n"
-" :return: The cross product.\n"
-" :rtype: :class:`Vector` or float when 2D vectors are used\n"
-"\n"
-" .. note:: both vectors must be 2D or 3D\n"
-);
+ ".. method:: cross(other)\n"
+ "\n"
+ " Return the cross product of this vector and another.\n"
+ "\n"
+ " :arg other: The other vector to perform the cross product with.\n"
+ " :type other: :class:`Vector`\n"
+ " :return: The cross product.\n"
+ " :rtype: :class:`Vector` or float when 2D vectors are used\n"
+ "\n"
+ " .. note:: both vectors must be 2D or 3D\n");
static PyObject *Vector_cross(VectorObject *self, PyObject *value)
{
- PyObject *ret;
- float tvec[3];
+ PyObject *ret;
+ float tvec[3];
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (self->size > 3) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D or 3D");
- return NULL;
- }
+ if (self->size > 3) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
+ return NULL;
+ }
- if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(
+ tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
- if (self->size == 3) {
- ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self));
- cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec);
- }
- else {
- /* size == 2 */
- ret = PyFloat_FromDouble(cross_v2v2(self->vec, tvec));
- }
- return ret;
+ if (self->size == 3) {
+ ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self));
+ cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec);
+ }
+ else {
+ /* size == 2 */
+ ret = PyFloat_FromDouble(cross_v2v2(self->vec, tvec));
+ }
+ return ret;
}
PyDoc_STRVAR(Vector_dot_doc,
-".. method:: dot(other)\n"
-"\n"
-" Return the dot product of this vector and another.\n"
-"\n"
-" :arg other: The other vector to perform the dot product with.\n"
-" :type other: :class:`Vector`\n"
-" :return: The dot product.\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. method:: dot(other)\n"
+ "\n"
+ " Return the dot product of this vector and another.\n"
+ "\n"
+ " :arg other: The other vector to perform the dot product with.\n"
+ " :type other: :class:`Vector`\n"
+ " :return: The dot product.\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_dot(VectorObject *self, PyObject *value)
{
- float *tvec;
- PyObject *ret;
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (mathutils_array_parse_alloc(&tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) {
- return NULL;
- }
-
- ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
- PyMem_Free(tvec);
- return ret;
-}
-
-PyDoc_STRVAR(Vector_angle_doc,
-".. function:: angle(other, fallback=None)\n"
-"\n"
-" Return the angle between two vectors.\n"
-"\n"
-" :arg other: another vector to compare the angle with\n"
-" :type other: :class:`Vector`\n"
-" :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
-" (instead of raising a :exc:`ValueError`).\n"
-" :type fallback: any\n"
-" :return: angle in radians or fallback when given\n"
-" :rtype: float\n"
-);
+ float *tvec;
+ PyObject *ret;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse_alloc(
+ &tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
+
+ ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
+ PyMem_Free(tvec);
+ return ret;
+}
+
+PyDoc_STRVAR(
+ Vector_angle_doc,
+ ".. function:: angle(other, fallback=None)\n"
+ "\n"
+ " Return the angle between two vectors.\n"
+ "\n"
+ " :arg other: another vector to compare the angle with\n"
+ " :type other: :class:`Vector`\n"
+ " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
+ " (instead of raising a :exc:`ValueError`).\n"
+ " :type fallback: any\n"
+ " :return: angle in radians or fallback when given\n"
+ " :rtype: float\n");
static PyObject *Vector_angle(VectorObject *self, PyObject *args)
{
- const int size = MIN2(self->size, 3); /* 4D angle makes no sense */
- float tvec[MAX_DIMENSIONS];
- PyObject *value;
- double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
- int x;
- PyObject *fallback = NULL;
-
- if (!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) {
- return NULL;
- }
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- /* don't use clamped size, rule of thumb is vector sizes must match,
- * even though n this case 'w' is ignored */
- if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1) {
- return NULL;
- }
-
- if (self->size > 4) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D, 3D or 4D");
- return NULL;
- }
-
- for (x = 0; x < size; x++) {
- dot_self += (double)self->vec[x] * (double)self->vec[x];
- dot_other += (double)tvec[x] * (double)tvec[x];
- dot += (double)self->vec[x] * (double)tvec[x];
- }
-
- if (!dot_self || !dot_other) {
- /* avoid exception */
- if (fallback) {
- Py_INCREF(fallback);
- return fallback;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.angle(other): "
- "zero length vectors have no valid angle");
- return NULL;
- }
- }
-
- return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other))));
-}
-
-PyDoc_STRVAR(Vector_angle_signed_doc,
-".. function:: angle_signed(other, fallback)\n"
-"\n"
-" Return the signed angle between two 2D vectors (clockwise is positive).\n"
-"\n"
-" :arg other: another vector to compare the angle with\n"
-" :type other: :class:`Vector`\n"
-" :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
-" (instead of raising a :exc:`ValueError`).\n"
-" :type fallback: any\n"
-" :return: angle in radians or fallback when given\n"
-" :rtype: float\n"
-);
+ const int size = MIN2(self->size, 3); /* 4D angle makes no sense */
+ float tvec[MAX_DIMENSIONS];
+ PyObject *value;
+ double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
+ int x;
+ PyObject *fallback = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ /* don't use clamped size, rule of thumb is vector sizes must match,
+ * even though n this case 'w' is ignored */
+ if (mathutils_array_parse(
+ tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
+
+ if (self->size > 4) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
+ return NULL;
+ }
+
+ for (x = 0; x < size; x++) {
+ dot_self += (double)self->vec[x] * (double)self->vec[x];
+ dot_other += (double)tvec[x] * (double)tvec[x];
+ dot += (double)self->vec[x] * (double)tvec[x];
+ }
+
+ if (!dot_self || !dot_other) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.angle(other): "
+ "zero length vectors have no valid angle");
+ return NULL;
+ }
+ }
+
+ return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other))));
+}
+
+PyDoc_STRVAR(
+ Vector_angle_signed_doc,
+ ".. function:: angle_signed(other, fallback)\n"
+ "\n"
+ " Return the signed angle between two 2D vectors (clockwise is positive).\n"
+ "\n"
+ " :arg other: another vector to compare the angle with\n"
+ " :type other: :class:`Vector`\n"
+ " :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
+ " (instead of raising a :exc:`ValueError`).\n"
+ " :type fallback: any\n"
+ " :return: angle in radians or fallback when given\n"
+ " :rtype: float\n");
static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args)
{
- float tvec[2];
-
- PyObject *value;
- PyObject *fallback = NULL;
+ float tvec[2];
- if (!PyArg_ParseTuple(args, "O|O:angle_signed", &value, &fallback)) {
- return NULL;
- }
+ PyObject *value;
+ PyObject *fallback = NULL;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "O|O:angle_signed", &value, &fallback)) {
+ return NULL;
+ }
- if (mathutils_array_parse(tvec, 2, 2, value, "Vector.angle_signed(other), invalid 'other' arg") == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (self->size != 2) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D");
- return NULL;
- }
+ if (mathutils_array_parse(
+ tvec, 2, 2, value, "Vector.angle_signed(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
- if (is_zero_v2(self->vec) || is_zero_v2(tvec)) {
- /* avoid exception */
- if (fallback) {
- Py_INCREF(fallback);
- return fallback;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.angle_signed(other): "
- "zero length vectors have no valid angle");
- return NULL;
- }
- }
+ if (self->size != 2) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 2D");
+ return NULL;
+ }
+ if (is_zero_v2(self->vec) || is_zero_v2(tvec)) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.angle_signed(other): "
+ "zero length vectors have no valid angle");
+ return NULL;
+ }
+ }
- return PyFloat_FromDouble(angle_signed_v2v2(self->vec, tvec));
+ return PyFloat_FromDouble(angle_signed_v2v2(self->vec, tvec));
}
-
PyDoc_STRVAR(Vector_rotation_difference_doc,
-".. function:: rotation_difference(other)\n"
-"\n"
-" Returns a quaternion representing the rotational difference between this\n"
-" vector and another.\n"
-"\n"
-" :arg other: second vector.\n"
-" :type other: :class:`Vector`\n"
-" :return: the rotational difference between the two vectors.\n"
-" :rtype: :class:`Quaternion`\n"
-"\n"
-" .. note:: 2D vectors raise an :exc:`AttributeError`.\n"
-);
+ ".. function:: rotation_difference(other)\n"
+ "\n"
+ " Returns a quaternion representing the rotational difference between this\n"
+ " vector and another.\n"
+ "\n"
+ " :arg other: second vector.\n"
+ " :type other: :class:`Vector`\n"
+ " :return: the rotational difference between the two vectors.\n"
+ " :rtype: :class:`Quaternion`\n"
+ "\n"
+ " .. note:: 2D vectors raise an :exc:`AttributeError`.\n");
static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
{
- float quat[4], vec_a[3], vec_b[3];
+ float quat[4], vec_a[3], vec_b[3];
- if (self->size < 3 || self->size > 4) {
- PyErr_SetString(PyExc_ValueError,
- "vec.difference(value): "
- "expects both vectors to be size 3 or 4");
- return NULL;
- }
+ if (self->size < 3 || self->size > 4) {
+ PyErr_SetString(PyExc_ValueError,
+ "vec.difference(value): "
+ "expects both vectors to be size 3 or 4");
+ return NULL;
+ }
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse(vec_b, 3, MAX_DIMENSIONS, value, "Vector.difference(other), invalid 'other' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(
+ vec_b, 3, MAX_DIMENSIONS, value, "Vector.difference(other), invalid 'other' arg") ==
+ -1) {
+ return NULL;
+ }
- normalize_v3_v3(vec_a, self->vec);
- normalize_v3(vec_b);
+ normalize_v3_v3(vec_a, self->vec);
+ normalize_v3(vec_b);
- rotation_between_vecs_to_quat(quat, vec_a, vec_b);
+ rotation_between_vecs_to_quat(quat, vec_a, vec_b);
- return Quaternion_CreatePyObject(quat, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
PyDoc_STRVAR(Vector_project_doc,
-".. function:: project(other)\n"
-"\n"
-" Return the projection of this vector onto the *other*.\n"
-"\n"
-" :arg other: second vector.\n"
-" :type other: :class:`Vector`\n"
-" :return: the parallel projection vector\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. function:: project(other)\n"
+ "\n"
+ " Return the projection of this vector onto the *other*.\n"
+ "\n"
+ " :arg other: second vector.\n"
+ " :type other: :class:`Vector`\n"
+ " :return: the parallel projection vector\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_project(VectorObject *self, PyObject *value)
{
- const int size = self->size;
- float *tvec;
- double dot = 0.0f, dot2 = 0.0f;
- int x;
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) {
- return NULL;
- }
-
- /* get dot products */
- for (x = 0; x < size; x++) {
- dot += (double)(self->vec[x] * tvec[x]);
- dot2 += (double)(tvec[x] * tvec[x]);
- }
- /* projection */
- dot /= dot2;
- for (x = 0; x < size; x++) {
- tvec[x] *= (float)dot;
- }
- return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
+ const int size = self->size;
+ float *tvec;
+ double dot = 0.0f, dot2 = 0.0f;
+ int x;
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse_alloc(
+ &tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
+
+ /* get dot products */
+ for (x = 0; x < size; x++) {
+ dot += (double)(self->vec[x] * tvec[x]);
+ dot2 += (double)(tvec[x] * tvec[x]);
+ }
+ /* projection */
+ dot /= dot2;
+ for (x = 0; x < size; x++) {
+ tvec[x] *= (float)dot;
+ }
+ return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_lerp_doc,
-".. function:: lerp(other, factor)\n"
-"\n"
-" Returns the interpolation of two vectors.\n"
-"\n"
-" :arg other: value to interpolate with.\n"
-" :type other: :class:`Vector`\n"
-" :arg factor: The interpolation value in [0.0, 1.0].\n"
-" :type factor: float\n"
-" :return: The interpolated vector.\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. function:: lerp(other, factor)\n"
+ "\n"
+ " Returns the interpolation of two vectors.\n"
+ "\n"
+ " :arg other: value to interpolate with.\n"
+ " :type other: :class:`Vector`\n"
+ " :arg factor: The interpolation value in [0.0, 1.0].\n"
+ " :type factor: float\n"
+ " :return: The interpolated vector.\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
{
- const int size = self->size;
- PyObject *value = NULL;
- float fac;
- float *tvec;
+ const int size = self->size;
+ PyObject *value = NULL;
+ float fac;
+ float *tvec;
- if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac)) {
+ return NULL;
+ }
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") ==
+ -1) {
+ return NULL;
+ }
- interp_vn_vn(tvec, self->vec, 1.0f - fac, size);
+ interp_vn_vn(tvec, self->vec, 1.0f - fac, size);
- return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
+ return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_slerp_doc,
-".. function:: slerp(other, factor, fallback=None)\n"
-"\n"
-" Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
-"\n"
-" :arg other: value to interpolate with.\n"
-" :type other: :class:`Vector`\n"
-" :arg factor: The interpolation value typically in [0.0, 1.0].\n"
-" :type factor: float\n"
-" :arg fallback: return this when the vector can't be calculated (zero length vector or direct opposites),\n"
-" (instead of raising a :exc:`ValueError`).\n"
-" :type fallback: any\n"
-" :return: The interpolated vector.\n"
-" :rtype: :class:`Vector`\n"
-);
+ ".. function:: slerp(other, factor, fallback=None)\n"
+ "\n"
+ " Returns the interpolation of two non-zero vectors (spherical coordinates).\n"
+ "\n"
+ " :arg other: value to interpolate with.\n"
+ " :type other: :class:`Vector`\n"
+ " :arg factor: The interpolation value typically in [0.0, 1.0].\n"
+ " :type factor: float\n"
+ " :arg fallback: return this when the vector can't be calculated (zero length "
+ "vector or direct opposites),\n"
+ " (instead of raising a :exc:`ValueError`).\n"
+ " :type fallback: any\n"
+ " :return: The interpolated vector.\n"
+ " :rtype: :class:`Vector`\n");
static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
{
- const int size = self->size;
- PyObject *value = NULL;
- float fac, cosom, w[2];
- float self_vec[3], other_vec[3], ret_vec[3];
- float self_len_sq, other_len_sq;
- int x;
- PyObject *fallback = NULL;
-
- if (!PyArg_ParseTuple(args, "Of|O:slerp", &value, &fac, &fallback)) {
- return NULL;
- }
-
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
-
- if (self->size > 3) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D or 3D");
- return NULL;
- }
-
- if (mathutils_array_parse(other_vec, size, size, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
- return NULL;
- }
-
- self_len_sq = normalize_vn_vn(self_vec, self->vec, size);
- other_len_sq = normalize_vn(other_vec, size);
-
- /* use fallbacks for zero length vectors */
- if (UNLIKELY((self_len_sq < FLT_EPSILON) ||
- (other_len_sq < FLT_EPSILON)))
- {
- /* avoid exception */
- if (fallback) {
- Py_INCREF(fallback);
- return fallback;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.slerp(): "
- "zero length vectors unsupported");
- return NULL;
- }
- }
-
- /* We have sane state, execute slerp */
- cosom = (float)dot_vn_vn(self_vec, other_vec, size);
-
- /* direct opposite, can't slerp */
- if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
- /* avoid exception */
- if (fallback) {
- Py_INCREF(fallback);
- return fallback;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.slerp(): "
- "opposite vectors unsupported");
- return NULL;
- }
- }
-
- interp_dot_slerp(fac, cosom, w);
-
- for (x = 0; x < size; x++) {
- ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
- }
-
- return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self));
+ const int size = self->size;
+ PyObject *value = NULL;
+ float fac, cosom, w[2];
+ float self_vec[3], other_vec[3], ret_vec[3];
+ float self_len_sq, other_len_sq;
+ int x;
+ PyObject *fallback = NULL;
+
+ if (!PyArg_ParseTuple(args, "Of|O:slerp", &value, &fac, &fallback)) {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
+
+ if (self->size > 3) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
+ return NULL;
+ }
+
+ if (mathutils_array_parse(
+ other_vec, size, size, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
+ return NULL;
+ }
+
+ self_len_sq = normalize_vn_vn(self_vec, self->vec, size);
+ other_len_sq = normalize_vn(other_vec, size);
+
+ /* use fallbacks for zero length vectors */
+ if (UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "zero length vectors unsupported");
+ return NULL;
+ }
+ }
+
+ /* We have sane state, execute slerp */
+ cosom = (float)dot_vn_vn(self_vec, other_vec, size);
+
+ /* direct opposite, can't slerp */
+ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "opposite vectors unsupported");
+ return NULL;
+ }
+ }
+
+ interp_dot_slerp(fac, cosom, w);
+
+ for (x = 0; x < size; x++) {
+ ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
+ }
+
+ return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_rotate_doc,
-".. function:: rotate(other)\n"
-"\n"
-" Rotate the vector by a rotation value.\n"
-"\n"
-" :arg other: rotation component of mathutils value\n"
-" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
-);
+ ".. function:: rotate(other)\n"
+ "\n"
+ " Rotate the vector by a rotation value.\n"
+ "\n"
+ " :arg other: rotation component of mathutils value\n"
+ " :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n");
static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
{
- float other_rmat[3][3];
+ float other_rmat[3][3];
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return NULL;
+ }
- if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1) {
- return NULL;
- }
+ if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1) {
+ return NULL;
+ }
- if (self->size < 3 || self->size > 4) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 3D or 4D");
- return NULL;
- }
+ if (self->size < 3 || self->size > 4) {
+ PyErr_SetString(PyExc_ValueError, "Vector must be 3D or 4D");
+ return NULL;
+ }
- mul_m3_v3(other_rmat, self->vec);
+ mul_m3_v3(other_rmat, self->vec);
- (void)BaseMath_WriteCallback(self);
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_copy_doc,
-".. function:: copy()\n"
-"\n"
-" Returns a copy of this vector.\n"
-"\n"
-" :return: A copy of the vector.\n"
-" :rtype: :class:`Vector`\n"
-"\n"
-" .. note:: use this to get a copy of a wrapped vector with\n"
-" no reference to the original data.\n"
-);
+ ".. function:: copy()\n"
+ "\n"
+ " Returns a copy of this vector.\n"
+ "\n"
+ " :return: A copy of the vector.\n"
+ " :rtype: :class:`Vector`\n"
+ "\n"
+ " .. note:: use this to get a copy of a wrapped vector with\n"
+ " no reference to the original data.\n");
static PyObject *Vector_copy(VectorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self));
}
static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args)
{
- if (!PyC_CheckArgs_DeepCopy(args)) {
- return NULL;
- }
- return Vector_copy(self);
+ if (!PyC_CheckArgs_DeepCopy(args)) {
+ return NULL;
+ }
+ return Vector_copy(self);
}
static PyObject *Vector_repr(VectorObject *self)
{
- PyObject *ret, *tuple;
+ PyObject *ret, *tuple;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- tuple = Vector_to_tuple_ext(self, -1);
- ret = PyUnicode_FromFormat("Vector(%R)", tuple);
- Py_DECREF(tuple);
- return ret;
+ tuple = Vector_to_tuple_ext(self, -1);
+ ret = PyUnicode_FromFormat("Vector(%R)", tuple);
+ Py_DECREF(tuple);
+ return ret;
}
#ifndef MATH_STANDALONE
static PyObject *Vector_str(VectorObject *self)
{
- int i;
+ int i;
- DynStr *ds;
+ DynStr *ds;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- ds = BLI_dynstr_new();
+ ds = BLI_dynstr_new();
- BLI_dynstr_append(ds, "<Vector (");
+ BLI_dynstr_append(ds, "<Vector (");
- for (i = 0; i < self->size; i++) {
- BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]);
- }
+ for (i = 0; i < self->size; i++) {
+ BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]);
+ }
- BLI_dynstr_append(ds, ")>");
+ BLI_dynstr_append(ds, ")>");
- return mathutils_dynstr_to_py(ds); /* frees ds */
+ return mathutils_dynstr_to_py(ds); /* frees ds */
}
#endif
@@ -1403,299 +1373,304 @@ static PyObject *Vector_str(VectorObject *self)
/* sequence length len(vector) */
static int Vector_len(VectorObject *self)
{
- return self->size;
+ return self->size;
}
/* sequence accessor (get): vector[index] */
static PyObject *vector_item_internal(VectorObject *self, int i, const bool is_attr)
{
- if (i < 0) {
- i = self->size - i;
- }
+ if (i < 0) {
+ i = self->size - i;
+ }
- if (i < 0 || i >= self->size) {
- if (is_attr) {
- PyErr_Format(PyExc_AttributeError,
- "Vector.%c: unavailable on %dd vector",
- *(((char *)"xyzw") + i), self->size);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "vector[index]: out of range");
- }
- return NULL;
- }
+ if (i < 0 || i >= self->size) {
+ if (is_attr) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector.%c: unavailable on %dd vector",
+ *(((char *)"xyzw") + i),
+ self->size);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "vector[index]: out of range");
+ }
+ return NULL;
+ }
- if (BaseMath_ReadIndexCallback(self, i) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadIndexCallback(self, i) == -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(self->vec[i]);
+ return PyFloat_FromDouble(self->vec[i]);
}
static PyObject *Vector_item(VectorObject *self, int i)
{
- return vector_item_internal(self, i, false);
+ return vector_item_internal(self, i, false);
}
/* sequence accessor (set): vector[index] = value */
static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const bool is_attr)
{
- float scalar;
-
- if (BaseMath_Prepare_ForWrite(self) == -1) {
- return -1;
- }
-
- if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "vector[index] = x: "
- "assigned value not a number");
- return -1;
- }
-
- if (i < 0) {
- i = self->size - i;
- }
-
- if (i < 0 || i >= self->size) {
- if (is_attr) {
- PyErr_Format(PyExc_AttributeError,
- "Vector.%c = x: unavailable on %dd vector",
- *(((char *)"xyzw") + i), self->size);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "vector[index] = x: "
- "assignment index out of range");
- }
- return -1;
- }
- self->vec[i] = scalar;
-
- if (BaseMath_WriteIndexCallback(self, i) == -1) {
- return -1;
- }
- return 0;
+ float scalar;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ if ((scalar = PyFloat_AsDouble(value)) == -1.0f &&
+ PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "vector[index] = x: "
+ "assigned value not a number");
+ return -1;
+ }
+
+ if (i < 0) {
+ i = self->size - i;
+ }
+
+ if (i < 0 || i >= self->size) {
+ if (is_attr) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector.%c = x: unavailable on %dd vector",
+ *(((char *)"xyzw") + i),
+ self->size);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "vector[index] = x: "
+ "assignment index out of range");
+ }
+ return -1;
+ }
+ self->vec[i] = scalar;
+
+ if (BaseMath_WriteIndexCallback(self, i) == -1) {
+ return -1;
+ }
+ return 0;
}
static int Vector_ass_item(VectorObject *self, int i, PyObject *value)
{
- return vector_ass_item_internal(self, i, value, false);
+ return vector_ass_item_internal(self, i, value, false);
}
/* sequence slice (get): vector[a:b] */
static PyObject *Vector_slice(VectorObject *self, int begin, int end)
{
- PyObject *tuple;
- int count;
+ PyObject *tuple;
+ int count;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- CLAMP(begin, 0, self->size);
- if (end < 0) {
- end = self->size + end + 1;
- }
- CLAMP(end, 0, self->size);
- begin = MIN2(begin, end);
+ CLAMP(begin, 0, self->size);
+ if (end < 0) {
+ end = self->size + end + 1;
+ }
+ CLAMP(end, 0, self->size);
+ begin = MIN2(begin, end);
- tuple = PyTuple_New(end - begin);
- for (count = begin; count < end; count++) {
- PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->vec[count]));
- }
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->vec[count]));
+ }
- return tuple;
+ return tuple;
}
/* sequence slice (set): vector[a:b] = value */
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
{
- int size = 0;
- float *vec = NULL;
+ int size = 0;
+ float *vec = NULL;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- CLAMP(begin, 0, self->size);
- CLAMP(end, 0, self->size);
- begin = MIN2(begin, end);
+ CLAMP(begin, 0, self->size);
+ CLAMP(end, 0, self->size);
+ begin = MIN2(begin, end);
- size = (end - begin);
- if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) {
- return -1;
- }
+ size = (end - begin);
+ if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) {
+ return -1;
+ }
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "vec[:] = seq: "
- "problem allocating pointer space");
- return -1;
- }
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "vec[:] = seq: "
+ "problem allocating pointer space");
+ return -1;
+ }
- /*parsed well - now set in vector*/
- memcpy(self->vec + begin, vec, size * sizeof(float));
+ /*parsed well - now set in vector*/
+ memcpy(self->vec + begin, vec, size * sizeof(float));
- PyMem_Free(vec);
+ PyMem_Free(vec);
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
- return 0;
+ return 0;
}
/* Numeric Protocols */
/* addition: obj + obj */
static PyObject *Vector_add(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float *vec = NULL;
-
- if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
- PyErr_Format(PyExc_AttributeError,
- "Vector addition: (%s + %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- vec1 = (VectorObject *)v1;
- vec2 = (VectorObject *)v2;
-
- if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
-
- /*VECTOR + VECTOR*/
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector addition: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
-
- vec = PyMem_Malloc(vec1->size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
-
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ VectorObject *vec1 = NULL, *vec2 = NULL;
+ float *vec = NULL;
+
+ if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector addition: (%s + %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ vec1 = (VectorObject *)v1;
+ vec2 = (VectorObject *)v2;
+
+ if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+
+ /*VECTOR + VECTOR*/
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector addition: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
+
+ vec = PyMem_Malloc(vec1->size * sizeof(float));
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
+
+ add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
+
+ return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
}
/* addition in-place: obj += obj */
static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
+ VectorObject *vec1 = NULL, *vec2 = NULL;
- if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
- PyErr_Format(PyExc_AttributeError,
- "Vector addition: (%s += %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- vec1 = (VectorObject *)v1;
- vec2 = (VectorObject *)v2;
+ if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector addition: (%s += %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ vec1 = (VectorObject *)v1;
+ vec2 = (VectorObject *)v2;
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector addition: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector addition: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
- if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
- add_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ add_vn_vn(vec1->vec, vec2->vec, vec1->size);
- (void)BaseMath_WriteCallback(vec1);
- Py_INCREF(v1);
- return v1;
+ (void)BaseMath_WriteCallback(vec1);
+ Py_INCREF(v1);
+ return v1;
}
/* subtraction: obj - obj */
static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float *vec;
+ VectorObject *vec1 = NULL, *vec2 = NULL;
+ float *vec;
- if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
- PyErr_Format(PyExc_AttributeError,
- "Vector subtraction: (%s - %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- vec1 = (VectorObject *)v1;
- vec2 = (VectorObject *)v2;
+ if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector subtraction: (%s - %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ vec1 = (VectorObject *)v1;
+ vec2 = (VectorObject *)v2;
- if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector subtraction: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector subtraction: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
- vec = PyMem_Malloc(vec1->size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector(): "
- "problem allocating pointer space");
- return NULL;
- }
+ vec = PyMem_Malloc(vec1->size * sizeof(float));
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating pointer space");
+ return NULL;
+ }
- sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
+ sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
}
/* subtraction in-place: obj -= obj */
static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
+ VectorObject *vec1 = NULL, *vec2 = NULL;
- if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
- PyErr_Format(PyExc_AttributeError,
- "Vector subtraction: (%s -= %s) "
- "invalid type for this operation",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
- vec1 = (VectorObject *)v1;
- vec2 = (VectorObject *)v2;
+ if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
+ PyErr_Format(PyExc_AttributeError,
+ "Vector subtraction: (%s -= %s) "
+ "invalid type for this operation",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+ vec1 = (VectorObject *)v1;
+ vec2 = (VectorObject *)v2;
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector subtraction: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector subtraction: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
- if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
- sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
- (void)BaseMath_WriteCallback(vec1);
- Py_INCREF(v1);
- return v1;
+ (void)BaseMath_WriteCallback(vec1);
+ Py_INCREF(v1);
+ return v1;
}
/*------------------------obj * obj------------------------------
* multiplication */
-
/**
* Column vector multiplication (Matrix * Vector).
* <pre>
@@ -1709,576 +1684,577 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
*/
int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
{
- float vec_cpy[MAX_DIMENSIONS];
- int row, col, z = 0;
+ float vec_cpy[MAX_DIMENSIONS];
+ int row, col, z = 0;
- if (mat->num_col != vec->size) {
- if (mat->num_col == 4 && vec->size == 3) {
- vec_cpy[3] = 1.0f;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "matrix * vector: "
- "len(matrix.col) and len(vector) must be the same, "
- "except for 4x4 matrix * 3D vector.");
- return -1;
- }
- }
+ if (mat->num_col != vec->size) {
+ if (mat->num_col == 4 && vec->size == 3) {
+ vec_cpy[3] = 1.0f;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "matrix * vector: "
+ "len(matrix.col) and len(vector) must be the same, "
+ "except for 4x4 matrix * 3D vector.");
+ return -1;
+ }
+ }
- memcpy(vec_cpy, vec->vec, vec->size * sizeof(float));
+ memcpy(vec_cpy, vec->vec, vec->size * sizeof(float));
- r_vec[3] = 1.0f;
+ r_vec[3] = 1.0f;
- for (row = 0; row < mat->num_row; row++) {
- double dot = 0.0f;
- for (col = 0; col < mat->num_col; col++) {
- dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]);
- }
- r_vec[z++] = (float)dot;
- }
+ for (row = 0; row < mat->num_row; row++) {
+ double dot = 0.0f;
+ for (col = 0; col < mat->num_col; col++) {
+ dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]);
+ }
+ r_vec[z++] = (float)dot;
+ }
- return 0;
+ return 0;
}
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
{
- float *tvec = PyMem_Malloc(vec->size * sizeof(float));
- if (tvec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "vec * float: "
- "problem allocating pointer space");
- return NULL;
- }
+ float *tvec = PyMem_Malloc(vec->size * sizeof(float));
+ if (tvec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "vec * float: "
+ "problem allocating pointer space");
+ return NULL;
+ }
- mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
- return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec));
+ mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
+ return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec));
}
#ifdef USE_MATHUTILS_ELEM_MUL
static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
{
- float *tvec = PyMem_Malloc(vec1->size * sizeof(float));
- if (tvec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "vec * vec: "
- "problem allocating pointer space");
- return NULL;
- }
+ float *tvec = PyMem_Malloc(vec1->size * sizeof(float));
+ if (tvec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "vec * vec: "
+ "problem allocating pointer space");
+ return NULL;
+ }
- mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size);
- return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1));
+ mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size);
+ return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1));
}
#endif
static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float scalar;
-
- if (VectorObject_Check(v1)) {
- vec1 = (VectorObject *)v1;
- if (BaseMath_ReadCallback(vec1) == -1) {
- return NULL;
- }
- }
- if (VectorObject_Check(v2)) {
- vec2 = (VectorObject *)v2;
- if (BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
- }
-
-
- /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
-
- /* make sure v1 is always the vector */
- if (vec1 && vec2) {
+ VectorObject *vec1 = NULL, *vec2 = NULL;
+ float scalar;
+
+ if (VectorObject_Check(v1)) {
+ vec1 = (VectorObject *)v1;
+ if (BaseMath_ReadCallback(vec1) == -1) {
+ return NULL;
+ }
+ }
+ if (VectorObject_Check(v2)) {
+ vec2 = (VectorObject *)v2;
+ if (BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+ }
+
+ /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
+
+ /* make sure v1 is always the vector */
+ if (vec1 && vec2) {
#ifdef USE_MATHUTILS_ELEM_MUL
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_ValueError,
- "Vector multiplication: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
-
- /* element-wise product */
- return vector_mul_vec(vec1, vec2);
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector multiplication: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
+
+ /* element-wise product */
+ return vector_mul_vec(vec1, vec2);
#endif
- }
- else if (vec1) {
- if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */
- return vector_mul_float(vec1, scalar);
- }
- }
- else if (vec2) {
- if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * VEC */
- return vector_mul_float(vec2, scalar);
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ }
+ else if (vec1) {
+ if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */
+ return vector_mul_float(vec1, scalar);
+ }
+ }
+ else if (vec2) {
+ if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * VEC */
+ return vector_mul_float(vec2, scalar);
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
}
/* multiplication in-place: obj *= obj */
static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- float scalar;
-
- if (VectorObject_Check(v1)) {
- vec1 = (VectorObject *)v1;
- if (BaseMath_ReadCallback(vec1) == -1) {
- return NULL;
- }
- }
- if (VectorObject_Check(v2)) {
- vec2 = (VectorObject *)v2;
- if (BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
- }
-
- if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
- return NULL;
- }
-
- /* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */
-
- if (vec1 && vec2) {
+ VectorObject *vec1 = NULL, *vec2 = NULL;
+ float scalar;
+
+ if (VectorObject_Check(v1)) {
+ vec1 = (VectorObject *)v1;
+ if (BaseMath_ReadCallback(vec1) == -1) {
+ return NULL;
+ }
+ }
+ if (VectorObject_Check(v2)) {
+ vec2 = (VectorObject *)v2;
+ if (BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+ }
+
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
+ return NULL;
+ }
+
+ /* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */
+
+ if (vec1 && vec2) {
#ifdef USE_MATHUTILS_ELEM_MUL
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_ValueError,
- "Vector multiplication: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
-
- /* element-wise product inplace */
- mul_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector multiplication: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
+
+ /* element-wise product inplace */
+ mul_vn_vn(vec1->vec, vec2->vec, vec1->size);
#else
- PyErr_Format(PyExc_TypeError,
- "Inplace element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "Inplace element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
#endif
- }
- else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0)) { /* VEC *= FLOAT */
- mul_vn_fl(vec1->vec, vec1->size, scalar);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "Inplace element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
- }
-
- (void)BaseMath_WriteCallback(vec1);
- Py_INCREF(v1);
- return v1;
+ }
+ else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) ==
+ 0)) { /* VEC *= FLOAT */
+ mul_vn_fl(vec1->vec, vec1->size, scalar);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "Inplace element-wise multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
+ }
+
+ (void)BaseMath_WriteCallback(vec1);
+ Py_INCREF(v1);
+ return v1;
}
static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
{
- VectorObject *vec1 = NULL, *vec2 = NULL;
- int vec_size;
-
- if (VectorObject_Check(v1)) {
- vec1 = (VectorObject *)v1;
- if (BaseMath_ReadCallback(vec1) == -1) {
- return NULL;
- }
- }
- if (VectorObject_Check(v2)) {
- vec2 = (VectorObject *)v2;
- if (BaseMath_ReadCallback(vec2) == -1) {
- return NULL;
- }
- }
-
-
- /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
-
- /* make sure v1 is always the vector */
- if (vec1 && vec2) {
- if (vec1->size != vec2->size) {
- PyErr_SetString(PyExc_ValueError,
- "Vector multiplication: "
- "vectors must have the same dimensions for this operation");
- return NULL;
- }
-
- /*dot product*/
- return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size));
- }
- else if (vec1) {
- if (MatrixObject_Check(v2)) {
- /* VEC @ MATRIX */
- float tvec[MAX_DIMENSIONS];
-
- if (BaseMath_ReadCallback((MatrixObject *)v2) == -1) {
- return NULL;
- }
- if (row_vector_multiplication(tvec, vec1, (MatrixObject *)v2) == -1) {
- return NULL;
- }
-
- if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) {
- vec_size = 3;
- }
- else {
- vec_size = ((MatrixObject *)v2)->num_col;
- }
-
- return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1));
- }
- }
-
- PyErr_Format(PyExc_TypeError,
- "Vector multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ VectorObject *vec1 = NULL, *vec2 = NULL;
+ int vec_size;
+
+ if (VectorObject_Check(v1)) {
+ vec1 = (VectorObject *)v1;
+ if (BaseMath_ReadCallback(vec1) == -1) {
+ return NULL;
+ }
+ }
+ if (VectorObject_Check(v2)) {
+ vec2 = (VectorObject *)v2;
+ if (BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+ }
+
+ /* Intentionally don't support (Quaternion) here, uses reverse order instead. */
+
+ /* make sure v1 is always the vector */
+ if (vec1 && vec2) {
+ if (vec1->size != vec2->size) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector multiplication: "
+ "vectors must have the same dimensions for this operation");
+ return NULL;
+ }
+
+ /*dot product*/
+ return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size));
+ }
+ else if (vec1) {
+ if (MatrixObject_Check(v2)) {
+ /* VEC @ MATRIX */
+ float tvec[MAX_DIMENSIONS];
+
+ if (BaseMath_ReadCallback((MatrixObject *)v2) == -1) {
+ return NULL;
+ }
+ if (row_vector_multiplication(tvec, vec1, (MatrixObject *)v2) == -1) {
+ return NULL;
+ }
+
+ if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) {
+ vec_size = 3;
+ }
+ else {
+ vec_size = ((MatrixObject *)v2)->num_col;
+ }
+
+ return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1));
+ }
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ "Vector multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
}
static PyObject *Vector_imatmul(PyObject *v1, PyObject *v2)
{
- PyErr_Format(PyExc_TypeError,
- "Inplace vector multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "Inplace vector multiplication: "
+ "not supported between '%.200s' and '%.200s' types",
+ Py_TYPE(v1)->tp_name,
+ Py_TYPE(v2)->tp_name);
+ return NULL;
}
/* divid: obj / obj */
static PyObject *Vector_div(PyObject *v1, PyObject *v2)
{
- float *vec = NULL, scalar;
- VectorObject *vec1 = NULL;
+ float *vec = NULL, scalar;
+ VectorObject *vec1 = NULL;
- if (!VectorObject_Check(v1)) { /* not a vector */
- PyErr_SetString(PyExc_TypeError,
- "Vector division: "
- "Vector must be divided by a float");
- return NULL;
- }
- vec1 = (VectorObject *)v1; /* vector */
+ if (!VectorObject_Check(v1)) { /* not a vector */
+ PyErr_SetString(PyExc_TypeError,
+ "Vector division: "
+ "Vector must be divided by a float");
+ return NULL;
+ }
+ vec1 = (VectorObject *)v1; /* vector */
- if (BaseMath_ReadCallback(vec1) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(vec1) == -1) {
+ return NULL;
+ }
- if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "Vector division: "
- "Vector must be divided by a float");
- return NULL;
- }
+ if ((scalar = PyFloat_AsDouble(v2)) == -1.0f &&
+ PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "Vector division: "
+ "Vector must be divided by a float");
+ return NULL;
+ }
- if (scalar == 0.0f) {
- PyErr_SetString(PyExc_ZeroDivisionError,
- "Vector division: "
- "divide by zero error");
- return NULL;
- }
+ if (scalar == 0.0f) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "Vector division: "
+ "divide by zero error");
+ return NULL;
+ }
- vec = PyMem_Malloc(vec1->size * sizeof(float));
+ vec = PyMem_Malloc(vec1->size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "vec / value: "
- "problem allocating pointer space");
- return NULL;
- }
+ if (vec == NULL) {
+ PyErr_SetString(PyExc_MemoryError,
+ "vec / value: "
+ "problem allocating pointer space");
+ return NULL;
+ }
- mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f / scalar);
+ mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f / scalar);
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
}
/* divide in-place: obj /= obj */
static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
{
- float scalar;
- VectorObject *vec1 = (VectorObject *)v1;
+ float scalar;
+ VectorObject *vec1 = (VectorObject *)v1;
- if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1) {
+ return NULL;
+ }
- if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
- PyErr_SetString(PyExc_TypeError,
- "Vector division: "
- "Vector must be divided by a float");
- return NULL;
- }
+ if ((scalar = PyFloat_AsDouble(v2)) == -1.0f &&
+ PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError,
+ "Vector division: "
+ "Vector must be divided by a float");
+ return NULL;
+ }
- if (scalar == 0.0f) {
- PyErr_SetString(PyExc_ZeroDivisionError,
- "Vector division: "
- "divide by zero error");
- return NULL;
- }
+ if (scalar == 0.0f) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "Vector division: "
+ "divide by zero error");
+ return NULL;
+ }
- mul_vn_fl(vec1->vec, vec1->size, 1.0f / scalar);
+ mul_vn_fl(vec1->vec, vec1->size, 1.0f / scalar);
- (void)BaseMath_WriteCallback(vec1);
+ (void)BaseMath_WriteCallback(vec1);
- Py_INCREF(v1);
- return v1;
+ Py_INCREF(v1);
+ return v1;
}
/* -obj
* returns the negative of this object*/
static PyObject *Vector_neg(VectorObject *self)
{
- float *tvec;
+ float *tvec;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- tvec = PyMem_Malloc(self->size * sizeof(float));
- negate_vn_vn(tvec, self->vec, self->size);
- return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self));
+ tvec = PyMem_Malloc(self->size * sizeof(float));
+ negate_vn_vn(tvec, self->vec, self->size);
+ return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self));
}
/*------------------------tp_richcmpr
* returns -1 exception, 0 false, 1 true */
static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
{
- VectorObject *vecA = NULL, *vecB = NULL;
- int result = 0;
- double epsilon = 0.000001f;
- double lenA, lenB;
-
- if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)) {
- if (comparison_type == Py_NE) {
- Py_RETURN_TRUE;
- }
- else {
- Py_RETURN_FALSE;
- }
- }
- vecA = (VectorObject *)objectA;
- vecB = (VectorObject *)objectB;
-
- if (BaseMath_ReadCallback(vecA) == -1 || BaseMath_ReadCallback(vecB) == -1) {
- return NULL;
- }
-
- if (vecA->size != vecB->size) {
- if (comparison_type == Py_NE) {
- Py_RETURN_TRUE;
- }
- else {
- Py_RETURN_FALSE;
- }
- }
-
- switch (comparison_type) {
- case Py_LT:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
- if (lenA < lenB) {
- result = 1;
- }
- break;
- case Py_LE:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
- if (lenA < lenB) {
- result = 1;
- }
- else {
- result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
- }
- break;
- case Py_EQ:
- result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
- break;
- case Py_NE:
- result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
- break;
- case Py_GT:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
- if (lenA > lenB) {
- result = 1;
- }
- break;
- case Py_GE:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
- if (lenA > lenB) {
- result = 1;
- }
- else {
- result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
- }
- break;
- default:
- printf("The result of the comparison could not be evaluated");
- break;
- }
- if (result == 1) {
- Py_RETURN_TRUE;
- }
- else {
- Py_RETURN_FALSE;
- }
+ VectorObject *vecA = NULL, *vecB = NULL;
+ int result = 0;
+ double epsilon = 0.000001f;
+ double lenA, lenB;
+
+ if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)) {
+ if (comparison_type == Py_NE) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+ }
+ vecA = (VectorObject *)objectA;
+ vecB = (VectorObject *)objectB;
+
+ if (BaseMath_ReadCallback(vecA) == -1 || BaseMath_ReadCallback(vecB) == -1) {
+ return NULL;
+ }
+
+ if (vecA->size != vecB->size) {
+ if (comparison_type == Py_NE) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+ }
+
+ switch (comparison_type) {
+ case Py_LT:
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
+ if (lenA < lenB) {
+ result = 1;
+ }
+ break;
+ case Py_LE:
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
+ if (lenA < lenB) {
+ result = 1;
+ }
+ else {
+ result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
+ }
+ break;
+ case Py_EQ:
+ result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
+ break;
+ case Py_NE:
+ result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
+ break;
+ case Py_GT:
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
+ if (lenA > lenB) {
+ result = 1;
+ }
+ break;
+ case Py_GE:
+ lenA = len_squared_vn(vecA->vec, vecA->size);
+ lenB = len_squared_vn(vecB->vec, vecB->size);
+ if (lenA > lenB) {
+ result = 1;
+ }
+ else {
+ result = (((lenA + epsilon) > lenB) && ((lenA - epsilon) < lenB));
+ }
+ break;
+ default:
+ printf("The result of the comparison could not be evaluated");
+ break;
+ }
+ if (result == 1) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
}
static Py_hash_t Vector_hash(VectorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return -1;
+ }
- if (BaseMathObject_Prepare_ForHash(self) == -1) {
- return -1;
- }
+ if (BaseMathObject_Prepare_ForHash(self) == -1) {
+ return -1;
+ }
- return mathutils_array_hash(self->vec, self->size);
+ return mathutils_array_hash(self->vec, self->size);
}
/*-----------------PROTCOL DECLARATIONS--------------------------*/
static PySequenceMethods Vector_SeqMethods = {
- (lenfunc) Vector_len, /* sq_length */
- (binaryfunc) NULL, /* sq_concat */
- (ssizeargfunc) NULL, /* sq_repeat */
- (ssizeargfunc) Vector_item, /* sq_item */
- NULL, /* py3 deprecated slice func */
- (ssizeobjargproc) Vector_ass_item, /* sq_ass_item */
- NULL, /* py3 deprecated slice assign func */
- (objobjproc) NULL, /* sq_contains */
- (binaryfunc) NULL, /* sq_inplace_concat */
- (ssizeargfunc) NULL, /* sq_inplace_repeat */
+ (lenfunc)Vector_len, /* sq_length */
+ (binaryfunc)NULL, /* sq_concat */
+ (ssizeargfunc)NULL, /* sq_repeat */
+ (ssizeargfunc)Vector_item, /* sq_item */
+ NULL, /* py3 deprecated slice func */
+ (ssizeobjargproc)Vector_ass_item, /* sq_ass_item */
+ NULL, /* py3 deprecated slice assign func */
+ (objobjproc)NULL, /* sq_contains */
+ (binaryfunc)NULL, /* sq_inplace_concat */
+ (ssizeargfunc)NULL, /* sq_inplace_repeat */
};
static PyObject *Vector_subscript(VectorObject *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->size;
- }
- return Vector_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else if (step == 1) {
- return Vector_slice(self, start, stop);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with vectors");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "vector indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return NULL;
- }
+ 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->size;
+ }
+ return Vector_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return Vector_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
+ }
}
static int Vector_ass_subscript(VectorObject *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->size;
- }
- return Vector_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
-
- if (step == 1) {
- return Vector_ass_slice(self, start, stop, value);
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "slice steps not supported with vectors");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "vector indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
- return -1;
- }
+ 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->size;
+ }
+ return Vector_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1) {
+ return Vector_ass_slice(self, start, stop, value);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(
+ PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
+ }
}
static PyMappingMethods Vector_AsMapping = {
- (lenfunc)Vector_len,
- (binaryfunc)Vector_subscript,
- (objobjargproc)Vector_ass_subscript,
+ (lenfunc)Vector_len,
+ (binaryfunc)Vector_subscript,
+ (objobjargproc)Vector_ass_subscript,
};
-
static PyNumberMethods Vector_NumMethods = {
- (binaryfunc) Vector_add, /*nb_add*/
- (binaryfunc) Vector_sub, /*nb_subtract*/
- (binaryfunc) Vector_mul, /*nb_multiply*/
- NULL, /*nb_remainder*/
- NULL, /*nb_divmod*/
- NULL, /*nb_power*/
- (unaryfunc) Vector_neg, /*nb_negative*/
- (unaryfunc) Vector_copy,/*tp_positive*/
- (unaryfunc) NULL, /*tp_absolute*/
- (inquiry) NULL, /*tp_bool*/
- (unaryfunc) NULL, /*nb_invert*/
- NULL, /*nb_lshift*/
- (binaryfunc)NULL, /*nb_rshift*/
- NULL, /*nb_and*/
- NULL, /*nb_xor*/
- NULL, /*nb_or*/
- NULL, /*nb_int*/
- NULL, /*nb_reserved*/
- NULL, /*nb_float*/
- Vector_iadd, /* nb_inplace_add */
- Vector_isub, /* nb_inplace_subtract */
- Vector_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 */
- Vector_div, /* nb_true_divide */
- NULL, /* nb_inplace_floor_divide */
- Vector_idiv, /* nb_inplace_true_divide */
- NULL, /* nb_index */
- (binaryfunc) Vector_matmul, /* nb_matrix_multiply */
- (binaryfunc) Vector_imatmul, /* nb_inplace_matrix_multiply */
+ (binaryfunc)Vector_add, /*nb_add*/
+ (binaryfunc)Vector_sub, /*nb_subtract*/
+ (binaryfunc)Vector_mul, /*nb_multiply*/
+ NULL, /*nb_remainder*/
+ NULL, /*nb_divmod*/
+ NULL, /*nb_power*/
+ (unaryfunc)Vector_neg, /*nb_negative*/
+ (unaryfunc)Vector_copy, /*tp_positive*/
+ (unaryfunc)NULL, /*tp_absolute*/
+ (inquiry)NULL, /*tp_bool*/
+ (unaryfunc)NULL, /*nb_invert*/
+ NULL, /*nb_lshift*/
+ (binaryfunc)NULL, /*nb_rshift*/
+ NULL, /*nb_and*/
+ NULL, /*nb_xor*/
+ NULL, /*nb_or*/
+ NULL, /*nb_int*/
+ NULL, /*nb_reserved*/
+ NULL, /*nb_float*/
+ Vector_iadd, /* nb_inplace_add */
+ Vector_isub, /* nb_inplace_subtract */
+ Vector_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 */
+ Vector_div, /* nb_true_divide */
+ NULL, /* nb_inplace_floor_divide */
+ Vector_idiv, /* nb_inplace_true_divide */
+ NULL, /* nb_index */
+ (binaryfunc)Vector_matmul, /* nb_matrix_multiply */
+ (binaryfunc)Vector_imatmul, /* nb_inplace_matrix_multiply */
};
/*------------------PY_OBECT DEFINITION--------------------------*/
@@ -2292,88 +2268,81 @@ PyDoc_STRVAR(Vector_axis_w_doc, "Vector W axis (4D Vectors only).\n\n:type: floa
static PyObject *Vector_axis_get(VectorObject *self, void *type)
{
- return vector_item_internal(self, POINTER_AS_INT(type), true);
+ return vector_item_internal(self, POINTER_AS_INT(type), true);
}
static int Vector_axis_set(VectorObject *self, PyObject *value, void *type)
{
- return vector_ass_item_internal(self, POINTER_AS_INT(type), value, true);
+ return vector_ass_item_internal(self, POINTER_AS_INT(type), value, true);
}
/* vector.length */
-PyDoc_STRVAR(Vector_length_doc,
-"Vector Length.\n\n:type: float"
-);
+PyDoc_STRVAR(Vector_length_doc, "Vector Length.\n\n:type: float");
static PyObject *Vector_length_get(VectorObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size)));
+ return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size)));
}
static int Vector_length_set(VectorObject *self, PyObject *value)
{
- double dot = 0.0f, param;
+ double dot = 0.0f, param;
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
- if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "length must be set to a number");
- return -1;
- }
+ if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "length must be set to a number");
+ return -1;
+ }
- if (param < 0.0) {
- PyErr_SetString(PyExc_ValueError,
- "cannot set a vectors length to a negative value");
- return -1;
- }
- if (param == 0.0) {
- copy_vn_fl(self->vec, self->size, 0.0f);
- return 0;
- }
+ if (param < 0.0) {
+ PyErr_SetString(PyExc_ValueError, "cannot set a vectors length to a negative value");
+ return -1;
+ }
+ if (param == 0.0) {
+ copy_vn_fl(self->vec, self->size, 0.0f);
+ return 0;
+ }
- dot = dot_vn_vn(self->vec, self->vec, self->size);
+ dot = dot_vn_vn(self->vec, self->vec, self->size);
- if (!dot) {
- /* cant sqrt zero */
- return 0;
- }
+ if (!dot) {
+ /* cant sqrt zero */
+ return 0;
+ }
- dot = sqrt(dot);
+ dot = sqrt(dot);
- if (dot == param) {
- return 0;
- }
+ if (dot == param) {
+ return 0;
+ }
- dot = dot / param;
+ dot = dot / param;
- mul_vn_fl(self->vec, self->size, 1.0 / dot);
+ mul_vn_fl(self->vec, self->size, 1.0 / dot);
- (void)BaseMath_WriteCallback(self); /* checked already */
+ (void)BaseMath_WriteCallback(self); /* checked already */
- return 0;
+ return 0;
}
/* vector.length_squared */
-PyDoc_STRVAR(Vector_length_squared_doc,
-"Vector length squared (v.dot(v)).\n\n:type: float"
-);
+PyDoc_STRVAR(Vector_length_squared_doc, "Vector length squared (v.dot(v)).\n\n:type: float");
static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(closure))
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->size));
+ return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->size));
}
-
/**
* Python script used to make swizzle array:
*
@@ -2434,33 +2403,33 @@ static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(clos
*/
static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
{
- size_t axis_to;
- size_t axis_from;
- float vec[MAX_DIMENSIONS];
- unsigned int swizzleClosure;
+ size_t axis_to;
+ size_t axis_from;
+ float vec[MAX_DIMENSIONS];
+ unsigned int swizzleClosure;
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- /* Unpack the axes from the closure into an array. */
- axis_to = 0;
- swizzleClosure = POINTER_AS_INT(closure);
- while (swizzleClosure & SWIZZLE_VALID_AXIS) {
- axis_from = swizzleClosure & SWIZZLE_AXIS;
- if (axis_from >= self->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector swizzle: "
- "specified axis not present");
- return NULL;
- }
+ /* Unpack the axes from the closure into an array. */
+ axis_to = 0;
+ swizzleClosure = POINTER_AS_INT(closure);
+ while (swizzleClosure & SWIZZLE_VALID_AXIS) {
+ axis_from = swizzleClosure & SWIZZLE_AXIS;
+ if (axis_from >= self->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector swizzle: "
+ "specified axis not present");
+ return NULL;
+ }
- vec[axis_to] = self->vec[axis_from];
- swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
- axis_to++;
- }
+ vec[axis_to] = self->vec[axis_from];
+ swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
+ axis_to++;
+ }
- return Vector_CreatePyObject(vec, axis_to, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, axis_to, Py_TYPE(self));
}
/**
@@ -2476,450 +2445,666 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
*/
static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure)
{
- size_t size_from;
- float scalarVal;
-
- size_t axis_from;
- size_t axis_to;
-
- unsigned int swizzleClosure;
-
- float tvec[MAX_DIMENSIONS];
- float vec_assign[MAX_DIMENSIONS];
-
- if (BaseMath_ReadCallback_ForWrite(self) == -1) {
- return -1;
- }
-
- /* Check that the closure can be used with this vector: even 2D vectors have
- * swizzles defined for axes z and w, but they would be invalid. */
- swizzleClosure = POINTER_AS_INT(closure);
- axis_from = 0;
-
- while (swizzleClosure & SWIZZLE_VALID_AXIS) {
- axis_to = swizzleClosure & SWIZZLE_AXIS;
- if (axis_to >= self->size) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector swizzle: "
- "specified axis not present");
- return -1;
- }
- swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
- axis_from++;
- }
-
- if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
- int i;
-
- for (i = 0; i < MAX_DIMENSIONS; i++) {
- vec_assign[i] = scalarVal;
- }
-
- size_from = axis_from;
- }
- else if (((void)PyErr_Clear()), /* run but ignore the result */
- (size_from = mathutils_array_parse(vec_assign, 2, 4, value,
- "mathutils.Vector.**** = swizzle assignment")) == -1)
- {
- return -1;
- }
-
- if (axis_from != size_from) {
- PyErr_SetString(PyExc_AttributeError,
- "Vector swizzle: size does not match swizzle");
- return -1;
- }
-
- /* Copy vector contents onto swizzled axes. */
- axis_from = 0;
- swizzleClosure = POINTER_AS_INT(closure);
-
- /* We must first copy current vec into tvec, else some org values may be lost.
- * See [#31760].
- * Assuming self->size can't be higher than MAX_DIMENSIONS! */
- memcpy(tvec, self->vec, self->size * sizeof(float));
-
- while (swizzleClosure & SWIZZLE_VALID_AXIS) {
- axis_to = swizzleClosure & SWIZZLE_AXIS;
- tvec[axis_to] = vec_assign[axis_from];
- swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
- axis_from++;
- }
-
- /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
- * See [#31760]. */
- memcpy(self->vec, tvec, self->size * sizeof(float));
- /* continue with BaseMathObject_WriteCallback at the end */
-
- if (BaseMath_WriteCallback(self) == -1) {
- return -1;
- }
- else {
- return 0;
- }
-}
-
-#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
-#define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
-#define _SWIZZLE3(a, b, c) (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
-#define _SWIZZLE4(a, b, c, d) (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
-
-#define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
-#define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
+ size_t size_from;
+ float scalarVal;
+
+ size_t axis_from;
+ size_t axis_to;
+
+ unsigned int swizzleClosure;
+
+ float tvec[MAX_DIMENSIONS];
+ float vec_assign[MAX_DIMENSIONS];
+
+ if (BaseMath_ReadCallback_ForWrite(self) == -1) {
+ return -1;
+ }
+
+ /* Check that the closure can be used with this vector: even 2D vectors have
+ * swizzles defined for axes z and w, but they would be invalid. */
+ swizzleClosure = POINTER_AS_INT(closure);
+ axis_from = 0;
+
+ while (swizzleClosure & SWIZZLE_VALID_AXIS) {
+ axis_to = swizzleClosure & SWIZZLE_AXIS;
+ if (axis_to >= self->size) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Vector swizzle: "
+ "specified axis not present");
+ return -1;
+ }
+ swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
+ axis_from++;
+ }
+
+ if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) {
+ int i;
+
+ for (i = 0; i < MAX_DIMENSIONS; i++) {
+ vec_assign[i] = scalarVal;
+ }
+
+ size_from = axis_from;
+ }
+ else if (((void)PyErr_Clear()), /* run but ignore the result */
+ (size_from = mathutils_array_parse(
+ vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) {
+ return -1;
+ }
+
+ if (axis_from != size_from) {
+ PyErr_SetString(PyExc_AttributeError, "Vector swizzle: size does not match swizzle");
+ return -1;
+ }
+
+ /* Copy vector contents onto swizzled axes. */
+ axis_from = 0;
+ swizzleClosure = POINTER_AS_INT(closure);
+
+ /* We must first copy current vec into tvec, else some org values may be lost.
+ * See [#31760].
+ * Assuming self->size can't be higher than MAX_DIMENSIONS! */
+ memcpy(tvec, self->vec, self->size * sizeof(float));
+
+ while (swizzleClosure & SWIZZLE_VALID_AXIS) {
+ axis_to = swizzleClosure & SWIZZLE_AXIS;
+ tvec[axis_to] = vec_assign[axis_from];
+ swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
+ axis_from++;
+ }
+
+ /* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
+ * See [#31760]. */
+ memcpy(self->vec, tvec, self->size * sizeof(float));
+ /* continue with BaseMathObject_WriteCallback at the end */
+
+ if (BaseMath_WriteCallback(self) == -1) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
+}
+
+#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
+#define _SWIZZLE2(a, b) (_SWIZZLE1(a) | (((b) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS)))
+#define _SWIZZLE3(a, b, c) \
+ (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
+#define _SWIZZLE4(a, b, c, d) \
+ (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
+
+#define SWIZZLE2(a, b) POINTER_FROM_INT(_SWIZZLE2(a, b))
+#define SWIZZLE3(a, b, c) POINTER_FROM_INT(_SWIZZLE3(a, b, c))
#define SWIZZLE4(a, b, c, d) POINTER_FROM_INT(_SWIZZLE4(a, b, c, d))
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Vector_getseters[] = {
- {(char *)"x", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_x_doc, (void *)0},
- {(char *)"y", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_y_doc, (void *)1},
- {(char *)"z", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_z_doc, (void *)2},
- {(char *)"w", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_w_doc, (void *)3},
- {(char *)"length", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL},
- {(char *)"length_squared", (getter)Vector_length_squared_get, (setter)NULL, Vector_length_squared_doc, NULL},
- {(char *)"magnitude", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL},
- {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
- {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
- {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
-
- /* autogenerated swizzle attrs, see Python script above */
- {(char *)"xx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(0, 0)},
- {(char *)"xxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 0)},
- {(char *)"xxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 0)},
- {(char *)"xxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 1)},
- {(char *)"xxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 2)},
- {(char *)"xxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 3)},
- {(char *)"xxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 1)},
- {(char *)"xxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 0)},
- {(char *)"xxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 1)},
- {(char *)"xxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 2)},
- {(char *)"xxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 3)},
- {(char *)"xxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 2)},
- {(char *)"xxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 0)},
- {(char *)"xxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 1)},
- {(char *)"xxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 2)},
- {(char *)"xxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 3)},
- {(char *)"xxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 3)},
- {(char *)"xxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 0)},
- {(char *)"xxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 1)},
- {(char *)"xxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 2)},
- {(char *)"xxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 3)},
- {(char *)"xy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 1)},
- {(char *)"xyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 0)},
- {(char *)"xyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 0)},
- {(char *)"xyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 1)},
- {(char *)"xyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 2)},
- {(char *)"xyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 3)},
- {(char *)"xyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 1)},
- {(char *)"xyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 0)},
- {(char *)"xyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 1)},
- {(char *)"xyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 2)},
- {(char *)"xyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 3)},
- {(char *)"xyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 1, 2)},
- {(char *)"xyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 0)},
- {(char *)"xyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 1)},
- {(char *)"xyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 2)},
- {(char *)"xyzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 1, 2, 3)},
- {(char *)"xyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 1, 3)},
- {(char *)"xywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 0)},
- {(char *)"xywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 1)},
- {(char *)"xywz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 1, 3, 2)},
- {(char *)"xyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 3)},
- {(char *)"xz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 2)},
- {(char *)"xzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 0)},
- {(char *)"xzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 0)},
- {(char *)"xzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 1)},
- {(char *)"xzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 2)},
- {(char *)"xzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 3)},
- {(char *)"xzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 2, 1)},
- {(char *)"xzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 0)},
- {(char *)"xzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 1)},
- {(char *)"xzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 2)},
- {(char *)"xzyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 2, 1, 3)},
- {(char *)"xzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 2)},
- {(char *)"xzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 0)},
- {(char *)"xzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 1)},
- {(char *)"xzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 2)},
- {(char *)"xzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 3)},
- {(char *)"xzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 2, 3)},
- {(char *)"xzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 0)},
- {(char *)"xzwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 2, 3, 1)},
- {(char *)"xzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 2)},
- {(char *)"xzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 3)},
- {(char *)"xw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 3)},
- {(char *)"xwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 0)},
- {(char *)"xwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 0)},
- {(char *)"xwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 1)},
- {(char *)"xwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 2)},
- {(char *)"xwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 3)},
- {(char *)"xwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 3, 1)},
- {(char *)"xwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 0)},
- {(char *)"xwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 1)},
- {(char *)"xwyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 3, 1, 2)},
- {(char *)"xwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 3)},
- {(char *)"xwz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(0, 3, 2)},
- {(char *)"xwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 0)},
- {(char *)"xwzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(0, 3, 2, 1)},
- {(char *)"xwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 2)},
- {(char *)"xwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 3)},
- {(char *)"xww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 3)},
- {(char *)"xwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 0)},
- {(char *)"xwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 1)},
- {(char *)"xwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 2)},
- {(char *)"xwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 3)},
- {(char *)"yx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 0)},
- {(char *)"yxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 0)},
- {(char *)"yxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 0)},
- {(char *)"yxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 1)},
- {(char *)"yxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 2)},
- {(char *)"yxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 3)},
- {(char *)"yxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 1)},
- {(char *)"yxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 0)},
- {(char *)"yxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 1)},
- {(char *)"yxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 2)},
- {(char *)"yxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 3)},
- {(char *)"yxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 0, 2)},
- {(char *)"yxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 0)},
- {(char *)"yxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 1)},
- {(char *)"yxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 2)},
- {(char *)"yxzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 0, 2, 3)},
- {(char *)"yxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 0, 3)},
- {(char *)"yxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 0)},
- {(char *)"yxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 1)},
- {(char *)"yxwz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 0, 3, 2)},
- {(char *)"yxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 3)},
- {(char *)"yy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(1, 1)},
- {(char *)"yyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 0)},
- {(char *)"yyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 0)},
- {(char *)"yyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 1)},
- {(char *)"yyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 2)},
- {(char *)"yyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 3)},
- {(char *)"yyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 1)},
- {(char *)"yyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 0)},
- {(char *)"yyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 1)},
- {(char *)"yyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 2)},
- {(char *)"yyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 3)},
- {(char *)"yyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 2)},
- {(char *)"yyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 0)},
- {(char *)"yyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 1)},
- {(char *)"yyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 2)},
- {(char *)"yyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 3)},
- {(char *)"yyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 3)},
- {(char *)"yywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 0)},
- {(char *)"yywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 1)},
- {(char *)"yywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 2)},
- {(char *)"yyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 3)},
- {(char *)"yz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 2)},
- {(char *)"yzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 2, 0)},
- {(char *)"yzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 0)},
- {(char *)"yzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 1)},
- {(char *)"yzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 2)},
- {(char *)"yzxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 2, 0, 3)},
- {(char *)"yzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 1)},
- {(char *)"yzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 0)},
- {(char *)"yzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 1)},
- {(char *)"yzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 2)},
- {(char *)"yzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 3)},
- {(char *)"yzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 2)},
- {(char *)"yzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 0)},
- {(char *)"yzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 1)},
- {(char *)"yzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 2)},
- {(char *)"yzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 3)},
- {(char *)"yzw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 2, 3)},
- {(char *)"yzwx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 2, 3, 0)},
- {(char *)"yzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 1)},
- {(char *)"yzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 2)},
- {(char *)"yzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 3)},
- {(char *)"yw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 3)},
- {(char *)"ywx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 3, 0)},
- {(char *)"ywxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 0)},
- {(char *)"ywxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 1)},
- {(char *)"ywxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 3, 0, 2)},
- {(char *)"ywxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 3)},
- {(char *)"ywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 1)},
- {(char *)"ywyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 0)},
- {(char *)"ywyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 1)},
- {(char *)"ywyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 2)},
- {(char *)"ywyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 3)},
- {(char *)"ywz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(1, 3, 2)},
- {(char *)"ywzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(1, 3, 2, 0)},
- {(char *)"ywzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 1)},
- {(char *)"ywzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 2)},
- {(char *)"ywzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 3)},
- {(char *)"yww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 3)},
- {(char *)"ywwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 0)},
- {(char *)"ywwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 1)},
- {(char *)"ywwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 2)},
- {(char *)"ywww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 3)},
- {(char *)"zx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 0)},
- {(char *)"zxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 0)},
- {(char *)"zxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 0)},
- {(char *)"zxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 1)},
- {(char *)"zxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 2)},
- {(char *)"zxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 3)},
- {(char *)"zxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 0, 1)},
- {(char *)"zxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 0)},
- {(char *)"zxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 1)},
- {(char *)"zxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 2)},
- {(char *)"zxyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 0, 1, 3)},
- {(char *)"zxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 2)},
- {(char *)"zxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 0)},
- {(char *)"zxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 1)},
- {(char *)"zxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 2)},
- {(char *)"zxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 3)},
- {(char *)"zxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 0, 3)},
- {(char *)"zxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 0)},
- {(char *)"zxwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 0, 3, 1)},
- {(char *)"zxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 2)},
- {(char *)"zxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 3)},
- {(char *)"zy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 1)},
- {(char *)"zyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 1, 0)},
- {(char *)"zyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 0)},
- {(char *)"zyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 1)},
- {(char *)"zyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 2)},
- {(char *)"zyxw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 1, 0, 3)},
- {(char *)"zyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 1)},
- {(char *)"zyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 0)},
- {(char *)"zyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 1)},
- {(char *)"zyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 2)},
- {(char *)"zyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 3)},
- {(char *)"zyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 2)},
- {(char *)"zyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 0)},
- {(char *)"zyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 1)},
- {(char *)"zyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 2)},
- {(char *)"zyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 3)},
- {(char *)"zyw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 1, 3)},
- {(char *)"zywx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 1, 3, 0)},
- {(char *)"zywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 1)},
- {(char *)"zywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 2)},
- {(char *)"zyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 3)},
- {(char *)"zz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(2, 2)},
- {(char *)"zzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 0)},
- {(char *)"zzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 0)},
- {(char *)"zzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 1)},
- {(char *)"zzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 2)},
- {(char *)"zzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 3)},
- {(char *)"zzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 1)},
- {(char *)"zzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 0)},
- {(char *)"zzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 1)},
- {(char *)"zzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 2)},
- {(char *)"zzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 3)},
- {(char *)"zzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 2)},
- {(char *)"zzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 0)},
- {(char *)"zzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 1)},
- {(char *)"zzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 2)},
- {(char *)"zzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 3)},
- {(char *)"zzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 3)},
- {(char *)"zzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 0)},
- {(char *)"zzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 1)},
- {(char *)"zzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 2)},
- {(char *)"zzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 3)},
- {(char *)"zw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 3)},
- {(char *)"zwx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 3, 0)},
- {(char *)"zwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 0)},
- {(char *)"zwxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 3, 0, 1)},
- {(char *)"zwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 2)},
- {(char *)"zwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 3)},
- {(char *)"zwy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(2, 3, 1)},
- {(char *)"zwyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(2, 3, 1, 0)},
- {(char *)"zwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 1)},
- {(char *)"zwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 2)},
- {(char *)"zwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 3)},
- {(char *)"zwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 2)},
- {(char *)"zwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 0)},
- {(char *)"zwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 1)},
- {(char *)"zwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 2)},
- {(char *)"zwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 3)},
- {(char *)"zww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 3)},
- {(char *)"zwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 0)},
- {(char *)"zwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 1)},
- {(char *)"zwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 2)},
- {(char *)"zwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 3)},
- {(char *)"wx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 0)},
- {(char *)"wxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 0)},
- {(char *)"wxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 0)},
- {(char *)"wxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 1)},
- {(char *)"wxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 2)},
- {(char *)"wxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 3)},
- {(char *)"wxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 0, 1)},
- {(char *)"wxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 0)},
- {(char *)"wxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 1)},
- {(char *)"wxyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 0, 1, 2)},
- {(char *)"wxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 3)},
- {(char *)"wxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 0, 2)},
- {(char *)"wxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 0)},
- {(char *)"wxzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 0, 2, 1)},
- {(char *)"wxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 2)},
- {(char *)"wxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 3)},
- {(char *)"wxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 3)},
- {(char *)"wxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 0)},
- {(char *)"wxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 1)},
- {(char *)"wxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 2)},
- {(char *)"wxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 3)},
- {(char *)"wy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 1)},
- {(char *)"wyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 1, 0)},
- {(char *)"wyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 0)},
- {(char *)"wyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 1)},
- {(char *)"wyxz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 1, 0, 2)},
- {(char *)"wyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 3)},
- {(char *)"wyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 1)},
- {(char *)"wyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 0)},
- {(char *)"wyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 1)},
- {(char *)"wyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 2)},
- {(char *)"wyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 3)},
- {(char *)"wyz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 1, 2)},
- {(char *)"wyzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 1, 2, 0)},
- {(char *)"wyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 1)},
- {(char *)"wyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 2)},
- {(char *)"wyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 3)},
- {(char *)"wyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 3)},
- {(char *)"wywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 0)},
- {(char *)"wywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 1)},
- {(char *)"wywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 2)},
- {(char *)"wyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 3)},
- {(char *)"wz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 2)},
- {(char *)"wzx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 2, 0)},
- {(char *)"wzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 0)},
- {(char *)"wzxy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 2, 0, 1)},
- {(char *)"wzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 2)},
- {(char *)"wzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 3)},
- {(char *)"wzy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE3(3, 2, 1)},
- {(char *)"wzyx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE4(3, 2, 1, 0)},
- {(char *)"wzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 1)},
- {(char *)"wzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 2)},
- {(char *)"wzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 3)},
- {(char *)"wzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 2)},
- {(char *)"wzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 0)},
- {(char *)"wzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 1)},
- {(char *)"wzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 2)},
- {(char *)"wzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 3)},
- {(char *)"wzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 3)},
- {(char *)"wzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 0)},
- {(char *)"wzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 1)},
- {(char *)"wzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 2)},
- {(char *)"wzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 3)},
- {(char *)"ww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(3, 3)},
- {(char *)"wwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 0)},
- {(char *)"wwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 0)},
- {(char *)"wwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 1)},
- {(char *)"wwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 2)},
- {(char *)"wwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 3)},
- {(char *)"wwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 1)},
- {(char *)"wwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 0)},
- {(char *)"wwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 1)},
- {(char *)"wwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 2)},
- {(char *)"wwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 3)},
- {(char *)"wwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 2)},
- {(char *)"wwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 0)},
- {(char *)"wwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 1)},
- {(char *)"wwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 2)},
- {(char *)"wwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 3)},
- {(char *)"www", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 3)},
- {(char *)"wwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 0)},
- {(char *)"wwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 1)},
- {(char *)"wwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 2)},
- {(char *)"wwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 3)},
+ {(char *)"x", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_x_doc, (void *)0},
+ {(char *)"y", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_y_doc, (void *)1},
+ {(char *)"z", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_z_doc, (void *)2},
+ {(char *)"w", (getter)Vector_axis_get, (setter)Vector_axis_set, Vector_axis_w_doc, (void *)3},
+ {(char *)"length",
+ (getter)Vector_length_get,
+ (setter)Vector_length_set,
+ Vector_length_doc,
+ NULL},
+ {(char *)"length_squared",
+ (getter)Vector_length_squared_get,
+ (setter)NULL,
+ Vector_length_squared_doc,
+ NULL},
+ {(char *)"magnitude",
+ (getter)Vector_length_get,
+ (setter)Vector_length_set,
+ Vector_length_doc,
+ NULL},
+ {(char *)"is_wrapped",
+ (getter)BaseMathObject_is_wrapped_get,
+ (setter)NULL,
+ BaseMathObject_is_wrapped_doc,
+ NULL},
+ {(char *)"is_frozen",
+ (getter)BaseMathObject_is_frozen_get,
+ (setter)NULL,
+ BaseMathObject_is_frozen_doc,
+ NULL},
+ {(char *)"owner",
+ (getter)BaseMathObject_owner_get,
+ (setter)NULL,
+ BaseMathObject_owner_doc,
+ NULL},
+
+ /* autogenerated swizzle attrs, see Python script above */
+ {(char *)"xx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(0, 0)},
+ {(char *)"xxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 0)},
+ {(char *)"xxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 0)},
+ {(char *)"xxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 1)},
+ {(char *)"xxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 2)},
+ {(char *)"xxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 0, 3)},
+ {(char *)"xxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 1)},
+ {(char *)"xxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 0)},
+ {(char *)"xxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 1)},
+ {(char *)"xxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 2)},
+ {(char *)"xxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 1, 3)},
+ {(char *)"xxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 2)},
+ {(char *)"xxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 0)},
+ {(char *)"xxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 1)},
+ {(char *)"xxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 2)},
+ {(char *)"xxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 2, 3)},
+ {(char *)"xxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 0, 3)},
+ {(char *)"xxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 0)},
+ {(char *)"xxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 1)},
+ {(char *)"xxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 2)},
+ {(char *)"xxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 0, 3, 3)},
+ {(char *)"xy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 1)},
+ {(char *)"xyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 0)},
+ {(char *)"xyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 0)},
+ {(char *)"xyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 1)},
+ {(char *)"xyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 2)},
+ {(char *)"xyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 0, 3)},
+ {(char *)"xyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 1, 1)},
+ {(char *)"xyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 0)},
+ {(char *)"xyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 1)},
+ {(char *)"xyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 2)},
+ {(char *)"xyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 1, 3)},
+ {(char *)"xyz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 1, 2)},
+ {(char *)"xyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 0)},
+ {(char *)"xyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 1)},
+ {(char *)"xyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 2, 2)},
+ {(char *)"xyzw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 1, 2, 3)},
+ {(char *)"xyw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 1, 3)},
+ {(char *)"xywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 0)},
+ {(char *)"xywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 1)},
+ {(char *)"xywz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 1, 3, 2)},
+ {(char *)"xyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 1, 3, 3)},
+ {(char *)"xz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 2)},
+ {(char *)"xzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 0)},
+ {(char *)"xzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 0)},
+ {(char *)"xzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 1)},
+ {(char *)"xzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 2)},
+ {(char *)"xzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 0, 3)},
+ {(char *)"xzy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 2, 1)},
+ {(char *)"xzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 0)},
+ {(char *)"xzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 1)},
+ {(char *)"xzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 1, 2)},
+ {(char *)"xzyw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 2, 1, 3)},
+ {(char *)"xzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 2, 2)},
+ {(char *)"xzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 0)},
+ {(char *)"xzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 1)},
+ {(char *)"xzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 2)},
+ {(char *)"xzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 2, 3)},
+ {(char *)"xzw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 2, 3)},
+ {(char *)"xzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 0)},
+ {(char *)"xzwy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 2, 3, 1)},
+ {(char *)"xzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 2)},
+ {(char *)"xzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 2, 3, 3)},
+ {(char *)"xw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(0, 3)},
+ {(char *)"xwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 0)},
+ {(char *)"xwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 0)},
+ {(char *)"xwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 1)},
+ {(char *)"xwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 2)},
+ {(char *)"xwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 0, 3)},
+ {(char *)"xwy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 3, 1)},
+ {(char *)"xwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 0)},
+ {(char *)"xwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 1)},
+ {(char *)"xwyz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 3, 1, 2)},
+ {(char *)"xwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 1, 3)},
+ {(char *)"xwz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(0, 3, 2)},
+ {(char *)"xwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 0)},
+ {(char *)"xwzy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(0, 3, 2, 1)},
+ {(char *)"xwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 2)},
+ {(char *)"xwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 2, 3)},
+ {(char *)"xww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(0, 3, 3)},
+ {(char *)"xwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 0)},
+ {(char *)"xwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 1)},
+ {(char *)"xwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 2)},
+ {(char *)"xwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(0, 3, 3, 3)},
+ {(char *)"yx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 0)},
+ {(char *)"yxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 0)},
+ {(char *)"yxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 0)},
+ {(char *)"yxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 1)},
+ {(char *)"yxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 2)},
+ {(char *)"yxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 0, 3)},
+ {(char *)"yxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 0, 1)},
+ {(char *)"yxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 0)},
+ {(char *)"yxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 1)},
+ {(char *)"yxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 2)},
+ {(char *)"yxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 1, 3)},
+ {(char *)"yxz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 0, 2)},
+ {(char *)"yxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 0)},
+ {(char *)"yxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 1)},
+ {(char *)"yxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 2, 2)},
+ {(char *)"yxzw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 0, 2, 3)},
+ {(char *)"yxw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 0, 3)},
+ {(char *)"yxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 0)},
+ {(char *)"yxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 1)},
+ {(char *)"yxwz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 0, 3, 2)},
+ {(char *)"yxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 0, 3, 3)},
+ {(char *)"yy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(1, 1)},
+ {(char *)"yyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 0)},
+ {(char *)"yyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 0)},
+ {(char *)"yyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 1)},
+ {(char *)"yyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 2)},
+ {(char *)"yyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 0, 3)},
+ {(char *)"yyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 1)},
+ {(char *)"yyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 0)},
+ {(char *)"yyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 1)},
+ {(char *)"yyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 2)},
+ {(char *)"yyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 1, 3)},
+ {(char *)"yyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 2)},
+ {(char *)"yyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 0)},
+ {(char *)"yyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 1)},
+ {(char *)"yyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 2)},
+ {(char *)"yyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 2, 3)},
+ {(char *)"yyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 1, 3)},
+ {(char *)"yywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 0)},
+ {(char *)"yywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 1)},
+ {(char *)"yywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 2)},
+ {(char *)"yyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 1, 3, 3)},
+ {(char *)"yz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 2)},
+ {(char *)"yzx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 2, 0)},
+ {(char *)"yzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 0)},
+ {(char *)"yzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 1)},
+ {(char *)"yzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 0, 2)},
+ {(char *)"yzxw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 2, 0, 3)},
+ {(char *)"yzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 1)},
+ {(char *)"yzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 0)},
+ {(char *)"yzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 1)},
+ {(char *)"yzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 2)},
+ {(char *)"yzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 1, 3)},
+ {(char *)"yzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 2, 2)},
+ {(char *)"yzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 0)},
+ {(char *)"yzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 1)},
+ {(char *)"yzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 2)},
+ {(char *)"yzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 2, 3)},
+ {(char *)"yzw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 2, 3)},
+ {(char *)"yzwx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 2, 3, 0)},
+ {(char *)"yzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 1)},
+ {(char *)"yzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 2)},
+ {(char *)"yzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 2, 3, 3)},
+ {(char *)"yw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(1, 3)},
+ {(char *)"ywx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 3, 0)},
+ {(char *)"ywxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 0)},
+ {(char *)"ywxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 1)},
+ {(char *)"ywxz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 3, 0, 2)},
+ {(char *)"ywxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 0, 3)},
+ {(char *)"ywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 1)},
+ {(char *)"ywyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 0)},
+ {(char *)"ywyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 1)},
+ {(char *)"ywyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 2)},
+ {(char *)"ywyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 1, 3)},
+ {(char *)"ywz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(1, 3, 2)},
+ {(char *)"ywzx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(1, 3, 2, 0)},
+ {(char *)"ywzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 1)},
+ {(char *)"ywzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 2)},
+ {(char *)"ywzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 2, 3)},
+ {(char *)"yww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(1, 3, 3)},
+ {(char *)"ywwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 0)},
+ {(char *)"ywwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 1)},
+ {(char *)"ywwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 2)},
+ {(char *)"ywww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(1, 3, 3, 3)},
+ {(char *)"zx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 0)},
+ {(char *)"zxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 0)},
+ {(char *)"zxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 0)},
+ {(char *)"zxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 1)},
+ {(char *)"zxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 2)},
+ {(char *)"zxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 0, 3)},
+ {(char *)"zxy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 0, 1)},
+ {(char *)"zxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 0)},
+ {(char *)"zxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 1)},
+ {(char *)"zxyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 1, 2)},
+ {(char *)"zxyw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 0, 1, 3)},
+ {(char *)"zxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 0, 2)},
+ {(char *)"zxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 0)},
+ {(char *)"zxzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 1)},
+ {(char *)"zxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 2)},
+ {(char *)"zxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 2, 3)},
+ {(char *)"zxw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 0, 3)},
+ {(char *)"zxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 0)},
+ {(char *)"zxwy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 0, 3, 1)},
+ {(char *)"zxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 2)},
+ {(char *)"zxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 0, 3, 3)},
+ {(char *)"zy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 1)},
+ {(char *)"zyx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 1, 0)},
+ {(char *)"zyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 0)},
+ {(char *)"zyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 1)},
+ {(char *)"zyxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 0, 2)},
+ {(char *)"zyxw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 1, 0, 3)},
+ {(char *)"zyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 1)},
+ {(char *)"zyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 0)},
+ {(char *)"zyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 1)},
+ {(char *)"zyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 2)},
+ {(char *)"zyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 1, 3)},
+ {(char *)"zyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 1, 2)},
+ {(char *)"zyzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 0)},
+ {(char *)"zyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 1)},
+ {(char *)"zyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 2)},
+ {(char *)"zyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 2, 3)},
+ {(char *)"zyw",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 1, 3)},
+ {(char *)"zywx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 1, 3, 0)},
+ {(char *)"zywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 1)},
+ {(char *)"zywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 2)},
+ {(char *)"zyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 1, 3, 3)},
+ {(char *)"zz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(2, 2)},
+ {(char *)"zzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 0)},
+ {(char *)"zzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 0)},
+ {(char *)"zzxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 1)},
+ {(char *)"zzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 2)},
+ {(char *)"zzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 0, 3)},
+ {(char *)"zzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 1)},
+ {(char *)"zzyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 0)},
+ {(char *)"zzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 1)},
+ {(char *)"zzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 2)},
+ {(char *)"zzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 1, 3)},
+ {(char *)"zzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 2)},
+ {(char *)"zzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 0)},
+ {(char *)"zzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 1)},
+ {(char *)"zzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 2)},
+ {(char *)"zzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 2, 3)},
+ {(char *)"zzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 2, 3)},
+ {(char *)"zzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 0)},
+ {(char *)"zzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 1)},
+ {(char *)"zzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 2)},
+ {(char *)"zzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 2, 3, 3)},
+ {(char *)"zw", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(2, 3)},
+ {(char *)"zwx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 3, 0)},
+ {(char *)"zwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 0)},
+ {(char *)"zwxy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 3, 0, 1)},
+ {(char *)"zwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 2)},
+ {(char *)"zwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 0, 3)},
+ {(char *)"zwy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(2, 3, 1)},
+ {(char *)"zwyx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(2, 3, 1, 0)},
+ {(char *)"zwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 1)},
+ {(char *)"zwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 2)},
+ {(char *)"zwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 1, 3)},
+ {(char *)"zwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 2)},
+ {(char *)"zwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 0)},
+ {(char *)"zwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 1)},
+ {(char *)"zwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 2)},
+ {(char *)"zwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 2, 3)},
+ {(char *)"zww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(2, 3, 3)},
+ {(char *)"zwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 0)},
+ {(char *)"zwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 1)},
+ {(char *)"zwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 2)},
+ {(char *)"zwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(2, 3, 3, 3)},
+ {(char *)"wx", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 0)},
+ {(char *)"wxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 0)},
+ {(char *)"wxxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 0)},
+ {(char *)"wxxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 1)},
+ {(char *)"wxxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 2)},
+ {(char *)"wxxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 0, 3)},
+ {(char *)"wxy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 0, 1)},
+ {(char *)"wxyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 0)},
+ {(char *)"wxyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 1)},
+ {(char *)"wxyz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 0, 1, 2)},
+ {(char *)"wxyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 1, 3)},
+ {(char *)"wxz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 0, 2)},
+ {(char *)"wxzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 0)},
+ {(char *)"wxzy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 0, 2, 1)},
+ {(char *)"wxzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 2)},
+ {(char *)"wxzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 2, 3)},
+ {(char *)"wxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 0, 3)},
+ {(char *)"wxwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 0)},
+ {(char *)"wxwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 1)},
+ {(char *)"wxwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 2)},
+ {(char *)"wxww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 0, 3, 3)},
+ {(char *)"wy", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 1)},
+ {(char *)"wyx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 1, 0)},
+ {(char *)"wyxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 0)},
+ {(char *)"wyxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 1)},
+ {(char *)"wyxz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 1, 0, 2)},
+ {(char *)"wyxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 0, 3)},
+ {(char *)"wyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 1)},
+ {(char *)"wyyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 0)},
+ {(char *)"wyyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 1)},
+ {(char *)"wyyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 2)},
+ {(char *)"wyyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 1, 3)},
+ {(char *)"wyz",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 1, 2)},
+ {(char *)"wyzx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 1, 2, 0)},
+ {(char *)"wyzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 1)},
+ {(char *)"wyzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 2)},
+ {(char *)"wyzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 2, 3)},
+ {(char *)"wyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 1, 3)},
+ {(char *)"wywx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 0)},
+ {(char *)"wywy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 1)},
+ {(char *)"wywz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 2)},
+ {(char *)"wyww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 1, 3, 3)},
+ {(char *)"wz", (getter)Vector_swizzle_get, (setter)Vector_swizzle_set, NULL, SWIZZLE2(3, 2)},
+ {(char *)"wzx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 2, 0)},
+ {(char *)"wzxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 0)},
+ {(char *)"wzxy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 2, 0, 1)},
+ {(char *)"wzxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 2)},
+ {(char *)"wzxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 0, 3)},
+ {(char *)"wzy",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE3(3, 2, 1)},
+ {(char *)"wzyx",
+ (getter)Vector_swizzle_get,
+ (setter)Vector_swizzle_set,
+ NULL,
+ SWIZZLE4(3, 2, 1, 0)},
+ {(char *)"wzyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 1)},
+ {(char *)"wzyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 2)},
+ {(char *)"wzyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 1, 3)},
+ {(char *)"wzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 2)},
+ {(char *)"wzzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 0)},
+ {(char *)"wzzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 1)},
+ {(char *)"wzzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 2)},
+ {(char *)"wzzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 2, 3)},
+ {(char *)"wzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 2, 3)},
+ {(char *)"wzwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 0)},
+ {(char *)"wzwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 1)},
+ {(char *)"wzwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 2)},
+ {(char *)"wzww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 2, 3, 3)},
+ {(char *)"ww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE2(3, 3)},
+ {(char *)"wwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 0)},
+ {(char *)"wwxx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 0)},
+ {(char *)"wwxy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 1)},
+ {(char *)"wwxz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 2)},
+ {(char *)"wwxw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 0, 3)},
+ {(char *)"wwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 1)},
+ {(char *)"wwyx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 0)},
+ {(char *)"wwyy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 1)},
+ {(char *)"wwyz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 2)},
+ {(char *)"wwyw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 1, 3)},
+ {(char *)"wwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 2)},
+ {(char *)"wwzx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 0)},
+ {(char *)"wwzy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 1)},
+ {(char *)"wwzz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 2)},
+ {(char *)"wwzw", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 2, 3)},
+ {(char *)"www", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE3(3, 3, 3)},
+ {(char *)"wwwx", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 0)},
+ {(char *)"wwwy", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 1)},
+ {(char *)"wwwz", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 2)},
+ {(char *)"wwww", (getter)Vector_swizzle_get, (setter)NULL, NULL, SWIZZLE4(3, 3, 3, 3)},
#undef AXIS_FROM_CHAR
#undef SWIZZLE1
@@ -2931,7 +3116,7 @@ static PyGetSetDef Vector_getseters[] = {
#undef _SWIZZLE3
#undef _SWIZZLE4
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/**
@@ -2943,108 +3128,111 @@ static PyGetSetDef Vector_getseters[] = {
* </pre>
* \note vector/matrix multiplication is not commutative.
*/
-static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
-{
- float vec_cpy[MAX_DIMENSIONS];
- int row, col, z = 0, vec_size = vec->size;
-
- if (mat->num_row != vec_size) {
- if (mat->num_row == 4 && vec_size == 3) {
- vec_cpy[3] = 1.0f;
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "vector * matrix: matrix column size "
- "and the vector size must be the same");
- return -1;
- }
- }
-
- if (BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1) {
- return -1;
- }
-
- memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
-
- r_vec[3] = 1.0f;
- /* muliplication */
- for (col = 0; col < mat->num_col; col++) {
- double dot = 0.0;
- for (row = 0; row < mat->num_row; row++) {
- dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]);
- }
- r_vec[z++] = (float)dot;
- }
- return 0;
+static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS],
+ VectorObject *vec,
+ MatrixObject *mat)
+{
+ float vec_cpy[MAX_DIMENSIONS];
+ int row, col, z = 0, vec_size = vec->size;
+
+ if (mat->num_row != vec_size) {
+ if (mat->num_row == 4 && vec_size == 3) {
+ vec_cpy[3] = 1.0f;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "vector * matrix: matrix column size "
+ "and the vector size must be the same");
+ return -1;
+ }
+ }
+
+ if (BaseMath_ReadCallback(vec) == -1 || BaseMath_ReadCallback(mat) == -1) {
+ return -1;
+ }
+
+ memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
+
+ r_vec[3] = 1.0f;
+ /* muliplication */
+ for (col = 0; col < mat->num_col; col++) {
+ double dot = 0.0;
+ for (row = 0; row < mat->num_row; row++) {
+ dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]);
+ }
+ r_vec[z++] = (float)dot;
+ }
+ return 0;
}
/*----------------------------Vector.negate() -------------------- */
PyDoc_STRVAR(Vector_negate_doc,
-".. method:: negate()\n"
-"\n"
-" Set all values to their negative.\n"
-);
+ ".. method:: negate()\n"
+ "\n"
+ " Set all values to their negative.\n");
static PyObject *Vector_negate(VectorObject *self)
{
- if (BaseMath_ReadCallback(self) == -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(self) == -1) {
+ return NULL;
+ }
- negate_vn(self->vec, self->size);
+ negate_vn(self->vec, self->size);
- (void)BaseMath_WriteCallback(self); /* already checked for error */
- Py_RETURN_NONE;
+ (void)BaseMath_WriteCallback(self); /* already checked for error */
+ Py_RETURN_NONE;
}
static struct PyMethodDef Vector_methods[] = {
- /* Class Methods */
- {"Fill", (PyCFunction) C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
- {"Range", (PyCFunction) C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
- {"Linspace", (PyCFunction) C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
- {"Repeat", (PyCFunction) C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
-
- /* in place only */
- {"zero", (PyCFunction) Vector_zero, METH_NOARGS, Vector_zero_doc},
- {"negate", (PyCFunction) Vector_negate, METH_NOARGS, Vector_negate_doc},
-
- /* operate on original or copy */
- {"normalize", (PyCFunction) Vector_normalize, METH_NOARGS, Vector_normalize_doc},
- {"normalized", (PyCFunction) Vector_normalized, METH_NOARGS, Vector_normalized_doc},
-
- {"resize", (PyCFunction) Vector_resize, METH_O, Vector_resize_doc},
- {"resized", (PyCFunction) Vector_resized, METH_O, Vector_resized_doc},
- {"to_2d", (PyCFunction) Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
- {"resize_2d", (PyCFunction) Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
- {"to_3d", (PyCFunction) Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
- {"resize_3d", (PyCFunction) Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
- {"to_4d", (PyCFunction) Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
- {"resize_4d", (PyCFunction) Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
- {"to_tuple", (PyCFunction) Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
- {"to_track_quat", (PyCFunction) Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
- {"orthogonal", (PyCFunction) Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
-
- /* operation between 2 or more types */
- {"reflect", (PyCFunction) Vector_reflect, METH_O, Vector_reflect_doc},
- {"cross", (PyCFunction) Vector_cross, METH_O, Vector_cross_doc},
- {"dot", (PyCFunction) Vector_dot, METH_O, Vector_dot_doc},
- {"angle", (PyCFunction) Vector_angle, METH_VARARGS, Vector_angle_doc},
- {"angle_signed", (PyCFunction) Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
- {"rotation_difference", (PyCFunction) Vector_rotation_difference, METH_O, Vector_rotation_difference_doc},
- {"project", (PyCFunction) Vector_project, METH_O, Vector_project_doc},
- {"lerp", (PyCFunction) Vector_lerp, METH_VARARGS, Vector_lerp_doc},
- {"slerp", (PyCFunction) Vector_slerp, METH_VARARGS, Vector_slerp_doc},
- {"rotate", (PyCFunction) Vector_rotate, METH_O, Vector_rotate_doc},
-
- /* base-math methods */
- {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
-
- {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
- {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL},
- {"__deepcopy__", (PyCFunction) Vector_deepcopy, METH_VARARGS, NULL},
- {NULL, NULL, 0, NULL},
+ /* Class Methods */
+ {"Fill", (PyCFunction)C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
+ {"Range", (PyCFunction)C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
+ {"Linspace", (PyCFunction)C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
+ {"Repeat", (PyCFunction)C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
+
+ /* in place only */
+ {"zero", (PyCFunction)Vector_zero, METH_NOARGS, Vector_zero_doc},
+ {"negate", (PyCFunction)Vector_negate, METH_NOARGS, Vector_negate_doc},
+
+ /* operate on original or copy */
+ {"normalize", (PyCFunction)Vector_normalize, METH_NOARGS, Vector_normalize_doc},
+ {"normalized", (PyCFunction)Vector_normalized, METH_NOARGS, Vector_normalized_doc},
+
+ {"resize", (PyCFunction)Vector_resize, METH_O, Vector_resize_doc},
+ {"resized", (PyCFunction)Vector_resized, METH_O, Vector_resized_doc},
+ {"to_2d", (PyCFunction)Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
+ {"resize_2d", (PyCFunction)Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
+ {"to_3d", (PyCFunction)Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
+ {"resize_3d", (PyCFunction)Vector_resize_3d, METH_NOARGS, Vector_resize_3d_doc},
+ {"to_4d", (PyCFunction)Vector_to_4d, METH_NOARGS, Vector_to_4d_doc},
+ {"resize_4d", (PyCFunction)Vector_resize_4d, METH_NOARGS, Vector_resize_4d_doc},
+ {"to_tuple", (PyCFunction)Vector_to_tuple, METH_VARARGS, Vector_to_tuple_doc},
+ {"to_track_quat", (PyCFunction)Vector_to_track_quat, METH_VARARGS, Vector_to_track_quat_doc},
+ {"orthogonal", (PyCFunction)Vector_orthogonal, METH_NOARGS, Vector_orthogonal_doc},
+
+ /* operation between 2 or more types */
+ {"reflect", (PyCFunction)Vector_reflect, METH_O, Vector_reflect_doc},
+ {"cross", (PyCFunction)Vector_cross, METH_O, Vector_cross_doc},
+ {"dot", (PyCFunction)Vector_dot, METH_O, Vector_dot_doc},
+ {"angle", (PyCFunction)Vector_angle, METH_VARARGS, Vector_angle_doc},
+ {"angle_signed", (PyCFunction)Vector_angle_signed, METH_VARARGS, Vector_angle_signed_doc},
+ {"rotation_difference",
+ (PyCFunction)Vector_rotation_difference,
+ METH_O,
+ Vector_rotation_difference_doc},
+ {"project", (PyCFunction)Vector_project, METH_O, Vector_project_doc},
+ {"lerp", (PyCFunction)Vector_lerp, METH_VARARGS, Vector_lerp_doc},
+ {"slerp", (PyCFunction)Vector_slerp, METH_VARARGS, Vector_slerp_doc},
+ {"rotate", (PyCFunction)Vector_rotate, METH_O, Vector_rotate_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
+ {"copy", (PyCFunction)Vector_copy, METH_NOARGS, Vector_copy_doc},
+ {"__copy__", (PyCFunction)Vector_copy, METH_NOARGS, NULL},
+ {"__deepcopy__", (PyCFunction)Vector_deepcopy, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL},
};
-
/**
* Note:
* #Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
@@ -3053,144 +3241,140 @@ static struct PyMethodDef Vector_methods[] = {
*/
PyDoc_STRVAR(vector_doc,
-".. class:: Vector(seq)\n"
-"\n"
-" This object gives access to Vectors in Blender.\n"
-"\n"
-" :param seq: Components of the vector, must be a sequence of at least two\n"
-" :type seq: sequence of numbers\n"
-);
+ ".. class:: Vector(seq)\n"
+ "\n"
+ " This object gives access to Vectors in Blender.\n"
+ "\n"
+ " :param seq: Components of the vector, must be a sequence of at least two\n"
+ " :type seq: sequence of numbers\n");
PyTypeObject vector_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- /* For printing, in format "<module>.<name>" */
- "Vector", /* char *tp_name; */
- sizeof(VectorObject), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* For printing, in format "<module>.<name>" */
+ "Vector", /* char *tp_name; */
+ sizeof(VectorObject), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
- /* Methods to implement standard operations */
+ /* Methods to implement standard operations */
- (destructor) BaseMathObject_dealloc, /* destructor tp_dealloc; */
- NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)Vector_repr, /* reprfunc tp_repr; */
+ (destructor)BaseMathObject_dealloc, /* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ (reprfunc)Vector_repr, /* reprfunc tp_repr; */
- /* Method suites for standard classes */
+ /* Method suites for standard classes */
- &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */
- &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */
- &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */
+ &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */
+ &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */
+ &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */
- /* More standard operations (here for binary compatibility) */
+ /* More standard operations (here for binary compatibility) */
- (hashfunc)Vector_hash, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
+ (hashfunc)Vector_hash, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
#ifndef MATH_STANDALONE
- (reprfunc)Vector_str, /* reprfunc tp_str; */
+ (reprfunc)Vector_str, /* reprfunc tp_str; */
#else
- NULL, /* reprfunc tp_str; */
+ NULL, /* reprfunc tp_str; */
#endif
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- vector_doc, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
-
- /* call function for all accessible objects */
- (traverseproc)BaseMathObject_traverse, /* tp_traverse */
-
- /* delete references to contained objects */
- (inquiry)BaseMathObject_clear, /* tp_clear */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- (richcmpfunc)Vector_richcmpr, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- Vector_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- Vector_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- Vector_new, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL,
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ vector_doc, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+
+ /* call function for all accessible objects */
+ (traverseproc)BaseMathObject_traverse, /* tp_traverse */
+
+ /* delete references to contained objects */
+ (inquiry)BaseMathObject_clear, /* tp_clear */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ (richcmpfunc)Vector_richcmpr, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ Vector_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ Vector_getseters, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ Vector_new, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL,
};
-PyObject *Vector_CreatePyObject(
- const float *vec, const int size,
- PyTypeObject *base_type)
-{
- VectorObject *self;
- float *vec_alloc;
-
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector(): invalid size");
- return NULL;
- }
-
- vec_alloc = PyMem_Malloc(size * sizeof(float));
- if (UNLIKELY(vec_alloc == NULL)) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector(): "
- "problem allocating data");
- return NULL;
- }
-
- self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
- if (self) {
- self->vec = vec_alloc;
- self->size = size;
-
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
-
- if (vec) {
- memcpy(self->vec, vec, size * sizeof(float));
- }
- else { /* new empty */
- copy_vn_fl(self->vec, size, 0.0f);
- if (size == 4) { /* do the homogeneous thing */
- self->vec[3] = 1.0f;
- }
- }
- self->flag = BASE_MATH_FLAG_DEFAULT;
- }
- else {
- PyMem_Free(vec_alloc);
- }
-
- return (PyObject *)self;
+PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *base_type)
+{
+ VectorObject *self;
+ float *vec_alloc;
+
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
+ return NULL;
+ }
+
+ vec_alloc = PyMem_Malloc(size * sizeof(float));
+ if (UNLIKELY(vec_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating data");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
+ if (self) {
+ self->vec = vec_alloc;
+ self->size = size;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ if (vec) {
+ memcpy(self->vec, vec, size * sizeof(float));
+ }
+ else { /* new empty */
+ copy_vn_fl(self->vec, size, 0.0f);
+ if (size == 4) { /* do the homogeneous thing */
+ self->vec[3] = 1.0f;
+ }
+ }
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(vec_alloc);
+ }
+
+ return (PyObject *)self;
}
/**
@@ -3198,64 +3382,60 @@ PyObject *Vector_CreatePyObject(
*
* \param vec: Use this vector in-place.
*/
-PyObject *Vector_CreatePyObject_wrap(
- float *vec, const int size,
- PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type)
{
- VectorObject *self;
+ VectorObject *self;
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError,
- "Vector(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
+ return NULL;
+ }
- self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
- if (self) {
- self->size = size;
+ self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
+ if (self) {
+ self->size = size;
- /* init callbacks as NULL */
- self->cb_user = NULL;
- self->cb_type = self->cb_subtype = 0;
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
- self->vec = vec;
- self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
- }
- return (PyObject *) self;
+ self->vec = vec;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+ }
+ return (PyObject *)self;
}
/**
* Create a vector where the value is defined by registered callbacks,
* see: #Mathutils_RegisterCallback
*/
-PyObject *Vector_CreatePyObject_cb(
- PyObject *cb_user, int size,
- unsigned char cb_type, unsigned char cb_subtype)
+PyObject *Vector_CreatePyObject_cb(PyObject *cb_user,
+ int size,
+ unsigned char cb_type,
+ unsigned char cb_subtype)
{
- VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL);
- if (self) {
- Py_INCREF(cb_user);
- self->cb_user = cb_user;
- self->cb_type = cb_type;
- self->cb_subtype = cb_subtype;
- PyObject_GC_Track(self);
- }
+ VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL);
+ if (self) {
+ Py_INCREF(cb_user);
+ self->cb_user = cb_user;
+ self->cb_type = cb_type;
+ self->cb_subtype = cb_subtype;
+ PyObject_GC_Track(self);
+ }
- return (PyObject *)self;
+ return (PyObject *)self;
}
/**
* \param vec: Initialized vector value to use in-place, allocated with: PyMem_Malloc
*/
-PyObject *Vector_CreatePyObject_alloc(
- float *vec, const int size,
- PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type)
{
- VectorObject *self;
- self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type);
- if (self) {
- self->flag = BASE_MATH_FLAG_DEFAULT;
- }
+ VectorObject *self;
+ self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type);
+ if (self) {
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
- return (PyObject *)self;
+ return (PyObject *)self;
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h
index 7ebc3fbf1d6..f75702bc54c 100644
--- a/source/blender/python/mathutils/mathutils_Vector.h
+++ b/source/blender/python/mathutils/mathutils_Vector.h
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#ifndef __MATHUTILS_VECTOR_H__
#define __MATHUTILS_VECTOR_H__
@@ -28,27 +27,26 @@ extern PyTypeObject vector_Type;
#define VectorObject_CheckExact(v) (Py_TYPE(v) == &vector_Type)
typedef struct {
- BASE_MATH_MEMBERS(vec);
+ BASE_MATH_MEMBERS(vec);
- int size; /* vec size 2 or more */
+ int size; /* vec size 2 or more */
} VectorObject;
/*prototypes*/
-PyObject *Vector_CreatePyObject(
- const float *vec, const int size,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Vector_CreatePyObject_wrap(
- float *vec, const int size,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-PyObject *Vector_CreatePyObject_cb(
- PyObject *user, int size,
- unsigned char cb_type, unsigned char subtype
- ) ATTR_WARN_UNUSED_RESULT;
-PyObject *Vector_CreatePyObject_alloc(
- float *vec, const int size,
- PyTypeObject *base_type
- ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-
-#endif /* __MATHUTILS_VECTOR_H__ */
+PyObject *Vector_CreatePyObject(const float *vec,
+ const int size,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
+PyObject *Vector_CreatePyObject_wrap(float *vec,
+ const int size,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+PyObject *Vector_CreatePyObject_cb(PyObject *user,
+ int size,
+ unsigned char cb_type,
+ unsigned char subtype) ATTR_WARN_UNUSED_RESULT;
+PyObject *Vector_CreatePyObject_alloc(float *vec,
+ const int size,
+ PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+
+#endif /* __MATHUTILS_VECTOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index b1420f316e6..cdb3035c0ca 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -38,52 +38,50 @@
#include "../generic/python_utildefines.h"
#include "mathutils.h"
-#include "mathutils_bvhtree.h" /* own include */
+#include "mathutils_bvhtree.h" /* own include */
#ifndef MATH_STANDALONE
-#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
+# include "DNA_object_types.h"
+# include "DNA_mesh_types.h"
+# include "DNA_meshdata_types.h"
-#include "BKE_customdata.h"
-#include "BKE_editmesh_bvh.h"
-#include "BKE_library.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
+# include "BKE_customdata.h"
+# include "BKE_editmesh_bvh.h"
+# include "BKE_library.h"
+# include "BKE_mesh.h"
+# include "BKE_mesh_runtime.h"
-#include "DEG_depsgraph_query.h"
+# include "DEG_depsgraph_query.h"
-#include "bmesh.h"
-
-#include "../bmesh/bmesh_py_types.h"
-#endif /* MATH_STANDALONE */
+# include "bmesh.h"
+# include "../bmesh/bmesh_py_types.h"
+#endif /* MATH_STANDALONE */
#include "BLI_strict_flags.h"
-
/* -------------------------------------------------------------------- */
/** \name Docstring (snippets)
* \{ */
#define PYBVH_FIND_GENERIC_DISTANCE_DOC \
-" :arg distance: Maximum distance threshold.\n" \
-" :type distance: float\n"
+ " :arg distance: Maximum distance threshold.\n" \
+ " :type distance: float\n"
#define PYBVH_FIND_GENERIC_RETURN_DOC \
-" :return: Returns a tuple\n" \
-" (:class:`Vector` location, :class:`Vector` normal, int index, float distance),\n" \
-" Values will all be None if no hit is found.\n" \
-" :rtype: :class:`tuple`\n"
+ " :return: Returns a tuple\n" \
+ " (:class:`Vector` location, :class:`Vector` normal, int index, float distance),\n" \
+ " Values will all be None if no hit is found.\n" \
+ " :rtype: :class:`tuple`\n"
#define PYBVH_FIND_GENERIC_RETURN_LIST_DOC \
-" :return: Returns a list of tuples\n" \
-" (:class:`Vector` location, :class:`Vector` normal, int index, float distance),\n" \
-" :rtype: :class:`list`\n"
+ " :return: Returns a list of tuples\n" \
+ " (:class:`Vector` location, :class:`Vector` normal, int index, float distance),\n" \
+ " :rtype: :class:`list`\n"
#define PYBVH_FROM_GENERIC_EPSILON_DOC \
-" :arg epsilon: Increase the threshold for detecting overlap and raycast hits.\n" \
-" :type epsilon: float\n"
+ " :arg epsilon: Increase the threshold for detecting overlap and raycast hits.\n" \
+ " :type epsilon: float\n"
/** \} */
@@ -95,160 +93,157 @@ static const char PY_BVH_TREE_TYPE_DEFAULT = 4;
static const char PY_BVH_AXIS_DEFAULT = 6;
typedef struct {
- PyObject_HEAD
- BVHTree *tree;
- float epsilon;
-
- float (*coords)[3];
- unsigned int (*tris)[3];
- unsigned int coords_len, tris_len;
-
- /* Optional members */
- /* aligned with 'tris' */
- int *orig_index;
- /* aligned with array that 'orig_index' points to */
- float (*orig_normal)[3];
+ PyObject_HEAD BVHTree *tree;
+ float epsilon;
+
+ float (*coords)[3];
+ unsigned int (*tris)[3];
+ unsigned int coords_len, tris_len;
+
+ /* Optional members */
+ /* aligned with 'tris' */
+ int *orig_index;
+ /* aligned with array that 'orig_index' points to */
+ float (*orig_normal)[3];
} PyBVHTree;
-
/* -------------------------------------------------------------------- */
/** \name Utility helper functions
* \{ */
-static PyObject *bvhtree_CreatePyObject(
- BVHTree *tree, float epsilon,
+static PyObject *bvhtree_CreatePyObject(BVHTree *tree,
+ float epsilon,
- float (*coords)[3], unsigned int coords_len,
- unsigned int (*tris)[3], unsigned int tris_len,
+ float (*coords)[3],
+ unsigned int coords_len,
+ unsigned int (*tris)[3],
+ unsigned int tris_len,
- /* optional arrays */
- int *orig_index, float (*orig_normal)[3])
+ /* optional arrays */
+ int *orig_index,
+ float (*orig_normal)[3])
{
- PyBVHTree *result = PyObject_New(PyBVHTree, &PyBVHTree_Type);
+ PyBVHTree *result = PyObject_New(PyBVHTree, &PyBVHTree_Type);
- result->tree = tree;
- result->epsilon = epsilon;
+ result->tree = tree;
+ result->epsilon = epsilon;
- result->coords = coords;
- result->tris = tris;
- result->coords_len = coords_len;
- result->tris_len = tris_len;
+ result->coords = coords;
+ result->tris = tris;
+ result->coords_len = coords_len;
+ result->tris_len = tris_len;
- result->orig_index = orig_index;
- result->orig_normal = orig_normal;
+ result->orig_index = orig_index;
+ result->orig_normal = orig_normal;
- return (PyObject *)result;
+ return (PyObject *)result;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BVHTreeRayHit to Python utilities
* \{ */
static void py_bvhtree_raycast_to_py_tuple(const BVHTreeRayHit *hit, PyObject *py_retval)
{
- BLI_assert(hit->index >= 0);
- BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
-
- PyTuple_SET_ITEMS(py_retval,
- Vector_CreatePyObject(hit->co, 3, NULL),
- Vector_CreatePyObject(hit->no, 3, NULL),
- PyLong_FromLong(hit->index),
- PyFloat_FromDouble(hit->dist));
-
+ BLI_assert(hit->index >= 0);
+ BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
+
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject(hit->co, 3, NULL),
+ Vector_CreatePyObject(hit->no, 3, NULL),
+ PyLong_FromLong(hit->index),
+ PyFloat_FromDouble(hit->dist));
}
static PyObject *py_bvhtree_raycast_to_py(const BVHTreeRayHit *hit)
{
- PyObject *py_retval = PyTuple_New(4);
+ PyObject *py_retval = PyTuple_New(4);
- py_bvhtree_raycast_to_py_tuple(hit, py_retval);
+ py_bvhtree_raycast_to_py_tuple(hit, py_retval);
- return py_retval;
+ return py_retval;
}
static PyObject *py_bvhtree_raycast_to_py_none(void)
{
- PyObject *py_retval = PyTuple_New(4);
+ PyObject *py_retval = PyTuple_New(4);
- PyC_Tuple_Fill(py_retval, Py_None);
+ PyC_Tuple_Fill(py_retval, Py_None);
- return py_retval;
+ return py_retval;
}
#if 0
static PyObject *py_bvhtree_raycast_to_py_and_check(const BVHTreeRayHit *hit)
{
- PyObject *py_retval;
+ PyObject *py_retval;
- py_retval = PyTuple_New(4);
+ py_retval = PyTuple_New(4);
- if (hit->index != -1) {
- py_bvhtree_raycast_to_py_tuple(hit, py_retval);
- }
- else {
- PyC_Tuple_Fill(py_retval, Py_None);
- }
+ if (hit->index != -1) {
+ py_bvhtree_raycast_to_py_tuple(hit, py_retval);
+ }
+ else {
+ PyC_Tuple_Fill(py_retval, Py_None);
+ }
- return py_retval;
+ return py_retval;
}
#endif
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BVHTreeNearest to Python utilities
* \{ */
static void py_bvhtree_nearest_to_py_tuple(const BVHTreeNearest *nearest, PyObject *py_retval)
{
- BLI_assert(nearest->index >= 0);
- BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
-
- PyTuple_SET_ITEMS(py_retval,
- Vector_CreatePyObject(nearest->co, 3, NULL),
- Vector_CreatePyObject(nearest->no, 3, NULL),
- PyLong_FromLong(nearest->index),
- PyFloat_FromDouble(sqrtf(nearest->dist_sq)));
-
+ BLI_assert(nearest->index >= 0);
+ BLI_assert(PyTuple_GET_SIZE(py_retval) == 4);
+
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject(nearest->co, 3, NULL),
+ Vector_CreatePyObject(nearest->no, 3, NULL),
+ PyLong_FromLong(nearest->index),
+ PyFloat_FromDouble(sqrtf(nearest->dist_sq)));
}
static PyObject *py_bvhtree_nearest_to_py(const BVHTreeNearest *nearest)
{
- PyObject *py_retval = PyTuple_New(4);
+ PyObject *py_retval = PyTuple_New(4);
- py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
+ py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
- return py_retval;
+ return py_retval;
}
static PyObject *py_bvhtree_nearest_to_py_none(void)
{
- PyObject *py_retval = PyTuple_New(4);
+ PyObject *py_retval = PyTuple_New(4);
- PyC_Tuple_Fill(py_retval, Py_None);
+ PyC_Tuple_Fill(py_retval, Py_None);
- return py_retval;
+ return py_retval;
}
#if 0
static PyObject *py_bvhtree_nearest_to_py_and_check(const BVHTreeNearest *nearest)
{
- PyObject *py_retval;
+ PyObject *py_retval;
- py_retval = PyTuple_New(4);
+ py_retval = PyTuple_New(4);
- if (nearest->index != -1) {
- py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
- }
- else {
- PyC_Tuple_Fill(py_retval, Py_None);
- }
+ if (nearest->index != -1) {
+ py_bvhtree_nearest_to_py_tuple(nearest, py_retval);
+ }
+ else {
+ PyC_Tuple_Fill(py_retval, Py_None);
+ }
- return py_retval;
+ return py_retval;
}
#endif
@@ -256,1082 +251,1098 @@ static PyObject *py_bvhtree_nearest_to_py_and_check(const BVHTreeNearest *neares
static void py_bvhtree__tp_dealloc(PyBVHTree *self)
{
- if (self->tree) {
- BLI_bvhtree_free(self->tree);
- }
+ if (self->tree) {
+ BLI_bvhtree_free(self->tree);
+ }
- MEM_SAFE_FREE(self->coords);
- MEM_SAFE_FREE(self->tris);
+ MEM_SAFE_FREE(self->coords);
+ MEM_SAFE_FREE(self->tris);
- MEM_SAFE_FREE(self->orig_index);
- MEM_SAFE_FREE(self->orig_normal);
+ MEM_SAFE_FREE(self->orig_index);
+ MEM_SAFE_FREE(self->orig_normal);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
}
-
/* -------------------------------------------------------------------- */
/** \name Methods
* \{ */
-static void py_bvhtree_raycast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+static void py_bvhtree_raycast_cb(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
{
- const PyBVHTree *self = userdata;
-
- const float (*coords)[3] = (const float (*)[3])self->coords;
- const unsigned int *tri = self->tris[index];
- const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
- float dist;
-
- if (self->epsilon == 0.0f) {
- dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(tri_co));
- }
- else {
- dist = bvhtree_sphereray_tri_intersection(ray, self->epsilon, hit->dist, UNPACK3(tri_co));
- }
-
- if (dist >= 0 && dist < hit->dist) {
- hit->index = self->orig_index ? self->orig_index[index] : index;
- hit->dist = dist;
- madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
- if (self->orig_normal) {
- copy_v3_v3(hit->no, self->orig_normal[hit->index]);
- }
- else {
- normal_tri_v3(hit->no, UNPACK3(tri_co));
- }
- }
+ const PyBVHTree *self = userdata;
+
+ const float(*coords)[3] = (const float(*)[3])self->coords;
+ const unsigned int *tri = self->tris[index];
+ const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
+ float dist;
+
+ if (self->epsilon == 0.0f) {
+ dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(tri_co));
+ }
+ else {
+ dist = bvhtree_sphereray_tri_intersection(ray, self->epsilon, hit->dist, UNPACK3(tri_co));
+ }
+
+ if (dist >= 0 && dist < hit->dist) {
+ hit->index = self->orig_index ? self->orig_index[index] : index;
+ hit->dist = dist;
+ madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
+ if (self->orig_normal) {
+ copy_v3_v3(hit->no, self->orig_normal[hit->index]);
+ }
+ else {
+ normal_tri_v3(hit->no, UNPACK3(tri_co));
+ }
+ }
}
-static void py_bvhtree_nearest_point_cb(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
+static void py_bvhtree_nearest_point_cb(void *userdata,
+ int index,
+ const float co[3],
+ BVHTreeNearest *nearest)
{
- PyBVHTree *self = userdata;
-
- const float (*coords)[3] = (const float (*)[3])self->coords;
- const unsigned int *tri = self->tris[index];
- const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
- float nearest_tmp[3], dist_sq;
-
- closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(tri_co));
- dist_sq = len_squared_v3v3(co, nearest_tmp);
-
- if (dist_sq < nearest->dist_sq) {
- nearest->index = self->orig_index ? self->orig_index[index] : index;
- nearest->dist_sq = dist_sq;
- copy_v3_v3(nearest->co, nearest_tmp);
- if (self->orig_normal) {
- copy_v3_v3(nearest->no, self->orig_normal[nearest->index]);
- }
- else {
- normal_tri_v3(nearest->no, UNPACK3(tri_co));
- }
- }
+ PyBVHTree *self = userdata;
+
+ const float(*coords)[3] = (const float(*)[3])self->coords;
+ const unsigned int *tri = self->tris[index];
+ const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
+ float nearest_tmp[3], dist_sq;
+
+ closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(tri_co));
+ dist_sq = len_squared_v3v3(co, nearest_tmp);
+
+ if (dist_sq < nearest->dist_sq) {
+ nearest->index = self->orig_index ? self->orig_index[index] : index;
+ nearest->dist_sq = dist_sq;
+ copy_v3_v3(nearest->co, nearest_tmp);
+ if (self->orig_normal) {
+ copy_v3_v3(nearest->no, self->orig_normal[nearest->index]);
+ }
+ else {
+ normal_tri_v3(nearest->no, UNPACK3(tri_co));
+ }
+ }
}
PyDoc_STRVAR(py_bvhtree_ray_cast_doc,
-".. method:: ray_cast(origin, direction, distance=sys.float_info.max)\n"
-"\n"
-" Cast a ray onto the mesh.\n"
-"\n"
-" :arg co: Start location of the ray in object space.\n"
-" :type co: :class:`Vector`\n"
-" :arg direction: Direction of the ray in object space.\n"
-" :type direction: :class:`Vector`\n"
-PYBVH_FIND_GENERIC_DISTANCE_DOC
-PYBVH_FIND_GENERIC_RETURN_DOC
-);
+ ".. method:: ray_cast(origin, direction, distance=sys.float_info.max)\n"
+ "\n"
+ " Cast a ray onto the mesh.\n"
+ "\n"
+ " :arg co: Start location of the ray in object space.\n"
+ " :type co: :class:`Vector`\n"
+ " :arg direction: Direction of the ray in object space.\n"
+ " :type direction: :class:`Vector`\n" PYBVH_FIND_GENERIC_DISTANCE_DOC
+ PYBVH_FIND_GENERIC_RETURN_DOC);
static PyObject *py_bvhtree_ray_cast(PyBVHTree *self, PyObject *args)
{
- const char *error_prefix = "ray_cast";
- float co[3], direction[3];
- float max_dist = FLT_MAX;
- BVHTreeRayHit hit;
-
- /* parse args */
- {
- PyObject *py_co, *py_direction;
-
- if (!PyArg_ParseTuple(
- args, (char *)"OO|f:ray_cast",
- &py_co, &py_direction, &max_dist))
- {
- return NULL;
- }
-
- if ((mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) ||
- (mathutils_array_parse(direction, 2, 3 | MU_ARRAY_ZERO, py_direction, error_prefix) == -1))
- {
- return NULL;
- }
-
- normalize_v3(direction);
- }
-
- hit.dist = max_dist;
- hit.index = -1;
-
- /* may fail if the mesh has no faces, in that case the ray-cast misses */
- if (self->tree) {
- if (BLI_bvhtree_ray_cast(
- self->tree, co, direction, 0.0f, &hit,
- py_bvhtree_raycast_cb, self) != -1)
- {
- return py_bvhtree_raycast_to_py(&hit);
- }
- }
-
- return py_bvhtree_raycast_to_py_none();
+ const char *error_prefix = "ray_cast";
+ float co[3], direction[3];
+ float max_dist = FLT_MAX;
+ BVHTreeRayHit hit;
+
+ /* parse args */
+ {
+ PyObject *py_co, *py_direction;
+
+ if (!PyArg_ParseTuple(args, (char *)"OO|f:ray_cast", &py_co, &py_direction, &max_dist)) {
+ return NULL;
+ }
+
+ if ((mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) ||
+ (mathutils_array_parse(direction, 2, 3 | MU_ARRAY_ZERO, py_direction, error_prefix) ==
+ -1)) {
+ return NULL;
+ }
+
+ normalize_v3(direction);
+ }
+
+ hit.dist = max_dist;
+ hit.index = -1;
+
+ /* may fail if the mesh has no faces, in that case the ray-cast misses */
+ if (self->tree) {
+ if (BLI_bvhtree_ray_cast(self->tree, co, direction, 0.0f, &hit, py_bvhtree_raycast_cb, self) !=
+ -1) {
+ return py_bvhtree_raycast_to_py(&hit);
+ }
+ }
+
+ return py_bvhtree_raycast_to_py_none();
}
PyDoc_STRVAR(py_bvhtree_find_nearest_doc,
-".. method:: find_nearest(origin, distance=" PYBVH_MAX_DIST_STR ")\n"
-"\n"
-" Find the nearest element (typically face index) to a point.\n"
-"\n"
-" :arg co: Find nearest element to this point.\n"
-" :type co: :class:`Vector`\n"
-PYBVH_FIND_GENERIC_DISTANCE_DOC
-PYBVH_FIND_GENERIC_RETURN_DOC
-);
+ ".. method:: find_nearest(origin, distance=" PYBVH_MAX_DIST_STR
+ ")\n"
+ "\n"
+ " Find the nearest element (typically face index) to a point.\n"
+ "\n"
+ " :arg co: Find nearest element to this point.\n"
+ " :type co: :class:`Vector`\n" PYBVH_FIND_GENERIC_DISTANCE_DOC
+ PYBVH_FIND_GENERIC_RETURN_DOC);
static PyObject *py_bvhtree_find_nearest(PyBVHTree *self, PyObject *args)
{
- const char *error_prefix = "find_nearest";
- float co[3];
- float max_dist = max_dist_default;
-
- BVHTreeNearest nearest;
-
- /* parse args */
- {
- PyObject *py_co;
-
- if (!PyArg_ParseTuple(
- args, (char *)"O|f:find_nearest",
- &py_co, &max_dist))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) {
- return NULL;
- }
- }
-
- nearest.index = -1;
- nearest.dist_sq = max_dist * max_dist;
-
- /* may fail if the mesh has no faces, in that case the ray-cast misses */
- if (self->tree) {
- if (BLI_bvhtree_find_nearest(
- self->tree, co, &nearest,
- py_bvhtree_nearest_point_cb, self) != -1)
- {
- return py_bvhtree_nearest_to_py(&nearest);
- }
- }
-
- return py_bvhtree_nearest_to_py_none();
+ const char *error_prefix = "find_nearest";
+ float co[3];
+ float max_dist = max_dist_default;
+
+ BVHTreeNearest nearest;
+
+ /* parse args */
+ {
+ PyObject *py_co;
+
+ if (!PyArg_ParseTuple(args, (char *)"O|f:find_nearest", &py_co, &max_dist)) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ nearest.index = -1;
+ nearest.dist_sq = max_dist * max_dist;
+
+ /* may fail if the mesh has no faces, in that case the ray-cast misses */
+ if (self->tree) {
+ if (BLI_bvhtree_find_nearest(self->tree, co, &nearest, py_bvhtree_nearest_point_cb, self) !=
+ -1) {
+ return py_bvhtree_nearest_to_py(&nearest);
+ }
+ }
+
+ return py_bvhtree_nearest_to_py_none();
}
struct PyBVH_RangeData {
- PyBVHTree *self;
- PyObject *result;
- float dist_sq;
+ PyBVHTree *self;
+ PyObject *result;
+ float dist_sq;
};
-static void py_bvhtree_nearest_point_range_cb(void *userdata, int index, const float co[3], float UNUSED(dist_sq_bvh))
+static void py_bvhtree_nearest_point_range_cb(void *userdata,
+ int index,
+ const float co[3],
+ float UNUSED(dist_sq_bvh))
{
- struct PyBVH_RangeData *data = userdata;
- PyBVHTree *self = data->self;
-
- const float (*coords)[3] = (const float (*)[3])self->coords;
- const unsigned int *tri = self->tris[index];
- const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
- float nearest_tmp[3], dist_sq;
-
- closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(tri_co));
- dist_sq = len_squared_v3v3(co, nearest_tmp);
-
- if (dist_sq < data->dist_sq) {
- BVHTreeNearest nearest;
- nearest.index = self->orig_index ? self->orig_index[index] : index;
- nearest.dist_sq = dist_sq;
- copy_v3_v3(nearest.co, nearest_tmp);
- if (self->orig_normal) {
- copy_v3_v3(nearest.no, self->orig_normal[nearest.index]);
- }
- else {
- normal_tri_v3(nearest.no, UNPACK3(tri_co));
- }
-
- PyList_APPEND(data->result, py_bvhtree_nearest_to_py(&nearest));
- }
+ struct PyBVH_RangeData *data = userdata;
+ PyBVHTree *self = data->self;
+
+ const float(*coords)[3] = (const float(*)[3])self->coords;
+ const unsigned int *tri = self->tris[index];
+ const float *tri_co[3] = {coords[tri[0]], coords[tri[1]], coords[tri[2]]};
+ float nearest_tmp[3], dist_sq;
+
+ closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(tri_co));
+ dist_sq = len_squared_v3v3(co, nearest_tmp);
+
+ if (dist_sq < data->dist_sq) {
+ BVHTreeNearest nearest;
+ nearest.index = self->orig_index ? self->orig_index[index] : index;
+ nearest.dist_sq = dist_sq;
+ copy_v3_v3(nearest.co, nearest_tmp);
+ if (self->orig_normal) {
+ copy_v3_v3(nearest.no, self->orig_normal[nearest.index]);
+ }
+ else {
+ normal_tri_v3(nearest.no, UNPACK3(tri_co));
+ }
+
+ PyList_APPEND(data->result, py_bvhtree_nearest_to_py(&nearest));
+ }
}
-PyDoc_STRVAR(py_bvhtree_find_nearest_range_doc,
-".. method:: find_nearest_range(origin, distance=" PYBVH_MAX_DIST_STR ")\n"
-"\n"
-" Find the nearest elements (typically face index) to a point in the distance range.\n"
-"\n"
-" :arg co: Find nearest elements to this point.\n"
-" :type co: :class:`Vector`\n"
-PYBVH_FIND_GENERIC_DISTANCE_DOC
-PYBVH_FIND_GENERIC_RETURN_LIST_DOC
-);
+PyDoc_STRVAR(
+ py_bvhtree_find_nearest_range_doc,
+ ".. method:: find_nearest_range(origin, distance=" PYBVH_MAX_DIST_STR
+ ")\n"
+ "\n"
+ " Find the nearest elements (typically face index) to a point in the distance range.\n"
+ "\n"
+ " :arg co: Find nearest elements to this point.\n"
+ " :type co: :class:`Vector`\n" PYBVH_FIND_GENERIC_DISTANCE_DOC
+ PYBVH_FIND_GENERIC_RETURN_LIST_DOC);
static PyObject *py_bvhtree_find_nearest_range(PyBVHTree *self, PyObject *args)
{
- const char *error_prefix = "find_nearest_range";
- float co[3];
- float max_dist = max_dist_default;
-
- /* parse args */
- {
- PyObject *py_co;
-
- if (!PyArg_ParseTuple(
- args, (char *)"O|f:find_nearest_range",
- &py_co, &max_dist))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) {
- return NULL;
- }
- }
-
- PyObject *ret = PyList_New(0);
-
- if (self->tree) {
- struct PyBVH_RangeData data = {
- .self = self,
- .result = ret,
- .dist_sq = SQUARE(max_dist),
- };
-
- BLI_bvhtree_range_query(
- self->tree, co, max_dist,
- py_bvhtree_nearest_point_range_cb, &data);
- }
-
- return ret;
-}
+ const char *error_prefix = "find_nearest_range";
+ float co[3];
+ float max_dist = max_dist_default;
+
+ /* parse args */
+ {
+ PyObject *py_co;
+
+ if (!PyArg_ParseTuple(args, (char *)"O|f:find_nearest_range", &py_co, &max_dist)) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(co, 2, 3 | MU_ARRAY_ZERO, py_co, error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ PyObject *ret = PyList_New(0);
+ if (self->tree) {
+ struct PyBVH_RangeData data = {
+ .self = self,
+ .result = ret,
+ .dist_sq = SQUARE(max_dist),
+ };
+
+ BLI_bvhtree_range_query(self->tree, co, max_dist, py_bvhtree_nearest_point_range_cb, &data);
+ }
+
+ return ret;
+}
BLI_INLINE unsigned int overlap_hash(const void *overlap_v)
{
- const BVHTreeOverlap *overlap = overlap_v;
- /* same constants as edge-hash */
- return (((unsigned int)overlap->indexA * 65) ^ ((unsigned int)overlap->indexA * 31));
+ const BVHTreeOverlap *overlap = overlap_v;
+ /* same constants as edge-hash */
+ return (((unsigned int)overlap->indexA * 65) ^ ((unsigned int)overlap->indexA * 31));
}
BLI_INLINE bool overlap_cmp(const void *a_v, const void *b_v)
{
- const BVHTreeOverlap *a = a_v;
- const BVHTreeOverlap *b = b_v;
- return (memcmp(a, b, sizeof(*a)) != 0);
+ const BVHTreeOverlap *a = a_v;
+ const BVHTreeOverlap *b = b_v;
+ return (memcmp(a, b, sizeof(*a)) != 0);
}
struct PyBVHTree_OverlapData {
- PyBVHTree *tree_pair[2];
- float epsilon;
+ PyBVHTree *tree_pair[2];
+ float epsilon;
};
static bool py_bvhtree_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
{
- struct PyBVHTree_OverlapData *data = userdata;
- PyBVHTree *tree_a = data->tree_pair[0];
- PyBVHTree *tree_b = data->tree_pair[1];
- const unsigned int *tri_a = tree_a->tris[index_a];
- const unsigned int *tri_b = tree_b->tris[index_b];
- const float *tri_a_co[3] = {tree_a->coords[tri_a[0]], tree_a->coords[tri_a[1]], tree_a->coords[tri_a[2]]};
- const float *tri_b_co[3] = {tree_b->coords[tri_b[0]], tree_b->coords[tri_b[1]], tree_b->coords[tri_b[2]]};
- float ix_pair[2][3];
- int verts_shared = 0;
-
- if (tree_a == tree_b) {
- if (UNLIKELY(index_a == index_b)) {
- return false;
- }
-
- verts_shared = (
- ELEM(tri_a_co[0], UNPACK3(tri_b_co)) +
- ELEM(tri_a_co[1], UNPACK3(tri_b_co)) +
- ELEM(tri_a_co[2], UNPACK3(tri_b_co)));
-
- /* if 2 points are shared, bail out */
- if (verts_shared >= 2) {
- return false;
- }
- }
-
- return (isect_tri_tri_epsilon_v3(UNPACK3(tri_a_co), UNPACK3(tri_b_co), ix_pair[0], ix_pair[1], data->epsilon) &&
- ((verts_shared == 0) || (len_squared_v3v3(ix_pair[0], ix_pair[1]) > data->epsilon)));
+ struct PyBVHTree_OverlapData *data = userdata;
+ PyBVHTree *tree_a = data->tree_pair[0];
+ PyBVHTree *tree_b = data->tree_pair[1];
+ const unsigned int *tri_a = tree_a->tris[index_a];
+ const unsigned int *tri_b = tree_b->tris[index_b];
+ const float *tri_a_co[3] = {
+ tree_a->coords[tri_a[0]], tree_a->coords[tri_a[1]], tree_a->coords[tri_a[2]]};
+ const float *tri_b_co[3] = {
+ tree_b->coords[tri_b[0]], tree_b->coords[tri_b[1]], tree_b->coords[tri_b[2]]};
+ float ix_pair[2][3];
+ int verts_shared = 0;
+
+ if (tree_a == tree_b) {
+ if (UNLIKELY(index_a == index_b)) {
+ return false;
+ }
+
+ verts_shared = (ELEM(tri_a_co[0], UNPACK3(tri_b_co)) + ELEM(tri_a_co[1], UNPACK3(tri_b_co)) +
+ ELEM(tri_a_co[2], UNPACK3(tri_b_co)));
+
+ /* if 2 points are shared, bail out */
+ if (verts_shared >= 2) {
+ return false;
+ }
+ }
+
+ return (isect_tri_tri_epsilon_v3(
+ UNPACK3(tri_a_co), UNPACK3(tri_b_co), ix_pair[0], ix_pair[1], data->epsilon) &&
+ ((verts_shared == 0) || (len_squared_v3v3(ix_pair[0], ix_pair[1]) > data->epsilon)));
}
-PyDoc_STRVAR(py_bvhtree_overlap_doc,
-".. method:: overlap(other_tree)\n"
-"\n"
-" Find overlapping indices between 2 trees.\n"
-"\n"
-" :arg other_tree: Other tree to perform overlap test on.\n"
-" :type other_tree: :class:`BVHTree`\n"
-" :return: Returns a list of unique index pairs,"
-" the first index referencing this tree, the second referencing the **other_tree**.\n"
-" :rtype: :class:`list`\n"
-);
+PyDoc_STRVAR(
+ py_bvhtree_overlap_doc,
+ ".. method:: overlap(other_tree)\n"
+ "\n"
+ " Find overlapping indices between 2 trees.\n"
+ "\n"
+ " :arg other_tree: Other tree to perform overlap test on.\n"
+ " :type other_tree: :class:`BVHTree`\n"
+ " :return: Returns a list of unique index pairs,"
+ " the first index referencing this tree, the second referencing the **other_tree**.\n"
+ " :rtype: :class:`list`\n");
static PyObject *py_bvhtree_overlap(PyBVHTree *self, PyBVHTree *other)
{
- struct PyBVHTree_OverlapData data;
- BVHTreeOverlap *overlap;
- unsigned int overlap_len = 0;
- PyObject *ret;
-
- if (!PyBVHTree_CheckExact(other)) {
- PyErr_SetString(PyExc_ValueError, "Expected a BVHTree argument");
- return NULL;
- }
-
- data.tree_pair[0] = self;
- data.tree_pair[1] = other;
- data.epsilon = max_ff(self->epsilon, other->epsilon);
-
- overlap = BLI_bvhtree_overlap(self->tree, other->tree, &overlap_len, py_bvhtree_overlap_cb, &data);
-
- ret = PyList_New(0);
-
- if (overlap == NULL) {
- /* pass */
- }
- else {
- bool use_unique = (self->orig_index || other->orig_index);
- GSet *pair_test = use_unique ? BLI_gset_new_ex(overlap_hash, overlap_cmp, __func__, overlap_len) : NULL;
- /* simple case, no index remapping */
- unsigned int i;
-
- for (i = 0; i < overlap_len; i++) {
- PyObject *item;
- if (use_unique) {
- if (self->orig_index) {
- overlap[i].indexA = self->orig_index[overlap[i].indexA];
- }
- if (other->orig_index) {
- overlap[i].indexB = other->orig_index[overlap[i].indexB];
- }
-
- /* skip if its already added */
- if (!BLI_gset_add(pair_test, &overlap[i])) {
- continue;
- }
- }
-
- item = PyTuple_New(2);
- PyTuple_SET_ITEMS(item,
- PyLong_FromLong(overlap[i].indexA),
- PyLong_FromLong(overlap[i].indexB));
-
- PyList_Append(ret, item);
- Py_DECREF(item);
- }
-
- if (pair_test) {
- BLI_gset_free(pair_test, NULL);
- }
- }
-
- if (overlap) {
- MEM_freeN(overlap);
- }
-
- return ret;
+ struct PyBVHTree_OverlapData data;
+ BVHTreeOverlap *overlap;
+ unsigned int overlap_len = 0;
+ PyObject *ret;
+
+ if (!PyBVHTree_CheckExact(other)) {
+ PyErr_SetString(PyExc_ValueError, "Expected a BVHTree argument");
+ return NULL;
+ }
+
+ data.tree_pair[0] = self;
+ data.tree_pair[1] = other;
+ data.epsilon = max_ff(self->epsilon, other->epsilon);
+
+ overlap = BLI_bvhtree_overlap(
+ self->tree, other->tree, &overlap_len, py_bvhtree_overlap_cb, &data);
+
+ ret = PyList_New(0);
+
+ if (overlap == NULL) {
+ /* pass */
+ }
+ else {
+ bool use_unique = (self->orig_index || other->orig_index);
+ GSet *pair_test = use_unique ?
+ BLI_gset_new_ex(overlap_hash, overlap_cmp, __func__, overlap_len) :
+ NULL;
+ /* simple case, no index remapping */
+ unsigned int i;
+
+ for (i = 0; i < overlap_len; i++) {
+ PyObject *item;
+ if (use_unique) {
+ if (self->orig_index) {
+ overlap[i].indexA = self->orig_index[overlap[i].indexA];
+ }
+ if (other->orig_index) {
+ overlap[i].indexB = other->orig_index[overlap[i].indexB];
+ }
+
+ /* skip if its already added */
+ if (!BLI_gset_add(pair_test, &overlap[i])) {
+ continue;
+ }
+ }
+
+ item = PyTuple_New(2);
+ PyTuple_SET_ITEMS(
+ item, PyLong_FromLong(overlap[i].indexA), PyLong_FromLong(overlap[i].indexB));
+
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+ }
+
+ if (pair_test) {
+ BLI_gset_free(pair_test, NULL);
+ }
+ }
+
+ if (overlap) {
+ MEM_freeN(overlap);
+ }
+
+ return ret;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Class Methods
* \{ */
-PyDoc_STRVAR(C_BVHTree_FromPolygons_doc,
-".. classmethod:: FromPolygons(vertices, polygons, all_triangles=False, epsilon=0.0)\n"
-"\n"
-" BVH tree constructed geometry passed in as arguments.\n"
-"\n"
-" :arg vertices: float triplets each representing ``(x, y, z)``\n"
-" :type vertices: float triplet sequence\n"
-" :arg polygons: Sequence of polyugons, each containing indices to the vertices argument.\n"
-" :type polygons: Sequence of sequences containing ints\n"
-" :arg all_triangles: Use when all **polygons** are triangles for more efficient conversion.\n"
-" :type all_triangles: bool\n"
-PYBVH_FROM_GENERIC_EPSILON_DOC
-);
+PyDoc_STRVAR(
+ C_BVHTree_FromPolygons_doc,
+ ".. classmethod:: FromPolygons(vertices, polygons, all_triangles=False, epsilon=0.0)\n"
+ "\n"
+ " BVH tree constructed geometry passed in as arguments.\n"
+ "\n"
+ " :arg vertices: float triplets each representing ``(x, y, z)``\n"
+ " :type vertices: float triplet sequence\n"
+ " :arg polygons: Sequence of polyugons, each containing indices to the vertices argument.\n"
+ " :type polygons: Sequence of sequences containing ints\n"
+ " :arg all_triangles: Use when all **polygons** are triangles for more efficient "
+ "conversion.\n"
+ " :type all_triangles: bool\n" PYBVH_FROM_GENERIC_EPSILON_DOC);
static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, PyObject *kwargs)
{
- const char *error_prefix = "BVHTree.FromPolygons";
- const char *keywords[] = {"vertices", "polygons", "all_triangles", "epsilon", NULL};
-
- PyObject *py_coords, *py_tris;
- PyObject *py_coords_fast = NULL, *py_tris_fast = NULL;
-
- MemArena *poly_arena = NULL;
- MemArena *pf_arena = NULL;
-
- float (*coords)[3] = NULL;
- unsigned int (*tris)[3] = NULL;
- unsigned int coords_len, tris_len;
- float epsilon = 0.0f;
- bool all_triangles = false;
-
- /* when all_triangles is False */
- int *orig_index = NULL;
- float (*orig_normal)[3] = NULL;
-
- unsigned int i;
- bool valid = true;
-
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *)"OO|$O&f:BVHTree.FromPolygons", (char **)keywords,
- &py_coords, &py_tris,
- PyC_ParseBool, &all_triangles,
- &epsilon))
- {
- return NULL;
- }
-
- if (!(py_coords_fast = PySequence_Fast(py_coords, error_prefix)) ||
- !(py_tris_fast = PySequence_Fast(py_tris, error_prefix)))
- {
- Py_XDECREF(py_coords_fast);
- return NULL;
- }
-
- if (valid) {
- PyObject **py_coords_fast_items = PySequence_Fast_ITEMS(py_coords_fast);
- coords_len = (unsigned int)PySequence_Fast_GET_SIZE(py_coords_fast);
- coords = MEM_mallocN((size_t)coords_len * sizeof(*coords), __func__);
-
- for (i = 0; i < coords_len; i++) {
- PyObject *py_vert = py_coords_fast_items[i];
-
- if (mathutils_array_parse(coords[i], 3, 3, py_vert, "BVHTree vertex: ") == -1) {
- valid = false;
- break;
- }
- }
- }
-
- if (valid == false) {
- /* pass */
- }
- else if (all_triangles) {
- /* all triangles, simple case */
- PyObject **py_tris_fast_items = PySequence_Fast_ITEMS(py_tris_fast);
- tris_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tris_fast);
- tris = MEM_mallocN((size_t)tris_len * sizeof(*tris), __func__);
-
- for (i = 0; i < tris_len; i++) {
- PyObject *py_tricoords = py_tris_fast_items[i];
- PyObject *py_tricoords_fast;
- PyObject **py_tricoords_fast_items;
- unsigned int *tri = tris[i];
- int j;
-
- if (!(py_tricoords_fast = PySequence_Fast(py_tricoords, error_prefix))) {
- valid = false;
- break;
- }
-
- if (PySequence_Fast_GET_SIZE(py_tricoords_fast) != 3) {
- Py_DECREF(py_tricoords_fast);
- PyErr_Format(PyExc_ValueError,
- "%s: non triangle found at index %d with length of %d",
- error_prefix, i, PySequence_Fast_GET_SIZE(py_tricoords_fast));
- valid = false;
- break;
- }
-
- py_tricoords_fast_items = PySequence_Fast_ITEMS(py_tricoords_fast);
-
- for (j = 0; j < 3; j++) {
- tri[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]);
- if (UNLIKELY(tri[j] >= (unsigned int)coords_len)) {
- PyErr_Format(PyExc_ValueError,
- "%s: index %d must be less than %d",
- error_prefix, tri[j], coords_len);
-
- /* decref below */
- valid = false;
- break;
- }
- }
-
- Py_DECREF(py_tricoords_fast);
- }
- }
- else {
- /* ngon support (much more involved) */
- const unsigned int polys_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tris_fast);
- struct PolyLink {
- struct PolyLink *next;
- unsigned int len;
- unsigned int poly[0];
- } *plink_first = NULL, **p_plink_prev = &plink_first, *plink = NULL;
- int poly_index;
-
- tris_len = 0;
-
- poly_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
-
- for (i = 0; i < polys_len; i++) {
- PyObject *py_tricoords = PySequence_Fast_GET_ITEM(py_tris_fast, i);
- PyObject *py_tricoords_fast;
- PyObject **py_tricoords_fast_items;
- unsigned int py_tricoords_len;
- unsigned int j;
-
- if (!(py_tricoords_fast = PySequence_Fast(py_tricoords, error_prefix))) {
- valid = false;
- break;
- }
-
- py_tricoords_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tricoords_fast);
- py_tricoords_fast_items = PySequence_Fast_ITEMS(py_tricoords_fast);
-
- plink = BLI_memarena_alloc(poly_arena, sizeof(*plink) + (sizeof(int) * (size_t)py_tricoords_len));
-
- plink->len = (unsigned int)py_tricoords_len;
- *p_plink_prev = plink;
- p_plink_prev = &plink->next;
-
- for (j = 0; j < py_tricoords_len; j++) {
- plink->poly[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]);
- if (UNLIKELY(plink->poly[j] >= (unsigned int)coords_len)) {
- PyErr_Format(PyExc_ValueError,
- "%s: index %d must be less than %d",
- error_prefix, plink->poly[j], coords_len);
- /* decref below */
- valid = false;
- break;
- }
- }
-
- Py_DECREF(py_tricoords_fast);
-
- if (py_tricoords_len >= 3) {
- tris_len += (py_tricoords_len - 2);
- }
- }
- *p_plink_prev = NULL;
-
- /* all ngon's are parsed, now tessellate */
-
- pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
- tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
-
- orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
- orig_normal = MEM_mallocN(sizeof(*orig_normal) * (size_t)polys_len, __func__);
-
- for (plink = plink_first, poly_index = 0, i = 0; plink; plink = plink->next, poly_index++) {
- if (plink->len == 3) {
- unsigned int *tri = tris[i];
- memcpy(tri, plink->poly, sizeof(unsigned int[3]));
- orig_index[i] = poly_index;
- normal_tri_v3(orig_normal[poly_index], coords[tri[0]], coords[tri[1]], coords[tri[2]]);
- i++;
- }
- else if (plink->len > 3) {
- float (*proj_coords)[2] = BLI_memarena_alloc(pf_arena, sizeof(*proj_coords) * plink->len);
- float *normal = orig_normal[poly_index];
- const float *co_prev;
- const float *co_curr;
- float axis_mat[3][3];
- unsigned int (*tris_offset)[3] = &tris[i];
- unsigned int j;
-
- /* calc normal and setup 'proj_coords' */
- zero_v3(normal);
- co_prev = coords[plink->poly[plink->len - 1]];
- for (j = 0; j < plink->len; j++) {
- co_curr = coords[plink->poly[j]];
- add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
- co_prev = co_curr;
- }
- normalize_v3(normal);
-
- axis_dominant_v3_to_m3_negate(axis_mat, normal);
-
- for (j = 0; j < plink->len; j++) {
- mul_v2_m3v3(proj_coords[j], axis_mat, coords[plink->poly[j]]);
- }
-
- BLI_polyfill_calc_arena(proj_coords, plink->len, 1, tris_offset, pf_arena);
-
- j = plink->len - 2;
- while (j--) {
- unsigned int *tri = tris_offset[j];
- /* remap to global indices */
- tri[0] = plink->poly[tri[0]];
- tri[1] = plink->poly[tri[1]];
- tri[2] = plink->poly[tri[2]];
-
- orig_index[i] = poly_index;
- i++;
- }
-
- BLI_memarena_clear(pf_arena);
- }
- else {
- zero_v3(orig_normal[poly_index]);
- }
- }
- }
-
- Py_DECREF(py_coords_fast);
- Py_DECREF(py_tris_fast);
-
- if (pf_arena) {
- BLI_memarena_free(pf_arena);
- }
-
- if (poly_arena) {
- BLI_memarena_free(poly_arena);
- }
-
- if (valid) {
- BVHTree *tree;
-
- tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
- if (tree) {
- for (i = 0; i < tris_len; i++) {
- float co[3][3];
-
- copy_v3_v3(co[0], coords[tris[i][0]]);
- copy_v3_v3(co[1], coords[tris[i][1]]);
- copy_v3_v3(co[2], coords[tris[i][2]]);
-
- BLI_bvhtree_insert(tree, (int)i, co[0], 3);
- }
-
- BLI_bvhtree_balance(tree);
- }
-
- return bvhtree_CreatePyObject(
- tree, epsilon,
- coords, coords_len,
- tris, tris_len,
- orig_index, orig_normal);
- }
- else {
- if (coords) {
- MEM_freeN(coords);
- }
- if (tris) {
- MEM_freeN(tris);
- }
-
- return NULL;
- }
+ const char *error_prefix = "BVHTree.FromPolygons";
+ const char *keywords[] = {"vertices", "polygons", "all_triangles", "epsilon", NULL};
+
+ PyObject *py_coords, *py_tris;
+ PyObject *py_coords_fast = NULL, *py_tris_fast = NULL;
+
+ MemArena *poly_arena = NULL;
+ MemArena *pf_arena = NULL;
+
+ float(*coords)[3] = NULL;
+ unsigned int(*tris)[3] = NULL;
+ unsigned int coords_len, tris_len;
+ float epsilon = 0.0f;
+ bool all_triangles = false;
+
+ /* when all_triangles is False */
+ int *orig_index = NULL;
+ float(*orig_normal)[3] = NULL;
+
+ unsigned int i;
+ bool valid = true;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ (char *)"OO|$O&f:BVHTree.FromPolygons",
+ (char **)keywords,
+ &py_coords,
+ &py_tris,
+ PyC_ParseBool,
+ &all_triangles,
+ &epsilon)) {
+ return NULL;
+ }
+
+ if (!(py_coords_fast = PySequence_Fast(py_coords, error_prefix)) ||
+ !(py_tris_fast = PySequence_Fast(py_tris, error_prefix))) {
+ Py_XDECREF(py_coords_fast);
+ return NULL;
+ }
+
+ if (valid) {
+ PyObject **py_coords_fast_items = PySequence_Fast_ITEMS(py_coords_fast);
+ coords_len = (unsigned int)PySequence_Fast_GET_SIZE(py_coords_fast);
+ coords = MEM_mallocN((size_t)coords_len * sizeof(*coords), __func__);
+
+ for (i = 0; i < coords_len; i++) {
+ PyObject *py_vert = py_coords_fast_items[i];
+
+ if (mathutils_array_parse(coords[i], 3, 3, py_vert, "BVHTree vertex: ") == -1) {
+ valid = false;
+ break;
+ }
+ }
+ }
+
+ if (valid == false) {
+ /* pass */
+ }
+ else if (all_triangles) {
+ /* all triangles, simple case */
+ PyObject **py_tris_fast_items = PySequence_Fast_ITEMS(py_tris_fast);
+ tris_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tris_fast);
+ tris = MEM_mallocN((size_t)tris_len * sizeof(*tris), __func__);
+
+ for (i = 0; i < tris_len; i++) {
+ PyObject *py_tricoords = py_tris_fast_items[i];
+ PyObject *py_tricoords_fast;
+ PyObject **py_tricoords_fast_items;
+ unsigned int *tri = tris[i];
+ int j;
+
+ if (!(py_tricoords_fast = PySequence_Fast(py_tricoords, error_prefix))) {
+ valid = false;
+ break;
+ }
+
+ if (PySequence_Fast_GET_SIZE(py_tricoords_fast) != 3) {
+ Py_DECREF(py_tricoords_fast);
+ PyErr_Format(PyExc_ValueError,
+ "%s: non triangle found at index %d with length of %d",
+ error_prefix,
+ i,
+ PySequence_Fast_GET_SIZE(py_tricoords_fast));
+ valid = false;
+ break;
+ }
+
+ py_tricoords_fast_items = PySequence_Fast_ITEMS(py_tricoords_fast);
+
+ for (j = 0; j < 3; j++) {
+ tri[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]);
+ if (UNLIKELY(tri[j] >= (unsigned int)coords_len)) {
+ PyErr_Format(PyExc_ValueError,
+ "%s: index %d must be less than %d",
+ error_prefix,
+ tri[j],
+ coords_len);
+
+ /* decref below */
+ valid = false;
+ break;
+ }
+ }
+
+ Py_DECREF(py_tricoords_fast);
+ }
+ }
+ else {
+ /* ngon support (much more involved) */
+ const unsigned int polys_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tris_fast);
+ struct PolyLink {
+ struct PolyLink *next;
+ unsigned int len;
+ unsigned int poly[0];
+ } *plink_first = NULL, **p_plink_prev = &plink_first, *plink = NULL;
+ int poly_index;
+
+ tris_len = 0;
+
+ poly_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ for (i = 0; i < polys_len; i++) {
+ PyObject *py_tricoords = PySequence_Fast_GET_ITEM(py_tris_fast, i);
+ PyObject *py_tricoords_fast;
+ PyObject **py_tricoords_fast_items;
+ unsigned int py_tricoords_len;
+ unsigned int j;
+
+ if (!(py_tricoords_fast = PySequence_Fast(py_tricoords, error_prefix))) {
+ valid = false;
+ break;
+ }
+
+ py_tricoords_len = (unsigned int)PySequence_Fast_GET_SIZE(py_tricoords_fast);
+ py_tricoords_fast_items = PySequence_Fast_ITEMS(py_tricoords_fast);
+
+ plink = BLI_memarena_alloc(poly_arena,
+ sizeof(*plink) + (sizeof(int) * (size_t)py_tricoords_len));
+
+ plink->len = (unsigned int)py_tricoords_len;
+ *p_plink_prev = plink;
+ p_plink_prev = &plink->next;
+
+ for (j = 0; j < py_tricoords_len; j++) {
+ plink->poly[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]);
+ if (UNLIKELY(plink->poly[j] >= (unsigned int)coords_len)) {
+ PyErr_Format(PyExc_ValueError,
+ "%s: index %d must be less than %d",
+ error_prefix,
+ plink->poly[j],
+ coords_len);
+ /* decref below */
+ valid = false;
+ break;
+ }
+ }
+
+ Py_DECREF(py_tricoords_fast);
+
+ if (py_tricoords_len >= 3) {
+ tris_len += (py_tricoords_len - 2);
+ }
+ }
+ *p_plink_prev = NULL;
+
+ /* all ngon's are parsed, now tessellate */
+
+ pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
+ tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
+
+ orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
+ orig_normal = MEM_mallocN(sizeof(*orig_normal) * (size_t)polys_len, __func__);
+
+ for (plink = plink_first, poly_index = 0, i = 0; plink; plink = plink->next, poly_index++) {
+ if (plink->len == 3) {
+ unsigned int *tri = tris[i];
+ memcpy(tri, plink->poly, sizeof(unsigned int[3]));
+ orig_index[i] = poly_index;
+ normal_tri_v3(orig_normal[poly_index], coords[tri[0]], coords[tri[1]], coords[tri[2]]);
+ i++;
+ }
+ else if (plink->len > 3) {
+ float(*proj_coords)[2] = BLI_memarena_alloc(pf_arena, sizeof(*proj_coords) * plink->len);
+ float *normal = orig_normal[poly_index];
+ const float *co_prev;
+ const float *co_curr;
+ float axis_mat[3][3];
+ unsigned int(*tris_offset)[3] = &tris[i];
+ unsigned int j;
+
+ /* calc normal and setup 'proj_coords' */
+ zero_v3(normal);
+ co_prev = coords[plink->poly[plink->len - 1]];
+ for (j = 0; j < plink->len; j++) {
+ co_curr = coords[plink->poly[j]];
+ add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
+ co_prev = co_curr;
+ }
+ normalize_v3(normal);
+
+ axis_dominant_v3_to_m3_negate(axis_mat, normal);
+
+ for (j = 0; j < plink->len; j++) {
+ mul_v2_m3v3(proj_coords[j], axis_mat, coords[plink->poly[j]]);
+ }
+
+ BLI_polyfill_calc_arena(proj_coords, plink->len, 1, tris_offset, pf_arena);
+
+ j = plink->len - 2;
+ while (j--) {
+ unsigned int *tri = tris_offset[j];
+ /* remap to global indices */
+ tri[0] = plink->poly[tri[0]];
+ tri[1] = plink->poly[tri[1]];
+ tri[2] = plink->poly[tri[2]];
+
+ orig_index[i] = poly_index;
+ i++;
+ }
+
+ BLI_memarena_clear(pf_arena);
+ }
+ else {
+ zero_v3(orig_normal[poly_index]);
+ }
+ }
+ }
+
+ Py_DECREF(py_coords_fast);
+ Py_DECREF(py_tris_fast);
+
+ if (pf_arena) {
+ BLI_memarena_free(pf_arena);
+ }
+
+ if (poly_arena) {
+ BLI_memarena_free(poly_arena);
+ }
+
+ if (valid) {
+ BVHTree *tree;
+
+ tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
+ if (tree) {
+ for (i = 0; i < tris_len; i++) {
+ float co[3][3];
+
+ copy_v3_v3(co[0], coords[tris[i][0]]);
+ copy_v3_v3(co[1], coords[tris[i][1]]);
+ copy_v3_v3(co[2], coords[tris[i][2]]);
+
+ BLI_bvhtree_insert(tree, (int)i, co[0], 3);
+ }
+
+ BLI_bvhtree_balance(tree);
+ }
+
+ return bvhtree_CreatePyObject(
+ tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal);
+ }
+ else {
+ if (coords) {
+ MEM_freeN(coords);
+ }
+ if (tris) {
+ MEM_freeN(tris);
+ }
+
+ return NULL;
+ }
}
-
#ifndef MATH_STANDALONE
PyDoc_STRVAR(C_BVHTree_FromBMesh_doc,
-".. classmethod:: FromBMesh(bmesh, epsilon=0.0)\n"
-"\n"
-" BVH tree based on :class:`BMesh` data.\n"
-"\n"
-" :arg bmesh: BMesh data.\n"
-" :type bmesh: :class:`BMesh`\n"
-PYBVH_FROM_GENERIC_EPSILON_DOC
-);
+ ".. classmethod:: FromBMesh(bmesh, epsilon=0.0)\n"
+ "\n"
+ " BVH tree based on :class:`BMesh` data.\n"
+ "\n"
+ " :arg bmesh: BMesh data.\n"
+ " :type bmesh: :class:`BMesh`\n" PYBVH_FROM_GENERIC_EPSILON_DOC);
static PyObject *C_BVHTree_FromBMesh(PyObject *UNUSED(cls), PyObject *args, PyObject *kwargs)
{
- const char *keywords[] = {"bmesh", "epsilon", NULL};
+ const char *keywords[] = {"bmesh", "epsilon", NULL};
- BPy_BMesh *py_bm;
+ BPy_BMesh *py_bm;
- float (*coords)[3] = NULL;
- unsigned int (*tris)[3] = NULL;
- unsigned int coords_len, tris_len;
- float epsilon = 0.0f;
+ float(*coords)[3] = NULL;
+ unsigned int(*tris)[3] = NULL;
+ unsigned int coords_len, tris_len;
+ float epsilon = 0.0f;
- BMesh *bm;
- BMLoop *(*looptris)[3];
+ BMesh *bm;
+ BMLoop *(*looptris)[3];
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *)"O!|$f:BVHTree.FromBMesh", (char **)keywords,
- &BPy_BMesh_Type, &py_bm, &epsilon))
- {
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ (char *)"O!|$f:BVHTree.FromBMesh",
+ (char **)keywords,
+ &BPy_BMesh_Type,
+ &py_bm,
+ &epsilon)) {
+ return NULL;
+ }
- bm = py_bm->bm;
+ bm = py_bm->bm;
- /* Get data for tessellation */
- {
- int tris_len_dummy;
+ /* Get data for tessellation */
+ {
+ int tris_len_dummy;
- coords_len = (unsigned int)bm->totvert;
- tris_len = (unsigned int)poly_to_tri_count(bm->totface, bm->totloop);
+ coords_len = (unsigned int)bm->totvert;
+ tris_len = (unsigned int)poly_to_tri_count(bm->totface, bm->totloop);
- coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__);
- tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
+ coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__);
+ tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
- looptris = MEM_mallocN(sizeof(*looptris) * (size_t)tris_len, __func__);
+ looptris = MEM_mallocN(sizeof(*looptris) * (size_t)tris_len, __func__);
- BM_mesh_calc_tessellation(bm, looptris, &tris_len_dummy);
- BLI_assert(tris_len_dummy == (int)tris_len);
- }
+ BM_mesh_calc_tessellation(bm, looptris, &tris_len_dummy);
+ BLI_assert(tris_len_dummy == (int)tris_len);
+ }
- {
- BMIter iter;
- BVHTree *tree;
- unsigned int i;
+ {
+ BMIter iter;
+ BVHTree *tree;
+ unsigned int i;
- int *orig_index = NULL;
- float (*orig_normal)[3] = NULL;
+ int *orig_index = NULL;
+ float(*orig_normal)[3] = NULL;
- tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
- if (tree) {
- BMFace *f;
- BMVert *v;
+ tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
+ if (tree) {
+ BMFace *f;
+ BMVert *v;
- orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
- orig_normal = MEM_mallocN(sizeof(*orig_normal) * (size_t)bm->totface, __func__);
+ orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
+ orig_normal = MEM_mallocN(sizeof(*orig_normal) * (size_t)bm->totface, __func__);
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- copy_v3_v3(coords[i], v->co);
- BM_elem_index_set(v, (int)i); /* set_inline */
- }
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- copy_v3_v3(orig_normal[i], f->no);
- BM_elem_index_set(f, (int)i); /* set_inline */
- }
- bm->elem_index_dirty &= (char)~(BM_VERT | BM_FACE);
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ copy_v3_v3(coords[i], v->co);
+ BM_elem_index_set(v, (int)i); /* set_inline */
+ }
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ copy_v3_v3(orig_normal[i], f->no);
+ BM_elem_index_set(f, (int)i); /* set_inline */
+ }
+ bm->elem_index_dirty &= (char)~(BM_VERT | BM_FACE);
- for (i = 0; i < tris_len; i++) {
- float co[3][3];
+ for (i = 0; i < tris_len; i++) {
+ float co[3][3];
- tris[i][0] = (unsigned int)BM_elem_index_get(looptris[i][0]->v);
- tris[i][1] = (unsigned int)BM_elem_index_get(looptris[i][1]->v);
- tris[i][2] = (unsigned int)BM_elem_index_get(looptris[i][2]->v);
+ tris[i][0] = (unsigned int)BM_elem_index_get(looptris[i][0]->v);
+ tris[i][1] = (unsigned int)BM_elem_index_get(looptris[i][1]->v);
+ tris[i][2] = (unsigned int)BM_elem_index_get(looptris[i][2]->v);
- copy_v3_v3(co[0], coords[tris[i][0]]);
- copy_v3_v3(co[1], coords[tris[i][1]]);
- copy_v3_v3(co[2], coords[tris[i][2]]);
+ copy_v3_v3(co[0], coords[tris[i][0]]);
+ copy_v3_v3(co[1], coords[tris[i][1]]);
+ copy_v3_v3(co[2], coords[tris[i][2]]);
- BLI_bvhtree_insert(tree, (int)i, co[0], 3);
- orig_index[i] = BM_elem_index_get(looptris[i][0]->f);
- }
+ BLI_bvhtree_insert(tree, (int)i, co[0], 3);
+ orig_index[i] = BM_elem_index_get(looptris[i][0]->f);
+ }
- BLI_bvhtree_balance(tree);
- }
+ BLI_bvhtree_balance(tree);
+ }
- MEM_freeN(looptris);
+ MEM_freeN(looptris);
- return bvhtree_CreatePyObject(
- tree, epsilon,
- coords, coords_len,
- tris, tris_len,
- orig_index, orig_normal);
- }
+ return bvhtree_CreatePyObject(
+ tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal);
+ }
}
/* return various derived meshes based on requested settings */
-static Mesh *bvh_get_mesh(
- const char *funcname, struct Depsgraph *depsgraph, struct Scene *scene, Object *ob,
- const bool use_deform, const bool use_cage, bool *r_free_mesh)
+static Mesh *bvh_get_mesh(const char *funcname,
+ struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ Object *ob,
+ const bool use_deform,
+ const bool use_cage,
+ bool *r_free_mesh)
{
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- /* we only need minimum mesh data for topology and vertex locations */
- CustomData_MeshMasks data_masks = CD_MASK_BAREMESH;
- const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
- *r_free_mesh = false;
-
- /* Write the display mesh into the dummy mesh */
- if (use_deform) {
- if (use_render) {
- if (use_cage) {
- PyErr_Format(PyExc_ValueError,
- "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER", funcname);
- return NULL;
- }
- else {
- *r_free_mesh = true;
- return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks);
- }
- }
- else if (ob_eval != NULL) {
- if (use_cage) {
- return mesh_get_eval_deform(depsgraph, scene, ob_eval, &data_masks);
- }
- else {
- return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks);
- }
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%s(...): Cannot get evaluated data from given dependency graph / object pair", funcname);
- return NULL;
- }
- }
- else {
- /* !use_deform */
- if (use_render) {
- if (use_cage) {
- PyErr_Format(PyExc_ValueError,
- "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER", funcname);
- return NULL;
- }
- else {
- *r_free_mesh = true;
- return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks);
- }
- }
- else {
- if (use_cage) {
- PyErr_Format(PyExc_ValueError,
- "%s(...): cage arg is unsupported when deform=False and dependency graph evaluation mode is not RENDER", funcname);
- return NULL;
- }
- else {
- *r_free_mesh = true;
- return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks);
- }
- }
- }
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ /* we only need minimum mesh data for topology and vertex locations */
+ CustomData_MeshMasks data_masks = CD_MASK_BAREMESH;
+ const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
+ *r_free_mesh = false;
+
+ /* Write the display mesh into the dummy mesh */
+ if (use_deform) {
+ if (use_render) {
+ if (use_cage) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER",
+ funcname);
+ return NULL;
+ }
+ else {
+ *r_free_mesh = true;
+ return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks);
+ }
+ }
+ else if (ob_eval != NULL) {
+ if (use_cage) {
+ return mesh_get_eval_deform(depsgraph, scene, ob_eval, &data_masks);
+ }
+ else {
+ return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks);
+ }
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%s(...): Cannot get evaluated data from given dependency graph / object pair",
+ funcname);
+ return NULL;
+ }
+ }
+ else {
+ /* !use_deform */
+ if (use_render) {
+ if (use_cage) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER",
+ funcname);
+ return NULL;
+ }
+ else {
+ *r_free_mesh = true;
+ return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks);
+ }
+ }
+ else {
+ if (use_cage) {
+ PyErr_Format(PyExc_ValueError,
+ "%s(...): cage arg is unsupported when deform=False and dependency graph "
+ "evaluation mode is not RENDER",
+ funcname);
+ return NULL;
+ }
+ else {
+ *r_free_mesh = true;
+ return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks);
+ }
+ }
+ }
}
PyDoc_STRVAR(C_BVHTree_FromObject_doc,
-".. classmethod:: FromObject(object, depsgraph, deform=True, render=False, cage=False, epsilon=0.0)\n"
-"\n"
-" BVH tree based on :class:`Object` data.\n"
-"\n"
-" :arg object: Object data.\n"
-" :type object: :class:`Object`\n"
-" :arg depsgraph: Depsgraph to use for evaluating the mesh.\n"
-" :type depsgraph: :class:`Depsgraph`\n"
-" :arg deform: Use mesh with deformations.\n"
-" :type deform: bool\n"
-" :arg cage: Use modifiers cage.\n"
-" :type cage: bool\n"
-PYBVH_FROM_GENERIC_EPSILON_DOC
-);
+ ".. classmethod:: FromObject(object, depsgraph, deform=True, render=False, "
+ "cage=False, epsilon=0.0)\n"
+ "\n"
+ " BVH tree based on :class:`Object` data.\n"
+ "\n"
+ " :arg object: Object data.\n"
+ " :type object: :class:`Object`\n"
+ " :arg depsgraph: Depsgraph to use for evaluating the mesh.\n"
+ " :type depsgraph: :class:`Depsgraph`\n"
+ " :arg deform: Use mesh with deformations.\n"
+ " :type deform: bool\n"
+ " :arg cage: Use modifiers cage.\n"
+ " :type cage: bool\n" PYBVH_FROM_GENERIC_EPSILON_DOC);
static PyObject *C_BVHTree_FromObject(PyObject *UNUSED(cls), PyObject *args, PyObject *kwargs)
{
- /* note, options here match 'bpy_bmesh_from_object' */
- const char *keywords[] = {"object", "depsgraph", "deform", "cage", "epsilon", NULL};
-
- PyObject *py_ob, *py_depsgraph;
- Object *ob;
- struct Depsgraph *depsgraph;
- struct Scene *scene;
- Mesh *mesh;
- bool use_deform = true;
- bool use_cage = false;
- bool free_mesh = false;
-
- const MLoopTri *lt;
- const MLoop *mloop;
-
- float (*coords)[3] = NULL;
- unsigned int (*tris)[3] = NULL;
- unsigned int coords_len, tris_len;
- float epsilon = 0.0f;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *)"OO|$O&O&f:BVHTree.FromObject", (char **)keywords,
- &py_ob, &py_depsgraph,
- PyC_ParseBool, &use_deform,
- PyC_ParseBool, &use_cage,
- &epsilon) ||
- ((ob = PyC_RNA_AsPointer(py_ob, "Object")) == NULL) ||
- ((depsgraph = PyC_RNA_AsPointer(py_depsgraph, "Depsgraph")) == NULL))
- {
- return NULL;
- }
-
- scene = DEG_get_evaluated_scene(depsgraph);
- mesh = bvh_get_mesh("BVHTree", depsgraph, scene, ob, use_deform, use_cage, &free_mesh);
-
- if (mesh == NULL) {
- return NULL;
- }
-
- /* Get data for tessellation */
- {
- lt = BKE_mesh_runtime_looptri_ensure(mesh);
-
- tris_len = (unsigned int)BKE_mesh_runtime_looptri_len(mesh);
- coords_len = (unsigned int)mesh->totvert;
-
- coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__);
- tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
-
- MVert *mv = mesh->mvert;
- for (int i = 0; i < mesh->totvert; i++, mv++) {
- copy_v3_v3(coords[i], mv->co);
- }
-
- mloop = mesh->mloop;
- }
-
- {
- BVHTree *tree;
- unsigned int i;
-
- int *orig_index = NULL;
- float (*orig_normal)[3] = NULL;
-
- tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
- if (tree) {
- orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
- CustomData *pdata = &mesh->pdata;
- orig_normal = CustomData_get_layer(pdata, CD_NORMAL); /* can be NULL */
- if (orig_normal) {
- orig_normal = MEM_dupallocN(orig_normal);
- }
-
- for (i = 0; i < tris_len; i++, lt++) {
- float co[3][3];
-
- tris[i][0] = mloop[lt->tri[0]].v;
- tris[i][1] = mloop[lt->tri[1]].v;
- tris[i][2] = mloop[lt->tri[2]].v;
-
- copy_v3_v3(co[0], coords[tris[i][0]]);
- copy_v3_v3(co[1], coords[tris[i][1]]);
- copy_v3_v3(co[2], coords[tris[i][2]]);
-
- BLI_bvhtree_insert(tree, (int)i, co[0], 3);
- orig_index[i] = (int)lt->poly;
- }
-
- BLI_bvhtree_balance(tree);
- }
-
- if (free_mesh) {
- BKE_id_free(NULL, mesh);
- }
-
- return bvhtree_CreatePyObject(
- tree, epsilon,
- coords, coords_len,
- tris, tris_len,
- orig_index, orig_normal);
- }
+ /* note, options here match 'bpy_bmesh_from_object' */
+ const char *keywords[] = {"object", "depsgraph", "deform", "cage", "epsilon", NULL};
+
+ PyObject *py_ob, *py_depsgraph;
+ Object *ob;
+ struct Depsgraph *depsgraph;
+ struct Scene *scene;
+ Mesh *mesh;
+ bool use_deform = true;
+ bool use_cage = false;
+ bool free_mesh = false;
+
+ const MLoopTri *lt;
+ const MLoop *mloop;
+
+ float(*coords)[3] = NULL;
+ unsigned int(*tris)[3] = NULL;
+ unsigned int coords_len, tris_len;
+ float epsilon = 0.0f;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ (char *)"OO|$O&O&f:BVHTree.FromObject",
+ (char **)keywords,
+ &py_ob,
+ &py_depsgraph,
+ PyC_ParseBool,
+ &use_deform,
+ PyC_ParseBool,
+ &use_cage,
+ &epsilon) ||
+ ((ob = PyC_RNA_AsPointer(py_ob, "Object")) == NULL) ||
+ ((depsgraph = PyC_RNA_AsPointer(py_depsgraph, "Depsgraph")) == NULL)) {
+ return NULL;
+ }
+
+ scene = DEG_get_evaluated_scene(depsgraph);
+ mesh = bvh_get_mesh("BVHTree", depsgraph, scene, ob, use_deform, use_cage, &free_mesh);
+
+ if (mesh == NULL) {
+ return NULL;
+ }
+
+ /* Get data for tessellation */
+ {
+ lt = BKE_mesh_runtime_looptri_ensure(mesh);
+
+ tris_len = (unsigned int)BKE_mesh_runtime_looptri_len(mesh);
+ coords_len = (unsigned int)mesh->totvert;
+
+ coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__);
+ tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__);
+
+ MVert *mv = mesh->mvert;
+ for (int i = 0; i < mesh->totvert; i++, mv++) {
+ copy_v3_v3(coords[i], mv->co);
+ }
+
+ mloop = mesh->mloop;
+ }
+
+ {
+ BVHTree *tree;
+ unsigned int i;
+
+ int *orig_index = NULL;
+ float(*orig_normal)[3] = NULL;
+
+ tree = BLI_bvhtree_new((int)tris_len, epsilon, PY_BVH_TREE_TYPE_DEFAULT, PY_BVH_AXIS_DEFAULT);
+ if (tree) {
+ orig_index = MEM_mallocN(sizeof(*orig_index) * (size_t)tris_len, __func__);
+ CustomData *pdata = &mesh->pdata;
+ orig_normal = CustomData_get_layer(pdata, CD_NORMAL); /* can be NULL */
+ if (orig_normal) {
+ orig_normal = MEM_dupallocN(orig_normal);
+ }
+
+ for (i = 0; i < tris_len; i++, lt++) {
+ float co[3][3];
+
+ tris[i][0] = mloop[lt->tri[0]].v;
+ tris[i][1] = mloop[lt->tri[1]].v;
+ tris[i][2] = mloop[lt->tri[2]].v;
+
+ copy_v3_v3(co[0], coords[tris[i][0]]);
+ copy_v3_v3(co[1], coords[tris[i][1]]);
+ copy_v3_v3(co[2], coords[tris[i][2]]);
+
+ BLI_bvhtree_insert(tree, (int)i, co[0], 3);
+ orig_index[i] = (int)lt->poly;
+ }
+
+ BLI_bvhtree_balance(tree);
+ }
+
+ if (free_mesh) {
+ BKE_id_free(NULL, mesh);
+ }
+
+ return bvhtree_CreatePyObject(
+ tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal);
+ }
}
-#endif /* MATH_STANDALONE */
+#endif /* MATH_STANDALONE */
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Module & Type definition
* \{ */
static PyMethodDef py_bvhtree_methods[] = {
- {"ray_cast", (PyCFunction)py_bvhtree_ray_cast, METH_VARARGS, py_bvhtree_ray_cast_doc},
- {"find_nearest", (PyCFunction)py_bvhtree_find_nearest, METH_VARARGS, py_bvhtree_find_nearest_doc},
- {"find_nearest_range", (PyCFunction)py_bvhtree_find_nearest_range, METH_VARARGS, py_bvhtree_find_nearest_range_doc},
- {"overlap", (PyCFunction)py_bvhtree_overlap, METH_O, py_bvhtree_overlap_doc},
-
- /* class methods */
- {"FromPolygons", (PyCFunction) C_BVHTree_FromPolygons, METH_VARARGS | METH_KEYWORDS | METH_CLASS, C_BVHTree_FromPolygons_doc},
+ {"ray_cast", (PyCFunction)py_bvhtree_ray_cast, METH_VARARGS, py_bvhtree_ray_cast_doc},
+ {"find_nearest",
+ (PyCFunction)py_bvhtree_find_nearest,
+ METH_VARARGS,
+ py_bvhtree_find_nearest_doc},
+ {"find_nearest_range",
+ (PyCFunction)py_bvhtree_find_nearest_range,
+ METH_VARARGS,
+ py_bvhtree_find_nearest_range_doc},
+ {"overlap", (PyCFunction)py_bvhtree_overlap, METH_O, py_bvhtree_overlap_doc},
+
+ /* class methods */
+ {"FromPolygons",
+ (PyCFunction)C_BVHTree_FromPolygons,
+ METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+ C_BVHTree_FromPolygons_doc},
#ifndef MATH_STANDALONE
- {"FromBMesh", (PyCFunction) C_BVHTree_FromBMesh, METH_VARARGS | METH_KEYWORDS | METH_CLASS, C_BVHTree_FromBMesh_doc},
- {"FromObject", (PyCFunction) C_BVHTree_FromObject, METH_VARARGS | METH_KEYWORDS | METH_CLASS, C_BVHTree_FromObject_doc},
+ {"FromBMesh",
+ (PyCFunction)C_BVHTree_FromBMesh,
+ METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+ C_BVHTree_FromBMesh_doc},
+ {"FromObject",
+ (PyCFunction)C_BVHTree_FromObject,
+ METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+ C_BVHTree_FromObject_doc},
#endif
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
PyTypeObject PyBVHTree_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "BVHTree", /* tp_name */
- sizeof(PyBVHTree), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)py_bvhtree__tp_dealloc, /* tp_dealloc */
- NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- NULL, /* tp_hash */
- NULL, /* tp_call */
- NULL, /* tp_str */
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- NULL, /* Documentation string */
- NULL, /* tp_traverse */
- NULL, /* tp_clear */
- NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- py_bvhtree_methods, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- NULL, /* tp_init */
- (allocfunc)PyType_GenericAlloc, /* tp_alloc */
- (newfunc)PyType_GenericNew, /* tp_new */
- (freefunc)0, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- (destructor)NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0) "BVHTree", /* tp_name */
+ sizeof(PyBVHTree), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)py_bvhtree__tp_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ NULL, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL, /* tp_hash */
+ NULL, /* tp_call */
+ NULL, /* tp_str */
+ NULL, /* tp_getattro */
+ NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ NULL, /* Documentation string */
+ NULL, /* tp_traverse */
+ NULL, /* tp_clear */
+ NULL, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ NULL, /* tp_iter */
+ NULL, /* tp_iternext */
+ py_bvhtree_methods, /* tp_methods */
+ NULL, /* tp_members */
+ NULL, /* tp_getset */
+ NULL, /* tp_base */
+ NULL, /* tp_dict */
+ NULL, /* tp_descr_get */
+ NULL, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ NULL, /* tp_init */
+ (allocfunc)PyType_GenericAlloc, /* tp_alloc */
+ (newfunc)PyType_GenericNew, /* tp_new */
+ (freefunc)0, /* tp_free */
+ NULL, /* tp_is_gc */
+ NULL, /* tp_bases */
+ NULL, /* tp_mro */
+ NULL, /* tp_cache */
+ NULL, /* tp_subclasses */
+ NULL, /* tp_weaklist */
+ (destructor)NULL, /* tp_del */
};
/* -------------------------------------------------------------------- */
/* Module definition */
PyDoc_STRVAR(py_bvhtree_doc,
-"BVH tree structures for proximity searches and ray casts on geometry."
-);
+ "BVH tree structures for proximity searches and ray casts on geometry.");
static struct PyModuleDef bvhtree_moduledef = {
- PyModuleDef_HEAD_INIT,
- "mathutils.bvhtree", /* m_name */
- py_bvhtree_doc, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils.bvhtree", /* m_name */
+ py_bvhtree_doc, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_mathutils_bvhtree(void)
{
- PyObject *m = PyModule_Create(&bvhtree_moduledef);
+ PyObject *m = PyModule_Create(&bvhtree_moduledef);
- if (m == NULL) {
- return NULL;
- }
+ if (m == NULL) {
+ return NULL;
+ }
- /* Register classes */
- if (PyType_Ready(&PyBVHTree_Type) < 0) {
- return NULL;
- }
+ /* Register classes */
+ if (PyType_Ready(&PyBVHTree_Type) < 0) {
+ return NULL;
+ }
- PyModule_AddObject(m, "BVHTree", (PyObject *)&PyBVHTree_Type);
+ PyModule_AddObject(m, "BVHTree", (PyObject *)&PyBVHTree_Type);
- return m;
+ return m;
}
/** \} */
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.h b/source/blender/python/mathutils/mathutils_bvhtree.h
index 6971eb5ccd4..2991982f3a2 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.h
+++ b/source/blender/python/mathutils/mathutils_bvhtree.h
@@ -14,7 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
/** \file
* \ingroup mathutils
*/
@@ -26,7 +25,7 @@ PyMODINIT_FUNC PyInit_mathutils_bvhtree(void);
extern PyTypeObject PyBVHTree_Type;
-#define PyBVHTree_Check(v) PyObject_TypeCheck((v), &PyBVHTree_Type)
-#define PyBVHTree_CheckExact(v) (Py_TYPE(v) == &PyBVHTree_Type)
+#define PyBVHTree_Check(v) PyObject_TypeCheck((v), &PyBVHTree_Type)
+#define PyBVHTree_CheckExact(v) (Py_TYPE(v) == &PyBVHTree_Type)
#endif /* __MATHUTILS_BVHTREE_H__ */
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 05ec57a004a..5fe3536d899 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -41,1497 +40,1534 @@
#include "../generic/python_utildefines.h"
/*-------------------------DOC STRINGS ---------------------------*/
-PyDoc_STRVAR(M_Geometry_doc,
-"The Blender geometry module"
-);
+PyDoc_STRVAR(M_Geometry_doc, "The Blender geometry module");
/* ---------------------------------INTERSECTION FUNCTIONS-------------------- */
PyDoc_STRVAR(M_Geometry_intersect_ray_tri_doc,
-".. function:: intersect_ray_tri(v1, v2, v3, ray, orig, clip=True)\n"
-"\n"
-" Returns the intersection between a ray and a triangle, if possible, returns None otherwise.\n"
-"\n"
-" :arg v1: Point1\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Point2\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: Point3\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :arg ray: Direction of the projection\n"
-" :type ray: :class:`mathutils.Vector`\n"
-" :arg orig: Origin\n"
-" :type orig: :class:`mathutils.Vector`\n"
-" :arg clip: When False, don't restrict the intersection to the area of the triangle, use the infinite plane defined by the triangle.\n"
-" :type clip: boolean\n"
-" :return: The point of intersection or None if no intersection is found\n"
-" :rtype: :class:`mathutils.Vector` or None\n"
-);
+ ".. function:: intersect_ray_tri(v1, v2, v3, ray, orig, clip=True)\n"
+ "\n"
+ " Returns the intersection between a ray and a triangle, if possible, returns None "
+ "otherwise.\n"
+ "\n"
+ " :arg v1: Point1\n"
+ " :type v1: :class:`mathutils.Vector`\n"
+ " :arg v2: Point2\n"
+ " :type v2: :class:`mathutils.Vector`\n"
+ " :arg v3: Point3\n"
+ " :type v3: :class:`mathutils.Vector`\n"
+ " :arg ray: Direction of the projection\n"
+ " :type ray: :class:`mathutils.Vector`\n"
+ " :arg orig: Origin\n"
+ " :type orig: :class:`mathutils.Vector`\n"
+ " :arg clip: When False, don't restrict the intersection to the area of the "
+ "triangle, use the infinite plane defined by the triangle.\n"
+ " :type clip: boolean\n"
+ " :return: The point of intersection or None if no intersection is found\n"
+ " :rtype: :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_ray_tri";
- PyObject *py_ray, *py_ray_off, *py_tri[3];
- float dir[3], orig[3], tri[3][3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
- float det, inv_det, u, v, t;
- bool clip = true;
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOOO|O&:intersect_ray_tri",
- UNPACK3_EX(&, py_tri, ),
- &py_ray, &py_ray_off,
- PyC_ParseBool, &clip))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(dir, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray, error_prefix) != -1) &&
- (mathutils_array_parse(orig, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray_off, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- for (i = 0; i < ARRAY_SIZE(tri); i++) {
- if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- normalize_v3(dir);
-
- /* find vectors for two edges sharing v1 */
- sub_v3_v3v3(e1, tri[1], tri[0]);
- sub_v3_v3v3(e2, tri[2], tri[0]);
-
- /* begin calculating determinant - also used to calculated U parameter */
- cross_v3_v3v3(pvec, dir, e2);
-
- /* if determinant is near zero, ray lies in plane of triangle */
- det = dot_v3v3(e1, pvec);
-
- if (det > -0.000001f && det < 0.000001f) {
- Py_RETURN_NONE;
- }
-
- inv_det = 1.0f / det;
-
- /* calculate distance from v1 to ray origin */
- sub_v3_v3v3(tvec, orig, tri[0]);
-
- /* calculate U parameter and test bounds */
- u = dot_v3v3(tvec, pvec) * inv_det;
- if (clip && (u < 0.0f || u > 1.0f)) {
- Py_RETURN_NONE;
- }
-
- /* prepare to test the V parameter */
- cross_v3_v3v3(qvec, tvec, e1);
-
- /* calculate V parameter and test bounds */
- v = dot_v3v3(dir, qvec) * inv_det;
-
- if (clip && (v < 0.0f || u + v > 1.0f)) {
- Py_RETURN_NONE;
- }
-
- /* calculate t, ray intersects triangle */
- t = dot_v3v3(e2, qvec) * inv_det;
-
- /* ray hit behind */
- if (t < 0.0f) {
- Py_RETURN_NONE;
- }
-
- mul_v3_fl(dir, t);
- add_v3_v3v3(pvec, orig, dir);
-
- return Vector_CreatePyObject(pvec, 3, NULL);
+ const char *error_prefix = "intersect_ray_tri";
+ PyObject *py_ray, *py_ray_off, *py_tri[3];
+ float dir[3], orig[3], tri[3][3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
+ float det, inv_det, u, v, t;
+ bool clip = true;
+ int i;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOOO|O&:intersect_ray_tri",
+ UNPACK3_EX(&, py_tri, ),
+ &py_ray,
+ &py_ray_off,
+ PyC_ParseBool,
+ &clip)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(dir, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray, error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(
+ orig, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray_off, error_prefix) != -1)) == 0) {
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(
+ tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ normalize_v3(dir);
+
+ /* find vectors for two edges sharing v1 */
+ sub_v3_v3v3(e1, tri[1], tri[0]);
+ sub_v3_v3v3(e2, tri[2], tri[0]);
+
+ /* begin calculating determinant - also used to calculated U parameter */
+ cross_v3_v3v3(pvec, dir, e2);
+
+ /* if determinant is near zero, ray lies in plane of triangle */
+ det = dot_v3v3(e1, pvec);
+
+ if (det > -0.000001f && det < 0.000001f) {
+ Py_RETURN_NONE;
+ }
+
+ inv_det = 1.0f / det;
+
+ /* calculate distance from v1 to ray origin */
+ sub_v3_v3v3(tvec, orig, tri[0]);
+
+ /* calculate U parameter and test bounds */
+ u = dot_v3v3(tvec, pvec) * inv_det;
+ if (clip && (u < 0.0f || u > 1.0f)) {
+ Py_RETURN_NONE;
+ }
+
+ /* prepare to test the V parameter */
+ cross_v3_v3v3(qvec, tvec, e1);
+
+ /* calculate V parameter and test bounds */
+ v = dot_v3v3(dir, qvec) * inv_det;
+
+ if (clip && (v < 0.0f || u + v > 1.0f)) {
+ Py_RETURN_NONE;
+ }
+
+ /* calculate t, ray intersects triangle */
+ t = dot_v3v3(e2, qvec) * inv_det;
+
+ /* ray hit behind */
+ if (t < 0.0f) {
+ Py_RETURN_NONE;
+ }
+
+ mul_v3_fl(dir, t);
+ add_v3_v3v3(pvec, orig, dir);
+
+ return Vector_CreatePyObject(pvec, 3, NULL);
}
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
PyDoc_STRVAR(M_Geometry_intersect_line_line_doc,
-".. function:: intersect_line_line(v1, v2, v3, v4)\n"
-"\n"
-" Returns a tuple with the points on each line respectively closest to the other.\n"
-"\n"
-" :arg v1: First point of the first line\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Second point of the first line\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: First point of the second line\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :arg v4: Second point of the second line\n"
-" :type v4: :class:`mathutils.Vector`\n"
-" :rtype: tuple of :class:`mathutils.Vector`'s\n"
-);
+ ".. function:: intersect_line_line(v1, v2, v3, v4)\n"
+ "\n"
+ " Returns a tuple with the points on each line respectively closest to the other.\n"
+ "\n"
+ " :arg v1: First point of the first line\n"
+ " :type v1: :class:`mathutils.Vector`\n"
+ " :arg v2: Second point of the first line\n"
+ " :type v2: :class:`mathutils.Vector`\n"
+ " :arg v3: First point of the second line\n"
+ " :type v3: :class:`mathutils.Vector`\n"
+ " :arg v4: Second point of the second line\n"
+ " :type v4: :class:`mathutils.Vector`\n"
+ " :rtype: tuple of :class:`mathutils.Vector`'s\n");
static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_line_line";
- PyObject *tuple;
- PyObject *py_lines[4];
- float lines[4][3], i1[3], i2[3];
- int len;
- int result;
-
- if (!PyArg_ParseTuple(
- args, "OOOO:intersect_line_line",
- UNPACK4_EX(&, py_lines, )))
- {
- return NULL;
- }
-
- if ((((len = mathutils_array_parse(lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) &&
- (mathutils_array_parse(lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) != -1) &&
- (mathutils_array_parse(lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) != -1) &&
- (mathutils_array_parse(lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- result = isect_line_line_v3(UNPACK4(lines), i1, i2);
- /* The return-code isnt exposed,
- * this way we can check know how close the lines are. */
- if (result == 1) {
- closest_to_line_v3(i2, i1, lines[2], lines[3]);
- }
-
- if (result == 0) {
- /* collinear */
- Py_RETURN_NONE;
- }
- else {
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEMS(tuple,
- Vector_CreatePyObject(i1, len, NULL),
- Vector_CreatePyObject(i2, len, NULL));
- return tuple;
- }
+ const char *error_prefix = "intersect_line_line";
+ PyObject *tuple;
+ PyObject *py_lines[4];
+ float lines[4][3], i1[3], i2[3];
+ int len;
+ int result;
+
+ if (!PyArg_ParseTuple(args, "OOOO:intersect_line_line", UNPACK4_EX(&, py_lines, ))) {
+ return NULL;
+ }
+
+ if ((((len = mathutils_array_parse(
+ lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) &&
+ (mathutils_array_parse(
+ lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(
+ lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(
+ lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+
+ result = isect_line_line_v3(UNPACK4(lines), i1, i2);
+ /* The return-code isnt exposed,
+ * this way we can check know how close the lines are. */
+ if (result == 1) {
+ closest_to_line_v3(i2, i1, lines[2], lines[3]);
+ }
+
+ if (result == 0) {
+ /* collinear */
+ Py_RETURN_NONE;
+ }
+ else {
+ tuple = PyTuple_New(2);
+ PyTuple_SET_ITEMS(
+ tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL));
+ return tuple;
+ }
}
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
-PyDoc_STRVAR(M_Geometry_intersect_sphere_sphere_2d_doc,
-".. function:: intersect_sphere_sphere_2d(p_a, radius_a, p_b, radius_b)\n"
-"\n"
-" Returns 2 points on between intersecting circles.\n"
-"\n"
-" :arg p_a: Center of the first circle\n"
-" :type p_a: :class:`mathutils.Vector`\n"
-" :arg radius_a: Radius of the first circle\n"
-" :type radius_a: float\n"
-" :arg p_b: Center of the second circle\n"
-" :type p_b: :class:`mathutils.Vector`\n"
-" :arg radius_b: Radius of the second circle\n"
-" :type radius_b: float\n"
-" :rtype: tuple of :class:`mathutils.Vector`'s or None when there is no intersection\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_sphere_sphere_2d_doc,
+ ".. function:: intersect_sphere_sphere_2d(p_a, radius_a, p_b, radius_b)\n"
+ "\n"
+ " Returns 2 points on between intersecting circles.\n"
+ "\n"
+ " :arg p_a: Center of the first circle\n"
+ " :type p_a: :class:`mathutils.Vector`\n"
+ " :arg radius_a: Radius of the first circle\n"
+ " :type radius_a: float\n"
+ " :arg p_b: Center of the second circle\n"
+ " :type p_b: :class:`mathutils.Vector`\n"
+ " :arg radius_b: Radius of the second circle\n"
+ " :type radius_b: float\n"
+ " :rtype: tuple of :class:`mathutils.Vector`'s or None when there is no intersection\n");
static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_sphere_sphere_2d";
- PyObject *ret;
- PyObject *py_v_a, *py_v_b;
- float v_a[2], v_b[2];
- float rad_a, rad_b;
- float v_ab[2];
- float dist;
-
- if (!PyArg_ParseTuple(
- args, "OfOf:intersect_sphere_sphere_2d",
- &py_v_a, &rad_a,
- &py_v_b, &rad_b))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(v_a, 2, 2, py_v_a, error_prefix) != -1) &&
- (mathutils_array_parse(v_b, 2, 2, py_v_b, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- ret = PyTuple_New(2);
-
- sub_v2_v2v2(v_ab, v_b, v_a);
- dist = len_v2(v_ab);
-
- if (/* out of range */
- (dist > rad_a + rad_b) ||
- /* fully-contained in the other */
- (dist < fabsf(rad_a - rad_b)) ||
- /* co-incident */
- (dist < FLT_EPSILON))
- {
- /* out of range */
- PyTuple_SET_ITEMS(ret,
- Py_INCREF_RET(Py_None),
- Py_INCREF_RET(Py_None));
- }
- else {
- const float dist_delta = ((rad_a * rad_a) - (rad_b * rad_b) + (dist * dist)) / (2.0f * dist);
- const float h = powf(fabsf((rad_a * rad_a) - (dist_delta * dist_delta)), 0.5f);
- float i_cent[2];
- float i1[2], i2[2];
-
- i_cent[0] = v_a[0] + ((v_ab[0] * dist_delta) / dist);
- i_cent[1] = v_a[1] + ((v_ab[1] * dist_delta) / dist);
-
- i1[0] = i_cent[0] + h * v_ab[1] / dist;
- i1[1] = i_cent[1] - h * v_ab[0] / dist;
-
- i2[0] = i_cent[0] - h * v_ab[1] / dist;
- i2[1] = i_cent[1] + h * v_ab[0] / dist;
-
- PyTuple_SET_ITEMS(ret,
- Vector_CreatePyObject(i1, 2, NULL),
- Vector_CreatePyObject(i2, 2, NULL));
- }
-
- return ret;
+ const char *error_prefix = "intersect_sphere_sphere_2d";
+ PyObject *ret;
+ PyObject *py_v_a, *py_v_b;
+ float v_a[2], v_b[2];
+ float rad_a, rad_b;
+ float v_ab[2];
+ float dist;
+
+ if (!PyArg_ParseTuple(
+ args, "OfOf:intersect_sphere_sphere_2d", &py_v_a, &rad_a, &py_v_b, &rad_b)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(v_a, 2, 2, py_v_a, error_prefix) != -1) &&
+ (mathutils_array_parse(v_b, 2, 2, py_v_b, error_prefix) != -1)) == 0) {
+ return NULL;
+ }
+
+ ret = PyTuple_New(2);
+
+ sub_v2_v2v2(v_ab, v_b, v_a);
+ dist = len_v2(v_ab);
+
+ if (/* out of range */
+ (dist > rad_a + rad_b) ||
+ /* fully-contained in the other */
+ (dist < fabsf(rad_a - rad_b)) ||
+ /* co-incident */
+ (dist < FLT_EPSILON)) {
+ /* out of range */
+ PyTuple_SET_ITEMS(ret, Py_INCREF_RET(Py_None), Py_INCREF_RET(Py_None));
+ }
+ else {
+ const float dist_delta = ((rad_a * rad_a) - (rad_b * rad_b) + (dist * dist)) / (2.0f * dist);
+ const float h = powf(fabsf((rad_a * rad_a) - (dist_delta * dist_delta)), 0.5f);
+ float i_cent[2];
+ float i1[2], i2[2];
+
+ i_cent[0] = v_a[0] + ((v_ab[0] * dist_delta) / dist);
+ i_cent[1] = v_a[1] + ((v_ab[1] * dist_delta) / dist);
+
+ i1[0] = i_cent[0] + h * v_ab[1] / dist;
+ i1[1] = i_cent[1] - h * v_ab[0] / dist;
+
+ i2[0] = i_cent[0] - h * v_ab[1] / dist;
+ i2[1] = i_cent[1] + h * v_ab[0] / dist;
+
+ PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(i1, 2, NULL), Vector_CreatePyObject(i2, 2, NULL));
+ }
+
+ return ret;
}
PyDoc_STRVAR(M_Geometry_normal_doc,
-".. function:: normal(vectors)\n"
-"\n"
-" Returns the normal of a 3D polygon.\n"
-"\n"
-" :arg vectors: Vectors to calculate normals with\n"
-" :type vectors: sequence of 3 or more 3d vector\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: normal(vectors)\n"
+ "\n"
+ " Returns the normal of a 3D polygon.\n"
+ "\n"
+ " :arg vectors: Vectors to calculate normals with\n"
+ " :type vectors: sequence of 3 or more 3d vector\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args)
{
- float (*coords)[3];
- int coords_len;
- float n[3];
- PyObject *ret = NULL;
+ float(*coords)[3];
+ int coords_len;
+ float n[3];
+ PyObject *ret = NULL;
- /* use */
- if (PyTuple_GET_SIZE(args) == 1) {
- args = PyTuple_GET_ITEM(args, 0);
- }
+ /* use */
+ if (PyTuple_GET_SIZE(args) == 1) {
+ args = PyTuple_GET_ITEM(args, 0);
+ }
- if ((coords_len = mathutils_array_parse_alloc_v((float **)&coords, 3 | MU_ARRAY_SPILL, args, "normal")) == -1) {
- return NULL;
- }
+ if ((coords_len = mathutils_array_parse_alloc_v(
+ (float **)&coords, 3 | MU_ARRAY_SPILL, args, "normal")) == -1) {
+ return NULL;
+ }
- if (coords_len < 3) {
- PyErr_SetString(PyExc_ValueError,
- "Expected 3 or more vectors");
- goto finally;
- }
+ if (coords_len < 3) {
+ PyErr_SetString(PyExc_ValueError, "Expected 3 or more vectors");
+ goto finally;
+ }
- normal_poly_v3(n, (const float (*)[3])coords, coords_len);
- ret = Vector_CreatePyObject(n, 3, NULL);
+ normal_poly_v3(n, (const float(*)[3])coords, coords_len);
+ ret = Vector_CreatePyObject(n, 3, NULL);
finally:
- PyMem_Free(coords);
- return ret;
+ PyMem_Free(coords);
+ return ret;
}
/* --------------------------------- AREA FUNCTIONS-------------------- */
PyDoc_STRVAR(M_Geometry_area_tri_doc,
-".. function:: area_tri(v1, v2, v3)\n"
-"\n"
-" Returns the area size of the 2D or 3D triangle defined.\n"
-"\n"
-" :arg v1: Point1\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Point2\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: Point3\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :rtype: float\n"
-);
+ ".. function:: area_tri(v1, v2, v3)\n"
+ "\n"
+ " Returns the area size of the 2D or 3D triangle defined.\n"
+ "\n"
+ " :arg v1: Point1\n"
+ " :type v1: :class:`mathutils.Vector`\n"
+ " :arg v2: Point2\n"
+ " :type v2: :class:`mathutils.Vector`\n"
+ " :arg v3: Point3\n"
+ " :type v3: :class:`mathutils.Vector`\n"
+ " :rtype: float\n");
static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "area_tri";
- PyObject *py_tri[3];
- float tri[3][3];
- int len;
-
- if (!PyArg_ParseTuple(
- args, "OOO:area_tri",
- UNPACK3_EX(&, py_tri, )))
- {
- return NULL;
- }
-
- if ((((len = mathutils_array_parse(tri[0], 2, 3, py_tri[0], error_prefix)) != -1) &&
- (mathutils_array_parse(tri[1], len, len, py_tri[1], error_prefix) != -1) &&
- (mathutils_array_parse(tri[2], len, len, py_tri[2], error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- return PyFloat_FromDouble((len == 3 ? area_tri_v3 : area_tri_v2)(UNPACK3(tri)));
+ const char *error_prefix = "area_tri";
+ PyObject *py_tri[3];
+ float tri[3][3];
+ int len;
+
+ if (!PyArg_ParseTuple(args, "OOO:area_tri", UNPACK3_EX(&, py_tri, ))) {
+ return NULL;
+ }
+
+ if ((((len = mathutils_array_parse(tri[0], 2, 3, py_tri[0], error_prefix)) != -1) &&
+ (mathutils_array_parse(tri[1], len, len, py_tri[1], error_prefix) != -1) &&
+ (mathutils_array_parse(tri[2], len, len, py_tri[2], error_prefix) != -1)) == 0) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble((len == 3 ? area_tri_v3 : area_tri_v2)(UNPACK3(tri)));
}
PyDoc_STRVAR(M_Geometry_volume_tetrahedron_doc,
-".. function:: volume_tetrahedron(v1, v2, v3, v4)\n"
-"\n"
-" Return the volume formed by a tetrahedron (points can be in any order).\n"
-"\n"
-" :arg v1: Point1\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Point2\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: Point3\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :arg v4: Point4\n"
-" :type v4: :class:`mathutils.Vector`\n"
-" :rtype: float\n"
-);
+ ".. function:: volume_tetrahedron(v1, v2, v3, v4)\n"
+ "\n"
+ " Return the volume formed by a tetrahedron (points can be in any order).\n"
+ "\n"
+ " :arg v1: Point1\n"
+ " :type v1: :class:`mathutils.Vector`\n"
+ " :arg v2: Point2\n"
+ " :type v2: :class:`mathutils.Vector`\n"
+ " :arg v3: Point3\n"
+ " :type v3: :class:`mathutils.Vector`\n"
+ " :arg v4: Point4\n"
+ " :type v4: :class:`mathutils.Vector`\n"
+ " :rtype: float\n");
static PyObject *M_Geometry_volume_tetrahedron(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "volume_tetrahedron";
- PyObject *py_tet[4];
- float tet[4][3];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOO:volume_tetrahedron",
- UNPACK4_EX(&, py_tet, )))
- {
- return NULL;
- }
-
- for (i = 0; i < ARRAY_SIZE(tet); i++) {
- if (mathutils_array_parse(tet[i], 3, 3 | MU_ARRAY_SPILL, py_tet[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- return PyFloat_FromDouble(volume_tetrahedron_v3(UNPACK4(tet)));
+ const char *error_prefix = "volume_tetrahedron";
+ PyObject *py_tet[4];
+ float tet[4][3];
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OOOO:volume_tetrahedron", UNPACK4_EX(&, py_tet, ))) {
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tet); i++) {
+ if (mathutils_array_parse(tet[i], 3, 3 | MU_ARRAY_SPILL, py_tet[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ return PyFloat_FromDouble(volume_tetrahedron_v3(UNPACK4(tet)));
}
-PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
-".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
-"\n"
-" Takes 2 segments (defined by 4 vectors) and returns a vector for their point of intersection or None.\n"
-"\n"
-" .. warning:: Despite its name, this function works on segments, and not on lines.\n"
-"\n"
-" :arg lineA_p1: First point of the first line\n"
-" :type lineA_p1: :class:`mathutils.Vector`\n"
-" :arg lineA_p2: Second point of the first line\n"
-" :type lineA_p2: :class:`mathutils.Vector`\n"
-" :arg lineB_p1: First point of the second line\n"
-" :type lineB_p1: :class:`mathutils.Vector`\n"
-" :arg lineB_p2: Second point of the second line\n"
-" :type lineB_p2: :class:`mathutils.Vector`\n"
-" :return: The point of intersection or None when not found\n"
-" :rtype: :class:`mathutils.Vector` or None\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_line_line_2d_doc,
+ ".. function:: intersect_line_line_2d(lineA_p1, lineA_p2, lineB_p1, lineB_p2)\n"
+ "\n"
+ " Takes 2 segments (defined by 4 vectors) and returns a vector for their point of "
+ "intersection or None.\n"
+ "\n"
+ " .. warning:: Despite its name, this function works on segments, and not on lines.\n"
+ "\n"
+ " :arg lineA_p1: First point of the first line\n"
+ " :type lineA_p1: :class:`mathutils.Vector`\n"
+ " :arg lineA_p2: Second point of the first line\n"
+ " :type lineA_p2: :class:`mathutils.Vector`\n"
+ " :arg lineB_p1: First point of the second line\n"
+ " :type lineB_p1: :class:`mathutils.Vector`\n"
+ " :arg lineB_p2: Second point of the second line\n"
+ " :type lineB_p2: :class:`mathutils.Vector`\n"
+ " :return: The point of intersection or None when not found\n"
+ " :rtype: :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_line_line_2d";
- PyObject *py_lines[4];
- float lines[4][2];
- float vi[2];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOO:intersect_line_line_2d",
- UNPACK4_EX(&, py_lines, )))
- {
- return NULL;
- }
-
- for (i = 0; i < ARRAY_SIZE(lines); i++) {
- if (mathutils_array_parse(lines[i], 2, 2 | MU_ARRAY_SPILL, py_lines[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) {
- return Vector_CreatePyObject(vi, 2, NULL);
- }
- else {
- Py_RETURN_NONE;
- }
+ const char *error_prefix = "intersect_line_line_2d";
+ PyObject *py_lines[4];
+ float lines[4][2];
+ float vi[2];
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OOOO:intersect_line_line_2d", UNPACK4_EX(&, py_lines, ))) {
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(lines); i++) {
+ if (mathutils_array_parse(lines[i], 2, 2 | MU_ARRAY_SPILL, py_lines[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) {
+ return Vector_CreatePyObject(vi, 2, NULL);
+ }
+ else {
+ Py_RETURN_NONE;
+ }
}
-
-PyDoc_STRVAR(M_Geometry_intersect_line_plane_doc,
-".. function:: intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)\n"
-"\n"
-" Calculate the intersection between a line (as 2 vectors) and a plane.\n"
-" Returns a vector for the intersection or None.\n"
-"\n"
-" :arg line_a: First point of the first line\n"
-" :type line_a: :class:`mathutils.Vector`\n"
-" :arg line_b: Second point of the first line\n"
-" :type line_b: :class:`mathutils.Vector`\n"
-" :arg plane_co: A point on the plane\n"
-" :type plane_co: :class:`mathutils.Vector`\n"
-" :arg plane_no: The direction the plane is facing\n"
-" :type plane_no: :class:`mathutils.Vector`\n"
-" :return: The point of intersection or None when not found\n"
-" :rtype: :class:`mathutils.Vector` or None\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_line_plane_doc,
+ ".. function:: intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)\n"
+ "\n"
+ " Calculate the intersection between a line (as 2 vectors) and a plane.\n"
+ " Returns a vector for the intersection or None.\n"
+ "\n"
+ " :arg line_a: First point of the first line\n"
+ " :type line_a: :class:`mathutils.Vector`\n"
+ " :arg line_b: Second point of the first line\n"
+ " :type line_b: :class:`mathutils.Vector`\n"
+ " :arg plane_co: A point on the plane\n"
+ " :type plane_co: :class:`mathutils.Vector`\n"
+ " :arg plane_no: The direction the plane is facing\n"
+ " :type plane_no: :class:`mathutils.Vector`\n"
+ " :return: The point of intersection or None when not found\n"
+ " :rtype: :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_line_plane";
- PyObject *py_line_a, *py_line_b, *py_plane_co, *py_plane_no;
- float line_a[3], line_b[3], plane_co[3], plane_no[3];
- float isect[3];
- bool no_flip = false;
-
- if (!PyArg_ParseTuple(
- args, "OOOO|O&:intersect_line_plane",
- &py_line_a, &py_line_b, &py_plane_co, &py_plane_no,
- PyC_ParseBool, &no_flip))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
- (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
- (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
- (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- /* TODO: implements no_flip */
- if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) {
- return Vector_CreatePyObject(isect, 3, NULL);
- }
- else {
- Py_RETURN_NONE;
- }
+ const char *error_prefix = "intersect_line_plane";
+ PyObject *py_line_a, *py_line_b, *py_plane_co, *py_plane_no;
+ float line_a[3], line_b[3], plane_co[3], plane_no[3];
+ float isect[3];
+ bool no_flip = false;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOO|O&:intersect_line_plane",
+ &py_line_a,
+ &py_line_b,
+ &py_plane_co,
+ &py_plane_no,
+ PyC_ParseBool,
+ &no_flip)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+
+ /* TODO: implements no_flip */
+ if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) {
+ return Vector_CreatePyObject(isect, 3, NULL);
+ }
+ else {
+ Py_RETURN_NONE;
+ }
}
-PyDoc_STRVAR(M_Geometry_intersect_plane_plane_doc,
-".. function:: intersect_plane_plane(plane_a_co, plane_a_no, plane_b_co, plane_b_no)\n"
-"\n"
-" Return the intersection between two planes\n"
-"\n"
-" :arg plane_a_co: Point on the first plane\n"
-" :type plane_a_co: :class:`mathutils.Vector`\n"
-" :arg plane_a_no: Normal of the first plane\n"
-" :type plane_a_no: :class:`mathutils.Vector`\n"
-" :arg plane_b_co: Point on the second plane\n"
-" :type plane_b_co: :class:`mathutils.Vector`\n"
-" :arg plane_b_no: Normal of the second plane\n"
-" :type plane_b_no: :class:`mathutils.Vector`\n"
-" :return: The line of the intersection represented as a point and a vector\n"
-" :rtype: tuple pair of :class:`mathutils.Vector` or None if the intersection can't be calculated\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_plane_plane_doc,
+ ".. function:: intersect_plane_plane(plane_a_co, plane_a_no, plane_b_co, plane_b_no)\n"
+ "\n"
+ " Return the intersection between two planes\n"
+ "\n"
+ " :arg plane_a_co: Point on the first plane\n"
+ " :type plane_a_co: :class:`mathutils.Vector`\n"
+ " :arg plane_a_no: Normal of the first plane\n"
+ " :type plane_a_no: :class:`mathutils.Vector`\n"
+ " :arg plane_b_co: Point on the second plane\n"
+ " :type plane_b_co: :class:`mathutils.Vector`\n"
+ " :arg plane_b_no: Normal of the second plane\n"
+ " :type plane_b_no: :class:`mathutils.Vector`\n"
+ " :return: The line of the intersection represented as a point and a vector\n"
+ " :rtype: tuple pair of :class:`mathutils.Vector` or None if the intersection can't be "
+ "calculated\n");
static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_plane_plane";
- PyObject *ret, *ret_co, *ret_no;
- PyObject *py_plane_a_co, *py_plane_a_no, *py_plane_b_co, *py_plane_b_no;
- float plane_a_co[3], plane_a_no[3], plane_b_co[3], plane_b_no[3];
- float plane_a[4], plane_b[4];
-
- float isect_co[3];
- float isect_no[3];
-
- if (!PyArg_ParseTuple(
- args, "OOOO:intersect_plane_plane",
- &py_plane_a_co, &py_plane_a_no, &py_plane_b_co, &py_plane_b_no))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(plane_a_co, 3, 3 | MU_ARRAY_SPILL, py_plane_a_co, error_prefix) != -1) &&
- (mathutils_array_parse(plane_a_no, 3, 3 | MU_ARRAY_SPILL, py_plane_a_no, error_prefix) != -1) &&
- (mathutils_array_parse(plane_b_co, 3, 3 | MU_ARRAY_SPILL, py_plane_b_co, error_prefix) != -1) &&
- (mathutils_array_parse(plane_b_no, 3, 3 | MU_ARRAY_SPILL, py_plane_b_no, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- plane_from_point_normal_v3(plane_a, plane_a_co, plane_a_no);
- plane_from_point_normal_v3(plane_b, plane_b_co, plane_b_no);
-
- if (isect_plane_plane_v3(
- plane_a, plane_b,
- isect_co, isect_no))
- {
- normalize_v3(isect_no);
-
- ret_co = Vector_CreatePyObject(isect_co, 3, NULL);
- ret_no = Vector_CreatePyObject(isect_no, 3, NULL);
- }
- else {
- ret_co = Py_INCREF_RET(Py_None);
- ret_no = Py_INCREF_RET(Py_None);
- }
-
- ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret,
- ret_co,
- ret_no);
- return ret;
+ const char *error_prefix = "intersect_plane_plane";
+ PyObject *ret, *ret_co, *ret_no;
+ PyObject *py_plane_a_co, *py_plane_a_no, *py_plane_b_co, *py_plane_b_no;
+ float plane_a_co[3], plane_a_no[3], plane_b_co[3], plane_b_no[3];
+ float plane_a[4], plane_b[4];
+
+ float isect_co[3];
+ float isect_no[3];
+
+ if (!PyArg_ParseTuple(args,
+ "OOOO:intersect_plane_plane",
+ &py_plane_a_co,
+ &py_plane_a_no,
+ &py_plane_b_co,
+ &py_plane_b_no)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(plane_a_co, 3, 3 | MU_ARRAY_SPILL, py_plane_a_co, error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(plane_a_no, 3, 3 | MU_ARRAY_SPILL, py_plane_a_no, error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(plane_b_co, 3, 3 | MU_ARRAY_SPILL, py_plane_b_co, error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(plane_b_no, 3, 3 | MU_ARRAY_SPILL, py_plane_b_no, error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+
+ plane_from_point_normal_v3(plane_a, plane_a_co, plane_a_no);
+ plane_from_point_normal_v3(plane_b, plane_b_co, plane_b_no);
+
+ if (isect_plane_plane_v3(plane_a, plane_b, isect_co, isect_no)) {
+ normalize_v3(isect_no);
+
+ ret_co = Vector_CreatePyObject(isect_co, 3, NULL);
+ ret_no = Vector_CreatePyObject(isect_no, 3, NULL);
+ }
+ else {
+ ret_co = Py_INCREF_RET(Py_None);
+ ret_no = Py_INCREF_RET(Py_None);
+ }
+
+ ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, ret_co, ret_no);
+ return ret;
}
-PyDoc_STRVAR(M_Geometry_intersect_line_sphere_doc,
-".. function:: intersect_line_sphere(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
-"\n"
-" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
-" returns the intersection\n"
-"\n"
-" :arg line_a: First point of the line\n"
-" :type line_a: :class:`mathutils.Vector`\n"
-" :arg line_b: Second point of the line\n"
-" :type line_b: :class:`mathutils.Vector`\n"
-" :arg sphere_co: The center of the sphere\n"
-" :type sphere_co: :class:`mathutils.Vector`\n"
-" :arg sphere_radius: Radius of the sphere\n"
-" :type sphere_radius: sphere_radius\n"
-" :return: The intersection points as a pair of vectors or None when there is no intersection\n"
-" :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_line_sphere_doc,
+ ".. function:: intersect_line_sphere(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
+ "\n"
+ " Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
+ " returns the intersection\n"
+ "\n"
+ " :arg line_a: First point of the line\n"
+ " :type line_a: :class:`mathutils.Vector`\n"
+ " :arg line_b: Second point of the line\n"
+ " :type line_b: :class:`mathutils.Vector`\n"
+ " :arg sphere_co: The center of the sphere\n"
+ " :type sphere_co: :class:`mathutils.Vector`\n"
+ " :arg sphere_radius: Radius of the sphere\n"
+ " :type sphere_radius: sphere_radius\n"
+ " :return: The intersection points as a pair of vectors or None when there is no "
+ "intersection\n"
+ " :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_line_sphere";
- PyObject *py_line_a, *py_line_b, *py_sphere_co;
- float line_a[3], line_b[3], sphere_co[3];
- float sphere_radius;
- bool clip = true;
-
- float isect_a[3];
- float isect_b[3];
-
- if (!PyArg_ParseTuple(
- args, "OOOf|O&:intersect_line_sphere",
- &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius,
- PyC_ParseBool, &clip))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
- (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
- (mathutils_array_parse(sphere_co, 3, 3 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
- else {
- bool use_a = true;
- bool use_b = true;
- float lambda;
-
- PyObject *ret = PyTuple_New(2);
-
- switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
- case 1:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_a = false; }
- use_b = false;
- break;
- case 2:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_a = false; }
- if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_b = false; }
- break;
- default:
- use_a = false;
- use_b = false;
- break;
- }
-
- PyTuple_SET_ITEMS(ret,
- use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
- use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
-
- return ret;
- }
+ const char *error_prefix = "intersect_line_sphere";
+ PyObject *py_line_a, *py_line_b, *py_sphere_co;
+ float line_a[3], line_b[3], sphere_co[3];
+ float sphere_radius;
+ bool clip = true;
+
+ float isect_a[3];
+ float isect_b[3];
+
+ if (!PyArg_ParseTuple(args,
+ "OOOf|O&:intersect_line_sphere",
+ &py_line_a,
+ &py_line_b,
+ &py_sphere_co,
+ &sphere_radius,
+ PyC_ParseBool,
+ &clip)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(sphere_co, 3, 3 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+ else {
+ bool use_a = true;
+ bool use_b = true;
+ float lambda;
+
+ PyObject *ret = PyTuple_New(2);
+
+ switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
+ case 1:
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ use_b = false;
+ break;
+ case 2:
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_b = false;
+ }
+ break;
+ default:
+ use_a = false;
+ use_b = false;
+ break;
+ }
+
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
+
+ return ret;
+ }
}
/* keep in sync with M_Geometry_intersect_line_sphere */
-PyDoc_STRVAR(M_Geometry_intersect_line_sphere_2d_doc,
-".. function:: intersect_line_sphere_2d(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
-"\n"
-" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
-" returns the intersection\n"
-"\n"
-" :arg line_a: First point of the line\n"
-" :type line_a: :class:`mathutils.Vector`\n"
-" :arg line_b: Second point of the line\n"
-" :type line_b: :class:`mathutils.Vector`\n"
-" :arg sphere_co: The center of the sphere\n"
-" :type sphere_co: :class:`mathutils.Vector`\n"
-" :arg sphere_radius: Radius of the sphere\n"
-" :type sphere_radius: sphere_radius\n"
-" :return: The intersection points as a pair of vectors or None when there is no intersection\n"
-" :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_line_sphere_2d_doc,
+ ".. function:: intersect_line_sphere_2d(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
+ "\n"
+ " Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
+ " returns the intersection\n"
+ "\n"
+ " :arg line_a: First point of the line\n"
+ " :type line_a: :class:`mathutils.Vector`\n"
+ " :arg line_b: Second point of the line\n"
+ " :type line_b: :class:`mathutils.Vector`\n"
+ " :arg sphere_co: The center of the sphere\n"
+ " :type sphere_co: :class:`mathutils.Vector`\n"
+ " :arg sphere_radius: Radius of the sphere\n"
+ " :type sphere_radius: sphere_radius\n"
+ " :return: The intersection points as a pair of vectors or None when there is no "
+ "intersection\n"
+ " :rtype: A tuple pair containing :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_line_sphere_2d";
- PyObject *py_line_a, *py_line_b, *py_sphere_co;
- float line_a[2], line_b[2], sphere_co[2];
- float sphere_radius;
- bool clip = true;
-
- float isect_a[2];
- float isect_b[2];
-
- if (!PyArg_ParseTuple(
- args, "OOOf|O&:intersect_line_sphere_2d",
- &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius,
- PyC_ParseBool, &clip))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(line_a, 2, 2 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
- (mathutils_array_parse(line_b, 2, 2 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
- (mathutils_array_parse(sphere_co, 2, 2 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
- else {
- bool use_a = true;
- bool use_b = true;
- float lambda;
-
- PyObject *ret = PyTuple_New(2);
-
- switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
- case 1:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_a = false; }
- use_b = false;
- break;
- case 2:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_a = false; }
- if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) { use_b = false; }
- break;
- default:
- use_a = false;
- use_b = false;
- break;
- }
-
- PyTuple_SET_ITEMS(ret,
- use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
- use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
-
- return ret;
- }
+ const char *error_prefix = "intersect_line_sphere_2d";
+ PyObject *py_line_a, *py_line_b, *py_sphere_co;
+ float line_a[2], line_b[2], sphere_co[2];
+ float sphere_radius;
+ bool clip = true;
+
+ float isect_a[2];
+ float isect_b[2];
+
+ if (!PyArg_ParseTuple(args,
+ "OOOf|O&:intersect_line_sphere_2d",
+ &py_line_a,
+ &py_line_b,
+ &py_sphere_co,
+ &sphere_radius,
+ PyC_ParseBool,
+ &clip)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(line_a, 2, 2 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 2, 2 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(sphere_co, 2, 2 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+ else {
+ bool use_a = true;
+ bool use_b = true;
+ float lambda;
+
+ PyObject *ret = PyTuple_New(2);
+
+ switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
+ case 1:
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ use_b = false;
+ break;
+ case 2:
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_b = false;
+ }
+ break;
+ default:
+ use_a = false;
+ use_b = false;
+ break;
+ }
+
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
+
+ return ret;
+ }
}
-PyDoc_STRVAR(M_Geometry_intersect_point_line_doc,
-".. function:: intersect_point_line(pt, line_p1, line_p2)\n"
-"\n"
-" Takes a point and a line and returns a tuple with the closest point on the line and its distance from the first point of the line as a percentage of the length of the line.\n"
-"\n"
-" :arg pt: Point\n"
-" :type pt: :class:`mathutils.Vector`\n"
-" :arg line_p1: First point of the line\n"
-" :type line_p1: :class:`mathutils.Vector`\n"
-" :arg line_p1: Second point of the line\n"
-" :type line_p1: :class:`mathutils.Vector`\n"
-" :rtype: (:class:`mathutils.Vector`, float)\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_point_line_doc,
+ ".. function:: intersect_point_line(pt, line_p1, line_p2)\n"
+ "\n"
+ " Takes a point and a line and returns a tuple with the closest point on the line and its "
+ "distance from the first point of the line as a percentage of the length of the line.\n"
+ "\n"
+ " :arg pt: Point\n"
+ " :type pt: :class:`mathutils.Vector`\n"
+ " :arg line_p1: First point of the line\n"
+ " :type line_p1: :class:`mathutils.Vector`\n"
+ " :arg line_p1: Second point of the line\n"
+ " :type line_p1: :class:`mathutils.Vector`\n"
+ " :rtype: (:class:`mathutils.Vector`, float)\n");
static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_point_line";
- PyObject *py_pt, *py_line_a, *py_line_b;
- float pt[3], pt_out[3], line_a[3], line_b[3];
- float lambda;
- PyObject *ret;
- int size = 2;
-
- if (!PyArg_ParseTuple(
- args, "OOO:intersect_point_line",
- &py_pt, &py_line_a, &py_line_b))
- {
- return NULL;
- }
-
- /* accept 2d verts */
- if ((((size = mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) &&
- (mathutils_array_parse(line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) &&
- (mathutils_array_parse(line_b, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_b, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- /* do the calculation */
- lambda = closest_to_line_v3(pt_out, pt, line_a, line_b);
-
- ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret,
- Vector_CreatePyObject(pt_out, size, NULL),
- PyFloat_FromDouble(lambda));
- return ret;
+ const char *error_prefix = "intersect_point_line";
+ PyObject *py_pt, *py_line_a, *py_line_b;
+ float pt[3], pt_out[3], line_a[3], line_b[3];
+ float lambda;
+ PyObject *ret;
+ int size = 2;
+
+ if (!PyArg_ParseTuple(args, "OOO:intersect_point_line", &py_pt, &py_line_a, &py_line_b)) {
+ return NULL;
+ }
+
+ /* accept 2d verts */
+ if ((((size = mathutils_array_parse(
+ pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) &&
+ (mathutils_array_parse(
+ line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(
+ line_b, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_b, error_prefix) != -1)) == 0) {
+ return NULL;
+ }
+
+ /* do the calculation */
+ lambda = closest_to_line_v3(pt_out, pt, line_a, line_b);
+
+ ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(pt_out, size, NULL), PyFloat_FromDouble(lambda));
+ return ret;
}
PyDoc_STRVAR(M_Geometry_intersect_point_tri_doc,
-".. function:: intersect_point_tri(pt, tri_p1, tri_p2, tri_p3)\n"
-"\n"
-" Takes 4 vectors: one is the point and the next 3 define the triangle.\n"
-"\n"
-" :arg pt: Point\n"
-" :type pt: :class:`mathutils.Vector`\n"
-" :arg tri_p1: First point of the triangle\n"
-" :type tri_p1: :class:`mathutils.Vector`\n"
-" :arg tri_p2: Second point of the triangle\n"
-" :type tri_p2: :class:`mathutils.Vector`\n"
-" :arg tri_p3: Third point of the triangle\n"
-" :type tri_p3: :class:`mathutils.Vector`\n"
-" :return: Point on the triangles plane or None if its outside the triangle\n"
-" :rtype: :class:`mathutils.Vector` or None\n"
-);
+ ".. function:: intersect_point_tri(pt, tri_p1, tri_p2, tri_p3)\n"
+ "\n"
+ " Takes 4 vectors: one is the point and the next 3 define the triangle.\n"
+ "\n"
+ " :arg pt: Point\n"
+ " :type pt: :class:`mathutils.Vector`\n"
+ " :arg tri_p1: First point of the triangle\n"
+ " :type tri_p1: :class:`mathutils.Vector`\n"
+ " :arg tri_p2: Second point of the triangle\n"
+ " :type tri_p2: :class:`mathutils.Vector`\n"
+ " :arg tri_p3: Third point of the triangle\n"
+ " :type tri_p3: :class:`mathutils.Vector`\n"
+ " :return: Point on the triangles plane or None if its outside the triangle\n"
+ " :rtype: :class:`mathutils.Vector` or None\n");
static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_point_tri";
- PyObject *py_pt, *py_tri[3];
- float pt[3], tri[3][3];
- float vi[3];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOO:intersect_point_tri",
- &py_pt, UNPACK3_EX(&, py_tri, )))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix) == -1) {
- return NULL;
- }
- for (i = 0; i < ARRAY_SIZE(tri); i++) {
- if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) {
- return Vector_CreatePyObject(vi, 3, NULL);
- }
- else {
- Py_RETURN_NONE;
- }
+ const char *error_prefix = "intersect_point_tri";
+ PyObject *py_pt, *py_tri[3];
+ float pt[3], tri[3][3];
+ float vi[3];
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OOOO:intersect_point_tri", &py_pt, UNPACK3_EX(&, py_tri, ))) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix) ==
+ -1) {
+ return NULL;
+ }
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(
+ tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) {
+ return Vector_CreatePyObject(vi, 3, NULL);
+ }
+ else {
+ Py_RETURN_NONE;
+ }
}
-PyDoc_STRVAR(M_Geometry_intersect_point_tri_2d_doc,
-".. function:: intersect_point_tri_2d(pt, tri_p1, tri_p2, tri_p3)\n"
-"\n"
-" Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 define the triangle. Returns 1 if the point is within the triangle, otherwise 0.\n"
-"\n"
-" :arg pt: Point\n"
-" :type pt: :class:`mathutils.Vector`\n"
-" :arg tri_p1: First point of the triangle\n"
-" :type tri_p1: :class:`mathutils.Vector`\n"
-" :arg tri_p2: Second point of the triangle\n"
-" :type tri_p2: :class:`mathutils.Vector`\n"
-" :arg tri_p3: Third point of the triangle\n"
-" :type tri_p3: :class:`mathutils.Vector`\n"
-" :rtype: int\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_intersect_point_tri_2d_doc,
+ ".. function:: intersect_point_tri_2d(pt, tri_p1, tri_p2, tri_p3)\n"
+ "\n"
+ " Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 "
+ "define the triangle. Returns 1 if the point is within the triangle, otherwise 0.\n"
+ "\n"
+ " :arg pt: Point\n"
+ " :type pt: :class:`mathutils.Vector`\n"
+ " :arg tri_p1: First point of the triangle\n"
+ " :type tri_p1: :class:`mathutils.Vector`\n"
+ " :arg tri_p2: Second point of the triangle\n"
+ " :type tri_p2: :class:`mathutils.Vector`\n"
+ " :arg tri_p3: Third point of the triangle\n"
+ " :type tri_p3: :class:`mathutils.Vector`\n"
+ " :rtype: int\n");
static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_point_tri_2d";
- PyObject *py_pt, *py_tri[3];
- float pt[2], tri[3][2];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOO:intersect_point_tri_2d",
- &py_pt, UNPACK3_EX(&, py_tri, )))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
- return NULL;
- }
- for (i = 0; i < ARRAY_SIZE(tri); i++) {
- if (mathutils_array_parse(tri[i], 2, 2 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- return PyLong_FromLong(isect_point_tri_v2(pt, UNPACK3(tri)));
+ const char *error_prefix = "intersect_point_tri_2d";
+ PyObject *py_pt, *py_tri[3];
+ float pt[2], tri[3][2];
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OOOO:intersect_point_tri_2d", &py_pt, UNPACK3_EX(&, py_tri, ))) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
+ return NULL;
+ }
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(tri[i], 2, 2 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ return PyLong_FromLong(isect_point_tri_v2(pt, UNPACK3(tri)));
}
PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc,
-".. function:: intersect_point_quad_2d(pt, quad_p1, quad_p2, quad_p3, quad_p4)\n"
-"\n"
-" Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad,\n"
-" only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0.\n"
-" Works only with convex quads without singular edges.\n"
-"\n"
-" :arg pt: Point\n"
-" :type pt: :class:`mathutils.Vector`\n"
-" :arg quad_p1: First point of the quad\n"
-" :type quad_p1: :class:`mathutils.Vector`\n"
-" :arg quad_p2: Second point of the quad\n"
-" :type quad_p2: :class:`mathutils.Vector`\n"
-" :arg quad_p3: Third point of the quad\n"
-" :type quad_p3: :class:`mathutils.Vector`\n"
-" :arg quad_p4: Fourth point of the quad\n"
-" :type quad_p4: :class:`mathutils.Vector`\n"
-" :rtype: int\n"
-);
+ ".. function:: intersect_point_quad_2d(pt, quad_p1, quad_p2, quad_p3, quad_p4)\n"
+ "\n"
+ " Takes 5 vectors (using only the x and y coordinates): one is the point and the "
+ "next 4 define the quad,\n"
+ " only the x and y are used from the vectors. Returns 1 if the point is within the "
+ "quad, otherwise 0.\n"
+ " Works only with convex quads without singular edges.\n"
+ "\n"
+ " :arg pt: Point\n"
+ " :type pt: :class:`mathutils.Vector`\n"
+ " :arg quad_p1: First point of the quad\n"
+ " :type quad_p1: :class:`mathutils.Vector`\n"
+ " :arg quad_p2: Second point of the quad\n"
+ " :type quad_p2: :class:`mathutils.Vector`\n"
+ " :arg quad_p3: Third point of the quad\n"
+ " :type quad_p3: :class:`mathutils.Vector`\n"
+ " :arg quad_p4: Fourth point of the quad\n"
+ " :type quad_p4: :class:`mathutils.Vector`\n"
+ " :rtype: int\n");
static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "intersect_point_quad_2d";
- PyObject *py_pt, *py_quad[4];
- float pt[2], quad[4][2];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOOO:intersect_point_quad_2d",
- &py_pt, UNPACK4_EX(&, py_quad, )))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
- return NULL;
- }
- for (i = 0; i < ARRAY_SIZE(quad); i++) {
- if (mathutils_array_parse(quad[i], 2, 2 | MU_ARRAY_SPILL, py_quad[i], error_prefix) == -1) {
- return NULL;
- }
- }
-
- return PyLong_FromLong(isect_point_quad_v2(pt, UNPACK4(quad)));
+ const char *error_prefix = "intersect_point_quad_2d";
+ PyObject *py_pt, *py_quad[4];
+ float pt[2], quad[4][2];
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OOOOO:intersect_point_quad_2d", &py_pt, UNPACK4_EX(&, py_quad, ))) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
+ return NULL;
+ }
+ for (i = 0; i < ARRAY_SIZE(quad); i++) {
+ if (mathutils_array_parse(quad[i], 2, 2 | MU_ARRAY_SPILL, py_quad[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
+
+ return PyLong_FromLong(isect_point_quad_v2(pt, UNPACK4(quad)));
}
PyDoc_STRVAR(M_Geometry_distance_point_to_plane_doc,
-".. function:: distance_point_to_plane(pt, plane_co, plane_no)\n"
-"\n"
-" Returns the signed distance between a point and a plane "
-" (negative when below the normal).\n"
-"\n"
-" :arg pt: Point\n"
-" :type pt: :class:`mathutils.Vector`\n"
-" :arg plane_co: A point on the plane\n"
-" :type plane_co: :class:`mathutils.Vector`\n"
-" :arg plane_no: The direction the plane is facing\n"
-" :type plane_no: :class:`mathutils.Vector`\n"
-" :rtype: float\n"
-);
+ ".. function:: distance_point_to_plane(pt, plane_co, plane_no)\n"
+ "\n"
+ " Returns the signed distance between a point and a plane "
+ " (negative when below the normal).\n"
+ "\n"
+ " :arg pt: Point\n"
+ " :type pt: :class:`mathutils.Vector`\n"
+ " :arg plane_co: A point on the plane\n"
+ " :type plane_co: :class:`mathutils.Vector`\n"
+ " :arg plane_no: The direction the plane is facing\n"
+ " :type plane_no: :class:`mathutils.Vector`\n"
+ " :rtype: float\n");
static PyObject *M_Geometry_distance_point_to_plane(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "distance_point_to_plane";
- PyObject *py_pt, *py_plane_co, *py_plane_no;
- float pt[3], plane_co[3], plane_no[3];
- float plane[4];
-
- if (!PyArg_ParseTuple(
- args, "OOO:distance_point_to_plane",
- &py_pt, &py_plane_co, &py_plane_no))
- {
- return NULL;
- }
-
- if (((mathutils_array_parse(pt, 3, 3 | MU_ARRAY_SPILL, py_pt, error_prefix) != -1) &&
- (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
- (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) != -1)) == 0)
- {
- return NULL;
- }
-
- plane_from_point_normal_v3(plane, plane_co, plane_no);
- return PyFloat_FromDouble(dist_signed_to_plane_v3(pt, plane));
+ const char *error_prefix = "distance_point_to_plane";
+ PyObject *py_pt, *py_plane_co, *py_plane_no;
+ float pt[3], plane_co[3], plane_no[3];
+ float plane[4];
+
+ if (!PyArg_ParseTuple(args, "OOO:distance_point_to_plane", &py_pt, &py_plane_co, &py_plane_no)) {
+ return NULL;
+ }
+
+ if (((mathutils_array_parse(pt, 3, 3 | MU_ARRAY_SPILL, py_pt, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+
+ plane_from_point_normal_v3(plane, plane_co, plane_no);
+ return PyFloat_FromDouble(dist_signed_to_plane_v3(pt, plane));
}
-PyDoc_STRVAR(M_Geometry_barycentric_transform_doc,
-".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n"
-"\n"
-" Return a transformed point, the transformation is defined by 2 triangles.\n"
-"\n"
-" :arg point: The point to transform.\n"
-" :type point: :class:`mathutils.Vector`\n"
-" :arg tri_a1: source triangle vertex.\n"
-" :type tri_a1: :class:`mathutils.Vector`\n"
-" :arg tri_a2: source triangle vertex.\n"
-" :type tri_a2: :class:`mathutils.Vector`\n"
-" :arg tri_a3: source triangle vertex.\n"
-" :type tri_a3: :class:`mathutils.Vector`\n"
-" :arg tri_b1: target triangle vertex.\n"
-" :type tri_b1: :class:`mathutils.Vector`\n"
-" :arg tri_b2: target triangle vertex.\n"
-" :type tri_b2: :class:`mathutils.Vector`\n"
-" :arg tri_b3: target triangle vertex.\n"
-" :type tri_b3: :class:`mathutils.Vector`\n"
-" :return: The transformed point\n"
-" :rtype: :class:`mathutils.Vector`'s\n"
-);
+PyDoc_STRVAR(
+ M_Geometry_barycentric_transform_doc,
+ ".. function:: barycentric_transform(point, tri_a1, tri_a2, tri_a3, tri_b1, tri_b2, tri_b3)\n"
+ "\n"
+ " Return a transformed point, the transformation is defined by 2 triangles.\n"
+ "\n"
+ " :arg point: The point to transform.\n"
+ " :type point: :class:`mathutils.Vector`\n"
+ " :arg tri_a1: source triangle vertex.\n"
+ " :type tri_a1: :class:`mathutils.Vector`\n"
+ " :arg tri_a2: source triangle vertex.\n"
+ " :type tri_a2: :class:`mathutils.Vector`\n"
+ " :arg tri_a3: source triangle vertex.\n"
+ " :type tri_a3: :class:`mathutils.Vector`\n"
+ " :arg tri_b1: target triangle vertex.\n"
+ " :type tri_b1: :class:`mathutils.Vector`\n"
+ " :arg tri_b2: target triangle vertex.\n"
+ " :type tri_b2: :class:`mathutils.Vector`\n"
+ " :arg tri_b3: target triangle vertex.\n"
+ " :type tri_b3: :class:`mathutils.Vector`\n"
+ " :return: The transformed point\n"
+ " :rtype: :class:`mathutils.Vector`'s\n");
static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "barycentric_transform";
- PyObject *py_pt_src, *py_tri_src[3], *py_tri_dst[3];
- float pt_src[3], pt_dst[3], tri_src[3][3], tri_dst[3][3];
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OOOOOOO:barycentric_transform",
- &py_pt_src,
- UNPACK3_EX(&, py_tri_src, ),
- UNPACK3_EX(&, py_tri_dst, )))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(pt_src, 3, 3 | MU_ARRAY_SPILL, py_pt_src, error_prefix) == -1) {
- return NULL;
- }
- for (i = 0; i < ARRAY_SIZE(tri_src); i++) {
- if (((mathutils_array_parse(tri_src[i], 3, 3 | MU_ARRAY_SPILL, py_tri_src[i], error_prefix) != -1) &&
- (mathutils_array_parse(tri_dst[i], 3, 3 | MU_ARRAY_SPILL, py_tri_dst[i], error_prefix) != -1)) == 0)
- {
- return NULL;
- }
- }
-
- transform_point_by_tri_v3(
- pt_dst, pt_src,
- UNPACK3(tri_dst),
- UNPACK3(tri_src));
-
- return Vector_CreatePyObject(pt_dst, 3, NULL);
+ const char *error_prefix = "barycentric_transform";
+ PyObject *py_pt_src, *py_tri_src[3], *py_tri_dst[3];
+ float pt_src[3], pt_dst[3], tri_src[3][3], tri_dst[3][3];
+ int i;
+
+ if (!PyArg_ParseTuple(args,
+ "OOOOOOO:barycentric_transform",
+ &py_pt_src,
+ UNPACK3_EX(&, py_tri_src, ),
+ UNPACK3_EX(&, py_tri_dst, ))) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(pt_src, 3, 3 | MU_ARRAY_SPILL, py_pt_src, error_prefix) == -1) {
+ return NULL;
+ }
+ for (i = 0; i < ARRAY_SIZE(tri_src); i++) {
+ if (((mathutils_array_parse(tri_src[i], 3, 3 | MU_ARRAY_SPILL, py_tri_src[i], error_prefix) !=
+ -1) &&
+ (mathutils_array_parse(tri_dst[i], 3, 3 | MU_ARRAY_SPILL, py_tri_dst[i], error_prefix) !=
+ -1)) == 0) {
+ return NULL;
+ }
+ }
+
+ transform_point_by_tri_v3(pt_dst, pt_src, UNPACK3(tri_dst), UNPACK3(tri_src));
+
+ return Vector_CreatePyObject(pt_dst, 3, NULL);
}
PyDoc_STRVAR(M_Geometry_points_in_planes_doc,
-".. function:: points_in_planes(planes)\n"
-"\n"
-" Returns a list of points inside all planes given and a list of index values for the planes used.\n"
-"\n"
-" :arg planes: List of planes (4D vectors).\n"
-" :type planes: list of :class:`mathutils.Vector`\n"
-" :return: two lists, once containing the vertices inside the planes, another containing the plane indices used\n"
-" :rtype: pair of lists\n"
-);
+ ".. function:: points_in_planes(planes)\n"
+ "\n"
+ " Returns a list of points inside all planes given and a list of index values for "
+ "the planes used.\n"
+ "\n"
+ " :arg planes: List of planes (4D vectors).\n"
+ " :type planes: list of :class:`mathutils.Vector`\n"
+ " :return: two lists, once containing the vertices inside the planes, another "
+ "containing the plane indices used\n"
+ " :rtype: pair of lists\n");
/* note: this function could be optimized by some spatial structure */
static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *args)
{
- PyObject *py_planes;
- float (*planes)[4];
- unsigned int planes_len;
-
- if (!PyArg_ParseTuple(
- args, "O:points_in_planes",
- &py_planes))
- {
- return NULL;
- }
-
- if ((planes_len = mathutils_array_parse_alloc_v((float **)&planes, 4, py_planes, "points_in_planes")) == -1) {
- return NULL;
- }
- else {
- /* note, this could be refactored into plain C easy - py bits are noted */
- const float eps = 0.0001f;
- const unsigned int len = (unsigned int)planes_len;
- unsigned int i, j, k, l;
-
- float n1n2[3], n2n3[3], n3n1[3];
- float potentialVertex[3];
- char *planes_used = PyMem_Malloc(sizeof(char) * len);
-
- /* python */
- PyObject *py_verts = PyList_New(0);
- PyObject *py_plane_index = PyList_New(0);
-
- memset(planes_used, 0, sizeof(char) * len);
-
- for (i = 0; i < len; i++) {
- const float *N1 = planes[i];
- for (j = i + 1; j < len; j++) {
- const float *N2 = planes[j];
- cross_v3_v3v3(n1n2, N1, N2);
- if (len_squared_v3(n1n2) > eps) {
- for (k = j + 1; k < len; k++) {
- const float *N3 = planes[k];
- cross_v3_v3v3(n2n3, N2, N3);
- if (len_squared_v3(n2n3) > eps) {
- cross_v3_v3v3(n3n1, N3, N1);
- if (len_squared_v3(n3n1) > eps) {
- const float quotient = dot_v3v3(N1, n2n3);
- if (fabsf(quotient) > eps) {
- /* potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (-1.0 / quotient); */
- const float quotient_ninv = -1.0f / quotient;
- potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) + (n1n2[0] * N3[3])) * quotient_ninv;
- potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) + (n1n2[1] * N3[3])) * quotient_ninv;
- potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) + (n1n2[2] * N3[3])) * quotient_ninv;
- for (l = 0; l < len; l++) {
- const float *NP = planes[l];
- if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) {
- break;
- }
- }
-
- if (l == len) { /* ok */
- /* python */
- PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
- planes_used[i] = planes_used[j] = planes_used[k] = true;
- }
- }
- }
- }
- }
- }
- }
- }
-
- PyMem_Free(planes);
-
- /* now make a list of used planes */
- for (i = 0; i < len; i++) {
- if (planes_used[i]) {
- PyList_APPEND(py_plane_index, PyLong_FromLong(i));
- }
- }
- PyMem_Free(planes_used);
-
- {
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret,
- py_verts,
- py_plane_index);
- return ret;
- }
- }
+ PyObject *py_planes;
+ float(*planes)[4];
+ unsigned int planes_len;
+
+ if (!PyArg_ParseTuple(args, "O:points_in_planes", &py_planes)) {
+ return NULL;
+ }
+
+ if ((planes_len = mathutils_array_parse_alloc_v(
+ (float **)&planes, 4, py_planes, "points_in_planes")) == -1) {
+ return NULL;
+ }
+ else {
+ /* note, this could be refactored into plain C easy - py bits are noted */
+ const float eps = 0.0001f;
+ const unsigned int len = (unsigned int)planes_len;
+ unsigned int i, j, k, l;
+
+ float n1n2[3], n2n3[3], n3n1[3];
+ float potentialVertex[3];
+ char *planes_used = PyMem_Malloc(sizeof(char) * len);
+
+ /* python */
+ PyObject *py_verts = PyList_New(0);
+ PyObject *py_plane_index = PyList_New(0);
+
+ memset(planes_used, 0, sizeof(char) * len);
+
+ for (i = 0; i < len; i++) {
+ const float *N1 = planes[i];
+ for (j = i + 1; j < len; j++) {
+ const float *N2 = planes[j];
+ cross_v3_v3v3(n1n2, N1, N2);
+ if (len_squared_v3(n1n2) > eps) {
+ for (k = j + 1; k < len; k++) {
+ const float *N3 = planes[k];
+ cross_v3_v3v3(n2n3, N2, N3);
+ if (len_squared_v3(n2n3) > eps) {
+ cross_v3_v3v3(n3n1, N3, N1);
+ if (len_squared_v3(n3n1) > eps) {
+ const float quotient = dot_v3v3(N1, n2n3);
+ if (fabsf(quotient) > eps) {
+ /* potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (-1.0 / quotient); */
+ const float quotient_ninv = -1.0f / quotient;
+ potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) +
+ (n1n2[0] * N3[3])) *
+ quotient_ninv;
+ potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) +
+ (n1n2[1] * N3[3])) *
+ quotient_ninv;
+ potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) +
+ (n1n2[2] * N3[3])) *
+ quotient_ninv;
+ for (l = 0; l < len; l++) {
+ const float *NP = planes[l];
+ if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) {
+ break;
+ }
+ }
+
+ if (l == len) { /* ok */
+ /* python */
+ PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
+ planes_used[i] = planes_used[j] = planes_used[k] = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ PyMem_Free(planes);
+
+ /* now make a list of used planes */
+ for (i = 0; i < len; i++) {
+ if (planes_used[i]) {
+ PyList_APPEND(py_plane_index, PyLong_FromLong(i));
+ }
+ }
+ PyMem_Free(planes_used);
+
+ {
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, py_verts, py_plane_index);
+ return ret;
+ }
+ }
}
#ifndef MATH_STANDALONE
PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc,
-".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n"
-"\n"
-" Interpolate a bezier spline segment.\n"
-"\n"
-" :arg knot1: First bezier spline point.\n"
-" :type knot1: :class:`mathutils.Vector`\n"
-" :arg handle1: First bezier spline handle.\n"
-" :type handle1: :class:`mathutils.Vector`\n"
-" :arg handle2: Second bezier spline handle.\n"
-" :type handle2: :class:`mathutils.Vector`\n"
-" :arg knot2: Second bezier spline point.\n"
-" :type knot2: :class:`mathutils.Vector`\n"
-" :arg resolution: Number of points to return.\n"
-" :type resolution: int\n"
-" :return: The interpolated points\n"
-" :rtype: list of :class:`mathutils.Vector`'s\n"
-);
+ ".. function:: interpolate_bezier(knot1, handle1, handle2, knot2, resolution)\n"
+ "\n"
+ " Interpolate a bezier spline segment.\n"
+ "\n"
+ " :arg knot1: First bezier spline point.\n"
+ " :type knot1: :class:`mathutils.Vector`\n"
+ " :arg handle1: First bezier spline handle.\n"
+ " :type handle1: :class:`mathutils.Vector`\n"
+ " :arg handle2: Second bezier spline handle.\n"
+ " :type handle2: :class:`mathutils.Vector`\n"
+ " :arg knot2: Second bezier spline point.\n"
+ " :type knot2: :class:`mathutils.Vector`\n"
+ " :arg resolution: Number of points to return.\n"
+ " :type resolution: int\n"
+ " :return: The interpolated points\n"
+ " :rtype: list of :class:`mathutils.Vector`'s\n");
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject *args)
{
- const char *error_prefix = "interpolate_bezier";
- PyObject *py_data[4];
- float data[4][4] = {{0.0f}};
- int resolu;
- int dims = 0;
- int i;
- float *coord_array, *fp;
- PyObject *list;
-
- if (!PyArg_ParseTuple(
- args, "OOOOi:interpolate_bezier",
- UNPACK4_EX(&, py_data, ), &resolu))
- {
- return NULL;
- }
-
- for (i = 0; i < 4; i++) {
- int dims_tmp;
- if ((dims_tmp = mathutils_array_parse(data[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_data[i], error_prefix)) == -1) {
- return NULL;
- }
- dims = max_ii(dims, dims_tmp);
- }
-
- if (resolu <= 1) {
- PyErr_SetString(PyExc_ValueError,
- "resolution must be 2 or over");
- return NULL;
- }
-
- coord_array = MEM_callocN(dims * (resolu) * sizeof(float), error_prefix);
- for (i = 0; i < dims; i++) {
- BKE_curve_forward_diff_bezier(UNPACK4_EX(, data, [i]), coord_array + i, resolu - 1, sizeof(float) * dims);
- }
-
- list = PyList_New(resolu);
- fp = coord_array;
- for (i = 0; i < resolu; i++, fp = fp + dims) {
- PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, NULL));
- }
- MEM_freeN(coord_array);
- return list;
+ const char *error_prefix = "interpolate_bezier";
+ PyObject *py_data[4];
+ float data[4][4] = {{0.0f}};
+ int resolu;
+ int dims = 0;
+ int i;
+ float *coord_array, *fp;
+ PyObject *list;
+
+ if (!PyArg_ParseTuple(args, "OOOOi:interpolate_bezier", UNPACK4_EX(&, py_data, ), &resolu)) {
+ return NULL;
+ }
+
+ for (i = 0; i < 4; i++) {
+ int dims_tmp;
+ if ((dims_tmp = mathutils_array_parse(
+ data[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_data[i], error_prefix)) == -1) {
+ return NULL;
+ }
+ dims = max_ii(dims, dims_tmp);
+ }
+
+ if (resolu <= 1) {
+ PyErr_SetString(PyExc_ValueError, "resolution must be 2 or over");
+ return NULL;
+ }
+
+ coord_array = MEM_callocN(dims * (resolu) * sizeof(float), error_prefix);
+ for (i = 0; i < dims; i++) {
+ BKE_curve_forward_diff_bezier(
+ UNPACK4_EX(, data, [i]), coord_array + i, resolu - 1, sizeof(float) * dims);
+ }
+
+ list = PyList_New(resolu);
+ fp = coord_array;
+ for (i = 0; i < resolu; i++, fp = fp + dims) {
+ PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, NULL));
+ }
+ MEM_freeN(coord_array);
+ return list;
}
-
PyDoc_STRVAR(M_Geometry_tessellate_polygon_doc,
-".. function:: tessellate_polygon(veclist_list)\n"
-"\n"
-" Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.\n"
-"\n"
-" :arg veclist_list: list of polylines\n"
-" :rtype: list\n"
-);
+ ".. function:: tessellate_polygon(veclist_list)\n"
+ "\n"
+ " Takes a list of polylines (each point a vector) and returns the point indices "
+ "for a polyline filled with triangles.\n"
+ "\n"
+ " :arg veclist_list: list of polylines\n"
+ " :rtype: list\n");
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
static PyObject *M_Geometry_tessellate_polygon(PyObject *UNUSED(self), PyObject *polyLineSeq)
{
- PyObject *tri_list; /*return this list of tri's */
- PyObject *polyLine, *polyVec;
- int i, len_polylines, len_polypoints, ls_error = 0;
-
- /* display listbase */
- ListBase dispbase = {NULL, NULL};
- DispList *dl;
- float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */
- int index, *dl_face, totpoints = 0;
-
- if (!PySequence_Check(polyLineSeq)) {
- PyErr_SetString(PyExc_TypeError,
- "expected a sequence of poly lines");
- return NULL;
- }
-
- len_polylines = PySequence_Size(polyLineSeq);
-
- for (i = 0; i < len_polylines; i++) {
- polyLine = PySequence_GetItem(polyLineSeq, i);
- if (!PySequence_Check(polyLine)) {
- BKE_displist_free(&dispbase);
- Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/
- PyErr_SetString(PyExc_TypeError,
- "One or more of the polylines is not a sequence of mathutils.Vector's");
- return NULL;
- }
-
- len_polypoints = PySequence_Size(polyLine);
- if (len_polypoints > 0) { /* don't bother adding edges as polylines */
-#if 0
- if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) {
- freedisplist(&dispbase);
- Py_DECREF(polyLine);
- PyErr_SetString(PyExc_TypeError,
- "A point in one of the polylines is not a mathutils.Vector type");
- return NULL;
- }
-#endif
- dl = MEM_callocN(sizeof(DispList), "poly disp");
- BLI_addtail(&dispbase, dl);
- dl->type = DL_INDEX3;
- dl->nr = len_polypoints;
- dl->type = DL_POLY;
- dl->parts = 1; /* no faces, 1 edge loop */
- dl->col = 0; /* no material */
- dl->verts = fp = MEM_callocN(sizeof(float) * 3 * len_polypoints, "dl verts");
- dl->index = MEM_callocN(sizeof(int) * 3 * len_polypoints, "dl index");
-
- for (index = 0; index < len_polypoints; index++, fp += 3) {
- polyVec = PySequence_GetItem(polyLine, index);
- if (VectorObject_Check(polyVec)) {
-
- if (BaseMath_ReadCallback((VectorObject *)polyVec) == -1) {
- ls_error = 1;
- }
-
- fp[0] = ((VectorObject *)polyVec)->vec[0];
- fp[1] = ((VectorObject *)polyVec)->vec[1];
- if (((VectorObject *)polyVec)->size > 2) {
- fp[2] = ((VectorObject *)polyVec)->vec[2];
- }
- else {
- /* if its a 2d vector then set the z to be zero */
- fp[2] = 0.0f;
- }
- }
- else {
- ls_error = 1;
- }
-
- totpoints++;
- Py_DECREF(polyVec);
- }
- }
- Py_DECREF(polyLine);
- }
-
- if (ls_error) {
- BKE_displist_free(&dispbase); /* possible some dl was allocated */
- PyErr_SetString(PyExc_TypeError,
- "A point in one of the polylines "
- "is not a mathutils.Vector type");
- return NULL;
- }
- else if (totpoints) {
- /* now make the list to return */
- /* TODO, add normal arg */
- BKE_displist_fill(&dispbase, &dispbase, NULL, false);
-
- /* The faces are stored in a new DisplayList
- * that's added to the head of the listbase */
- dl = dispbase.first;
-
- tri_list = PyList_New(dl->parts);
- if (!tri_list) {
- BKE_displist_free(&dispbase);
- PyErr_SetString(PyExc_RuntimeError,
- "failed to make a new list");
- return NULL;
- }
-
- index = 0;
- dl_face = dl->index;
- while (index < dl->parts) {
- PyList_SET_ITEM(tri_list, index, PyC_Tuple_Pack_I32(dl_face[0], dl_face[1], dl_face[2]));
- dl_face += 3;
- index++;
- }
- BKE_displist_free(&dispbase);
- }
- else {
- /* no points, do this so scripts don't barf */
- BKE_displist_free(&dispbase); /* possible some dl was allocated */
- tri_list = PyList_New(0);
- }
-
- return tri_list;
+ PyObject *tri_list; /*return this list of tri's */
+ PyObject *polyLine, *polyVec;
+ int i, len_polylines, len_polypoints, ls_error = 0;
+
+ /* display listbase */
+ ListBase dispbase = {NULL, NULL};
+ DispList *dl;
+ float *fp; /*pointer to the array of malloced dl->verts to set the points from the vectors */
+ int index, *dl_face, totpoints = 0;
+
+ if (!PySequence_Check(polyLineSeq)) {
+ PyErr_SetString(PyExc_TypeError, "expected a sequence of poly lines");
+ return NULL;
+ }
+
+ len_polylines = PySequence_Size(polyLineSeq);
+
+ for (i = 0; i < len_polylines; i++) {
+ polyLine = PySequence_GetItem(polyLineSeq, i);
+ if (!PySequence_Check(polyLine)) {
+ BKE_displist_free(&dispbase);
+ Py_XDECREF(polyLine); /* may be null so use Py_XDECREF*/
+ PyErr_SetString(PyExc_TypeError,
+ "One or more of the polylines is not a sequence of mathutils.Vector's");
+ return NULL;
+ }
+
+ len_polypoints = PySequence_Size(polyLine);
+ if (len_polypoints > 0) { /* don't bother adding edges as polylines */
+# if 0
+ if (EXPP_check_sequence_consistency(polyLine, &vector_Type) != 1) {
+ freedisplist(&dispbase);
+ Py_DECREF(polyLine);
+ PyErr_SetString(PyExc_TypeError,
+ "A point in one of the polylines is not a mathutils.Vector type");
+ return NULL;
+ }
+# endif
+ dl = MEM_callocN(sizeof(DispList), "poly disp");
+ BLI_addtail(&dispbase, dl);
+ dl->type = DL_INDEX3;
+ dl->nr = len_polypoints;
+ dl->type = DL_POLY;
+ dl->parts = 1; /* no faces, 1 edge loop */
+ dl->col = 0; /* no material */
+ dl->verts = fp = MEM_callocN(sizeof(float) * 3 * len_polypoints, "dl verts");
+ dl->index = MEM_callocN(sizeof(int) * 3 * len_polypoints, "dl index");
+
+ for (index = 0; index < len_polypoints; index++, fp += 3) {
+ polyVec = PySequence_GetItem(polyLine, index);
+ if (VectorObject_Check(polyVec)) {
+
+ if (BaseMath_ReadCallback((VectorObject *)polyVec) == -1) {
+ ls_error = 1;
+ }
+
+ fp[0] = ((VectorObject *)polyVec)->vec[0];
+ fp[1] = ((VectorObject *)polyVec)->vec[1];
+ if (((VectorObject *)polyVec)->size > 2) {
+ fp[2] = ((VectorObject *)polyVec)->vec[2];
+ }
+ else {
+ /* if its a 2d vector then set the z to be zero */
+ fp[2] = 0.0f;
+ }
+ }
+ else {
+ ls_error = 1;
+ }
+
+ totpoints++;
+ Py_DECREF(polyVec);
+ }
+ }
+ Py_DECREF(polyLine);
+ }
+
+ if (ls_error) {
+ BKE_displist_free(&dispbase); /* possible some dl was allocated */
+ PyErr_SetString(PyExc_TypeError,
+ "A point in one of the polylines "
+ "is not a mathutils.Vector type");
+ return NULL;
+ }
+ else if (totpoints) {
+ /* now make the list to return */
+ /* TODO, add normal arg */
+ BKE_displist_fill(&dispbase, &dispbase, NULL, false);
+
+ /* The faces are stored in a new DisplayList
+ * that's added to the head of the listbase */
+ dl = dispbase.first;
+
+ tri_list = PyList_New(dl->parts);
+ if (!tri_list) {
+ BKE_displist_free(&dispbase);
+ PyErr_SetString(PyExc_RuntimeError, "failed to make a new list");
+ return NULL;
+ }
+
+ index = 0;
+ dl_face = dl->index;
+ while (index < dl->parts) {
+ PyList_SET_ITEM(tri_list, index, PyC_Tuple_Pack_I32(dl_face[0], dl_face[1], dl_face[2]));
+ dl_face += 3;
+ index++;
+ }
+ BKE_displist_free(&dispbase);
+ }
+ else {
+ /* no points, do this so scripts don't barf */
+ BKE_displist_free(&dispbase); /* possible some dl was allocated */
+ tri_list = PyList_New(0);
+ }
+
+ return tri_list;
}
-
static int boxPack_FromPyObject(PyObject *value, BoxPack **boxarray)
{
- Py_ssize_t len, i;
- PyObject *list_item, *item_1, *item_2;
- BoxPack *box;
-
-
- /* Error checking must already be done */
- if (!PyList_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "can only back a list of [x, y, w, h]");
- return -1;
- }
-
- len = PyList_GET_SIZE(value);
-
- *boxarray = MEM_mallocN(len * sizeof(BoxPack), "BoxPack box");
-
-
- for (i = 0; i < len; i++) {
- list_item = PyList_GET_ITEM(value, i);
- if (!PyList_Check(list_item) || PyList_GET_SIZE(list_item) < 4) {
- MEM_freeN(*boxarray);
- PyErr_SetString(PyExc_TypeError,
- "can only pack a list of [x, y, w, h]");
- return -1;
- }
-
- box = (*boxarray) + i;
-
- item_1 = PyList_GET_ITEM(list_item, 2);
- item_2 = PyList_GET_ITEM(list_item, 3);
-
- box->w = (float)PyFloat_AsDouble(item_1);
- box->h = (float)PyFloat_AsDouble(item_2);
- box->index = i;
-
- /* accounts for error case too and overwrites with own error */
- if (box->w < 0.0f || box->h < 0.0f) {
- MEM_freeN(*boxarray);
- PyErr_SetString(PyExc_TypeError,
- "error parsing width and height values from list: "
- "[x, y, w, h], not numbers or below zero");
- return -1;
- }
-
- /* verts will be added later */
- }
- return 0;
+ Py_ssize_t len, i;
+ PyObject *list_item, *item_1, *item_2;
+ BoxPack *box;
+
+ /* Error checking must already be done */
+ if (!PyList_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "can only back a list of [x, y, w, h]");
+ return -1;
+ }
+
+ len = PyList_GET_SIZE(value);
+
+ *boxarray = MEM_mallocN(len * sizeof(BoxPack), "BoxPack box");
+
+ for (i = 0; i < len; i++) {
+ list_item = PyList_GET_ITEM(value, i);
+ if (!PyList_Check(list_item) || PyList_GET_SIZE(list_item) < 4) {
+ MEM_freeN(*boxarray);
+ PyErr_SetString(PyExc_TypeError, "can only pack a list of [x, y, w, h]");
+ return -1;
+ }
+
+ box = (*boxarray) + i;
+
+ item_1 = PyList_GET_ITEM(list_item, 2);
+ item_2 = PyList_GET_ITEM(list_item, 3);
+
+ box->w = (float)PyFloat_AsDouble(item_1);
+ box->h = (float)PyFloat_AsDouble(item_2);
+ box->index = i;
+
+ /* accounts for error case too and overwrites with own error */
+ if (box->w < 0.0f || box->h < 0.0f) {
+ MEM_freeN(*boxarray);
+ PyErr_SetString(PyExc_TypeError,
+ "error parsing width and height values from list: "
+ "[x, y, w, h], not numbers or below zero");
+ return -1;
+ }
+
+ /* verts will be added later */
+ }
+ return 0;
}
static void boxPack_ToPyObject(PyObject *value, BoxPack **boxarray)
{
- Py_ssize_t len, i;
- PyObject *list_item;
- BoxPack *box;
-
- len = PyList_GET_SIZE(value);
-
- for (i = 0; i < len; i++) {
- box = (*boxarray) + i;
- list_item = PyList_GET_ITEM(value, box->index);
- PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
- PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
- }
- MEM_freeN(*boxarray);
+ Py_ssize_t len, i;
+ PyObject *list_item;
+ BoxPack *box;
+
+ len = PyList_GET_SIZE(value);
+
+ for (i = 0; i < len; i++) {
+ box = (*boxarray) + i;
+ list_item = PyList_GET_ITEM(value, box->index);
+ PyList_SET_ITEM(list_item, 0, PyFloat_FromDouble(box->x));
+ PyList_SET_ITEM(list_item, 1, PyFloat_FromDouble(box->y));
+ }
+ MEM_freeN(*boxarray);
}
PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
-".. function:: box_pack_2d(boxes)\n"
-"\n"
-" Returns the normal of the 3D tri or quad.\n"
-"\n"
-" :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, width, height, ...] other items are ignored.\n"
-" :type boxes: list\n"
-" :return: the width and height of the packed bounding box\n"
-" :rtype: tuple, pair of floats\n"
-);
+ ".. function:: box_pack_2d(boxes)\n"
+ "\n"
+ " Returns the normal of the 3D tri or quad.\n"
+ "\n"
+ " :arg boxes: list of boxes, each box is a list where the first 4 items are [x, y, "
+ "width, height, ...] other items are ignored.\n"
+ " :type boxes: list\n"
+ " :return: the width and height of the packed bounding box\n"
+ " :rtype: tuple, pair of floats\n");
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
{
- float tot_width = 0.0f, tot_height = 0.0f;
- Py_ssize_t len;
-
- PyObject *ret;
-
- if (!PyList_Check(boxlist)) {
- PyErr_SetString(PyExc_TypeError,
- "expected a list of boxes [[x, y, w, h], ... ]");
- return NULL;
- }
-
- len = PyList_GET_SIZE(boxlist);
- if (len) {
- BoxPack *boxarray = NULL;
- if (boxPack_FromPyObject(boxlist, &boxarray) == -1) {
- return NULL; /* exception set */
- }
-
- /* Non Python function */
- BLI_box_pack_2d(boxarray, len, &tot_width, &tot_height);
-
- boxPack_ToPyObject(boxlist, &boxarray);
- }
-
- ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret,
- PyFloat_FromDouble(tot_width),
- PyFloat_FromDouble(tot_height));
- return ret;
+ float tot_width = 0.0f, tot_height = 0.0f;
+ Py_ssize_t len;
+
+ PyObject *ret;
+
+ if (!PyList_Check(boxlist)) {
+ PyErr_SetString(PyExc_TypeError, "expected a list of boxes [[x, y, w, h], ... ]");
+ return NULL;
+ }
+
+ len = PyList_GET_SIZE(boxlist);
+ if (len) {
+ BoxPack *boxarray = NULL;
+ if (boxPack_FromPyObject(boxlist, &boxarray) == -1) {
+ return NULL; /* exception set */
+ }
+
+ /* Non Python function */
+ BLI_box_pack_2d(boxarray, len, &tot_width, &tot_height);
+
+ boxPack_ToPyObject(boxlist, &boxarray);
+ }
+
+ ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, PyFloat_FromDouble(tot_width), PyFloat_FromDouble(tot_height));
+ return ret;
}
PyDoc_STRVAR(M_Geometry_box_fit_2d_doc,
-".. function:: box_fit_2d(points)\n"
-"\n"
-" Returns an angle that best fits the points to an axis aligned rectangle\n"
-"\n"
-" :arg points: list of 2d points.\n"
-" :type points: list\n"
-" :return: angle\n"
-" :rtype: float\n"
-);
+ ".. function:: box_fit_2d(points)\n"
+ "\n"
+ " Returns an angle that best fits the points to an axis aligned rectangle\n"
+ "\n"
+ " :arg points: list of 2d points.\n"
+ " :type points: list\n"
+ " :return: angle\n"
+ " :rtype: float\n");
static PyObject *M_Geometry_box_fit_2d(PyObject *UNUSED(self), PyObject *pointlist)
{
- float (*points)[2];
- Py_ssize_t len;
+ float(*points)[2];
+ Py_ssize_t len;
- float angle = 0.0f;
+ float angle = 0.0f;
- len = mathutils_array_parse_alloc_v(((float **)&points), 2, pointlist, "box_fit_2d");
- if (len == -1) {
- return NULL;
- }
+ len = mathutils_array_parse_alloc_v(((float **)&points), 2, pointlist, "box_fit_2d");
+ if (len == -1) {
+ return NULL;
+ }
- if (len) {
- /* Non Python function */
- angle = BLI_convexhull_aabb_fit_points_2d(points, len);
+ if (len) {
+ /* Non Python function */
+ angle = BLI_convexhull_aabb_fit_points_2d(points, len);
- PyMem_Free(points);
- }
+ PyMem_Free(points);
+ }
-
- return PyFloat_FromDouble(angle);
+ return PyFloat_FromDouble(angle);
}
PyDoc_STRVAR(M_Geometry_convex_hull_2d_doc,
-".. function:: convex_hull_2d(points)\n"
-"\n"
-" Returns a list of indices into the list given\n"
-"\n"
-" :arg points: list of 2d points.\n"
-" :type points: list\n"
-" :return: a list of indices\n"
-" :rtype: list of ints\n"
-);
+ ".. function:: convex_hull_2d(points)\n"
+ "\n"
+ " Returns a list of indices into the list given\n"
+ "\n"
+ " :arg points: list of 2d points.\n"
+ " :type points: list\n"
+ " :return: a list of indices\n"
+ " :rtype: list of ints\n");
static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *pointlist)
{
- float (*points)[2];
- Py_ssize_t len;
-
- PyObject *ret;
+ float(*points)[2];
+ Py_ssize_t len;
- len = mathutils_array_parse_alloc_v(((float **)&points), 2, pointlist, "convex_hull_2d");
- if (len == -1) {
- return NULL;
- }
+ PyObject *ret;
- if (len) {
- int *index_map;
- Py_ssize_t len_ret, i;
+ len = mathutils_array_parse_alloc_v(((float **)&points), 2, pointlist, "convex_hull_2d");
+ if (len == -1) {
+ return NULL;
+ }
- index_map = MEM_mallocN(sizeof(*index_map) * len * 2, __func__);
+ if (len) {
+ int *index_map;
+ Py_ssize_t len_ret, i;
- /* Non Python function */
- len_ret = BLI_convexhull_2d(points, len, index_map);
+ index_map = MEM_mallocN(sizeof(*index_map) * len * 2, __func__);
- ret = PyList_New(len_ret);
- for (i = 0; i < len_ret; i++) {
- PyList_SET_ITEM(ret, i, PyLong_FromLong(index_map[i]));
- }
+ /* Non Python function */
+ len_ret = BLI_convexhull_2d(points, len, index_map);
- MEM_freeN(index_map);
+ ret = PyList_New(len_ret);
+ for (i = 0; i < len_ret; i++) {
+ PyList_SET_ITEM(ret, i, PyLong_FromLong(index_map[i]));
+ }
- PyMem_Free(points);
- }
- else {
- ret = PyList_New(0);
- }
+ MEM_freeN(index_map);
+ PyMem_Free(points);
+ }
+ else {
+ ret = PyList_New(0);
+ }
- return ret;
+ return ret;
}
#endif /* MATH_STANDALONE */
-
static PyMethodDef M_Geometry_methods[] = {
- {"intersect_ray_tri", (PyCFunction) M_Geometry_intersect_ray_tri, METH_VARARGS, M_Geometry_intersect_ray_tri_doc},
- {"intersect_point_line", (PyCFunction) M_Geometry_intersect_point_line, METH_VARARGS, M_Geometry_intersect_point_line_doc},
- {"intersect_point_tri", (PyCFunction) M_Geometry_intersect_point_tri, METH_VARARGS, M_Geometry_intersect_point_tri_doc},
- {"intersect_point_tri_2d", (PyCFunction) M_Geometry_intersect_point_tri_2d, METH_VARARGS, M_Geometry_intersect_point_tri_2d_doc},
- {"intersect_point_quad_2d", (PyCFunction) M_Geometry_intersect_point_quad_2d, METH_VARARGS, M_Geometry_intersect_point_quad_2d_doc},
- {"intersect_line_line", (PyCFunction) M_Geometry_intersect_line_line, METH_VARARGS, M_Geometry_intersect_line_line_doc},
- {"intersect_line_line_2d", (PyCFunction) M_Geometry_intersect_line_line_2d, METH_VARARGS, M_Geometry_intersect_line_line_2d_doc},
- {"intersect_line_plane", (PyCFunction) M_Geometry_intersect_line_plane, METH_VARARGS, M_Geometry_intersect_line_plane_doc},
- {"intersect_plane_plane", (PyCFunction) M_Geometry_intersect_plane_plane, METH_VARARGS, M_Geometry_intersect_plane_plane_doc},
- {"intersect_line_sphere", (PyCFunction) M_Geometry_intersect_line_sphere, METH_VARARGS, M_Geometry_intersect_line_sphere_doc},
- {"intersect_line_sphere_2d", (PyCFunction) M_Geometry_intersect_line_sphere_2d, METH_VARARGS, M_Geometry_intersect_line_sphere_2d_doc},
- {"distance_point_to_plane", (PyCFunction) M_Geometry_distance_point_to_plane, METH_VARARGS, M_Geometry_distance_point_to_plane_doc},
- {"intersect_sphere_sphere_2d", (PyCFunction) M_Geometry_intersect_sphere_sphere_2d, METH_VARARGS, M_Geometry_intersect_sphere_sphere_2d_doc},
- {"area_tri", (PyCFunction) M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
- {"volume_tetrahedron", (PyCFunction) M_Geometry_volume_tetrahedron, METH_VARARGS, M_Geometry_volume_tetrahedron_doc},
- {"normal", (PyCFunction) M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},
- {"barycentric_transform", (PyCFunction) M_Geometry_barycentric_transform, METH_VARARGS, M_Geometry_barycentric_transform_doc},
- {"points_in_planes", (PyCFunction) M_Geometry_points_in_planes, METH_VARARGS, M_Geometry_points_in_planes_doc},
+ {"intersect_ray_tri",
+ (PyCFunction)M_Geometry_intersect_ray_tri,
+ METH_VARARGS,
+ M_Geometry_intersect_ray_tri_doc},
+ {"intersect_point_line",
+ (PyCFunction)M_Geometry_intersect_point_line,
+ METH_VARARGS,
+ M_Geometry_intersect_point_line_doc},
+ {"intersect_point_tri",
+ (PyCFunction)M_Geometry_intersect_point_tri,
+ METH_VARARGS,
+ M_Geometry_intersect_point_tri_doc},
+ {"intersect_point_tri_2d",
+ (PyCFunction)M_Geometry_intersect_point_tri_2d,
+ METH_VARARGS,
+ M_Geometry_intersect_point_tri_2d_doc},
+ {"intersect_point_quad_2d",
+ (PyCFunction)M_Geometry_intersect_point_quad_2d,
+ METH_VARARGS,
+ M_Geometry_intersect_point_quad_2d_doc},
+ {"intersect_line_line",
+ (PyCFunction)M_Geometry_intersect_line_line,
+ METH_VARARGS,
+ M_Geometry_intersect_line_line_doc},
+ {"intersect_line_line_2d",
+ (PyCFunction)M_Geometry_intersect_line_line_2d,
+ METH_VARARGS,
+ M_Geometry_intersect_line_line_2d_doc},
+ {"intersect_line_plane",
+ (PyCFunction)M_Geometry_intersect_line_plane,
+ METH_VARARGS,
+ M_Geometry_intersect_line_plane_doc},
+ {"intersect_plane_plane",
+ (PyCFunction)M_Geometry_intersect_plane_plane,
+ METH_VARARGS,
+ M_Geometry_intersect_plane_plane_doc},
+ {"intersect_line_sphere",
+ (PyCFunction)M_Geometry_intersect_line_sphere,
+ METH_VARARGS,
+ M_Geometry_intersect_line_sphere_doc},
+ {"intersect_line_sphere_2d",
+ (PyCFunction)M_Geometry_intersect_line_sphere_2d,
+ METH_VARARGS,
+ M_Geometry_intersect_line_sphere_2d_doc},
+ {"distance_point_to_plane",
+ (PyCFunction)M_Geometry_distance_point_to_plane,
+ METH_VARARGS,
+ M_Geometry_distance_point_to_plane_doc},
+ {"intersect_sphere_sphere_2d",
+ (PyCFunction)M_Geometry_intersect_sphere_sphere_2d,
+ METH_VARARGS,
+ M_Geometry_intersect_sphere_sphere_2d_doc},
+ {"area_tri", (PyCFunction)M_Geometry_area_tri, METH_VARARGS, M_Geometry_area_tri_doc},
+ {"volume_tetrahedron",
+ (PyCFunction)M_Geometry_volume_tetrahedron,
+ METH_VARARGS,
+ M_Geometry_volume_tetrahedron_doc},
+ {"normal", (PyCFunction)M_Geometry_normal, METH_VARARGS, M_Geometry_normal_doc},
+ {"barycentric_transform",
+ (PyCFunction)M_Geometry_barycentric_transform,
+ METH_VARARGS,
+ M_Geometry_barycentric_transform_doc},
+ {"points_in_planes",
+ (PyCFunction)M_Geometry_points_in_planes,
+ METH_VARARGS,
+ M_Geometry_points_in_planes_doc},
#ifndef MATH_STANDALONE
- {"interpolate_bezier", (PyCFunction) M_Geometry_interpolate_bezier, METH_VARARGS, M_Geometry_interpolate_bezier_doc},
- {"tessellate_polygon", (PyCFunction) M_Geometry_tessellate_polygon, METH_O, M_Geometry_tessellate_polygon_doc},
- {"convex_hull_2d", (PyCFunction) M_Geometry_convex_hull_2d, METH_O, M_Geometry_convex_hull_2d_doc},
- {"box_fit_2d", (PyCFunction) M_Geometry_box_fit_2d, METH_O, M_Geometry_box_fit_2d_doc},
- {"box_pack_2d", (PyCFunction) M_Geometry_box_pack_2d, METH_O, M_Geometry_box_pack_2d_doc},
+ {"interpolate_bezier",
+ (PyCFunction)M_Geometry_interpolate_bezier,
+ METH_VARARGS,
+ M_Geometry_interpolate_bezier_doc},
+ {"tessellate_polygon",
+ (PyCFunction)M_Geometry_tessellate_polygon,
+ METH_O,
+ M_Geometry_tessellate_polygon_doc},
+ {"convex_hull_2d",
+ (PyCFunction)M_Geometry_convex_hull_2d,
+ METH_O,
+ M_Geometry_convex_hull_2d_doc},
+ {"box_fit_2d", (PyCFunction)M_Geometry_box_fit_2d, METH_O, M_Geometry_box_fit_2d_doc},
+ {"box_pack_2d", (PyCFunction)M_Geometry_box_pack_2d, METH_O, M_Geometry_box_pack_2d_doc},
#endif
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef M_Geometry_module_def = {
- PyModuleDef_HEAD_INIT,
- "mathutils.geometry", /* m_name */
- M_Geometry_doc, /* m_doc */
- 0, /* m_size */
- M_Geometry_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils.geometry", /* m_name */
+ M_Geometry_doc, /* m_doc */
+ 0, /* m_size */
+ M_Geometry_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
/*----------------------------MODULE INIT-------------------------*/
PyMODINIT_FUNC PyInit_mathutils_geometry(void)
{
- PyObject *submodule = PyModule_Create(&M_Geometry_module_def);
- return submodule;
+ PyObject *submodule = PyModule_Create(&M_Geometry_module_def);
+ return submodule;
}
diff --git a/source/blender/python/mathutils/mathutils_interpolate.c b/source/blender/python/mathutils/mathutils_interpolate.c
index 792f8b1f065..6abb66899d5 100644
--- a/source/blender/python/mathutils/mathutils_interpolate.c
+++ b/source/blender/python/mathutils/mathutils_interpolate.c
@@ -18,7 +18,6 @@
* \ingroup pymathutils
*/
-
#include <Python.h>
#include "mathutils.h"
@@ -32,105 +31,100 @@
#endif
/*-------------------------DOC STRINGS ---------------------------*/
-PyDoc_STRVAR(M_Interpolate_doc,
-"The Blender interpolate module"
-);
+PyDoc_STRVAR(M_Interpolate_doc, "The Blender interpolate module");
/* ---------------------------------WEIGHT CALCULATION ----------------------- */
#ifndef MATH_STANDALONE
PyDoc_STRVAR(M_Interpolate_poly_3d_calc_doc,
-".. function:: poly_3d_calc(veclist, pt)\n"
-"\n"
-" Calculate barycentric weights for a point on a polygon.\n"
-"\n"
-" :arg veclist: list of vectors\n"
-" :arg pt: point"
-" :rtype: list of per-vector weights\n"
-);
+ ".. function:: poly_3d_calc(veclist, pt)\n"
+ "\n"
+ " Calculate barycentric weights for a point on a polygon.\n"
+ "\n"
+ " :arg veclist: list of vectors\n"
+ " :arg pt: point"
+ " :rtype: list of per-vector weights\n");
static PyObject *M_Interpolate_poly_3d_calc(PyObject *UNUSED(self), PyObject *args)
{
- float fp[3];
- float (*vecs)[3];
- Py_ssize_t len;
-
- PyObject *point, *veclist, *ret;
- int i;
-
- if (!PyArg_ParseTuple(
- args, "OO!:poly_3d_calc",
- &veclist,
- &vector_Type, &point))
- {
- return NULL;
- }
-
- if (BaseMath_ReadCallback((VectorObject *)point) == -1) {
- return NULL;
- }
-
- fp[0] = ((VectorObject *)point)->vec[0];
- fp[1] = ((VectorObject *)point)->vec[1];
- if (((VectorObject *)point)->size > 2) {
- fp[2] = ((VectorObject *)point)->vec[2];
- }
- else {
- /* if its a 2d vector then set the z to be zero */
- fp[2] = 0.0f;
- }
-
- len = mathutils_array_parse_alloc_v(((float **)&vecs), 3, veclist, __func__);
- if (len == -1) {
- return NULL;
- }
-
- if (len) {
- float *weights = MEM_mallocN(sizeof(float) * len, __func__);
-
- interp_weights_poly_v3(weights, vecs, len, fp);
-
- ret = PyList_New(len);
- for (i = 0; i < len; i++) {
- PyList_SET_ITEM(ret, i, PyFloat_FromDouble(weights[i]));
- }
-
- MEM_freeN(weights);
-
- PyMem_Free(vecs);
- }
- else {
- ret = PyList_New(0);
- }
-
- return ret;
+ float fp[3];
+ float(*vecs)[3];
+ Py_ssize_t len;
+
+ PyObject *point, *veclist, *ret;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OO!:poly_3d_calc", &veclist, &vector_Type, &point)) {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback((VectorObject *)point) == -1) {
+ return NULL;
+ }
+
+ fp[0] = ((VectorObject *)point)->vec[0];
+ fp[1] = ((VectorObject *)point)->vec[1];
+ if (((VectorObject *)point)->size > 2) {
+ fp[2] = ((VectorObject *)point)->vec[2];
+ }
+ else {
+ /* if its a 2d vector then set the z to be zero */
+ fp[2] = 0.0f;
+ }
+
+ len = mathutils_array_parse_alloc_v(((float **)&vecs), 3, veclist, __func__);
+ if (len == -1) {
+ return NULL;
+ }
+
+ if (len) {
+ float *weights = MEM_mallocN(sizeof(float) * len, __func__);
+
+ interp_weights_poly_v3(weights, vecs, len, fp);
+
+ ret = PyList_New(len);
+ for (i = 0; i < len; i++) {
+ PyList_SET_ITEM(ret, i, PyFloat_FromDouble(weights[i]));
+ }
+
+ MEM_freeN(weights);
+
+ PyMem_Free(vecs);
+ }
+ else {
+ ret = PyList_New(0);
+ }
+
+ return ret;
}
#endif /* MATH_STANDALONE */
-
static PyMethodDef M_Interpolate_methods[] = {
#ifndef MATH_STANDALONE
- {"poly_3d_calc", (PyCFunction) M_Interpolate_poly_3d_calc, METH_VARARGS, M_Interpolate_poly_3d_calc_doc},
+ {"poly_3d_calc",
+ (PyCFunction)M_Interpolate_poly_3d_calc,
+ METH_VARARGS,
+ M_Interpolate_poly_3d_calc_doc},
#endif
- {NULL, NULL, 0, NULL},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef M_Interpolate_module_def = {
- PyModuleDef_HEAD_INIT,
- "mathutils.interpolate", /* m_name */
- M_Interpolate_doc, /* m_doc */
- 0, /* m_size */
- M_Interpolate_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils.interpolate", /* m_name */
+ M_Interpolate_doc, /* m_doc */
+ 0, /* m_size */
+ M_Interpolate_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
/*----------------------------MODULE INIT-------------------------*/
PyMODINIT_FUNC PyInit_mathutils_interpolate(void)
{
- PyObject *submodule = PyModule_Create(&M_Interpolate_module_def);
- return submodule;
+ PyObject *submodule = PyModule_Create(&M_Interpolate_module_def);
+ return submodule;
}
diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c
index b1cda85f6ea..b8a7f4d8708 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.c
+++ b/source/blender/python/mathutils/mathutils_kdtree.c
@@ -32,61 +32,58 @@
#include "../generic/python_utildefines.h"
#include "mathutils.h"
-#include "mathutils_kdtree.h" /* own include */
+#include "mathutils_kdtree.h" /* own include */
#include "BLI_strict_flags.h"
typedef struct {
- PyObject_HEAD
- KDTree_3d *obj;
- unsigned int maxsize;
- unsigned int count;
- unsigned int count_balance; /* size when we last balanced */
+ PyObject_HEAD KDTree_3d *obj;
+ unsigned int maxsize;
+ unsigned int count;
+ unsigned int count_balance; /* size when we last balanced */
} PyKDTree;
-
/* -------------------------------------------------------------------- */
/* Utility helper functions */
static void kdtree_nearest_to_py_tuple(const KDTreeNearest_3d *nearest, PyObject *py_retval)
{
- BLI_assert(nearest->index >= 0);
- BLI_assert(PyTuple_GET_SIZE(py_retval) == 3);
+ BLI_assert(nearest->index >= 0);
+ BLI_assert(PyTuple_GET_SIZE(py_retval) == 3);
- PyTuple_SET_ITEMS(py_retval,
- Vector_CreatePyObject((float *)nearest->co, 3, NULL),
- PyLong_FromLong(nearest->index),
- PyFloat_FromDouble(nearest->dist));
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject((float *)nearest->co, 3, NULL),
+ PyLong_FromLong(nearest->index),
+ PyFloat_FromDouble(nearest->dist));
}
static PyObject *kdtree_nearest_to_py(const KDTreeNearest_3d *nearest)
{
- PyObject *py_retval;
+ PyObject *py_retval;
- py_retval = PyTuple_New(3);
+ py_retval = PyTuple_New(3);
- kdtree_nearest_to_py_tuple(nearest, py_retval);
+ kdtree_nearest_to_py_tuple(nearest, py_retval);
- return py_retval;
+ return py_retval;
}
static PyObject *kdtree_nearest_to_py_and_check(const KDTreeNearest_3d *nearest)
{
- PyObject *py_retval;
+ PyObject *py_retval;
- py_retval = PyTuple_New(3);
+ py_retval = PyTuple_New(3);
- if (nearest->index != -1) {
- kdtree_nearest_to_py_tuple(nearest, py_retval);
- }
- else {
- PyC_Tuple_Fill(py_retval, Py_None);
- }
+ if (nearest->index != -1) {
+ kdtree_nearest_to_py_tuple(nearest, py_retval);
+ }
+ else {
+ PyC_Tuple_Fill(py_retval, Py_None);
+ }
- return py_retval;
+ return py_retval;
}
-
/* -------------------------------------------------------------------- */
/* KDTree */
@@ -95,395 +92,376 @@ static PyObject *kdtree_nearest_to_py_and_check(const KDTreeNearest_3d *nearest)
static int PyKDTree__tp_init(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
- unsigned int maxsize;
- const char *keywords[] = {"size", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "I:KDTree", (char **)keywords,
- &maxsize))
- {
- return -1;
- }
-
- if (UINT_IS_NEG(maxsize)) {
- PyErr_SetString(PyExc_ValueError, "negative 'size' given");
- return -1;
- }
-
- self->obj = BLI_kdtree_3d_new(maxsize);
- self->maxsize = maxsize;
- self->count = 0;
- self->count_balance = 0;
-
- return 0;
+ unsigned int maxsize;
+ const char *keywords[] = {"size", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "I:KDTree", (char **)keywords, &maxsize)) {
+ return -1;
+ }
+
+ if (UINT_IS_NEG(maxsize)) {
+ PyErr_SetString(PyExc_ValueError, "negative 'size' given");
+ return -1;
+ }
+
+ self->obj = BLI_kdtree_3d_new(maxsize);
+ self->maxsize = maxsize;
+ self->count = 0;
+ self->count_balance = 0;
+
+ return 0;
}
static void PyKDTree__tp_dealloc(PyKDTree *self)
{
- BLI_kdtree_3d_free(self->obj);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ BLI_kdtree_3d_free(self->obj);
+ Py_TYPE(self)->tp_free((PyObject *)self);
}
PyDoc_STRVAR(py_kdtree_insert_doc,
-".. method:: insert(co, index)\n"
-"\n"
-" Insert a point into the KDTree.\n"
-"\n"
-" :arg co: Point 3d position.\n"
-" :type co: float triplet\n"
-" :arg index: The index of the point.\n"
-" :type index: int\n"
-);
+ ".. method:: insert(co, index)\n"
+ "\n"
+ " Insert a point into the KDTree.\n"
+ "\n"
+ " :arg co: Point 3d position.\n"
+ " :type co: float triplet\n"
+ " :arg index: The index of the point.\n"
+ " :type index: int\n");
static PyObject *py_kdtree_insert(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
- PyObject *py_co;
- float co[3];
- int index;
- const char *keywords[] = {"co", "index", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *) "Oi:insert", (char **)keywords,
- &py_co, &index))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(co, 3, 3, py_co, "insert: invalid 'co' arg") == -1) {
- return NULL;
- }
-
- if (index < 0) {
- PyErr_SetString(PyExc_ValueError, "negative index given");
- return NULL;
- }
-
- if (self->count >= self->maxsize) {
- PyErr_SetString(PyExc_RuntimeError, "Trying to insert more items than KDTree has room for");
- return NULL;
- }
-
- BLI_kdtree_3d_insert(self->obj, index, co);
- self->count++;
-
- Py_RETURN_NONE;
+ PyObject *py_co;
+ float co[3];
+ int index;
+ const char *keywords[] = {"co", "index", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwargs, (char *)"Oi:insert", (char **)keywords, &py_co, &index)) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(co, 3, 3, py_co, "insert: invalid 'co' arg") == -1) {
+ return NULL;
+ }
+
+ if (index < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative index given");
+ return NULL;
+ }
+
+ if (self->count >= self->maxsize) {
+ PyErr_SetString(PyExc_RuntimeError, "Trying to insert more items than KDTree has room for");
+ return NULL;
+ }
+
+ BLI_kdtree_3d_insert(self->obj, index, co);
+ self->count++;
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(py_kdtree_balance_doc,
-".. method:: balance()\n"
-"\n"
-" Balance the tree.\n"
-"\n"
-".. note::\n"
-"\n"
-" This builds the entire tree, avoid calling after each insertion.\n"
-);
+ ".. method:: balance()\n"
+ "\n"
+ " Balance the tree.\n"
+ "\n"
+ ".. note::\n"
+ "\n"
+ " This builds the entire tree, avoid calling after each insertion.\n");
static PyObject *py_kdtree_balance(PyKDTree *self)
{
- BLI_kdtree_3d_balance(self->obj);
- self->count_balance = self->count;
- Py_RETURN_NONE;
+ BLI_kdtree_3d_balance(self->obj);
+ self->count_balance = self->count;
+ Py_RETURN_NONE;
}
struct PyKDTree_NearestData {
- PyObject *py_filter;
- bool is_error;
+ PyObject *py_filter;
+ bool is_error;
};
static int py_find_nearest_cb(void *user_data, int index, const float co[3], float dist_sq)
{
- UNUSED_VARS(co, dist_sq);
-
- struct PyKDTree_NearestData *data = user_data;
-
- PyObject *py_args = PyTuple_New(1);
- PyTuple_SET_ITEM(py_args, 0, PyLong_FromLong(index));
- PyObject *result = PyObject_CallObject(data->py_filter, py_args);
- Py_DECREF(py_args);
-
- if (result) {
- bool use_node;
- int ok = PyC_ParseBool(result, &use_node);
- Py_DECREF(result);
- if (ok) {
- return (int)use_node;
- }
- }
-
- data->is_error = true;
- return -1;
+ UNUSED_VARS(co, dist_sq);
+
+ struct PyKDTree_NearestData *data = user_data;
+
+ PyObject *py_args = PyTuple_New(1);
+ PyTuple_SET_ITEM(py_args, 0, PyLong_FromLong(index));
+ PyObject *result = PyObject_CallObject(data->py_filter, py_args);
+ Py_DECREF(py_args);
+
+ if (result) {
+ bool use_node;
+ int ok = PyC_ParseBool(result, &use_node);
+ Py_DECREF(result);
+ if (ok) {
+ return (int)use_node;
+ }
+ }
+
+ data->is_error = true;
+ return -1;
}
PyDoc_STRVAR(py_kdtree_find_doc,
-".. method:: find(co, filter=None)\n"
-"\n"
-" Find nearest point to ``co``.\n"
-"\n"
-" :arg co: 3d coordinates.\n"
-" :type co: float triplet\n"
-" :arg filter: function which takes an index and returns True for indices to include in the search.\n"
-" :type filter: callable\n"
-" :return: Returns (:class:`Vector`, index, distance).\n"
-" :rtype: :class:`tuple`\n"
-);
+ ".. method:: find(co, filter=None)\n"
+ "\n"
+ " Find nearest point to ``co``.\n"
+ "\n"
+ " :arg co: 3d coordinates.\n"
+ " :type co: float triplet\n"
+ " :arg filter: function which takes an index and returns True for indices to "
+ "include in the search.\n"
+ " :type filter: callable\n"
+ " :return: Returns (:class:`Vector`, index, distance).\n"
+ " :rtype: :class:`tuple`\n");
static PyObject *py_kdtree_find(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
- PyObject *py_co, *py_filter = NULL;
- float co[3];
- KDTreeNearest_3d nearest;
- const char *keywords[] = {"co", "filter", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *) "O|O:find", (char **)keywords,
- &py_co, &py_filter))
- {
- return NULL;
- }
-
- if (mathutils_array_parse(co, 3, 3, py_co, "find: invalid 'co' arg") == -1) {
- return NULL;
- }
-
- if (self->count != self->count_balance) {
- PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find()");
- return NULL;
- }
-
- nearest.index = -1;
-
- if (py_filter == NULL) {
- BLI_kdtree_3d_find_nearest(self->obj, co, &nearest);
- }
- else {
- struct PyKDTree_NearestData data = {0};
-
- data.py_filter = py_filter;
- data.is_error = false;
-
- BLI_kdtree_3d_find_nearest_cb(
- self->obj, co,
- py_find_nearest_cb, &data,
- &nearest);
-
- if (data.is_error) {
- return NULL;
- }
- }
-
- return kdtree_nearest_to_py_and_check(&nearest);
+ PyObject *py_co, *py_filter = NULL;
+ float co[3];
+ KDTreeNearest_3d nearest;
+ const char *keywords[] = {"co", "filter", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwargs, (char *)"O|O:find", (char **)keywords, &py_co, &py_filter)) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(co, 3, 3, py_co, "find: invalid 'co' arg") == -1) {
+ return NULL;
+ }
+
+ if (self->count != self->count_balance) {
+ PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find()");
+ return NULL;
+ }
+
+ nearest.index = -1;
+
+ if (py_filter == NULL) {
+ BLI_kdtree_3d_find_nearest(self->obj, co, &nearest);
+ }
+ else {
+ struct PyKDTree_NearestData data = {0};
+
+ data.py_filter = py_filter;
+ data.is_error = false;
+
+ BLI_kdtree_3d_find_nearest_cb(self->obj, co, py_find_nearest_cb, &data, &nearest);
+
+ if (data.is_error) {
+ return NULL;
+ }
+ }
+
+ return kdtree_nearest_to_py_and_check(&nearest);
}
PyDoc_STRVAR(py_kdtree_find_n_doc,
-".. method:: find_n(co, n)\n"
-"\n"
-" Find nearest ``n`` points to ``co``.\n"
-"\n"
-" :arg co: 3d coordinates.\n"
-" :type co: float triplet\n"
-" :arg n: Number of points to find.\n"
-" :type n: int\n"
-" :return: Returns a list of tuples (:class:`Vector`, index, distance).\n"
-" :rtype: :class:`list`\n"
-);
+ ".. method:: find_n(co, n)\n"
+ "\n"
+ " Find nearest ``n`` points to ``co``.\n"
+ "\n"
+ " :arg co: 3d coordinates.\n"
+ " :type co: float triplet\n"
+ " :arg n: Number of points to find.\n"
+ " :type n: int\n"
+ " :return: Returns a list of tuples (:class:`Vector`, index, distance).\n"
+ " :rtype: :class:`list`\n");
static PyObject *py_kdtree_find_n(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
- PyObject *py_list;
- PyObject *py_co;
- float co[3];
- KDTreeNearest_3d *nearest;
- unsigned int n;
- int i, found;
- const char *keywords[] = {"co", "n", NULL};
+ PyObject *py_list;
+ PyObject *py_co;
+ float co[3];
+ KDTreeNearest_3d *nearest;
+ unsigned int n;
+ int i, found;
+ const char *keywords[] = {"co", "n", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *) "OI:find_n", (char **)keywords,
- &py_co, &n))
- {
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwargs, (char *)"OI:find_n", (char **)keywords, &py_co, &n)) {
+ return NULL;
+ }
- if (mathutils_array_parse(co, 3, 3, py_co, "find_n: invalid 'co' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(co, 3, 3, py_co, "find_n: invalid 'co' arg") == -1) {
+ return NULL;
+ }
- if (UINT_IS_NEG(n)) {
- PyErr_SetString(PyExc_RuntimeError, "negative 'n' given");
- return NULL;
- }
+ if (UINT_IS_NEG(n)) {
+ PyErr_SetString(PyExc_RuntimeError, "negative 'n' given");
+ return NULL;
+ }
- if (self->count != self->count_balance) {
- PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find_n()");
- return NULL;
- }
+ if (self->count != self->count_balance) {
+ PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find_n()");
+ return NULL;
+ }
- nearest = MEM_mallocN(sizeof(KDTreeNearest_3d) * n, __func__);
+ nearest = MEM_mallocN(sizeof(KDTreeNearest_3d) * n, __func__);
- found = BLI_kdtree_3d_find_nearest_n(self->obj, co, nearest, n);
+ found = BLI_kdtree_3d_find_nearest_n(self->obj, co, nearest, n);
- py_list = PyList_New(found);
+ py_list = PyList_New(found);
- for (i = 0; i < found; i++) {
- PyList_SET_ITEM(py_list, i, kdtree_nearest_to_py(&nearest[i]));
- }
+ for (i = 0; i < found; i++) {
+ PyList_SET_ITEM(py_list, i, kdtree_nearest_to_py(&nearest[i]));
+ }
- MEM_freeN(nearest);
+ MEM_freeN(nearest);
- return py_list;
+ return py_list;
}
PyDoc_STRVAR(py_kdtree_find_range_doc,
-".. method:: find_range(co, radius)\n"
-"\n"
-" Find all points within ``radius`` of ``co``.\n"
-"\n"
-" :arg co: 3d coordinates.\n"
-" :type co: float triplet\n"
-" :arg radius: Distance to search for points.\n"
-" :type radius: float\n"
-" :return: Returns a list of tuples (:class:`Vector`, index, distance).\n"
-" :rtype: :class:`list`\n"
-);
+ ".. method:: find_range(co, radius)\n"
+ "\n"
+ " Find all points within ``radius`` of ``co``.\n"
+ "\n"
+ " :arg co: 3d coordinates.\n"
+ " :type co: float triplet\n"
+ " :arg radius: Distance to search for points.\n"
+ " :type radius: float\n"
+ " :return: Returns a list of tuples (:class:`Vector`, index, distance).\n"
+ " :rtype: :class:`list`\n");
static PyObject *py_kdtree_find_range(PyKDTree *self, PyObject *args, PyObject *kwargs)
{
- PyObject *py_list;
- PyObject *py_co;
- float co[3];
- KDTreeNearest_3d *nearest = NULL;
- float radius;
- int i, found;
+ PyObject *py_list;
+ PyObject *py_co;
+ float co[3];
+ KDTreeNearest_3d *nearest = NULL;
+ float radius;
+ int i, found;
- const char *keywords[] = {"co", "radius", NULL};
+ const char *keywords[] = {"co", "radius", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, (char *) "Of:find_range", (char **)keywords,
- &py_co, &radius))
- {
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwargs, (char *)"Of:find_range", (char **)keywords, &py_co, &radius)) {
+ return NULL;
+ }
- if (mathutils_array_parse(co, 3, 3, py_co, "find_range: invalid 'co' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(co, 3, 3, py_co, "find_range: invalid 'co' arg") == -1) {
+ return NULL;
+ }
- if (radius < 0.0f) {
- PyErr_SetString(PyExc_RuntimeError, "negative radius given");
- return NULL;
- }
+ if (radius < 0.0f) {
+ PyErr_SetString(PyExc_RuntimeError, "negative radius given");
+ return NULL;
+ }
- if (self->count != self->count_balance) {
- PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find_range()");
- return NULL;
- }
+ if (self->count != self->count_balance) {
+ PyErr_SetString(PyExc_RuntimeError, "KDTree must be balanced before calling find_range()");
+ return NULL;
+ }
- found = BLI_kdtree_3d_range_search(self->obj, co, &nearest, radius);
+ found = BLI_kdtree_3d_range_search(self->obj, co, &nearest, radius);
- py_list = PyList_New(found);
+ py_list = PyList_New(found);
- for (i = 0; i < found; i++) {
- PyList_SET_ITEM(py_list, i, kdtree_nearest_to_py(&nearest[i]));
- }
+ for (i = 0; i < found; i++) {
+ PyList_SET_ITEM(py_list, i, kdtree_nearest_to_py(&nearest[i]));
+ }
- if (nearest) {
- MEM_freeN(nearest);
- }
+ if (nearest) {
+ MEM_freeN(nearest);
+ }
- return py_list;
+ return py_list;
}
-
static PyMethodDef PyKDTree_methods[] = {
- {"insert", (PyCFunction)py_kdtree_insert, METH_VARARGS | METH_KEYWORDS, py_kdtree_insert_doc},
- {"balance", (PyCFunction)py_kdtree_balance, METH_NOARGS, py_kdtree_balance_doc},
- {"find", (PyCFunction)py_kdtree_find, METH_VARARGS | METH_KEYWORDS, py_kdtree_find_doc},
- {"find_n", (PyCFunction)py_kdtree_find_n, METH_VARARGS | METH_KEYWORDS, py_kdtree_find_n_doc},
- {"find_range", (PyCFunction)py_kdtree_find_range, METH_VARARGS | METH_KEYWORDS, py_kdtree_find_range_doc},
- {NULL, NULL, 0, NULL},
+ {"insert", (PyCFunction)py_kdtree_insert, METH_VARARGS | METH_KEYWORDS, py_kdtree_insert_doc},
+ {"balance", (PyCFunction)py_kdtree_balance, METH_NOARGS, py_kdtree_balance_doc},
+ {"find", (PyCFunction)py_kdtree_find, METH_VARARGS | METH_KEYWORDS, py_kdtree_find_doc},
+ {"find_n", (PyCFunction)py_kdtree_find_n, METH_VARARGS | METH_KEYWORDS, py_kdtree_find_n_doc},
+ {"find_range",
+ (PyCFunction)py_kdtree_find_range,
+ METH_VARARGS | METH_KEYWORDS,
+ py_kdtree_find_range_doc},
+ {NULL, NULL, 0, NULL},
};
PyDoc_STRVAR(py_KDtree_doc,
-"KdTree(size) -> new kd-tree initialized to hold ``size`` items.\n"
-"\n"
-".. note::\n"
-"\n"
-" :class:`KDTree.balance` must have been called before using any of the ``find`` methods.\n"
-);
+ "KdTree(size) -> new kd-tree initialized to hold ``size`` items.\n"
+ "\n"
+ ".. note::\n"
+ "\n"
+ " :class:`KDTree.balance` must have been called before using any of the ``find`` "
+ "methods.\n");
PyTypeObject PyKDTree_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "KDTree", /* tp_name */
- sizeof(PyKDTree), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)PyKDTree__tp_dealloc, /* tp_dealloc */
- NULL, /* tp_print */
- NULL, /* tp_getattr */
- NULL, /* tp_setattr */
- NULL, /* tp_compare */
- NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- NULL, /* tp_hash */
- NULL, /* tp_call */
- NULL, /* tp_str */
- NULL, /* tp_getattro */
- NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- py_KDtree_doc, /* Documentation string */
- NULL, /* tp_traverse */
- NULL, /* tp_clear */
- NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- NULL, /* tp_iter */
- NULL, /* tp_iternext */
- (struct PyMethodDef *)PyKDTree_methods, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- NULL, /* tp_base */
- NULL, /* tp_dict */
- NULL, /* tp_descr_get */
- NULL, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)PyKDTree__tp_init, /* tp_init */
- (allocfunc)PyType_GenericAlloc, /* tp_alloc */
- (newfunc)PyType_GenericNew, /* tp_new */
- (freefunc)0, /* tp_free */
- NULL, /* tp_is_gc */
- NULL, /* tp_bases */
- NULL, /* tp_mro */
- NULL, /* tp_cache */
- NULL, /* tp_subclasses */
- NULL, /* tp_weaklist */
- (destructor)NULL, /* tp_del */
+ PyVarObject_HEAD_INIT(NULL, 0) "KDTree", /* tp_name */
+ sizeof(PyKDTree), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)PyKDTree__tp_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ NULL, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL, /* tp_hash */
+ NULL, /* tp_call */
+ NULL, /* tp_str */
+ NULL, /* tp_getattro */
+ NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ py_KDtree_doc, /* Documentation string */
+ NULL, /* tp_traverse */
+ NULL, /* tp_clear */
+ NULL, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ NULL, /* tp_iter */
+ NULL, /* tp_iternext */
+ (struct PyMethodDef *)PyKDTree_methods, /* tp_methods */
+ NULL, /* tp_members */
+ NULL, /* tp_getset */
+ NULL, /* tp_base */
+ NULL, /* tp_dict */
+ NULL, /* tp_descr_get */
+ NULL, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)PyKDTree__tp_init, /* tp_init */
+ (allocfunc)PyType_GenericAlloc, /* tp_alloc */
+ (newfunc)PyType_GenericNew, /* tp_new */
+ (freefunc)0, /* tp_free */
+ NULL, /* tp_is_gc */
+ NULL, /* tp_bases */
+ NULL, /* tp_mro */
+ NULL, /* tp_cache */
+ NULL, /* tp_subclasses */
+ NULL, /* tp_weaklist */
+ (destructor)NULL, /* tp_del */
};
-PyDoc_STRVAR(py_kdtree_doc,
-"Generic 3-dimentional kd-tree to perform spatial searches."
-);
+PyDoc_STRVAR(py_kdtree_doc, "Generic 3-dimentional kd-tree to perform spatial searches.");
static struct PyModuleDef kdtree_moduledef = {
- PyModuleDef_HEAD_INIT,
- "mathutils.kdtree", /* m_name */
- py_kdtree_doc, /* m_doc */
- 0, /* m_size */
- NULL, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils.kdtree", /* m_name */
+ py_kdtree_doc, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_mathutils_kdtree(void)
{
- PyObject *m = PyModule_Create(&kdtree_moduledef);
+ PyObject *m = PyModule_Create(&kdtree_moduledef);
- if (m == NULL) {
- return NULL;
- }
+ if (m == NULL) {
+ return NULL;
+ }
- /* Register the 'KDTree' class */
- if (PyType_Ready(&PyKDTree_Type)) {
- return NULL;
- }
- PyModule_AddObject(m, "KDTree", (PyObject *) &PyKDTree_Type);
+ /* Register the 'KDTree' class */
+ if (PyType_Ready(&PyKDTree_Type)) {
+ return NULL;
+ }
+ PyModule_AddObject(m, "KDTree", (PyObject *)&PyKDTree_Type);
- return m;
+ return m;
}
diff --git a/source/blender/python/mathutils/mathutils_kdtree.h b/source/blender/python/mathutils/mathutils_kdtree.h
index 4a4e1740ad8..99411997282 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.h
+++ b/source/blender/python/mathutils/mathutils_kdtree.h
@@ -14,7 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
/** \file
* \ingroup mathutils
*/
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 04cadb9b592..b890295d32f 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -21,7 +21,6 @@
* blenders noise functions.
*/
-
/************************/
/* Blender Noise Module */
/************************/
@@ -88,13 +87,13 @@
/* Period parameters */
#define N 624
#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UMASK 0x80000000UL /* most significant w-r bits */
-#define LMASK 0x7fffffffUL /* least significant r bits */
-#define MIXBITS(u, v) (((u) & UMASK) | ((v) & LMASK))
-#define TWIST(u, v) ((MIXBITS(u, v) >> 1) ^ ((v) & 1UL ? MATRIX_A : 0UL))
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UMASK 0x80000000UL /* most significant w-r bits */
+#define LMASK 0x7fffffffUL /* least significant r bits */
+#define MIXBITS(u, v) (((u)&UMASK) | ((v)&LMASK))
+#define TWIST(u, v) ((MIXBITS(u, v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
-static unsigned long state[N]; /* the array for the state vector */
+static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
@@ -103,86 +102,84 @@ static float state_offset_vector[3 * 3];
/* initializes state[N] with a seed */
static void init_genrand(unsigned long s)
{
- int j;
- state[0] = s & 0xffffffffUL;
- for (j = 1; j < N; j++) {
- state[j] =
- (1812433253UL *
- (state[j - 1] ^ (state[j - 1] >> 30)) + j);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array state[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- state[j] &= 0xffffffffUL; /* for >32 bit machines */
- }
- left = 1;
- initf = 1;
-
- /* update vector offset */
- {
- const unsigned long *state_offset = &state[N - ARRAY_SIZE(state_offset_vector)];
- const float range = 32; /* range in both pos/neg direction */
- for (j = 0; j < ARRAY_SIZE(state_offset_vector); j++, state_offset++) {
- /* overflow is fine here */
- state_offset_vector[j] = (float)(int)(*state_offset) * (1.0f / (INT_MAX / range));
- }
- }
+ int j;
+ state[0] = s & 0xffffffffUL;
+ for (j = 1; j < N; j++) {
+ state[j] = (1812433253UL * (state[j - 1] ^ (state[j - 1] >> 30)) + j);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array state[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ state[j] &= 0xffffffffUL; /* for >32 bit machines */
+ }
+ left = 1;
+ initf = 1;
+
+ /* update vector offset */
+ {
+ const unsigned long *state_offset = &state[N - ARRAY_SIZE(state_offset_vector)];
+ const float range = 32; /* range in both pos/neg direction */
+ for (j = 0; j < ARRAY_SIZE(state_offset_vector); j++, state_offset++) {
+ /* overflow is fine here */
+ state_offset_vector[j] = (float)(int)(*state_offset) * (1.0f / (INT_MAX / range));
+ }
+ }
}
static void next_state(void)
{
- unsigned long *p = state;
- int j;
+ unsigned long *p = state;
+ int j;
- /* if init_genrand() has not been called, */
- /* a default initial seed is used */
- if (initf == 0) {
- init_genrand(5489UL);
- }
+ /* if init_genrand() has not been called, */
+ /* a default initial seed is used */
+ if (initf == 0) {
+ init_genrand(5489UL);
+ }
- left = N;
- next = state;
+ left = N;
+ next = state;
- for (j = N - M + 1; --j; p++) {
- *p = p[M] ^ TWIST(p[0], p[1]);
- }
+ for (j = N - M + 1; --j; p++) {
+ *p = p[M] ^ TWIST(p[0], p[1]);
+ }
- for (j = M; --j; p++) {
- *p = p[M - N] ^ TWIST(p[0], p[1]);
- }
+ for (j = M; --j; p++) {
+ *p = p[M - N] ^ TWIST(p[0], p[1]);
+ }
- *p = p[M - N] ^ TWIST(p[0], state[0]);
+ *p = p[M - N] ^ TWIST(p[0], state[0]);
}
/*------------------------------------------------------------*/
static void setRndSeed(int seed)
{
- if (seed == 0) {
- init_genrand(time(NULL));
- }
- else {
- init_genrand(seed);
- }
+ if (seed == 0) {
+ init_genrand(time(NULL));
+ }
+ else {
+ init_genrand(seed);
+ }
}
/* float number in range [0, 1) using the mersenne twister rng */
static float frand(void)
{
- unsigned long y;
+ unsigned long y;
- if (--left == 0) {
- next_state();
- }
- y = *next++;
+ if (--left == 0) {
+ next_state();
+ }
+ y = *next++;
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
- return (float) y / 4294967296.f;
+ return (float)y / 4294967296.f;
}
/*------------------------------------------------------------*/
@@ -190,898 +187,960 @@ static float frand(void)
/*------------------------------------------------------------*/
#define BPY_NOISE_BASIS_ENUM_DOC \
-" :arg noise_basis: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
- "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
- "'CELLNOISE'].\n" \
-" :type noise_basis: string\n" \
+ " :arg noise_basis: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', " \
+ "'VORONOI_F1', 'VORONOI_F2', " \
+ "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
+ "'CELLNOISE'].\n" \
+ " :type noise_basis: string\n"
#define BPY_NOISE_METRIC_ENUM_DOC \
-" :arg distance_metric: Enumerator in ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV', " \
- "'MINKOVSKY', 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR'].\n" \
-" :type distance_metric: string\n" \
+ " :arg distance_metric: Enumerator in ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', " \
+ "'CHEBYCHEV', " \
+ "'MINKOVSKY', 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR'].\n" \
+ " :type distance_metric: string\n"
/* Noise basis enum */
#define DEFAULT_NOISE_TYPE TEX_STDPERLIN
static PyC_FlagSet bpy_noise_types[] = {
- {TEX_BLENDER, "BLENDER"},
- {TEX_STDPERLIN, "PERLIN_ORIGINAL"},
- {TEX_NEWPERLIN, "PERLIN_NEW"},
- {TEX_VORONOI_F1, "VORONOI_F1"},
- {TEX_VORONOI_F2, "VORONOI_F2"},
- {TEX_VORONOI_F3, "VORONOI_F3"},
- {TEX_VORONOI_F4, "VORONOI_F4"},
- {TEX_VORONOI_F2F1, "VORONOI_F2F1"},
- {TEX_VORONOI_CRACKLE, "VORONOI_CRACKLE"},
- {TEX_CELLNOISE, "CELLNOISE"},
- {0, NULL},
+ {TEX_BLENDER, "BLENDER"},
+ {TEX_STDPERLIN, "PERLIN_ORIGINAL"},
+ {TEX_NEWPERLIN, "PERLIN_NEW"},
+ {TEX_VORONOI_F1, "VORONOI_F1"},
+ {TEX_VORONOI_F2, "VORONOI_F2"},
+ {TEX_VORONOI_F3, "VORONOI_F3"},
+ {TEX_VORONOI_F4, "VORONOI_F4"},
+ {TEX_VORONOI_F2F1, "VORONOI_F2F1"},
+ {TEX_VORONOI_CRACKLE, "VORONOI_CRACKLE"},
+ {TEX_CELLNOISE, "CELLNOISE"},
+ {0, NULL},
};
/* Metric basis enum */
#define DEFAULT_METRIC_TYPE TEX_DISTANCE
static PyC_FlagSet bpy_noise_metrics[] = {
- {TEX_DISTANCE, "DISTANCE"},
- {TEX_DISTANCE_SQUARED, "DISTANCE_SQUARED"},
- {TEX_MANHATTAN, "MANHATTAN"},
- {TEX_CHEBYCHEV, "CHEBYCHEV"},
- {TEX_MINKOVSKY, "MINKOVSKY"},
- {TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF"},
- {TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR"},
- {0, NULL},
+ {TEX_DISTANCE, "DISTANCE"},
+ {TEX_DISTANCE_SQUARED, "DISTANCE_SQUARED"},
+ {TEX_MANHATTAN, "MANHATTAN"},
+ {TEX_CHEBYCHEV, "CHEBYCHEV"},
+ {TEX_MINKOVSKY, "MINKOVSKY"},
+ {TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF"},
+ {TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR"},
+ {0, NULL},
};
/* Fills an array of length size with random numbers in the range (-1, 1)*/
static void rand_vn(float *array_tar, const int size)
{
- float *array_pt = array_tar + (size - 1);
- int i = size;
- while (i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
+ float *array_pt = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) = 2.0f * frand() - 1.0f;
+ }
}
/* Fills an array of length 3 with noise values */
static void noise_vector(float x, float y, float z, int nb, float v[3])
{
- /* Simply evaluate noise at 3 different positions */
- const float *ofs = state_offset_vector;
- for (int j = 0; j < 3; j++) {
- v[j] = (2.0f * BLI_gNoise(1.0f, x + ofs[0], y + ofs[1], z + ofs[2], 0, nb) - 1.0f);
- ofs += 3;
- }
+ /* Simply evaluate noise at 3 different positions */
+ const float *ofs = state_offset_vector;
+ for (int j = 0; j < 3; j++) {
+ v[j] = (2.0f * BLI_gNoise(1.0f, x + ofs[0], y + ofs[1], z + ofs[2], 0, nb) - 1.0f);
+ ofs += 3;
+ }
}
/* Returns a turbulence value for a given position (x, y, z) */
static float turb(
- float x, float y, float z, int oct, int hard, int nb,
- float ampscale, float freqscale)
+ float x, float y, float z, int oct, int hard, int nb, float ampscale, float freqscale)
{
- float amp, out, t;
- int i;
- amp = 1.f;
- out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
- if (hard) {
- out = fabsf(out);
- }
- for (i = 1; i < oct; i++) {
- amp *= ampscale;
- x *= freqscale;
- y *= freqscale;
- z *= freqscale;
- t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
- if (hard) {
- t = fabsf(t);
- }
- out += t;
- }
- return out;
+ float amp, out, t;
+ int i;
+ amp = 1.f;
+ out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f);
+ if (hard) {
+ out = fabsf(out);
+ }
+ for (i = 1; i < oct; i++) {
+ amp *= ampscale;
+ x *= freqscale;
+ y *= freqscale;
+ z *= freqscale;
+ t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f));
+ if (hard) {
+ t = fabsf(t);
+ }
+ out += t;
+ }
+ return out;
}
/* Fills an array of length 3 with the turbulence vector for a given
* position (x, y, z) */
-static void vTurb(
- float x, float y, float z, int oct, int hard, int nb,
- float ampscale, float freqscale, float v[3])
+static void vTurb(float x,
+ float y,
+ float z,
+ int oct,
+ int hard,
+ int nb,
+ float ampscale,
+ float freqscale,
+ float v[3])
{
- float amp, t[3];
- int i;
- amp = 1.f;
- noise_vector(x, y, z, nb, v);
- if (hard) {
- v[0] = fabsf(v[0]);
- v[1] = fabsf(v[1]);
- v[2] = fabsf(v[2]);
- }
- for (i = 1; i < oct; i++) {
- amp *= ampscale;
- x *= freqscale;
- y *= freqscale;
- z *= freqscale;
- noise_vector(x, y, z, nb, t);
- if (hard) {
- t[0] = fabsf(t[0]);
- t[1] = fabsf(t[1]);
- t[2] = fabsf(t[2]);
- }
- v[0] += amp * t[0];
- v[1] += amp * t[1];
- v[2] += amp * t[2];
- }
+ float amp, t[3];
+ int i;
+ amp = 1.f;
+ noise_vector(x, y, z, nb, v);
+ if (hard) {
+ v[0] = fabsf(v[0]);
+ v[1] = fabsf(v[1]);
+ v[2] = fabsf(v[2]);
+ }
+ for (i = 1; i < oct; i++) {
+ amp *= ampscale;
+ x *= freqscale;
+ y *= freqscale;
+ z *= freqscale;
+ noise_vector(x, y, z, nb, t);
+ if (hard) {
+ t[0] = fabsf(t[0]);
+ t[1] = fabsf(t[1]);
+ t[2] = fabsf(t[2]);
+ }
+ v[0] += amp * t[0];
+ v[1] += amp * t[1];
+ v[2] += amp * t[2];
+ }
}
/*-------------------------DOC STRINGS ---------------------------*/
-PyDoc_STRVAR(M_Noise_doc,
-"The Blender noise module"
-);
+PyDoc_STRVAR(M_Noise_doc, "The Blender noise module");
/*------------------------------------------------------------*/
/* Python Functions */
/*------------------------------------------------------------*/
PyDoc_STRVAR(M_Noise_random_doc,
-".. function:: random()\n"
-"\n"
-" Returns a random number in the range [0, 1).\n"
-"\n"
-" :return: The random number.\n"
-" :rtype: float\n"
-);
+ ".. function:: random()\n"
+ "\n"
+ " Returns a random number in the range [0, 1).\n"
+ "\n"
+ " :return: The random number.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_random(PyObject *UNUSED(self))
{
- return PyFloat_FromDouble(frand());
+ return PyFloat_FromDouble(frand());
}
PyDoc_STRVAR(M_Noise_random_unit_vector_doc,
-".. function:: random_unit_vector(size=3)\n"
-"\n"
-" Returns a unit vector with random entries.\n"
-"\n"
-" :arg size: The size of the vector to be produced, in the range [2, 4].\n"
-" :type size: int\n"
-" :return: The random unit vector.\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: random_unit_vector(size=3)\n"
+ "\n"
+ " Returns a unit vector with random entries.\n"
+ "\n"
+ " :arg size: The size of the vector to be produced, in the range [2, 4].\n"
+ " :type size: int\n"
+ " :return: The random unit vector.\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"size", NULL};
- float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float norm = 2.0f;
- int size = 3;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "|$i:random_unit_vector", (char **)kwlist,
- &size))
- {
- return NULL;
- }
-
- if (size > 4 || size < 2) {
- PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
- return NULL;
- }
-
- while (norm == 0.0f || norm > 1.0f) {
- rand_vn(vec, size);
- norm = normalize_vn(vec, size);
- }
-
- return Vector_CreatePyObject(vec, size, NULL);
+ static const char *kwlist[] = {"size", NULL};
+ float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float norm = 2.0f;
+ int size = 3;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_unit_vector", (char **)kwlist, &size)) {
+ return NULL;
+ }
+
+ if (size > 4 || size < 2) {
+ PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
+ return NULL;
+ }
+
+ while (norm == 0.0f || norm > 1.0f) {
+ rand_vn(vec, size);
+ norm = normalize_vn(vec, size);
+ }
+
+ return Vector_CreatePyObject(vec, size, NULL);
}
PyDoc_STRVAR(M_Noise_random_vector_doc,
-".. function:: random_vector(size=3)\n"
-"\n"
-" Returns a vector with random entries in the range (-1, 1).\n"
-"\n"
-" :arg size: The size of the vector to be produced.\n"
-" :type size: int\n"
-" :return: The random vector.\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: random_vector(size=3)\n"
+ "\n"
+ " Returns a vector with random entries in the range (-1, 1).\n"
+ "\n"
+ " :arg size: The size of the vector to be produced.\n"
+ " :type size: int\n"
+ " :return: The random vector.\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"size", NULL};
- float *vec = NULL;
- int size = 3;
+ static const char *kwlist[] = {"size", NULL};
+ float *vec = NULL;
+ int size = 3;
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "|$i:random_vector", (char **)kwlist,
- &size))
- {
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_vector", (char **)kwlist, &size)) {
+ return NULL;
+ }
- if (size < 2) {
- PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
- return NULL;
- }
+ if (size < 2) {
+ PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
+ return NULL;
+ }
- vec = PyMem_New(float, size);
+ vec = PyMem_New(float, size);
- rand_vn(vec, size);
+ rand_vn(vec, size);
- return Vector_CreatePyObject_alloc(vec, size, NULL);
+ return Vector_CreatePyObject_alloc(vec, size, NULL);
}
PyDoc_STRVAR(M_Noise_seed_set_doc,
-".. function:: seed_set(seed)\n"
-"\n"
-" Sets the random seed used for random_unit_vector, and random.\n"
-"\n"
-" :arg seed: Seed used for the random generator.\n"
-" When seed is zero, the current time will be used instead.\n"
-" :type seed: int\n"
-);
+ ".. function:: seed_set(seed)\n"
+ "\n"
+ " Sets the random seed used for random_unit_vector, and random.\n"
+ "\n"
+ " :arg seed: Seed used for the random generator.\n"
+ " When seed is zero, the current time will be used instead.\n"
+ " :type seed: int\n");
static PyObject *M_Noise_seed_set(PyObject *UNUSED(self), PyObject *args)
{
- int s;
- if (!PyArg_ParseTuple(args, "i:seed_set", &s)) {
- return NULL;
- }
- setRndSeed(s);
- Py_RETURN_NONE;
+ int s;
+ if (!PyArg_ParseTuple(args, "i:seed_set", &s)) {
+ return NULL;
+ }
+ setRndSeed(s);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(M_Noise_noise_doc,
-".. function:: noise(position, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns noise value from the noise basis at the position specified.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The noise value.\n"
-" :rtype: float\n"
-);
+ ".. function:: noise(position, noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns noise value from the noise basis at the position specified.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The noise value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_noise(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O|$s:noise", (char **)kwlist,
- &value, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "noise: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, noise_basis_enum) - 1.0f));
+ static const char *kwlist[] = {"", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "O|$s:noise", (char **)kwlist, &value, &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise") ==
+ -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "noise: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ (2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, noise_basis_enum) - 1.0f));
}
PyDoc_STRVAR(M_Noise_noise_vector_doc,
-".. function:: noise_vector(position, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns the noise vector from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The noise vector.\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: noise_vector(position, noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns the noise vector from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The noise vector.\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "noise_basis", NULL};
- PyObject *value;
- float vec[3], r_vec[3];
- const char *noise_basis_str = NULL;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O|$s:noise_vector", (char **)kwlist,
- &value, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise_vector") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "noise_vector: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- noise_vector(vec[0], vec[1], vec[2], noise_basis_enum, r_vec);
-
- return Vector_CreatePyObject(r_vec, 3, NULL);
+ static const char *kwlist[] = {"", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3], r_vec[3];
+ const char *noise_basis_str = NULL;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "O|$s:noise_vector", (char **)kwlist, &value, &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "noise_vector") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "noise_vector: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ noise_vector(vec[0], vec[1], vec[2], noise_basis_enum, r_vec);
+
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
PyDoc_STRVAR(M_Noise_turbulence_doc,
-".. function:: turbulence(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)\n"
-"\n"
-" Returns the turbulence value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-" :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
-" :type hard: boolean\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :arg amplitude_scale: The amplitude scaling factor.\n"
-" :type amplitude_scale: float\n"
-" :arg frequency_scale: The frequency scaling factor\n"
-" :type frequency_scale: float\n"
-" :return: The turbulence value.\n"
-" :rtype: float\n"
-);
+ ".. function:: turbulence(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', "
+ "amplitude_scale=0.5, frequency_scale=2.0)\n"
+ "\n"
+ " Returns the turbulence value from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n"
+ " :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or "
+ "soft (smooth transitions).\n"
+ " :type hard: boolean\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :arg amplitude_scale: The amplitude scaling factor.\n"
+ " :type amplitude_scale: float\n"
+ " :arg frequency_scale: The frequency scaling factor\n"
+ " :type frequency_scale: float\n"
+ " :return: The turbulence value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_turbulence(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
- float as = 0.5f, fs = 2.0f;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Oii|$sff:turbulence", (char **)kwlist,
- &value, &oct, &hd, &noise_basis_str, &as, &fs))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "turbulence: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(turb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs));
+ static const char *kwlist[] = {
+ "", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
+ float as = 0.5f, fs = 2.0f;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Oii|$sff:turbulence",
+ (char **)kwlist,
+ &value,
+ &oct,
+ &hd,
+ &noise_basis_str,
+ &as,
+ &fs)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "turbulence: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(turb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs));
}
PyDoc_STRVAR(M_Noise_turbulence_vector_doc,
-".. function:: turbulence_vector(position, octaves, hard, noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)\n"
-"\n"
-" Returns the turbulence vector from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-" :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or soft (smooth transitions).\n"
-" :type hard: :boolean\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :arg amplitude_scale: The amplitude scaling factor.\n"
-" :type amplitude_scale: float\n"
-" :arg frequency_scale: The frequency scaling factor\n"
-" :type frequency_scale: float\n"
-" :return: The turbulence vector.\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: turbulence_vector(position, octaves, hard, "
+ "noise_basis='PERLIN_ORIGINAL', amplitude_scale=0.5, frequency_scale=2.0)\n"
+ "\n"
+ " Returns the turbulence vector from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n"
+ " :arg hard: Specifies whether returned turbulence is hard (sharp transitions) or "
+ "soft (smooth transitions).\n"
+ " :type hard: :boolean\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :arg amplitude_scale: The amplitude scaling factor.\n"
+ " :type amplitude_scale: float\n"
+ " :arg frequency_scale: The frequency scaling factor\n"
+ " :type frequency_scale: float\n"
+ " :return: The turbulence vector.\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
- PyObject *value;
- float vec[3], r_vec[3];
- const char *noise_basis_str = NULL;
- int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
- float as = 0.5f, fs = 2.0f;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Oii|$sff:turbulence_vector", (char **)kwlist,
- &value, &oct, &hd, &noise_basis_str, &as, &fs))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence_vector") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "turbulence_vector: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- vTurb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs, r_vec);
-
- return Vector_CreatePyObject(r_vec, 3, NULL);
+ static const char *kwlist[] = {
+ "", "", "", "noise_basis", "amplitude_scale", "frequency_scale", NULL};
+ PyObject *value;
+ float vec[3], r_vec[3];
+ const char *noise_basis_str = NULL;
+ int oct, hd, noise_basis_enum = DEFAULT_NOISE_TYPE;
+ float as = 0.5f, fs = 2.0f;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Oii|$sff:turbulence_vector",
+ (char **)kwlist,
+ &value,
+ &oct,
+ &hd,
+ &noise_basis_str,
+ &as,
+ &fs)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "turbulence_vector") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "turbulence_vector: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ vTurb(vec[0], vec[1], vec[2], oct, hd, noise_basis_enum, as, fs, r_vec);
+
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
/* F. Kenton Musgrave's fractal functions */
-PyDoc_STRVAR(M_Noise_fractal_doc,
-".. function:: fractal(position, H, lacunarity, octaves, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns the fractal Brownian motion (fBm) noise value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg H: The fractal increment factor.\n"
-" :type H: float\n"
-" :arg lacunarity: The gap between successive frequencies.\n"
-" :type lacunarity: float\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The fractal Brownian motion noise value.\n"
-" :rtype: float\n"
-);
+PyDoc_STRVAR(
+ M_Noise_fractal_doc,
+ ".. function:: fractal(position, H, lacunarity, octaves, noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns the fractal Brownian motion (fBm) noise value from the noise basis at the "
+ "specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg H: The fractal increment factor.\n"
+ " :type H: float\n"
+ " :arg lacunarity: The gap between successive frequencies.\n"
+ " :type lacunarity: float\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The fractal Brownian motion noise value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- float H, lac, oct;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Offf|$s:fractal", (char **)kwlist,
- &value, &H, &lac, &oct, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "fractal") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "fractal: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
+ static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ float H, lac, oct;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Offf|$s:fractal",
+ (char **)kwlist,
+ &value,
+ &H,
+ &lac,
+ &oct,
+ &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "fractal") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "fractal: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
}
-PyDoc_STRVAR(M_Noise_multi_fractal_doc,
-".. function:: multi_fractal(position, H, lacunarity, octaves, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns multifractal noise value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg H: The fractal increment factor.\n"
-" :type H: float\n"
-" :arg lacunarity: The gap between successive frequencies.\n"
-" :type lacunarity: float\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The multifractal noise value.\n"
-" :rtype: float\n"
-);
+PyDoc_STRVAR(
+ M_Noise_multi_fractal_doc,
+ ".. function:: multi_fractal(position, H, lacunarity, octaves, "
+ "noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns multifractal noise value from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg H: The fractal increment factor.\n"
+ " :type H: float\n"
+ " :arg lacunarity: The gap between successive frequencies.\n"
+ " :type lacunarity: float\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The multifractal noise value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- float H, lac, oct;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Offf|$s:multi_fractal", (char **)kwlist,
- &value, &H, &lac, &oct, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "multi_fractal") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "multi_fractal: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
+ static const char *kwlist[] = {"", "", "", "", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ float H, lac, oct;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Offf|$s:multi_fractal",
+ (char **)kwlist,
+ &value,
+ &H,
+ &lac,
+ &oct,
+ &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "multi_fractal") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "multi_fractal: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum));
}
PyDoc_STRVAR(M_Noise_variable_lacunarity_doc,
-".. function:: variable_lacunarity(position, distortion, noise_type1='PERLIN_ORIGINAL', noise_type2='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns variable lacunarity noise value, a distorted variety of noise, from noise type 1 distorted by noise type 2 at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg distortion: The amount of distortion.\n"
-" :type distortion: float\n"
-" :arg noise_type1: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
- "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
- "'CELLNOISE'].\n"
-" :type noise_type1: string\n"
-" :arg noise_type2: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', 'VORONOI_F1', 'VORONOI_F2', " \
- "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', " \
- "'CELLNOISE'].\n"
-" :type noise_type2: string\n"
-" :return: The variable lacunarity noise value.\n"
-" :rtype: float\n"
-);
+ ".. function:: variable_lacunarity(position, distortion, "
+ "noise_type1='PERLIN_ORIGINAL', noise_type2='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns variable lacunarity noise value, a distorted variety of noise, from "
+ "noise type 1 distorted by noise type 2 at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg distortion: The amount of distortion.\n"
+ " :type distortion: float\n"
+ " :arg noise_type1: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', "
+ "'VORONOI_F1', 'VORONOI_F2', "
+ "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', "
+ "'CELLNOISE'].\n"
+ " :type noise_type1: string\n"
+ " :arg noise_type2: Enumerator in ['BLENDER', 'PERLIN_ORIGINAL', 'PERLIN_NEW', "
+ "'VORONOI_F1', 'VORONOI_F2', "
+ "'VORONOI_F3', 'VORONOI_F4', 'VORONOI_F2F1', 'VORONOI_CRACKLE', "
+ "'CELLNOISE'].\n"
+ " :type noise_type2: string\n"
+ " :return: The variable lacunarity noise value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_variable_lacunarity(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "noise_type1", "noise_type2", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_type1_str = NULL, *noise_type2_str = NULL;
- float d;
- int noise_type1_enum = DEFAULT_NOISE_TYPE, noise_type2_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Of|$ss:variable_lacunarity", (char **)kwlist,
- &value, &d, &noise_type1_str, &noise_type2_str))
- {
- return NULL;
- }
-
- if (!noise_type1_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_type1_str, &noise_type1_enum, "variable_lacunarity") == -1)
- {
- return NULL;
- }
-
- if (!noise_type2_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_type2_str, &noise_type2_enum, "variable_lacunarity") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "variable_lacunarity: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_VLNoise(vec[0], vec[1], vec[2], d, noise_type1_enum, noise_type2_enum));
+ static const char *kwlist[] = {"", "", "noise_type1", "noise_type2", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_type1_str = NULL, *noise_type2_str = NULL;
+ float d;
+ int noise_type1_enum = DEFAULT_NOISE_TYPE, noise_type2_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Of|$ss:variable_lacunarity",
+ (char **)kwlist,
+ &value,
+ &d,
+ &noise_type1_str,
+ &noise_type2_str)) {
+ return NULL;
+ }
+
+ if (!noise_type1_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_type1_str, &noise_type1_enum, "variable_lacunarity") == -1) {
+ return NULL;
+ }
+
+ if (!noise_type2_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_type2_str, &noise_type2_enum, "variable_lacunarity") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "variable_lacunarity: invalid 'position' arg") ==
+ -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ mg_VLNoise(vec[0], vec[1], vec[2], d, noise_type1_enum, noise_type2_enum));
}
-PyDoc_STRVAR(M_Noise_hetero_terrain_doc,
-".. function:: hetero_terrain(position, H, lacunarity, octaves, offset, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns the heterogeneous terrain value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg H: The fractal dimension of the roughest areas.\n"
-" :type H: float\n"
-" :arg lacunarity: The gap between successive frequencies.\n"
-" :type lacunarity: float\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-" :arg offset: The height of the terrain above 'sea level'.\n"
-" :type offset: float\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The heterogeneous terrain value.\n"
-" :rtype: float\n"
-);
+PyDoc_STRVAR(
+ M_Noise_hetero_terrain_doc,
+ ".. function:: hetero_terrain(position, H, lacunarity, octaves, offset, "
+ "noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns the heterogeneous terrain value from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg H: The fractal dimension of the roughest areas.\n"
+ " :type H: float\n"
+ " :arg lacunarity: The gap between successive frequencies.\n"
+ " :type lacunarity: float\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n"
+ " :arg offset: The height of the terrain above 'sea level'.\n"
+ " :type offset: float\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The heterogeneous terrain value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "", "", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- float H, lac, oct, ofs;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Offff|$s:hetero_terrain", (char **)kwlist,
- &value, &H, &lac, &oct, &ofs, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "hetero_terrain") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "hetero_terrain: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, noise_basis_enum));
+ static const char *kwlist[] = {"", "", "", "", "", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ float H, lac, oct, ofs;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Offff|$s:hetero_terrain",
+ (char **)kwlist,
+ &value,
+ &H,
+ &lac,
+ &oct,
+ &ofs,
+ &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "hetero_terrain") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "hetero_terrain: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, noise_basis_enum));
}
-PyDoc_STRVAR(M_Noise_hybrid_multi_fractal_doc,
-".. function:: hybrid_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns hybrid multifractal value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg H: The fractal dimension of the roughest areas.\n"
-" :type H: float\n"
-" :arg lacunarity: The gap between successive frequencies.\n"
-" :type lacunarity: float\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-" :arg offset: The height of the terrain above 'sea level'.\n"
-" :type offset: float\n"
-" :arg gain: Scaling applied to the values.\n"
-" :type gain: float\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The hybrid multifractal value.\n"
-" :rtype: float\n"
-);
+PyDoc_STRVAR(
+ M_Noise_hybrid_multi_fractal_doc,
+ ".. function:: hybrid_multi_fractal(position, H, lacunarity, octaves, offset, gain, "
+ "noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns hybrid multifractal value from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg H: The fractal dimension of the roughest areas.\n"
+ " :type H: float\n"
+ " :arg lacunarity: The gap between successive frequencies.\n"
+ " :type lacunarity: float\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n"
+ " :arg offset: The height of the terrain above 'sea level'.\n"
+ " :type offset: float\n"
+ " :arg gain: Scaling applied to the values.\n"
+ " :type gain: float\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The hybrid multifractal value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- float H, lac, oct, ofs, gn;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Offfff|$s:hybrid_multi_fractal", (char **)kwlist,
- &value, &H, &lac, &oct, &ofs, &gn, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "hybrid_multi_fractal") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
+ static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ float H, lac, oct, ofs, gn;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Offfff|$s:hybrid_multi_fractal",
+ (char **)kwlist,
+ &value,
+ &H,
+ &lac,
+ &oct,
+ &ofs,
+ &gn,
+ &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "hybrid_multi_fractal") ==
+ -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") ==
+ -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
}
-PyDoc_STRVAR(M_Noise_ridged_multi_fractal_doc,
-".. function:: ridged_multi_fractal(position, H, lacunarity, octaves, offset, gain, noise_basis='PERLIN_ORIGINAL')\n"
-"\n"
-" Returns ridged multifractal value from the noise basis at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :arg H: The fractal dimension of the roughest areas.\n"
-" :type H: float\n"
-" :arg lacunarity: The gap between successive frequencies.\n"
-" :type lacunarity: float\n"
-" :arg octaves: The number of different noise frequencies used.\n"
-" :type octaves: int\n"
-" :arg offset: The height of the terrain above 'sea level'.\n"
-" :type offset: float\n"
-" :arg gain: Scaling applied to the values.\n"
-" :type gain: float\n"
-BPY_NOISE_BASIS_ENUM_DOC
-" :return: The ridged multifractal value.\n"
-" :rtype: float\n"
-);
+PyDoc_STRVAR(
+ M_Noise_ridged_multi_fractal_doc,
+ ".. function:: ridged_multi_fractal(position, H, lacunarity, octaves, offset, gain, "
+ "noise_basis='PERLIN_ORIGINAL')\n"
+ "\n"
+ " Returns ridged multifractal value from the noise basis at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :arg H: The fractal dimension of the roughest areas.\n"
+ " :type H: float\n"
+ " :arg lacunarity: The gap between successive frequencies.\n"
+ " :type lacunarity: float\n"
+ " :arg octaves: The number of different noise frequencies used.\n"
+ " :type octaves: int\n"
+ " :arg offset: The height of the terrain above 'sea level'.\n"
+ " :type offset: float\n"
+ " :arg gain: Scaling applied to the values.\n"
+ " :type gain: float\n" BPY_NOISE_BASIS_ENUM_DOC
+ " :return: The ridged multifractal value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
- PyObject *value;
- float vec[3];
- const char *noise_basis_str = NULL;
- float H, lac, oct, ofs, gn;
- int noise_basis_enum = DEFAULT_NOISE_TYPE;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "Offfff|$s:ridged_multi_fractal", (char **)kwlist,
- &value, &H, &lac, &oct, &ofs, &gn, &noise_basis_str))
- {
- return NULL;
- }
-
- if (!noise_basis_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_types, noise_basis_str, &noise_basis_enum, "ridged_multi_fractal") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "ridged_multi_fractal: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- return PyFloat_FromDouble(mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
+ static const char *kwlist[] = {"", "", "", "", "", "", "noise_basis", NULL};
+ PyObject *value;
+ float vec[3];
+ const char *noise_basis_str = NULL;
+ float H, lac, oct, ofs, gn;
+ int noise_basis_enum = DEFAULT_NOISE_TYPE;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kw,
+ "Offfff|$s:ridged_multi_fractal",
+ (char **)kwlist,
+ &value,
+ &H,
+ &lac,
+ &oct,
+ &ofs,
+ &gn,
+ &noise_basis_str)) {
+ return NULL;
+ }
+
+ if (!noise_basis_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(
+ bpy_noise_types, noise_basis_str, &noise_basis_enum, "ridged_multi_fractal") ==
+ -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "ridged_multi_fractal: invalid 'position' arg") ==
+ -1) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(
+ mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum));
}
PyDoc_STRVAR(M_Noise_voronoi_doc,
-".. function:: voronoi(position, distance_metric='DISTANCE', exponent=2.5)\n"
-"\n"
-" Returns a list of distances to the four closest features and their locations.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-BPY_NOISE_METRIC_ENUM_DOC
-" :arg exponent: The exponent for Minkowski distance metric.\n"
-" :type exponent: float\n"
-" :return: A list of distances to the four closest features and their locations.\n"
-" :rtype: list of four floats, list of four :class:`mathutils.Vector` types\n"
-);
+ ".. function:: voronoi(position, distance_metric='DISTANCE', exponent=2.5)\n"
+ "\n"
+ " Returns a list of distances to the four closest features and their locations.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n" BPY_NOISE_METRIC_ENUM_DOC
+ " :arg exponent: The exponent for Minkowski distance metric.\n"
+ " :type exponent: float\n"
+ " :return: A list of distances to the four closest features and their locations.\n"
+ " :rtype: list of four floats, list of four :class:`mathutils.Vector` types\n");
static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"", "distance_metric", "exponent", NULL};
- PyObject *value;
- PyObject *list;
- PyObject *ret;
- float vec[3];
- const char *metric_str = NULL;
- float da[4], pa[12];
- int metric_enum = DEFAULT_METRIC_TYPE;
- float me = 2.5f; /* default minkowski exponent */
-
- int i;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O|$sf:voronoi", (char **)kwlist,
- &value, &metric_str, &me))
- {
- return NULL;
- }
-
- if (!metric_str) {
- /* pass through */
- }
- else if (PyC_FlagSet_ValueFromID(
- bpy_noise_metrics, metric_str, &metric_enum, "voronoi") == -1)
- {
- return NULL;
- }
-
- if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1) {
- return NULL;
- }
-
- list = PyList_New(4);
-
- voronoi(vec[0], vec[1], vec[2], da, pa, me, metric_enum);
-
- for (i = 0; i < 4; i++) {
- PyObject *v = Vector_CreatePyObject(pa + 3 * i, 3, NULL);
- PyList_SET_ITEM(list, i, v);
- }
-
- ret = Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
- Py_DECREF(list);
- return ret;
+ static const char *kwlist[] = {"", "distance_metric", "exponent", NULL};
+ PyObject *value;
+ PyObject *list;
+ PyObject *ret;
+ float vec[3];
+ const char *metric_str = NULL;
+ float da[4], pa[12];
+ int metric_enum = DEFAULT_METRIC_TYPE;
+ float me = 2.5f; /* default minkowski exponent */
+
+ int i;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "O|$sf:voronoi", (char **)kwlist, &value, &metric_str, &me)) {
+ return NULL;
+ }
+
+ if (!metric_str) {
+ /* pass through */
+ }
+ else if (PyC_FlagSet_ValueFromID(bpy_noise_metrics, metric_str, &metric_enum, "voronoi") == -1) {
+ return NULL;
+ }
+
+ if (mathutils_array_parse(vec, 3, 3, value, "voronoi: invalid 'position' arg") == -1) {
+ return NULL;
+ }
+
+ list = PyList_New(4);
+
+ voronoi(vec[0], vec[1], vec[2], da, pa, me, metric_enum);
+
+ for (i = 0; i < 4; i++) {
+ PyObject *v = Vector_CreatePyObject(pa + 3 * i, 3, NULL);
+ PyList_SET_ITEM(list, i, v);
+ }
+
+ ret = Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
+ Py_DECREF(list);
+ return ret;
}
PyDoc_STRVAR(M_Noise_cell_doc,
-".. function:: cell(position)\n"
-"\n"
-" Returns cell noise value at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :return: The cell noise value.\n"
-" :rtype: float\n"
-);
+ ".. function:: cell(position)\n"
+ "\n"
+ " Returns cell noise value at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :return: The cell noise value.\n"
+ " :rtype: float\n");
static PyObject *M_Noise_cell(PyObject *UNUSED(self), PyObject *args)
{
- PyObject *value;
- float vec[3];
+ PyObject *value;
+ float vec[3];
- if (!PyArg_ParseTuple(args, "O:cell", &value)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "O:cell", &value)) {
+ return NULL;
+ }
- if (mathutils_array_parse(vec, 3, 3, value, "cell: invalid 'position' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(vec, 3, 3, value, "cell: invalid 'position' arg") == -1) {
+ return NULL;
+ }
- return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2]));
+ return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2]));
}
PyDoc_STRVAR(M_Noise_cell_vector_doc,
-".. function:: cell_vector(position)\n"
-"\n"
-" Returns cell noise vector at the specified position.\n"
-"\n"
-" :arg position: The position to evaluate the selected noise function.\n"
-" :type position: :class:`mathutils.Vector`\n"
-" :return: The cell noise vector.\n"
-" :rtype: :class:`mathutils.Vector`\n"
-);
+ ".. function:: cell_vector(position)\n"
+ "\n"
+ " Returns cell noise vector at the specified position.\n"
+ "\n"
+ " :arg position: The position to evaluate the selected noise function.\n"
+ " :type position: :class:`mathutils.Vector`\n"
+ " :return: The cell noise vector.\n"
+ " :rtype: :class:`mathutils.Vector`\n");
static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
{
- PyObject *value;
- float vec[3], r_vec[3];
+ PyObject *value;
+ float vec[3], r_vec[3];
- if (!PyArg_ParseTuple(args, "O:cell_vector", &value)) {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "O:cell_vector", &value)) {
+ return NULL;
+ }
- if (mathutils_array_parse(vec, 3, 3, value, "cell_vector: invalid 'position' arg") == -1) {
- return NULL;
- }
+ if (mathutils_array_parse(vec, 3, 3, value, "cell_vector: invalid 'position' arg") == -1) {
+ return NULL;
+ }
- cellNoiseV(vec[0], vec[1], vec[2], r_vec);
- return Vector_CreatePyObject(r_vec, 3, NULL);
+ cellNoiseV(vec[0], vec[1], vec[2], r_vec);
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
static PyMethodDef M_Noise_methods[] = {
- {"seed_set", (PyCFunction) M_Noise_seed_set, METH_VARARGS, M_Noise_seed_set_doc},
- {"random", (PyCFunction) M_Noise_random, METH_NOARGS, M_Noise_random_doc},
- {"random_unit_vector", (PyCFunction) M_Noise_random_unit_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_random_unit_vector_doc},
- {"random_vector", (PyCFunction) M_Noise_random_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_random_vector_doc},
- {"noise", (PyCFunction) M_Noise_noise, METH_VARARGS | METH_KEYWORDS, M_Noise_noise_doc},
- {"noise_vector", (PyCFunction) M_Noise_noise_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_noise_vector_doc},
- {"turbulence", (PyCFunction) M_Noise_turbulence, METH_VARARGS | METH_KEYWORDS, M_Noise_turbulence_doc},
- {"turbulence_vector", (PyCFunction) M_Noise_turbulence_vector, METH_VARARGS | METH_KEYWORDS, M_Noise_turbulence_vector_doc},
- {"fractal", (PyCFunction) M_Noise_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_fractal_doc},
- {"multi_fractal", (PyCFunction) M_Noise_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_multi_fractal_doc},
- {"variable_lacunarity", (PyCFunction) M_Noise_variable_lacunarity, METH_VARARGS | METH_KEYWORDS, M_Noise_variable_lacunarity_doc},
- {"hetero_terrain", (PyCFunction) M_Noise_hetero_terrain, METH_VARARGS | METH_KEYWORDS, M_Noise_hetero_terrain_doc},
- {"hybrid_multi_fractal", (PyCFunction) M_Noise_hybrid_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_hybrid_multi_fractal_doc},
- {"ridged_multi_fractal", (PyCFunction) M_Noise_ridged_multi_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_ridged_multi_fractal_doc},
- {"voronoi", (PyCFunction) M_Noise_voronoi, METH_VARARGS | METH_KEYWORDS, M_Noise_voronoi_doc},
- {"cell", (PyCFunction) M_Noise_cell, METH_VARARGS, M_Noise_cell_doc},
- {"cell_vector", (PyCFunction) M_Noise_cell_vector, METH_VARARGS, M_Noise_cell_vector_doc},
- {NULL, NULL, 0, NULL},
+ {"seed_set", (PyCFunction)M_Noise_seed_set, METH_VARARGS, M_Noise_seed_set_doc},
+ {"random", (PyCFunction)M_Noise_random, METH_NOARGS, M_Noise_random_doc},
+ {"random_unit_vector",
+ (PyCFunction)M_Noise_random_unit_vector,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_random_unit_vector_doc},
+ {"random_vector",
+ (PyCFunction)M_Noise_random_vector,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_random_vector_doc},
+ {"noise", (PyCFunction)M_Noise_noise, METH_VARARGS | METH_KEYWORDS, M_Noise_noise_doc},
+ {"noise_vector",
+ (PyCFunction)M_Noise_noise_vector,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_noise_vector_doc},
+ {"turbulence",
+ (PyCFunction)M_Noise_turbulence,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_turbulence_doc},
+ {"turbulence_vector",
+ (PyCFunction)M_Noise_turbulence_vector,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_turbulence_vector_doc},
+ {"fractal", (PyCFunction)M_Noise_fractal, METH_VARARGS | METH_KEYWORDS, M_Noise_fractal_doc},
+ {"multi_fractal",
+ (PyCFunction)M_Noise_multi_fractal,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_multi_fractal_doc},
+ {"variable_lacunarity",
+ (PyCFunction)M_Noise_variable_lacunarity,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_variable_lacunarity_doc},
+ {"hetero_terrain",
+ (PyCFunction)M_Noise_hetero_terrain,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_hetero_terrain_doc},
+ {"hybrid_multi_fractal",
+ (PyCFunction)M_Noise_hybrid_multi_fractal,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_hybrid_multi_fractal_doc},
+ {"ridged_multi_fractal",
+ (PyCFunction)M_Noise_ridged_multi_fractal,
+ METH_VARARGS | METH_KEYWORDS,
+ M_Noise_ridged_multi_fractal_doc},
+ {"voronoi", (PyCFunction)M_Noise_voronoi, METH_VARARGS | METH_KEYWORDS, M_Noise_voronoi_doc},
+ {"cell", (PyCFunction)M_Noise_cell, METH_VARARGS, M_Noise_cell_doc},
+ {"cell_vector", (PyCFunction)M_Noise_cell_vector, METH_VARARGS, M_Noise_cell_vector_doc},
+ {NULL, NULL, 0, NULL},
};
static struct PyModuleDef M_Noise_module_def = {
- PyModuleDef_HEAD_INIT,
- "mathutils.noise", /* m_name */
- M_Noise_doc, /* m_doc */
- 0, /* m_size */
- M_Noise_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ PyModuleDef_HEAD_INIT,
+ "mathutils.noise", /* m_name */
+ M_Noise_doc, /* m_doc */
+ 0, /* m_size */
+ M_Noise_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
};
/*----------------------------MODULE INIT-------------------------*/
PyMODINIT_FUNC PyInit_mathutils_noise(void)
{
- PyObject *submodule = PyModule_Create(&M_Noise_module_def);
+ PyObject *submodule = PyModule_Create(&M_Noise_module_def);
- /* use current time as seed for random number generator by default */
- setRndSeed(0);
+ /* use current time as seed for random number generator by default */
+ setRndSeed(0);
- return submodule;
+ return submodule;
}