19#ifndef MATH_STANDALONE
26 "This module provides access to math operations.\n"
30 " Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
31 " such as tuples, lists.\n"
33 "The :mod:`mathutils` module provides the following classes:\n"
37 "- :class:`Matrix`,\n"
38 "- :class:`Quaternion`,\n"
39 "- :class:`Vector`,\n");
43 const char *error_prefix)
46 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
53 if (((
array[
i] = PyFloat_AsDouble(item = value_fast_items[
i])) == -1.0f) && PyErr_Occurred()) {
54 PyErr_Format(PyExc_TypeError,
55 "%.200s: sequence index %d expected a number, "
56 "found '%.200s' type, ",
59 Py_TYPE(item)->tp_name);
76 mult = _PyHASH_MULTIPLIER;
81 y = _Py_HashDouble(
nullptr,
double(
array[
i++]));
90 if (
x == (Py_uhash_t)-1) {
97 float *
array,
int array_num_min,
int array_num_max, PyObject *value,
const char *error_prefix)
118 if (
num > array_num_max ||
num < array_num_min) {
119 if (array_num_max == array_num_min) {
120 PyErr_Format(PyExc_ValueError,
121 "%.200s: sequence length is %d, expected %d",
127 PyErr_Format(PyExc_ValueError,
128 "%.200s: sequence length is %d, expected [%d - %d]",
142 PyObject *value_fast =
nullptr;
145 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
150 num = PySequence_Fast_GET_SIZE(value_fast);
156 if (
num > array_num_max ||
num < array_num_min) {
157 if (array_num_max == array_num_min) {
158 PyErr_Format(PyExc_ValueError,
159 "%.200s: sequence length is %d, expected %d",
165 PyErr_Format(PyExc_ValueError,
166 "%.200s: sequence length is %d, expected [%d - %d]",
182 const int array_num_left = array_num_max -
num;
183 if (array_num_left) {
184 memset(&
array[
num], 0,
sizeof(
float) * array_num_left);
195 const char *error_prefix)
209 if (
num < array_num_min) {
210 PyErr_Format(PyExc_ValueError,
211 "%.200s: sequence size is %d, expected >= %d",
218 *
array =
static_cast<float *
>(PyMem_Malloc(
num *
sizeof(
float)));
225 PyObject *value_fast =
nullptr;
230 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
235 num = PySequence_Fast_GET_SIZE(value_fast);
237 if (
num < array_num_min) {
239 PyErr_Format(PyExc_ValueError,
240 "%.200s: sequence size is %d, expected >= %d",
247 *
array =
static_cast<float *
>(PyMem_Malloc(
num *
sizeof(
float)));
262 const char *error_prefix)
264 PyObject *value_fast;
265 const int array_dim_flag = array_dim;
269 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
274 num = PySequence_Fast_GET_SIZE(value_fast);
277 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
282 fp = *
array =
static_cast<float *
>(PyMem_Malloc(
num * array_dim *
sizeof(
float)));
284 for (
i = 0;
i <
num;
i++, fp += array_dim) {
285 PyObject *item = value_fast_items[
i];
303 PyObject *value_fast, **value_fast_items, *item;
305 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
310 if ((
size = PySequence_Fast_GET_SIZE(value_fast)) != array_dim) {
311 PyErr_Format(PyExc_ValueError,
312 "%.200s: sequence size is %d, expected %d",
320 value_fast_items = PySequence_Fast_ITEMS(value_fast);
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);
338 const char *error_prefix)
340 PyObject *value_fast;
343 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
348 size = PySequence_Fast_GET_SIZE(value_fast);
351 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
354 ip = *
array =
static_cast<int *
>(PyMem_Malloc(
size * array_dim *
sizeof(
int)));
356 for (
i = 0;
i <
size;
i++, ip += array_dim) {
357 PyObject *item = value_fast_items[
i];
373 const char *error_prefix,
376 PyObject *value_fast;
377 if (!(value_fast = PySequence_Fast(value, error_prefix))) {
382 const int size = PySequence_Fast_GET_SIZE(value_fast);
384 PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
385 r_data.reinitialize(
size);
386 for (
const int64_t i : r_data.index_range()) {
387 PyObject *subseq = value_fast_items[
i];
388 const int subseq_len = int(PySequence_Size(subseq));
389 if (subseq_len == -1) {
391 PyExc_ValueError,
"%.200s: sequence expected to have subsequences", error_prefix);
395 r_data[
i].resize(subseq_len);
434 PyExc_ValueError,
"%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
443 PyErr_Format(PyExc_TypeError,
444 "%.200s: expected a Euler, Quaternion or Matrix type, "
447 Py_TYPE(value)->tp_name);
468#define SIGNMASK(i) (-int((uint(i)) >> 31))
474 const int ai = *(
const int *)(&af);
475 const int bi = *(
const int *)(&bf);
479 BLI_assert((0 == test) || (0xFFFFFFFF == test));
480 diff = (ai ^ (test & 0x7fffffff)) - bi;
483 return (v1 |
v2) >= 0;
500#ifndef MATH_STANDALONE
504 char *ds_buf =
static_cast<char *
>(PyMem_Malloc(ds_len + 1));
508 ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
518#define MATHUTILS_TOT_CB 17
557 if (!PyErr_Occurred()) {
558 PyErr_Format(PyExc_RuntimeError,
"%s read, user has become invalid", Py_TYPE(
self)->tp_name);
570 if (!PyErr_Occurred()) {
571 PyErr_Format(PyExc_RuntimeError,
"%s write, user has become invalid", Py_TYPE(
self)->tp_name);
583 if (!PyErr_Occurred()) {
585 PyExc_RuntimeError,
"%s read index, user has become invalid", Py_TYPE(
self)->tp_name);
597 if (!PyErr_Occurred()) {
599 PyExc_RuntimeError,
"%s write index, user has become invalid", Py_TYPE(
self)->tp_name);
606 PyErr_Format(PyExc_TypeError,
"%s is frozen (immutable)", Py_TYPE(
self)->tp_name);
612 PyExc_TypeError,
"%s is not frozen (mutable), call freeze first", Py_TYPE(
self)->tp_name);
618 PyErr_Format(PyExc_ValueError,
"%s: cannot resize frozen data", error_prefix);
622 PyErr_Format(PyExc_ValueError,
"%s: cannot resize wrapped data", error_prefix);
626 PyErr_Format(PyExc_BufferError,
627 "%s: cannot resize data while exported to buffer protocol",
632 PyErr_Format(PyExc_ValueError,
"%s: cannot resize owned data", error_prefix);
641 PyErr_SetString(PyExc_BufferError,
"null view in get-buffer is obsolete");
645 PyErr_SetString(PyExc_BufferError,
646 "Data is already exported via buffer protocol, "
647 "multiple simultaneous exports are not allowed.");
650 if (flags & PyBUF_WRITABLE) {
655 PyErr_SetString(PyExc_BufferError,
"Data is frozen, cannot get a writable buffer");
667 PyObject *
ret =
self->cb_user ?
self->cb_user : Py_None;
668 return Py_NewRef(
ret);
672 "True when this object wraps external data (read-only).\n\n:type: bool";
679 "True when this object has been frozen (read-only).\n\n:type: bool";
692 ".. function:: freeze()\n"
694 " Make this object immutable.\n"
696 " After this the object can be hashed, used in dictionaries & sets.\n"
698 " :return: An instance of this object.\n";
702 PyErr_SetString(PyExc_TypeError,
"Cannot freeze wrapped/owned data");
707 PyErr_SetString(PyExc_BufferError,
"Cannot freeze data while exported to buffer protocol");
713 return Py_NewRef(
self);
718 Py_VISIT(
self->cb_user);
724 Py_CLEAR(
self->cb_user);
732 PyObject *cb_user =
self->cb_user;
733 self->cb_user = (PyObject *)uintptr_t(-1);
734 bool is_tracked = PyObject_GC_IsTracked((PyObject *)
self);
735 self->cb_user = cb_user;
744 PyMem_Free(
self->data);
749 PyObject_GC_UnTrack(
self);
755 PyObject_GC_UnTrack(
self);
764 return self->cb_user !=
nullptr;
770 if (
ELEM(base_type,
nullptr, root_type)) {
771 obj = _PyObject_GC_New(root_type);
779 obj = base_type->tp_alloc(base_type, 0);
782 PyObject_GC_UnTrack(obj);
792 {
nullptr,
nullptr, 0,
nullptr},
810#ifndef MATH_STANDALONE
820 PyObject *sys_modules = PyImport_GetModuleDict();
855 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
861 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
863#ifndef MATH_STANDALONE
866 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
870 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
874 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 size_t num
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
constexpr T * data() const
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
static Mathutils_Callback * mathutils_callbacks[MATHUTILS_TOT_CB]
int _BaseMathObject_CheckCallback(BaseMathObject *self)
int _BaseMathObject_RaiseBufferViewExc(BaseMathObject *self, Py_buffer *view, int flags)
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
int _BaseMathObject_ResizeOkOrRaiseExc(BaseMathObject *self, const char *error_prefix)
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)
#define BaseMath_WriteCallback(_self)
@ BASE_MATH_FLAG_HAS_BUFFER_VIEW
@ 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()
BaseMathSetIndexFunc set_index
BaseMathGetIndexFunc get_index