1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 */ 16 17 #pragma once 18 19 /** \file 20 * \ingroup pymathutils 21 */ 22 23 /* Can cast different mathutils types to this, use for generic funcs */ 24 25 #include "BLI_compiler_attrs.h" 26 27 struct DynStr; 28 29 extern char BaseMathObject_is_wrapped_doc[]; 30 extern char BaseMathObject_is_frozen_doc[]; 31 extern char BaseMathObject_owner_doc[]; 32 33 #define BASE_MATH_NEW(struct_name, root_type, base_type) \ 34 ((struct_name *)((base_type ? (base_type)->tp_alloc(base_type, 0) : \ 35 _PyObject_GC_New(&(root_type))))) 36 37 /** BaseMathObject.flag */ 38 enum { 39 /** 40 * Do not own the memory used in this vector, 41 * \note This is error prone if the memory may be freed while this vector is in use. 42 * Prefer using callbacks where possible, see: #Mathutils_RegisterCallback 43 */ 44 BASE_MATH_FLAG_IS_WRAP = (1 << 0), 45 /** 46 * Prevent changes to the vector so it can be used as a set or dictionary key for example. 47 * (typical use cases for tuple). 48 */ 49 BASE_MATH_FLAG_IS_FROZEN = (1 << 1), 50 }; 51 #define BASE_MATH_FLAG_DEFAULT 0 52 53 #define BASE_MATH_MEMBERS(_data) \ 54 /** Array of data (alias), wrapped status depends on wrapped status. */ \ 55 PyObject_VAR_HEAD float *_data; \ 56 /** If this vector references another object, otherwise NULL, *Note* this owns its reference */ \ 57 PyObject *cb_user; \ 58 /** Which user funcs do we adhere to, RNA, etc */ \ 59 unsigned char cb_type; \ 60 /** Subtype: location, rotation... \ 61 * to avoid defining many new functions for every attribute of the same type */ \ 62 unsigned char cb_subtype; \ 63 /** Wrapped data type. */ \ 64 unsigned char flag 65 66 typedef struct { 67 BASE_MATH_MEMBERS(data); 68 } BaseMathObject; 69 70 /* types */ 71 #include "mathutils_Color.h" 72 #include "mathutils_Euler.h" 73 #include "mathutils_Matrix.h" 74 #include "mathutils_Quaternion.h" 75 #include "mathutils_Vector.h" 76 77 /* avoid checking all types */ 78 #define BaseMathObject_CheckExact(v) (Py_TYPE(v)->tp_dealloc == (destructor)BaseMathObject_dealloc) 79 80 PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *); 81 PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *); 82 PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *); 83 84 extern char BaseMathObject_freeze_doc[]; 85 PyObject *BaseMathObject_freeze(BaseMathObject *self); 86 87 int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg); 88 int BaseMathObject_clear(BaseMathObject *self); 89 void BaseMathObject_dealloc(BaseMathObject *self); 90 91 PyMODINIT_FUNC PyInit_mathutils(void); 92 93 int EXPP_FloatsAreEqual(float A, float B, int maxDiff); 94 int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps); 95 96 typedef struct Mathutils_Callback Mathutils_Callback; 97 98 /** Checks the user is still valid. */ 99 typedef int (*BaseMathCheckFunc)(BaseMathObject *); 100 /** Gets the vector from the user. */ 101 typedef int (*BaseMathGetFunc)(BaseMathObject *, int); 102 /** Sets the users vector values once its modified. */ 103 typedef int (*BaseMathSetFunc)(BaseMathObject *, int); 104 /** Same as above but only for an index. */ 105 typedef int (*BaseMathGetIndexFunc)(BaseMathObject *, int, int); 106 /** Same as above but only for an index. */ 107 typedef int (*BaseMathSetIndexFunc)(BaseMathObject *, int, int); 108 109 struct Mathutils_Callback { 110 BaseMathCheckFunc check; 111 BaseMathGetFunc get; 112 BaseMathSetFunc set; 113 BaseMathGetIndexFunc get_index; 114 BaseMathSetIndexFunc set_index; 115 }; 116 117 unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb); 118 119 int _BaseMathObject_ReadCallback(BaseMathObject *self); 120 int _BaseMathObject_WriteCallback(BaseMathObject *self); 121 int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index); 122 int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index); 123 124 void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self); 125 void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self); 126 127 /* since this is called so often avoid where possible */ 128 #define BaseMath_ReadCallback(_self) \ 129 (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self) : 0)) 130 #define BaseMath_WriteCallback(_self) \ 131 (((_self)->cb_user ? _BaseMathObject_WriteCallback((BaseMathObject *)_self) : 0)) 132 #define BaseMath_ReadIndexCallback(_self, _index) \ 133 (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index) : 0)) 134 #define BaseMath_WriteIndexCallback(_self, _index) \ 135 (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index) : 0)) 136 137 /* support BASE_MATH_FLAG_IS_FROZEN */ 138 #define BaseMath_ReadCallback_ForWrite(_self) \ 139 (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \ 140 (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \ 141 (BaseMath_ReadCallback(_self))) 142 143 #define BaseMath_ReadIndexCallback_ForWrite(_self, _index) \ 144 (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \ 145 (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \ 146 (BaseMath_ReadIndexCallback(_self, _index))) 147 148 #define BaseMath_Prepare_ForWrite(_self) \ 149 (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \ 150 (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : \ 151 0) 152 153 #define BaseMathObject_Prepare_ForHash(_self) \ 154 (UNLIKELY(((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) == 0) ? \ 155 (_BaseMathObject_RaiseNotFrozenExc((BaseMathObject *)_self), -1) : \ 156 0) 157 158 /* utility func */ 159 int mathutils_array_parse( 160 float *array, int array_min, int array_max, PyObject *value, const char *error_prefix); 161 int mathutils_array_parse_alloc(float **array, 162 int array_min, 163 PyObject *value, 164 const char *error_prefix); 165 int mathutils_array_parse_alloc_v(float **array, 166 int array_dim, 167 PyObject *value, 168 const char *error_prefix); 169 int mathutils_int_array_parse(int *array, 170 int array_dim, 171 PyObject *value, 172 const char *error_prefix); 173 int mathutils_array_parse_alloc_vi(int **array, 174 int array_dim, 175 PyObject *value, 176 const char *error_prefix); 177 int mathutils_array_parse_alloc_viseq( 178 int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix); 179 int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix); 180 181 Py_hash_t mathutils_array_hash(const float *float_array, size_t array_len); 182 183 /* zero remaining unused elements of the array */ 184 #define MU_ARRAY_ZERO (1u << 30) 185 /* ignore larger py sequences than requested (just use first elements), 186 * handy when using 3d vectors as 2d */ 187 #define MU_ARRAY_SPILL (1u << 31) 188 189 #define MU_ARRAY_FLAGS (MU_ARRAY_ZERO | MU_ARRAY_SPILL) 190 191 int column_vector_multiplication(float r_vec[4], VectorObject *vec, MatrixObject *mat); 192 193 #ifndef MATH_STANDALONE 194 /* dynstr as python string utility functions */ 195 PyObject *mathutils_dynstr_to_py(struct DynStr *ds); 196 #endif 197