Blender  V3.3
mathutils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <Python.h>
8 
9 #include "mathutils.h"
10 
11 #include "BLI_math.h"
12 #include "BLI_utildefines.h"
13 
14 #include "../generic/py_capi_utils.h"
15 #include "../generic/python_utildefines.h"
16 
17 #ifndef MATH_STANDALONE
18 # include "BLI_dynstr.h"
19 #endif
20 
22  M_Mathutils_doc,
23  "This module provides access to math operations.\n"
24  "\n"
25  ".. note::\n"
26  "\n"
27  " Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
28  " such as tuples, lists.\n"
29  "\n"
30  "The :mod:`mathutils` module provides the following classes:\n"
31  "\n"
32  "- :class:`Color`,\n"
33  "- :class:`Euler`,\n"
34  "- :class:`Matrix`,\n"
35  "- :class:`Quaternion`,\n"
36  "- :class:`Vector`,\n");
38  int size,
39  PyObject *value_fast,
40  const char *error_prefix)
41 {
42  PyObject *item;
43  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
44 
45  int i;
46 
47  i = size;
48  do {
49  i--;
50  if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
51  PyErr_Occurred()) {
52  PyErr_Format(PyExc_TypeError,
53  "%.200s: sequence index %d expected a number, "
54  "found '%.200s' type, ",
55  error_prefix,
56  i,
57  Py_TYPE(item)->tp_name);
58  size = -1;
59  break;
60  }
61  } while (i);
62 
63  return size;
64 }
65 
66 Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
67 {
68  int i;
69  Py_uhash_t x; /* Unsigned for defined overflow behavior. */
70  Py_hash_t y;
71  Py_uhash_t mult;
72  Py_ssize_t len;
73 
74  mult = _PyHASH_MULTIPLIER;
75  len = array_len;
76  x = 0x345678UL;
77  i = 0;
78  while (--len >= 0) {
79 #if PY_VERSION_HEX < 0x030a0000
80  y = _Py_HashDouble((double)(array[i++]));
81 #else
82  y = _Py_HashDouble(NULL, (double)(array[i++]));
83 #endif
84  if (y == -1) {
85  return -1;
86  }
87  x = (x ^ y) * mult;
88  /* the cast might truncate len; that doesn't change hash stability */
89  mult += (Py_hash_t)(82520UL + len + len);
90  }
91  x += 97531UL;
92  if (x == (Py_uhash_t)-1) {
93  x = -2;
94  }
95  return x;
96 }
97 
99  float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
100 {
101  const uint flag = array_num_max;
102  int num;
103 
104  array_num_max &= ~MU_ARRAY_FLAGS;
105 
106 #if 1 /* approx 6x speedup for mathutils types */
107 
108  if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||
109  (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||
110  (num = ColorObject_Check(value) ? 3 : 0)) {
111  if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
112  return -1;
113  }
114 
115  if (flag & MU_ARRAY_SPILL) {
116  CLAMP_MAX(num, array_num_max);
117  }
118 
119  if (num > array_num_max || num < array_num_min) {
120  if (array_num_max == array_num_min) {
121  PyErr_Format(PyExc_ValueError,
122  "%.200s: sequence length is %d, expected %d",
123  error_prefix,
124  num,
125  array_num_max);
126  }
127  else {
128  PyErr_Format(PyExc_ValueError,
129  "%.200s: sequence length is %d, expected [%d - %d]",
130  error_prefix,
131  num,
132  array_num_min,
133  array_num_max);
134  }
135  return -1;
136  }
137 
138  memcpy(array, ((const BaseMathObject *)value)->data, num * sizeof(float));
139  }
140  else
141 #endif
142  {
143  PyObject *value_fast = NULL;
144 
145  /* non list/tuple cases */
146  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
147  /* PySequence_Fast sets the error */
148  return -1;
149  }
150 
151  num = PySequence_Fast_GET_SIZE(value_fast);
152 
153  if (flag & MU_ARRAY_SPILL) {
154  CLAMP_MAX(num, array_num_max);
155  }
156 
157  if (num > array_num_max || num < array_num_min) {
158  if (array_num_max == array_num_min) {
159  PyErr_Format(PyExc_ValueError,
160  "%.200s: sequence length is %d, expected %d",
161  error_prefix,
162  num,
163  array_num_max);
164  }
165  else {
166  PyErr_Format(PyExc_ValueError,
167  "%.200s: sequence length is %d, expected [%d - %d]",
168  error_prefix,
169  num,
170  array_num_min,
171  array_num_max);
172  }
173  Py_DECREF(value_fast);
174  return -1;
175  }
176 
177  num = mathutils_array_parse_fast(array, num, value_fast, error_prefix);
178  Py_DECREF(value_fast);
179  }
180 
181  if (num != -1) {
182  if (flag & MU_ARRAY_ZERO) {
183  const int array_num_left = array_num_max - num;
184  if (array_num_left) {
185  memset(&array[num], 0, sizeof(float) * array_num_left);
186  }
187  }
188  }
189 
190  return num;
191 }
192 
194  int array_num,
195  PyObject *value,
196  const char *error_prefix)
197 {
198  int num;
199 
200 #if 1 /* approx 6x speedup for mathutils types */
201 
202  if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||
203  (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||
204  (num = ColorObject_Check(value) ? 3 : 0)) {
205  if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
206  return -1;
207  }
208 
209  if (num < array_num) {
210  PyErr_Format(PyExc_ValueError,
211  "%.200s: sequence size is %d, expected > %d",
212  error_prefix,
213  num,
214  array_num);
215  return -1;
216  }
217 
218  *array = PyMem_Malloc(num * sizeof(float));
219  memcpy(*array, ((const BaseMathObject *)value)->data, num * sizeof(float));
220  return num;
221  }
222 
223 #endif
224 
225  PyObject *value_fast = NULL;
226  // *array = NULL;
227  int ret;
228 
229  /* non list/tuple cases */
230  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
231  /* PySequence_Fast sets the error */
232  return -1;
233  }
234 
235  num = PySequence_Fast_GET_SIZE(value_fast);
236 
237  if (num < array_num) {
238  Py_DECREF(value_fast);
239  PyErr_Format(PyExc_ValueError,
240  "%.200s: sequence size is %d, expected > %d",
241  error_prefix,
242  num,
243  array_num);
244  return -1;
245  }
246 
247  *array = PyMem_Malloc(num * sizeof(float));
248 
249  ret = mathutils_array_parse_fast(*array, num, value_fast, error_prefix);
250  Py_DECREF(value_fast);
251 
252  if (ret == -1) {
253  PyMem_Free(*array);
254  }
255 
256  return ret;
257 }
258 
260  int array_dim,
261  PyObject *value,
262  const char *error_prefix)
263 {
264  PyObject *value_fast;
265  const int array_dim_flag = array_dim;
266  int i, num;
267 
268  /* non list/tuple cases */
269  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
270  /* PySequence_Fast sets the error */
271  return -1;
272  }
273 
274  num = PySequence_Fast_GET_SIZE(value_fast);
275 
276  if (num != 0) {
277  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
278  float *fp;
279 
280  array_dim &= ~MU_ARRAY_FLAGS;
281 
282  fp = *array = PyMem_Malloc(num * array_dim * sizeof(float));
283 
284  for (i = 0; i < num; i++, fp += array_dim) {
285  PyObject *item = value_fast_items[i];
286 
287  if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
288  PyMem_Free(*array);
289  *array = NULL;
290  num = -1;
291  break;
292  }
293  }
294  }
295 
296  Py_DECREF(value_fast);
297  return num;
298 }
299 
300 int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
301 {
302  int size, i;
303  PyObject *value_fast, **value_fast_items, *item;
304 
305  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
306  /* PySequence_Fast sets the error */
307  return -1;
308  }
309 
310  if ((size = PySequence_Fast_GET_SIZE(value_fast)) != array_dim) {
311  PyErr_Format(PyExc_ValueError,
312  "%.200s: sequence size is %d, expected %d",
313  error_prefix,
314  size,
315  array_dim);
316  Py_DECREF(value_fast);
317  return -1;
318  }
319 
320  value_fast_items = PySequence_Fast_ITEMS(value_fast);
321  i = size;
322  while (i > 0) {
323  i--;
324  if (((array[i] = PyC_Long_AsI32((item = value_fast_items[i]))) == -1) && PyErr_Occurred()) {
325  PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected an int", error_prefix, i);
326  size = -1;
327  break;
328  }
329  }
330  Py_DECREF(value_fast);
331 
332  return size;
333 }
334 
336  int array_dim,
337  PyObject *value,
338  const char *error_prefix)
339 {
340  PyObject *value_fast;
341  int i, size;
342 
343  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
344  /* PySequence_Fast sets the error */
345  return -1;
346  }
347 
348  size = PySequence_Fast_GET_SIZE(value_fast);
349 
350  if (size != 0) {
351  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
352  int *ip;
353 
354  ip = *array = PyMem_Malloc(size * array_dim * sizeof(int));
355 
356  for (i = 0; i < size; i++, ip += array_dim) {
357  PyObject *item = value_fast_items[i];
358 
359  if (mathutils_int_array_parse(ip, array_dim, item, error_prefix) == -1) {
360  PyMem_Free(*array);
361  *array = NULL;
362  size = -1;
363  break;
364  }
365  }
366  }
367 
368  Py_DECREF(value_fast);
369  return size;
370 }
371 
373  int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix)
374 {
375  PyObject *value_fast, *subseq;
376  int i, size, start, subseq_len;
377  int *ip;
378 
379  *array = NULL;
380  *start_table = NULL;
381  *len_table = NULL;
382  if (!(value_fast = PySequence_Fast(value, error_prefix))) {
383  /* PySequence_Fast sets the error */
384  return -1;
385  }
386 
387  size = PySequence_Fast_GET_SIZE(value_fast);
388 
389  if (size != 0) {
390  PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
391 
392  *start_table = PyMem_Malloc(size * sizeof(int));
393  *len_table = PyMem_Malloc(size * sizeof(int));
394 
395  /* First pass to set starts and len, and calculate size of array needed */
396  start = 0;
397  for (i = 0; i < size; i++) {
398  subseq = value_fast_items[i];
399  if ((subseq_len = (int)PySequence_Size(subseq)) == -1) {
400  PyErr_Format(
401  PyExc_ValueError, "%.200s: sequence expected to have subsequences", error_prefix);
402  PyMem_Free(*start_table);
403  PyMem_Free(*len_table);
404  Py_DECREF(value_fast);
405  *start_table = NULL;
406  *len_table = NULL;
407  return -1;
408  }
409  (*start_table)[i] = start;
410  (*len_table)[i] = subseq_len;
411  start += subseq_len;
412  }
413 
414  ip = *array = PyMem_Malloc(start * sizeof(int));
415 
416  /* Second pass to parse the subsequences into array */
417  for (i = 0; i < size; i++) {
418  subseq = value_fast_items[i];
419  subseq_len = (*len_table)[i];
420 
421  if (mathutils_int_array_parse(ip, subseq_len, subseq, error_prefix) == -1) {
422  PyMem_Free(*array);
423  PyMem_Free(*start_table);
424  PyMem_Free(*len_table);
425  *array = NULL;
426  *len_table = NULL;
427  *start_table = NULL;
428  size = -1;
429  break;
430  }
431  ip += subseq_len;
432  }
433  }
434 
435  Py_DECREF(value_fast);
436  return size;
437 }
438 
439 int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
440 {
441  if (EulerObject_Check(value)) {
442  if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
443  return -1;
444  }
445 
446  eulO_to_mat3(rmat, ((const EulerObject *)value)->eul, ((const EulerObject *)value)->order);
447  return 0;
448  }
449  if (QuaternionObject_Check(value)) {
450  if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
451  return -1;
452  }
453 
454  float tquat[4];
455  normalize_qt_qt(tquat, ((const QuaternionObject *)value)->quat);
456  quat_to_mat3(rmat, tquat);
457  return 0;
458  }
459  if (MatrixObject_Check(value)) {
460  if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
461  return -1;
462  }
463  if (((MatrixObject *)value)->row_num < 3 || ((MatrixObject *)value)->col_num < 3) {
464  PyErr_Format(
465  PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
466  return -1;
467  }
468 
469  matrix_as_3x3(rmat, (MatrixObject *)value);
470  normalize_m3(rmat);
471  return 0;
472  }
473 
474  PyErr_Format(PyExc_TypeError,
475  "%.200s: expected a Euler, Quaternion or Matrix type, "
476  "found %.200s",
477  error_prefix,
478  Py_TYPE(value)->tp_name);
479  return -1;
480 }
481 
482 /* ----------------------------------MATRIX FUNCTIONS-------------------- */
483 
484 /* Utility functions */
485 
486 /* LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon */
487 /* XXX We may want to use 'safer' BLI's compare_ff_relative ultimately?
488  * LomontRRDCompare4() is an optimized version of Dawson's AlmostEqual2sComplement()
489  * (see [1] and [2]).
490  * Dawson himself now claims this is not a 'safe' thing to do
491  * (pushing ULP method beyond its limits),
492  * an recommends using work from [3] instead, which is done in BLI func...
493  *
494  * [1] http://www.randydillon.org/Papers/2007/everfast.htm
495  * [2] http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
496  * [3] https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
497  * instead.
498  */
499 #define SIGNMASK(i) (-(int)(((uint)(i)) >> 31))
500 
501 int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
502 {
503  /* solid, fast routine across all platforms
504  * with constant time behavior */
505  const int ai = *(const int *)(&af);
506  const int bi = *(const int *)(&bf);
507  const int test = SIGNMASK(ai ^ bi);
508  int diff, v1, v2;
509 
510  BLI_assert((0 == test) || (0xFFFFFFFF == test));
511  diff = (ai ^ (test & 0x7fffffff)) - bi;
512  v1 = maxDiff + diff;
513  v2 = maxDiff - diff;
514  return (v1 | v2) >= 0;
515 }
516 
517 /*---------------------- EXPP_VectorsAreEqual -------------------------
518  * Builds on EXPP_FloatsAreEqual to test vectors */
519 int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
520 {
521  int x;
522  for (x = 0; x < size; x++) {
523  if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) {
524  return 0;
525  }
526  }
527  return 1;
528 }
529 
530 #ifndef MATH_STANDALONE
531 PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
532 {
533  const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */
534  char *ds_buf = PyMem_Malloc(ds_len + 1);
535  PyObject *ret;
536  BLI_dynstr_get_cstring_ex(ds, ds_buf);
537  BLI_dynstr_free(ds);
538  ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
539  PyMem_Free(ds_buf);
540  return ret;
541 }
542 #endif
543 
544 /* Mathutils Callbacks */
545 
546 /* For mathutils internal use only,
547  * eventually should re-alloc but to start with we only have a few users. */
548 #define MATHUTILS_TOT_CB 17
550 
552 {
553  uchar i;
554 
555  /* find the first free slot */
556  for (i = 0; mathutils_callbacks[i]; i++) {
557  if (mathutils_callbacks[i] == cb) {
558  /* already registered? */
559  return i;
560  }
561  }
562 
563  BLI_assert(i + 1 < MATHUTILS_TOT_CB);
564 
565  mathutils_callbacks[i] = cb;
566  return i;
567 }
568 
570 {
571  Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
572  if (LIKELY(cb->check(self) != -1)) {
573  return 0;
574  }
575  return -1;
576 }
577 
578 /* use macros to check for NULL */
580 {
581  Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
582  if (LIKELY(cb->get(self, self->cb_subtype) != -1)) {
583  return 0;
584  }
585 
586  if (!PyErr_Occurred()) {
587  PyErr_Format(PyExc_RuntimeError, "%s read, user has become invalid", Py_TYPE(self)->tp_name);
588  }
589  return -1;
590 }
591 
593 {
594  Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
595  if (LIKELY(cb->set(self, self->cb_subtype) != -1)) {
596  return 0;
597  }
598 
599  if (!PyErr_Occurred()) {
600  PyErr_Format(PyExc_RuntimeError, "%s write, user has become invalid", Py_TYPE(self)->tp_name);
601  }
602  return -1;
603 }
604 
606 {
607  Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
608  if (LIKELY(cb->get_index(self, self->cb_subtype, index) != -1)) {
609  return 0;
610  }
611 
612  if (!PyErr_Occurred()) {
613  PyErr_Format(
614  PyExc_RuntimeError, "%s read index, user has become invalid", Py_TYPE(self)->tp_name);
615  }
616  return -1;
617 }
618 
620 {
621  Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];
622  if (LIKELY(cb->set_index(self, self->cb_subtype, index) != -1)) {
623  return 0;
624  }
625 
626  if (!PyErr_Occurred()) {
627  PyErr_Format(
628  PyExc_RuntimeError, "%s write index, user has become invalid", Py_TYPE(self)->tp_name);
629  }
630  return -1;
631 }
632 
634 {
635  PyErr_Format(PyExc_TypeError, "%s is frozen (immutable)", Py_TYPE(self)->tp_name);
636 }
637 
639 {
640  PyErr_Format(
641  PyExc_TypeError, "%s is not frozen (mutable), call freeze first", Py_TYPE(self)->tp_name);
642 }
643 
644 /* BaseMathObject generic functions for all mathutils types */
645 char BaseMathObject_owner_doc[] = "The item this is wrapping or None (read-only).";
646 PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
647 {
648  PyObject *ret = self->cb_user ? self->cb_user : Py_None;
649  return Py_INCREF_RET(ret);
650 }
651 
653  "True when this object wraps external data (read-only).\n\n:type: boolean";
654 PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
655 {
656  return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0);
657 }
658 
660  "True when this object has been frozen (read-only).\n\n:type: boolean";
661 PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
662 {
663  return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_FROZEN) != 0);
664 }
665 
667  "True when the owner of this data is valid.\n\n:type: boolean";
668 PyObject *BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
669 {
670  return PyBool_FromLong(BaseMath_CheckCallback(self) == 0);
671 }
672 
674  ".. function:: freeze()\n"
675  "\n"
676  " Make this object immutable.\n"
677  "\n"
678  " After this the object can be hashed, used in dictionaries & sets.\n"
679  "\n"
680  " :return: An instance of this object.\n";
682 {
683  if ((self->flag & BASE_MATH_FLAG_IS_WRAP) || (self->cb_user != NULL)) {
684  PyErr_SetString(PyExc_TypeError, "Cannot freeze wrapped/owned data");
685  return NULL;
686  }
687 
688  self->flag |= BASE_MATH_FLAG_IS_FROZEN;
689 
690  return Py_INCREF_RET((PyObject *)self);
691 }
692 
693 int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
694 {
695  Py_VISIT(self->cb_user);
696  return 0;
697 }
698 
700 {
701  Py_CLEAR(self->cb_user);
702  return 0;
703 }
704 
706 {
707  /* only free non wrapped */
708  if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) {
709  PyMem_Free(self->data);
710  }
711 
712  if (self->cb_user) {
713  PyObject_GC_UnTrack(self);
714  BaseMathObject_clear(self);
715  }
716 
717  Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks subtypes. */
718 }
719 
720 /*----------------------------MODULE INIT-------------------------*/
721 static struct PyMethodDef M_Mathutils_methods[] = {
722  {NULL, NULL, 0, NULL},
723 };
724 
725 static struct PyModuleDef M_Mathutils_module_def = {
726  PyModuleDef_HEAD_INIT,
727  "mathutils", /* m_name */
728  M_Mathutils_doc, /* m_doc */
729  0, /* m_size */
730  M_Mathutils_methods, /* m_methods */
731  NULL, /* m_reload */
732  NULL, /* m_traverse */
733  NULL, /* m_clear */
734  NULL, /* m_free */
735 };
736 
737 /* submodules only */
738 #include "mathutils_geometry.h"
739 #include "mathutils_interpolate.h"
740 #ifndef MATH_STANDALONE
741 # include "mathutils_bvhtree.h"
742 # include "mathutils_kdtree.h"
743 # include "mathutils_noise.h"
744 #endif
745 
746 PyMODINIT_FUNC PyInit_mathutils(void)
747 {
748  PyObject *mod;
749  PyObject *submodule;
750  PyObject *sys_modules = PyImport_GetModuleDict();
751 
752  if (PyType_Ready(&vector_Type) < 0) {
753  return NULL;
754  }
755  if (PyType_Ready(&matrix_Type) < 0) {
756  return NULL;
757  }
758  if (PyType_Ready(&matrix_access_Type) < 0) {
759  return NULL;
760  }
761  if (PyType_Ready(&euler_Type) < 0) {
762  return NULL;
763  }
764  if (PyType_Ready(&quaternion_Type) < 0) {
765  return NULL;
766  }
767  if (PyType_Ready(&color_Type) < 0) {
768  return NULL;
769  }
770 
771  mod = PyModule_Create(&M_Mathutils_module_def);
772 
773  /* each type has its own new() function */
774  PyModule_AddType(mod, &vector_Type);
775  PyModule_AddType(mod, &matrix_Type);
776  PyModule_AddType(mod, &euler_Type);
777  PyModule_AddType(mod, &quaternion_Type);
778  PyModule_AddType(mod, &color_Type);
779 
780  /* submodule */
781  PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry()));
782  /* XXX, python doesn't do imports with this usefully yet
783  * 'from mathutils.geometry import PolyFill'
784  * ...fails without this. */
785  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
786 
787  PyModule_AddObject(mod, "interpolate", (submodule = PyInit_mathutils_interpolate()));
788  /* XXX, python doesn't do imports with this usefully yet
789  * 'from mathutils.geometry import PolyFill'
790  * ...fails without this. */
791  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
792 
793 #ifndef MATH_STANDALONE
794  /* Noise submodule */
795  PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));
796  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
797 
798  /* BVHTree submodule */
799  PyModule_AddObject(mod, "bvhtree", (submodule = PyInit_mathutils_bvhtree()));
800  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
801 
802  /* KDTree_3d submodule */
803  PyModule_AddObject(mod, "kdtree", (submodule = PyInit_mathutils_kdtree()));
804  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
805 #endif
806 
811 
812  return mod;
813 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
A dynamically sized string ADT.
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:235
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition: BLI_dynstr.c:281
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
Definition: BLI_dynstr.c:240
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
void eulO_to_mat3(float mat[3][3], const float eul[3], short order)
float normalize_qt_qt(float r[4], const float q[4])
void quat_to_mat3(float mat[3][3], const float q[4])
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define CLAMP_MAX(a, c)
#define UNUSED(x)
#define LIKELY(x)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
PyObject * self
Definition: bpy_driver.c:165
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE void mult(const btTransform &t1, const btTransform &t2)
Set the current transform as the value of the product of two transforms.
Definition: btTransform.h:76
int len
Definition: draw_manager.c:108
static struct PyModuleDef M_Mathutils_module_def
Definition: mathutils.c:725
static Mathutils_Callback * mathutils_callbacks[MATHUTILS_TOT_CB]
Definition: mathutils.c:549
PyObject * BaseMathObject_freeze(BaseMathObject *self)
Definition: mathutils.c:681
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:661
int _BaseMathObject_CheckCallback(BaseMathObject *self)
Definition: mathutils.c:569
PyMODINIT_FUNC PyInit_mathutils(void)
Definition: mathutils.c:746
static int mathutils_array_parse_fast(float *array, int size, PyObject *value_fast, const char *error_prefix)
Definition: mathutils.c:37
int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
Definition: mathutils.c:501
#define SIGNMASK(i)
Definition: mathutils.c:499
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:654
PyObject * mathutils_dynstr_to_py(struct DynStr *ds)
Definition: mathutils.c:531
int mathutils_array_parse_alloc_viseq(int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix)
Definition: mathutils.c:372
#define MATHUTILS_TOT_CB
Definition: mathutils.c:548
void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self)
Definition: mathutils.c:633
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
Definition: mathutils.c:66
void BaseMathObject_dealloc(BaseMathObject *self)
Definition: mathutils.c:705
int _BaseMathObject_WriteCallback(BaseMathObject *self)
Definition: mathutils.c:592
int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
Definition: mathutils.c:300
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
Definition: mathutils.c:519
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition: mathutils.c:98
int mathutils_array_parse_alloc_vi(int **array, int array_dim, PyObject *value, const char *error_prefix)
Definition: mathutils.c:335
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition: mathutils.c:551
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
Definition: mathutils.c:259
char BaseMathObject_is_valid_doc[]
Definition: mathutils.c:666
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:646
char BaseMathObject_is_wrapped_doc[]
Definition: mathutils.c:652
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" "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")
char BaseMathObject_is_frozen_doc[]
Definition: mathutils.c:659
static struct PyMethodDef M_Mathutils_methods[]
Definition: mathutils.c:721
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
Definition: mathutils.c:439
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
Definition: mathutils.c:668
char BaseMathObject_owner_doc[]
Definition: mathutils.c:645
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
Definition: mathutils.c:619
char BaseMathObject_freeze_doc[]
Definition: mathutils.c:673
int mathutils_array_parse_alloc(float **array, int array_num, PyObject *value, const char *error_prefix)
Definition: mathutils.c:193
int BaseMathObject_clear(BaseMathObject *self)
Definition: mathutils.c:699
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
Definition: mathutils.c:605
int _BaseMathObject_ReadCallback(BaseMathObject *self)
Definition: mathutils.c:579
void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
Definition: mathutils.c:638
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
Definition: mathutils.c:693
#define BaseMath_CheckCallback(_self)
Definition: mathutils.h:117
@ BASE_MATH_FLAG_IS_WRAP
Definition: mathutils.h:31
@ BASE_MATH_FLAG_IS_FROZEN
Definition: mathutils.h:36
#define MU_ARRAY_ZERO
Definition: mathutils.h:203
#define MU_ARRAY_FLAGS
Definition: mathutils.h:208
#define MU_ARRAY_SPILL
Definition: mathutils.h:206
#define BaseMath_ReadCallback(_self)
Definition: mathutils.h:119
PyTypeObject color_Type
#define ColorObject_Check(v)
PyTypeObject euler_Type
#define EulerObject_Check(v)
Mathutils_Callback mathutils_matrix_col_cb
PyTypeObject matrix_access_Type
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
Mathutils_Callback mathutils_matrix_row_cb
Mathutils_Callback mathutils_matrix_translation_cb
uchar mathutils_matrix_col_cb_index
uchar mathutils_matrix_row_cb_index
uchar mathutils_matrix_translation_cb_index
PyTypeObject matrix_Type
#define MatrixObject_Check(v)
PyTypeObject quaternion_Type
#define QuaternionObject_Check(v)
PyTypeObject vector_Type
#define VectorObject_Check(v)
PyMODINIT_FUNC PyInit_mathutils_bvhtree(void)
PyMODINIT_FUNC PyInit_mathutils_geometry(void)
PyMODINIT_FUNC PyInit_mathutils_interpolate(void)
PyMODINIT_FUNC PyInit_mathutils_kdtree(void)
PyMODINIT_FUNC PyInit_mathutils_noise(void)
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
return ret
BaseMathSetIndexFunc set_index
Definition: mathutils.h:102
BaseMathCheckFunc check
Definition: mathutils.h:98
BaseMathGetIndexFunc get_index
Definition: mathutils.h:101
BaseMathSetFunc set
Definition: mathutils.h:100
BaseMathGetFunc get
Definition: mathutils.h:99
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490