20#ifndef MATH_STANDALONE
27 "This module provides access to math operations.\n"
31 " Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
32 " such as tuples, lists.\n"
34 "The :mod:`mathutils` module provides the following classes:\n"
38 "- :class:`Matrix`,\n"
39 "- :class:`Quaternion`,\n"
40 "- :class:`Vector`,\n");
44 const char *error_prefix)
47 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
54 if (((
array[i] = PyFloat_AsDouble(item = value_fast_items[i])) == -1.0f) && PyErr_Occurred()) {
55 PyErr_Format(PyExc_TypeError,
56 "%.200s: sequence index %d expected a number, "
57 "found '%.200s' type, ",
60 Py_TYPE(item)->tp_name);
77 mult = _PyHASH_MULTIPLIER;
82 y = _Py_HashDouble(
nullptr,
double(
array[i++]));
91 if (x == (Py_uhash_t)-1) {
98 float *
array,
int array_num_min,
int array_num_max, PyObject *value,
const char *error_prefix)
103 array_num_max &= ~MU_ARRAY_FLAGS;
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",
128 PyErr_Format(PyExc_ValueError,
129 "%.200s: sequence length is %d, expected [%d - %d]",
143 PyObject *value_fast =
nullptr;
146 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
151 num = PySequence_Fast_GET_SIZE(value_fast);
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",
166 PyErr_Format(PyExc_ValueError,
167 "%.200s: sequence length is %d, expected [%d - %d]",
173 Py_DECREF(value_fast);
178 Py_DECREF(value_fast);
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);
196 const char *error_prefix)
210 if (num < array_num_min) {
211 PyErr_Format(PyExc_ValueError,
212 "%.200s: sequence size is %d, expected >= %d",
219 *
array =
static_cast<float *
>(PyMem_Malloc(num *
sizeof(
float)));
226 PyObject *value_fast =
nullptr;
231 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
236 num = PySequence_Fast_GET_SIZE(value_fast);
238 if (num < array_num_min) {
239 Py_DECREF(value_fast);
240 PyErr_Format(PyExc_ValueError,
241 "%.200s: sequence size is %d, expected >= %d",
248 *
array =
static_cast<float *
>(PyMem_Malloc(num *
sizeof(
float)));
251 Py_DECREF(value_fast);
263 const char *error_prefix)
265 PyObject *value_fast;
266 const int array_dim_flag = array_dim;
270 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
275 num = PySequence_Fast_GET_SIZE(value_fast);
278 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
281 array_dim &= ~MU_ARRAY_FLAGS;
283 fp = *
array =
static_cast<float *
>(PyMem_Malloc(num * array_dim *
sizeof(
float)));
285 for (i = 0; i < num; i++, fp += array_dim) {
286 PyObject *item = value_fast_items[i];
297 Py_DECREF(value_fast);
304 PyObject *value_fast, **value_fast_items, *item;
306 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
311 if ((size = PySequence_Fast_GET_SIZE(value_fast)) != array_dim) {
312 PyErr_Format(PyExc_ValueError,
313 "%.200s: sequence size is %d, expected %d",
317 Py_DECREF(value_fast);
321 value_fast_items = PySequence_Fast_ITEMS(value_fast);
325 if (((
array[i] = PyC_Long_AsI32(item = value_fast_items[i])) == -1) && PyErr_Occurred()) {
326 PyErr_Format(PyExc_TypeError,
"%.200s: sequence index %d expected an int", error_prefix, i);
331 Py_DECREF(value_fast);
339 const char *error_prefix)
341 PyObject *value_fast;
344 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
349 size = PySequence_Fast_GET_SIZE(value_fast);
352 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
355 ip = *
array =
static_cast<int *
>(PyMem_Malloc(size * array_dim *
sizeof(
int)));
357 for (i = 0; i <
size; i++, ip += array_dim) {
358 PyObject *item = value_fast_items[i];
369 Py_DECREF(value_fast);
374 const char *error_prefix,
377 PyObject *value_fast;
378 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
383 const int size = PySequence_Fast_GET_SIZE(value_fast);
385 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
386 r_data.reinitialize(size);
387 for (
const int64_t i : r_data.index_range()) {
388 PyObject *subseq = value_fast_items[i];
389 const int subseq_len =
int(PySequence_Size(subseq));
390 if (subseq_len == -1) {
392 PyExc_ValueError,
"%.200s: sequence expected to have subsequences", error_prefix);
393 Py_DECREF(value_fast);
396 r_data[i].resize(subseq_len);
399 Py_DECREF(value_fast);
405 Py_DECREF(value_fast);
435 PyExc_ValueError,
"%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
444 PyErr_Format(PyExc_TypeError,
445 "%.200s: expected a Euler, Quaternion or Matrix type, "
448 Py_TYPE(value)->tp_name);
469#define SIGNMASK(i) (-int((uint(i)) >> 31))
475 const int ai = *(
const int *)(&af);
476 const int bi = *(
const int *)(&bf);
480 BLI_assert((0 == test) || (0xFFFFFFFF == test));
481 diff = (ai ^ (test & 0x7fffffff)) - bi;
484 return (v1 |
v2) >= 0;
493 for (x = 0; x <
size; x++) {
501#ifndef MATH_STANDALONE
505 char *ds_buf =
static_cast<char *
>(PyMem_Malloc(ds_len + 1));
509 ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
519#define MATHUTILS_TOT_CB 17
558 if (!PyErr_Occurred()) {
559 PyErr_Format(PyExc_RuntimeError,
"%s read, user has become invalid", Py_TYPE(
self)->tp_name);
571 if (!PyErr_Occurred()) {
572 PyErr_Format(PyExc_RuntimeError,
"%s write, user has become invalid", Py_TYPE(
self)->tp_name);
584 if (!PyErr_Occurred()) {
586 PyExc_RuntimeError,
"%s read index, user has become invalid", Py_TYPE(
self)->tp_name);
598 if (!PyErr_Occurred()) {
600 PyExc_RuntimeError,
"%s write index, user has become invalid", Py_TYPE(
self)->tp_name);
607 PyErr_Format(PyExc_TypeError,
"%s is frozen (immutable)", Py_TYPE(
self)->tp_name);
613 PyExc_TypeError,
"%s is not frozen (mutable), call freeze first", Py_TYPE(
self)->tp_name);
621 PyObject *
ret =
self->cb_user ?
self->cb_user : Py_None;
622 return Py_NewRef(
ret);
626 "True when this object wraps external data (read-only).\n\n:type: bool";
633 "True when this object has been frozen (read-only).\n\n:type: bool";
646 ".. function:: freeze()\n"
648 " Make this object immutable.\n"
650 " After this the object can be hashed, used in dictionaries & sets.\n"
652 " :return: An instance of this object.\n";
656 PyErr_SetString(PyExc_TypeError,
"Cannot freeze wrapped/owned data");
662 return Py_NewRef(
self);
667 Py_VISIT(
self->cb_user);
673 Py_CLEAR(
self->cb_user);
681 PyObject *cb_user =
self->cb_user;
683 bool is_tracked = PyObject_GC_IsTracked((PyObject *)
self);
684 self->cb_user = cb_user;
693 PyMem_Free(
self->data);
698 PyObject_GC_UnTrack(
self);
704 PyObject_GC_UnTrack(
self);
713 return self->cb_user !=
nullptr;
719 if (
ELEM(base_type,
nullptr, root_type)) {
720 obj = _PyObject_GC_New(root_type);
728 obj = base_type->tp_alloc(base_type, 0);
731 PyObject_GC_UnTrack(obj);
741 {
nullptr,
nullptr, 0,
nullptr},
745 PyModuleDef_HEAD_INIT,
759#ifndef MATH_STANDALONE
769 PyObject *sys_modules = PyImport_GetModuleDict();
804 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
810 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
812#ifndef MATH_STANDALONE
815 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
819 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
823 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
A dynamically sized string ADT.
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void normalize_m3(float R[3][3]) ATTR_NONNULL()
void quat_to_mat3(float m[3][3], const float q[4])
float normalize_qt_qt(float r[4], const float q[4])
void eulO_to_mat3(float M[3][3], const float e[3], short order)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
static Mathutils_Callback * mathutils_callbacks[MATHUTILS_TOT_CB]
int _BaseMathObject_CheckCallback(BaseMathObject *self)
static int mathutils_array_parse_fast(float *array, int size, PyObject *value_fast, const char *error_prefix)
int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
bool mathutils_array_parse_alloc_viseq(PyObject *value, const char *error_prefix, blender::Array< blender::Vector< int > > &r_data)
PyMODINIT_FUNC PyInit_mathutils()
int mathutils_array_parse_alloc(float **array, int array_num_min, PyObject *value, const char *error_prefix)
int BaseMathObject_is_gc(BaseMathObject *self)
void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self)
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
void BaseMathObject_dealloc(BaseMathObject *self)
int _BaseMathObject_WriteCallback(BaseMathObject *self)
int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
static bool BaseMathObject_is_tracked(BaseMathObject *self)
int mathutils_array_parse_alloc_vi(int **array, int array_dim, PyObject *value, const char *error_prefix)
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
char BaseMathObject_is_valid_doc[]
static PyModuleDef M_Mathutils_module_def
char BaseMathObject_is_wrapped_doc[]
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")
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *)
char BaseMathObject_is_frozen_doc[]
static PyMethodDef M_Mathutils_methods[]
PyObject * mathutils_dynstr_to_py(DynStr *ds)
PyObject * _BaseMathObject_new_impl(PyTypeObject *root_type, PyTypeObject *base_type)
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *)
PyObject * BaseMathObject_freeze(BaseMathObject *self)
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *)
char BaseMathObject_owner_doc[]
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
char BaseMathObject_freeze_doc[]
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *)
int BaseMathObject_clear(BaseMathObject *self)
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
int _BaseMathObject_ReadCallback(BaseMathObject *self)
void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
#define BaseMath_CheckCallback(_self)
@ BASE_MATH_FLAG_IS_FROZEN
#define BaseMath_ReadCallback(_self)
#define BaseMathObject_CheckExact(v)
#define ColorObject_Check(v)
#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
#define MatrixObject_Check(v)
PyTypeObject quaternion_Type
#define QuaternionObject_Check(v)
#define VectorObject_Check(v)
PyMODINIT_FUNC PyInit_mathutils_bvhtree()
PyMODINIT_FUNC PyInit_mathutils_geometry()
PyMODINIT_FUNC PyInit_mathutils_interpolate()
PyMODINIT_FUNC PyInit_mathutils_kdtree()
PyMODINIT_FUNC PyInit_mathutils_noise()
_W64 unsigned int uintptr_t
BaseMathSetIndexFunc set_index
BaseMathGetIndexFunc get_index
ccl_device_inline int mod(int x, int m)