From 8106a6b75d45cc7472fd92f3b045697e30be8c73 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jan 2015 17:03:54 +1100 Subject: mathutils: refactor instantiation remove 'type' argument, very few mathutils objects are wrapped, add new function for creating wrapped objects. also fixes unlikely memory leak if the data-array can't be allocated. --- .../freestyle/intern/python/BPy_Convert.cpp | 6 +- .../freestyle/intern/python/BPy_Freestyle.cpp | 4 +- source/blender/python/bmesh/bmesh_py_ops_call.c | 4 +- source/blender/python/bmesh/bmesh_py_types.c | 18 +-- .../python/bmesh/bmesh_py_types_customdata.c | 2 +- .../blender/python/bmesh/bmesh_py_types_meshdata.c | 4 +- source/blender/python/intern/bpy_rna.c | 18 +-- source/blender/python/mathutils/mathutils.c | 4 +- source/blender/python/mathutils/mathutils.h | 17 ++- source/blender/python/mathutils/mathutils_Color.c | 84 +++++++----- source/blender/python/mathutils/mathutils_Color.h | 15 ++- source/blender/python/mathutils/mathutils_Euler.c | 83 +++++++----- source/blender/python/mathutils/mathutils_Euler.h | 15 ++- source/blender/python/mathutils/mathutils_Matrix.c | 145 ++++++++++++--------- source/blender/python/mathutils/mathutils_Matrix.h | 21 ++- .../python/mathutils/mathutils_Quaternion.c | 97 ++++++++------ .../python/mathutils/mathutils_Quaternion.h | 15 ++- source/blender/python/mathutils/mathutils_Vector.c | 144 +++++++++++--------- source/blender/python/mathutils/mathutils_Vector.h | 22 +++- .../blender/python/mathutils/mathutils_geometry.c | 38 +++--- source/blender/python/mathutils/mathutils_kdtree.c | 2 +- source/blender/python/mathutils/mathutils_noise.c | 12 +- source/gameengine/Converter/BL_ArmatureChannel.cpp | 2 +- source/gameengine/Expressions/PyObjectPlus.cpp | 6 +- source/gameengine/Ketsji/KXNetwork/CMakeLists.txt | 1 + source/gameengine/Ketsji/KXNetwork/SConscript | 1 + source/gameengine/Ketsji/KX_PyMath.cpp | 12 +- source/gameengine/Network/CMakeLists.txt | 1 + source/gameengine/Network/SConscript | 1 + 29 files changed, 481 insertions(+), 313 deletions(-) (limited to 'source') diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp index dbd836bc562..b0b43acb8da 100644 --- a/source/blender/freestyle/intern/python/BPy_Convert.cpp +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -81,7 +81,7 @@ PyObject *Vector_from_Vec2f(Vec2f& vec) float vec_data[2]; // because vec->_coord is protected vec_data[0] = vec.x(); vec_data[1] = vec.y(); - return Vector_CreatePyObject(vec_data, 2, Py_NEW, NULL); + return Vector_CreatePyObject(vec_data, 2, NULL); } PyObject *Vector_from_Vec3f(Vec3f& vec) @@ -90,7 +90,7 @@ PyObject *Vector_from_Vec3f(Vec3f& vec) vec_data[0] = vec.x(); vec_data[1] = vec.y(); vec_data[2] = vec.z(); - return Vector_CreatePyObject(vec_data, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vec_data, 3, NULL); } PyObject *Vector_from_Vec3r(Vec3r& vec) @@ -99,7 +99,7 @@ PyObject *Vector_from_Vec3r(Vec3r& vec) vec_data[0] = vec.x(); vec_data[1] = vec.y(); vec_data[2] = vec.z(); - return Vector_CreatePyObject(vec_data, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vec_data, 3, NULL); } PyObject *BPy_Id_from_Id(Id& id) diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index ee0e7dfab3e..f4ead300d5e 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -153,7 +153,7 @@ static PyObject *Freestyle_blendRamp(PyObject *self, PyObject *args) return NULL; } ramp_blend(type, a, fac, b); - return Vector_CreatePyObject(a, 3, Py_NEW, NULL); + return Vector_CreatePyObject(a, 3, NULL); } #include "BKE_texture.h" /* do_colorband() */ @@ -187,7 +187,7 @@ static PyObject *Freestyle_evaluateColorRamp(PyObject *self, PyObject *args) PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp"); return NULL; } - return Vector_CreatePyObject(out, 4, Py_NEW, NULL); + return Vector_CreatePyObject(out, 4, NULL); } #include "DNA_color_types.h" diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index ec6810fe49a..e8ef4c58895 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -540,10 +540,10 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot)); break; case BMO_OP_SLOT_MAT: - item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL); + item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, NULL); break; case BMO_OP_SLOT_VEC: - item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL); + item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, NULL); break; case BMO_OP_SLOT_PTR: BLI_assert(0); /* currently we don't have any pointer return values in use */ diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 8c13a66bea0..d3f4bfcacda 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -342,7 +342,7 @@ PyDoc_STRVAR(bpy_bmvert_co_doc, static PyObject *bpy_bmvert_co_get(BPy_BMVert *self) { BPY_BM_CHECK_OBJ(self); - return Vector_CreatePyObject(self->v->co, 3, Py_WRAP, NULL); + return Vector_CreatePyObject_wrap(self->v->co, 3, NULL); } static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value) @@ -364,7 +364,7 @@ PyDoc_STRVAR(bpy_bmvert_normal_doc, static PyObject *bpy_bmvert_normal_get(BPy_BMVert *self) { BPY_BM_CHECK_OBJ(self); - return Vector_CreatePyObject(self->v->no, 3, Py_WRAP, NULL); + return Vector_CreatePyObject_wrap(self->v->no, 3, NULL); } static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value) @@ -468,7 +468,7 @@ PyDoc_STRVAR(bpy_bmface_normal_doc, static PyObject *bpy_bmface_normal_get(BPy_BMFace *self) { BPY_BM_CHECK_OBJ(self); - return Vector_CreatePyObject(self->f->no, 3, Py_WRAP, NULL); + return Vector_CreatePyObject_wrap(self->f->no, 3, NULL); } static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value) @@ -1530,7 +1530,7 @@ static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args) BPY_BM_CHECK_OBJ(py_loop); /* no need to check if they are from the same mesh or even connected */ BM_edge_calc_face_tangent(self->e, py_loop->l, vec); - return Vector_CreatePyObject(vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vec, 3, NULL); } } @@ -1711,7 +1711,7 @@ static PyObject *bpy_bmface_calc_center_mean(BPy_BMFace *self) BPY_BM_CHECK_OBJ(self); BM_face_calc_center_mean(self->f, cent); - return Vector_CreatePyObject(cent, 3, Py_NEW, NULL); + return Vector_CreatePyObject(cent, 3, NULL); } PyDoc_STRVAR(bpy_bmface_calc_center_mean_weighted_doc, @@ -1728,7 +1728,7 @@ static PyObject *bpy_bmface_calc_center_mean_weighted(BPy_BMFace *self) BPY_BM_CHECK_OBJ(self); BM_face_calc_center_mean_weighted(self->f, cent); - return Vector_CreatePyObject(cent, 3, Py_NEW, NULL); + return Vector_CreatePyObject(cent, 3, NULL); } PyDoc_STRVAR(bpy_bmface_calc_center_bounds_doc, @@ -1745,7 +1745,7 @@ static PyObject *bpy_bmface_calc_center_bounds(BPy_BMFace *self) BPY_BM_CHECK_OBJ(self); BM_face_calc_center_bounds(self->f, cent); - return Vector_CreatePyObject(cent, 3, Py_NEW, NULL); + return Vector_CreatePyObject(cent, 3, NULL); } @@ -1849,7 +1849,7 @@ static PyObject *bpy_bmloop_calc_normal(BPy_BMLoop *self) float vec[3]; BPY_BM_CHECK_OBJ(self); BM_loop_calc_face_normal(self->l, vec); - return Vector_CreatePyObject(vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vec, 3, NULL); } PyDoc_STRVAR(bpy_bmloop_calc_tangent_doc, @@ -1866,7 +1866,7 @@ static PyObject *bpy_bmloop_calc_tangent(BPy_BMLoop *self) float vec[3]; BPY_BM_CHECK_OBJ(self); BM_loop_calc_face_tangent(self->l, vec); - return Vector_CreatePyObject(vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vec, 3, NULL); } /* Vert Seq diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 6ecb01a8528..3c1502dc72b 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -1014,7 +1014,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) } case CD_SHAPEKEY: { - ret = Vector_CreatePyObject((float *)value, 3, Py_WRAP, NULL); + ret = Vector_CreatePyObject_wrap((float *)value, 3, NULL); break; } case CD_BWEIGHT: diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index 4fa5d0f755c..df0c39fd3b3 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -150,7 +150,7 @@ PyDoc_STRVAR(bpy_bmloopuv_uv_doc, ); static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure)) { - return Vector_CreatePyObject(self->data->uv, 2, Py_WRAP, NULL); + return Vector_CreatePyObject_wrap(self->data->uv, 2, NULL); } static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure)) @@ -263,7 +263,7 @@ PyDoc_STRVAR(bpy_bmvertskin_radius_doc, ); static PyObject *bpy_bmvertskin_radius_get(BPy_BMVertSkin *self, void *UNUSED(closure)) { - return Vector_CreatePyObject(self->data->radius, 2, Py_WRAP, NULL); + return Vector_CreatePyObject_wrap(self->data->radius, 2, NULL); } static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void *UNUSED(closure)) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index b06907b6208..be316a8b702 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -637,7 +637,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) case PROP_ALL_VECTOR_SUBTYPES: if (len >= 2 && len <= 4) { if (is_thick) { - ret = Vector_CreatePyObject(NULL, len, Py_NEW, NULL); + ret = Vector_CreatePyObject(NULL, len, NULL); RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec); } else { @@ -650,7 +650,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) case PROP_MATRIX: if (len == 16) { if (is_thick) { - ret = Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL); + ret = Matrix_CreatePyObject(NULL, 4, 4, NULL); RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { @@ -661,7 +661,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) } else if (len == 9) { if (is_thick) { - ret = Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL); + ret = Matrix_CreatePyObject(NULL, 3, 3, NULL); RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { @@ -679,7 +679,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) PropertyRNA *prop_eul_order = NULL; short order = pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ); - ret = Euler_CreatePyObject(NULL, order, Py_NEW, NULL); /* TODO, get order from RNA */ + ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA */ RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); } else { @@ -691,7 +691,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) } else if (len == 4) { if (is_thick) { - ret = Quaternion_CreatePyObject(NULL, Py_NEW, NULL); + ret = Quaternion_CreatePyObject(NULL, NULL); RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat); } else { @@ -705,7 +705,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) case PROP_COLOR_GAMMA: if (len == 3) { /* color */ if (is_thick) { - ret = Color_CreatePyObject(NULL, Py_NEW, NULL); + ret = Color_CreatePyObject(NULL, NULL); RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); } else { @@ -4851,15 +4851,15 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat switch (RNA_property_subtype(prop)) { #ifdef USE_MATHUTILS case PROP_ALL_VECTOR_SUBTYPES: - ret = Vector_CreatePyObject(data, len, Py_NEW, NULL); + ret = Vector_CreatePyObject(data, len, NULL); break; case PROP_MATRIX: if (len == 16) { - ret = Matrix_CreatePyObject(data, 4, 4, Py_NEW, NULL); + ret = Matrix_CreatePyObject(data, 4, 4, NULL); break; } else if (len == 9) { - ret = Matrix_CreatePyObject(data, 3, 3, Py_NEW, NULL); + ret = Matrix_CreatePyObject(data, 3, 3, NULL); break; } /* fall-through */ diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 8aaf47f090f..0a550105124 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -451,7 +451,7 @@ PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure)) 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->wrapped == Py_WRAP) ? 1 : 0); + return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0); } int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg) @@ -469,7 +469,7 @@ int BaseMathObject_clear(BaseMathObject *self) void BaseMathObject_dealloc(BaseMathObject *self) { /* only free non wrapped */ - if (self->wrapped != Py_WRAP) { + if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) { PyMem_Free(self->data); } diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h index be2b45d349f..296b8cf9559 100644 --- a/source/blender/python/mathutils/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -29,11 +29,23 @@ /* Can cast different mathutils types to this, use for generic funcs */ +#include "BLI_compiler_attrs.h" + struct DynStr; extern char BaseMathObject_is_wrapped_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)))); + + +/* BaseMathObject.flag */ +enum { + BASE_MATH_FLAG_IS_WRAP = (1 << 0), +}; +#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 */ \ @@ -42,7 +54,7 @@ extern char BaseMathObject_owner_doc[]; unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ \ unsigned char cb_subtype; /* subtype: location, rotation... \ * to avoid defining many new functions for every attribute of the same type */ \ - unsigned char wrapped /* wrapped data type? */ \ + unsigned char flag /* wrapped data type? */ \ typedef struct { BASE_MATH_MEMBERS(data); @@ -67,9 +79,6 @@ PyMODINIT_FUNC PyInit_mathutils(void); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps); -#define Py_NEW 1 -#define Py_WRAP 2 - typedef struct Mathutils_Callback Mathutils_Callback; typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */ diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index aee2b9e9711..5bc6f6177de 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -64,7 +64,7 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "more than a single arg given"); return NULL; } - return Color_CreatePyObject(col, Py_NEW, type); + return Color_CreatePyObject(col, type); } /* -----------------------------METHODS---------------------------- */ @@ -107,7 +107,7 @@ static PyObject *Color_copy(ColorObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Color_CreatePyObject(self->col, Py_NEW, Py_TYPE(self)); + return Color_CreatePyObject(self->col, Py_TYPE(self)); } static PyObject *Color_deepcopy(ColorObject *self, PyObject *args) { @@ -411,7 +411,7 @@ static PyObject *Color_add(PyObject *v1, PyObject *v2) add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); - return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1)); + return Color_CreatePyObject(col, Py_TYPE(v1)); } /* addition in-place: obj += obj */ @@ -460,7 +460,7 @@ static PyObject *Color_sub(PyObject *v1, PyObject *v2) sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); - return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1)); + return Color_CreatePyObject(col, Py_TYPE(v1)); } /* subtraction in-place: obj -= obj */ @@ -492,7 +492,7 @@ 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_NEW, Py_TYPE(color)); + return Color_CreatePyObject(tcol, Py_TYPE(color)); } @@ -639,7 +639,7 @@ static PyObject *Color_neg(ColorObject *self) return NULL; negate_vn_vn(tcol, self->col, COLOR_SIZE); - return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(self)); + return Color_CreatePyObject(tcol, Py_TYPE(self)); } @@ -862,40 +862,60 @@ PyTypeObject color_Type = { NULL, /* tp_weaklist */ NULL /* tp_del */ }; -/* ------------------------Color_CreatePyObject (internal)------------- */ -/* creates a new color object */ -/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - * (i.e. it was allocated elsewhere by MEM_mallocN()) - * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type) + +PyObject *Color_CreatePyObject( + const float col[3], + PyTypeObject *base_type) { ColorObject *self; + float *col_alloc; - self = base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) : - (ColorObject *)PyObject_GC_New(ColorObject, &color_Type); + 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; - if (type == Py_WRAP) { - self->col = col; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW) { - self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float)); - if (col) - copy_v3_v3(self->col, col); - else - zero_v3(self->col); - - self->wrapped = Py_NEW; - } - else { - Py_FatalError("Color(): invalid type!"); - } + /* 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) +{ + 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; + + /* WRAP */ + self->col = col; + self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP; } return (PyObject *)self; @@ -904,7 +924,7 @@ PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type) PyObject *Color_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype) { - ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL); + ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index 193d30a2b6f..1290f73da62 100644 --- a/source/blender/python/mathutils/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -42,8 +42,17 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both*/ /* prototypes */ -PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type); -PyObject *Color_CreatePyObject_cb(PyObject *cb_user, - unsigned char cb_type, unsigned char cb_subtype); +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 1c49774cd0f..1c45d5e88ac 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -70,7 +70,7 @@ static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; break; } - return Euler_CreatePyObject(eul, order, Py_NEW, type); + return Euler_CreatePyObject(eul, order, type); } /* internal use, assume read callback is done */ @@ -150,7 +150,7 @@ static PyObject *Euler_to_quaternion(EulerObject *self) eulO_to_quat(quat, self->eul, self->order); - return Quaternion_CreatePyObject(quat, Py_NEW, NULL); + return Quaternion_CreatePyObject(quat, NULL); } /* return a matrix representation of the euler */ @@ -171,7 +171,7 @@ static PyObject *Euler_to_matrix(EulerObject *self) eulO_to_mat3((float (*)[3])mat, self->eul, self->order); - return Matrix_CreatePyObject(mat, 3, 3, Py_NEW, NULL); + return Matrix_CreatePyObject(mat, 3, 3, NULL); } PyDoc_STRVAR(Euler_zero_doc, @@ -304,7 +304,7 @@ static PyObject *Euler_copy(EulerObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Euler_CreatePyObject(self->eul, self->order, Py_NEW, Py_TYPE(self)); + return Euler_CreatePyObject(self->eul, self->order, Py_TYPE(self)); } static PyObject *Euler_deepcopy(EulerObject *self, PyObject *args) { @@ -710,53 +710,74 @@ PyTypeObject euler_Type = { NULL, /* tp_weaklist */ NULL /* tp_del */ }; -/* ------------------------Euler_CreatePyObject (internal)------------- */ -/* creates a new euler object */ -/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - * (i.e. it was allocated elsewhere by MEM_mallocN()) - * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type) + + +PyObject *Euler_CreatePyObject( + const float eul[3], const short order, + PyTypeObject *base_type) { EulerObject *self; + float *eul_alloc; - self = base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) : - (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type); + 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 (type == Py_WRAP) { - self->eul = eul; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW) { - self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float)); - if (eul) { - copy_v3_v3(self->eul, eul); - } - else { - zero_v3(self->eul); - } - - self->wrapped = Py_NEW; + if (eul) { + copy_v3_v3(self->eul, eul); } else { - Py_FatalError("Euler(): invalid type!"); + 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) +{ + 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->eul = eul; + self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP; + self->order = order; } 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, Py_NEW, NULL); + EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h index 62fb83ef234..744f39faed1 100644 --- a/source/blender/python/mathutils/mathutils_Euler.h +++ b/source/blender/python/mathutils/mathutils_Euler.h @@ -43,9 +43,18 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both */ /* prototypes */ -PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type); -PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, const short order, - unsigned char cb_type, unsigned char cb_subtype); +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); diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 23e83050c88..5be4fdedff1 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -344,7 +344,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) switch (PyTuple_GET_SIZE(args)) { case 0: - return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type); + return Matrix_CreatePyObject(NULL, 4, 4, type); case 1: { PyObject *arg = PyTuple_GET_ITEM(args, 0); @@ -363,7 +363,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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, Py_NEW, type); + PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type); if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { return matrix; } @@ -444,7 +444,7 @@ static PyObject *C_Matrix_Identity(PyObject *cls, PyObject *args) return NULL; } - return Matrix_CreatePyObject(NULL, matSize, matSize, Py_NEW, (PyTypeObject *)cls); + return Matrix_CreatePyObject(NULL, matSize, matSize, (PyTypeObject *)cls); } PyDoc_STRVAR(C_Matrix_Rotation_doc, @@ -535,7 +535,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) matrix_3x3_as_4x4(mat); } /* pass to matrix creation */ - return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); + return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls); } @@ -558,7 +558,7 @@ static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value) 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, Py_NEW, (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. */ @@ -650,7 +650,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) matrix_3x3_as_4x4(mat); } /* pass to matrix creation */ - return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); + 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. */ @@ -771,7 +771,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) matrix_3x3_as_4x4(mat); } /* pass to matrix creation */ - return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); + return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls); } PyDoc_STRVAR(C_Matrix_Shear_doc, @@ -874,7 +874,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args) matrix_3x3_as_4x4(mat); } /* pass to matrix creation */ - return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls); + return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls); } void matrix_as_3x3(float mat[3][3], MatrixObject *self) @@ -1078,7 +1078,7 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self) mat4_to_quat(quat, (float (*)[4])self->matrix); } - return Quaternion_CreatePyObject(quat, Py_NEW, NULL); + return Quaternion_CreatePyObject(quat, NULL); } /*---------------------------matrix.toEuler() --------------------*/ @@ -1152,7 +1152,7 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args) else mat3_to_eulO(eul, order, mat); } - return Euler_CreatePyObject(eul, order, Py_NEW, NULL); + return Euler_CreatePyObject(eul, order, NULL); } PyDoc_STRVAR(Matrix_resize_4x4_doc, @@ -1165,7 +1165,7 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) float mat[4][4]; int col; - if (self->wrapped == Py_WRAP) { + 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"); @@ -1214,12 +1214,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self) return NULL; if (self->num_row == 4 && self->num_col == 4) { - return Matrix_CreatePyObject(self->matrix, 4, 4, Py_NEW, Py_TYPE(self)); + 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_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject((float *)mat, 4, 4, Py_TYPE(self)); } /* TODO, 2x2 matrix */ @@ -1252,7 +1252,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self) matrix_as_3x3(mat, self); - return Matrix_CreatePyObject((float *)mat, 3, 3, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject((float *)mat, 3, 3, Py_TYPE(self)); } PyDoc_STRVAR(Matrix_to_translation_doc, @@ -1275,7 +1275,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self) return NULL; } - return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, Py_NEW, NULL); + return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, NULL); } PyDoc_STRVAR(Matrix_to_scale_doc, @@ -1310,7 +1310,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) /* compatible mat4_to_loc_rot_size */ mat3_to_rot_size(rot, size, mat); - return Vector_CreatePyObject(size, 3, Py_NEW, NULL); + return Vector_CreatePyObject(size, 3, NULL); } /*---------------------------matrix.invert() ---------------------*/ @@ -1653,9 +1653,9 @@ static PyObject *Matrix_decompose(MatrixObject *self) mat3_to_quat(quat, rot); ret = PyTuple_New(3); - PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(loc, 3, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 1, Quaternion_CreatePyObject(quat, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 2, Vector_CreatePyObject(size, 3, Py_NEW, NULL)); + PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(loc, 3, NULL)); + PyTuple_SET_ITEM(ret, 1, Quaternion_CreatePyObject(quat, NULL)); + PyTuple_SET_ITEM(ret, 2, Vector_CreatePyObject(size, 3, NULL)); return ret; } @@ -1706,7 +1706,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) return NULL; } - return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self)); } /*---------------------------matrix.determinant() ----------------*/ @@ -1898,7 +1898,7 @@ static PyObject *Matrix_identity(MatrixObject *self) static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix) { - return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_TYPE(self)); } PyDoc_STRVAR(Matrix_copy_doc, @@ -2240,7 +2240,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2) 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_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); } /*------------------------obj - obj------------------------------ * subtraction */ @@ -2272,7 +2272,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) 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_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); } /*------------------------obj * obj------------------------------ * multiplication */ @@ -2280,7 +2280,7 @@ 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_NEW, Py_TYPE(mat)); + return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat)); } static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) @@ -2324,7 +2324,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) } } - return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); } else if (mat2) { /*FLOAT/INT * MATRIX */ @@ -2350,7 +2350,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) vec_size = mat1->num_row; } - return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(m2)); + return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2)); } /*FLOAT/INT * MATRIX */ else if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) { @@ -2769,15 +2769,13 @@ PyTypeObject matrix_Type = { NULL /*tp_del*/ }; -/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - * (i.e. it was allocated elsewhere by MEM_mallocN()) - * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - * (i.e. it must be created here with PyMEM_malloc()) */ -PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short num_col, const unsigned short num_row, - int type, PyTypeObject *base_type) +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) { @@ -2787,10 +2785,17 @@ PyObject *Matrix_CreatePyObject(float *mat, return NULL; } - self = base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : - (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); + 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; @@ -2798,36 +2803,52 @@ PyObject *Matrix_CreatePyObject(float *mat, self->cb_user = NULL; self->cb_type = self->cb_subtype = 0; - if (type == Py_WRAP) { - self->matrix = mat; - self->wrapped = Py_WRAP; + if (mat) { /*if a float array passed*/ + memcpy(self->matrix, mat, num_col * num_row * sizeof(float)); } - else if (type == Py_NEW) { - self->matrix = PyMem_Malloc(num_col * num_row * sizeof(float)); - if (self->matrix == NULL) { /*allocation failure*/ - PyErr_SetString(PyExc_MemoryError, - "Matrix(): " - "problem allocating pointer space"); - return NULL; - } - - 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->wrapped = Py_NEW; + else if (num_col == num_row) { + /* or if no arguments are passed return identity matrix for square matrices */ + matrix_identity_internal(self); } else { - Py_FatalError("Matrix(): invalid type!"); - return NULL; + /* 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; } @@ -2836,7 +2857,7 @@ 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, Py_NEW, NULL); + MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index f94af9e540e..9ae5a4bd61d 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -61,12 +61,21 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both */ /* prototypes */ -PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short num_col, const unsigned short num_row, - int type, PyTypeObject *base_type); -PyObject *Matrix_CreatePyObject_cb(PyObject *user, - const unsigned short num_col, const unsigned short num_row, - unsigned char cb_type, unsigned char cb_subtype); +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; extern unsigned char mathutils_matrix_row_cb_index; /* default */ extern unsigned char mathutils_matrix_col_cb_index; diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 615ffb909dc..7e15a3fc604 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -121,7 +121,7 @@ static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args) else quat_to_eulO(eul, order, tquat); } - return Euler_CreatePyObject(eul, order, Py_NEW, NULL); + return Euler_CreatePyObject(eul, order, NULL); } PyDoc_STRVAR(Quaternion_to_matrix_doc, @@ -140,7 +140,7 @@ static PyObject *Quaternion_to_matrix(QuaternionObject *self) return NULL; quat_to_mat3((float (*)[3])mat, self->quat); - return Matrix_CreatePyObject(mat, 3, 3, Py_NEW, NULL); + return Matrix_CreatePyObject(mat, 3, 3, NULL); } PyDoc_STRVAR(Quaternion_to_axis_angle_doc, @@ -169,7 +169,7 @@ static PyObject *Quaternion_to_axis_angle(QuaternionObject *self) quat__axis_angle_sanitize(axis, &angle); ret = PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(axis, 3, Py_NEW, NULL)); + PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(axis, 3, NULL)); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(angle)); return ret; } @@ -198,7 +198,7 @@ static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value) } mul_qt_qtqt(quat, self->quat, tquat); - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); + return Quaternion_CreatePyObject(quat, Py_TYPE(self)); } PyDoc_STRVAR(Quaternion_dot_doc, @@ -252,7 +252,7 @@ static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject rotation_between_quats_to_quat(quat, self->quat, tquat); - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); + return Quaternion_CreatePyObject(quat, Py_TYPE(self)); } PyDoc_STRVAR(Quaternion_slerp_doc, @@ -297,7 +297,7 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args) interp_qt_qtqt(quat, self->quat, tquat, fac); - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self)); + return Quaternion_CreatePyObject(quat, Py_TYPE(self)); } PyDoc_STRVAR(Quaternion_rotate_doc, @@ -468,7 +468,7 @@ static PyObject *Quaternion_copy(QuaternionObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Quaternion_CreatePyObject(self->quat, Py_NEW, Py_TYPE(self)); + return Quaternion_CreatePyObject(self->quat, Py_TYPE(self)); } static PyObject *Quaternion_deepcopy(QuaternionObject *self, PyObject *args) { @@ -748,7 +748,7 @@ static PyObject *Quaternion_add(PyObject *q1, PyObject *q2) return NULL; add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f); - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); + return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); } /* ------------------------obj - obj------------------------------ */ /* subtraction */ @@ -776,7 +776,7 @@ static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2) quat[x] = quat1->quat[x] - quat2->quat[x]; } - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); + return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); } static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar) @@ -784,7 +784,7 @@ 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_NEW, Py_TYPE(quat)); + return Quaternion_CreatePyObject(tquat, Py_TYPE(quat)); } /*------------------------obj * obj------------------------------ @@ -807,7 +807,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) if (quat1 && quat2) { /* QUAT * QUAT (cross product) */ mul_qt_qtqt(quat, quat1->quat, quat2->quat); - return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1)); + return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); } /* the only case this can happen (for a supported type is "FLOAT * QUAT") */ else if (quat2) { /* FLOAT * QUAT */ @@ -835,7 +835,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) copy_v3_v3(tvec, vec2->vec); mul_qt_v3(quat1->quat, tvec); - return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2)); + return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec2)); } /* QUAT * FLOAT */ else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { @@ -863,7 +863,7 @@ static PyObject *Quaternion_neg(QuaternionObject *self) return NULL; negate_v4_v4(tquat, self->quat); - return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(self)); + return Quaternion_CreatePyObject(tquat, Py_TYPE(self)); } @@ -1021,7 +1021,7 @@ static PyObject *Quaternion_axis_vector_get(QuaternionObject *self, void *UNUSED quat__axis_angle_sanitize(axis, NULL); - return Vector_CreatePyObject(axis, 3, Py_NEW, NULL); + return Vector_CreatePyObject(axis, 3, NULL); } static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) @@ -1087,7 +1087,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw /* PyArg_ParseTuple assures no more than 2 */ } } - return Quaternion_CreatePyObject(quat, Py_NEW, type); + return Quaternion_CreatePyObject(quat, type); } static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self) @@ -1238,41 +1238,60 @@ PyTypeObject quaternion_Type = { NULL, /* tp_weaklist */ NULL, /* tp_del */ }; -/* ------------------------Quaternion_CreatePyObject (internal)------------- */ -/* creates a new quaternion object */ -/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - * (i.e. it was allocated elsewhere by MEM_mallocN()) - * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type) + +PyObject *Quaternion_CreatePyObject( + const float quat[4], + PyTypeObject *base_type) { QuaternionObject *self; + float *quat_alloc; - self = base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) : - (QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type); + 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; - if (type == Py_WRAP) { - self->quat = quat; - self->wrapped = Py_WRAP; - } - else if (type == Py_NEW) { - self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float)); - if (!quat) { /* new empty */ - unit_qt(self->quat); - } - else { - copy_qt_qt(self->quat, quat); - } - self->wrapped = Py_NEW; + /* NEW */ + if (!quat) { /* new empty */ + unit_qt(self->quat); } else { - Py_FatalError("Quaternion(): invalid type!"); + 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) +{ + 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; } @@ -1280,7 +1299,7 @@ PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_ PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype) { - QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL); + QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h index 36036c6d3fa..66ee3362906 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.h +++ b/source/blender/python/mathutils/mathutils_Quaternion.h @@ -40,8 +40,17 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both */ /* prototypes */ -PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type); -PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user, - unsigned char cb_type, unsigned char cb_subtype); +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 15a9860be0a..167fb5bcf3d 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -387,7 +387,7 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value) { int size; - if (self->wrapped == Py_WRAP) { + if (self->flag & BASE_MATH_FLAG_IS_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize(): " "cannot resize wrapped data - only python vectors"); @@ -475,7 +475,7 @@ PyDoc_STRVAR(Vector_resize_2d_doc, ); static PyObject *Vector_resize_2d(VectorObject *self) { - if (self->wrapped == Py_WRAP) { + if (self->flag & BASE_MATH_FLAG_IS_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_2d(): " "cannot resize wrapped data - only python vectors"); @@ -507,7 +507,7 @@ PyDoc_STRVAR(Vector_resize_3d_doc, ); static PyObject *Vector_resize_3d(VectorObject *self) { - if (self->wrapped == Py_WRAP) { + if (self->flag & BASE_MATH_FLAG_IS_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_3d(): " "cannot resize wrapped data - only python vectors"); @@ -542,7 +542,7 @@ PyDoc_STRVAR(Vector_resize_4d_doc, ); static PyObject *Vector_resize_4d(VectorObject *self) { - if (self->wrapped == Py_WRAP) { + if (self->flag & BASE_MATH_FLAG_IS_WRAP) { PyErr_SetString(PyExc_TypeError, "Vector.resize_4d(): " "cannot resize wrapped data - only python vectors"); @@ -586,7 +586,7 @@ static PyObject *Vector_to_2d(VectorObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Vector_CreatePyObject(self->vec, 2, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(self->vec, 2, Py_TYPE(self)); } PyDoc_STRVAR(Vector_to_3d_doc, ".. method:: to_3d()\n" @@ -604,7 +604,7 @@ static PyObject *Vector_to_3d(VectorObject *self) return NULL; memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3)); - return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(tvec, 3, Py_TYPE(self)); } PyDoc_STRVAR(Vector_to_4d_doc, ".. method:: to_4d()\n" @@ -622,7 +622,7 @@ static PyObject *Vector_to_4d(VectorObject *self) return NULL; memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4)); - return Vector_CreatePyObject(tvec, 4, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(tvec, 4, Py_TYPE(self)); } PyDoc_STRVAR(Vector_to_tuple_doc, @@ -797,7 +797,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args) vec_to_quat(quat, vec, track, up); - return Quaternion_CreatePyObject(quat, Py_NEW, NULL); + return Quaternion_CreatePyObject(quat, NULL); } PyDoc_STRVAR(Vector_orthogonal_doc, @@ -829,7 +829,7 @@ static PyObject *Vector_orthogonal(VectorObject *self) else ortho_v2_v2(vec, self->vec); - return Vector_CreatePyObject(vec, self->size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(vec, self->size, Py_TYPE(self)); } @@ -877,7 +877,7 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value) normalize_v3(mirror); reflect_v3_v3v3(reflect, vec, mirror); - return Vector_CreatePyObject(reflect, self->size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self)); } PyDoc_STRVAR(Vector_cross_doc, @@ -910,7 +910,7 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value) return NULL; if (self->size == 3) { - ret = Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self)); + ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self)); cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec); } else { @@ -1102,7 +1102,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value) rotation_between_vecs_to_quat(quat, vec_a, vec_b); - return Quaternion_CreatePyObject(quat, Py_NEW, NULL); + return Quaternion_CreatePyObject(quat, NULL); } PyDoc_STRVAR(Vector_project_doc, @@ -1148,7 +1148,7 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value) for (x = 0; x < size; x++) { vec[x] = (float)dot * tvec[x]; } - return Vector_CreatePyObject(vec, size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(vec, size, Py_TYPE(self)); } PyDoc_STRVAR(Vector_lerp_doc, @@ -1287,7 +1287,7 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args) ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]); } - return Vector_CreatePyObject(ret_vec, size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self)); } PyDoc_STRVAR(Vector_rotate_doc, @@ -1336,7 +1336,7 @@ static PyObject *Vector_copy(VectorObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Vector_CreatePyObject(self->vec, self->size, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self)); } static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args) { @@ -1540,8 +1540,7 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2) } vec = PyMem_Malloc(vec1->size * sizeof(float)); - - if (vec == NULL) { /*allocation failure*/ + if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, "Vector(): " "problem allocating pointer space"); @@ -1612,8 +1611,7 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2) } vec = PyMem_Malloc(vec1->size * sizeof(float)); - - if (vec == NULL) { /*allocation failure*/ + if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, "Vector(): " "problem allocating pointer space"); @@ -1705,8 +1703,7 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, static PyObject *vector_mul_float(VectorObject *vec, const float scalar) { float *tvec = PyMem_Malloc(vec->size * sizeof(float)); - - if (tvec == NULL) { /*allocation failure*/ + if (tvec == NULL) { PyErr_SetString(PyExc_MemoryError, "vec * float: " "problem allocating pointer space"); @@ -1765,7 +1762,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) vec_size = ((MatrixObject *)v2)->num_col; } - return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(vec1)); + return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1)); } else if (QuaternionObject_Check(v2)) { /* VEC * QUAT */ @@ -1791,7 +1788,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) copy_v3_v3(tvec, vec1->vec); mul_qt_v3(quat2->quat, tvec); - return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec1)); + return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec1)); #endif /* ------ to be removed ------*/ } @@ -1923,7 +1920,7 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2) vec = PyMem_Malloc(vec1->size * sizeof(float)); - if (vec == NULL) { /*allocation failure*/ + if (vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vec / value: " "problem allocating pointer space"); @@ -2308,7 +2305,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure) axis_to++; } - return Vector_CreatePyObject(vec, axis_to, Py_NEW, Py_TYPE(self)); + return Vector_CreatePyObject(vec, axis_to, Py_TYPE(self)); } /* Set the items of this vector using a swizzle. @@ -2994,15 +2991,12 @@ PyTypeObject vector_Type = { NULL }; -/*------------------------Vector_CreatePyObject (internal)------------- - * creates a new vector object - * pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER - * (i.e. it was allocated elsewhere by MEM_mallocN()) - * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON - * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type) +PyObject *Vector_CreatePyObject( + const float *vec, const int size, + PyTypeObject *base_type) { VectorObject *self; + float *vec_alloc; if (size < 2) { PyErr_SetString(PyExc_RuntimeError, @@ -3010,44 +3004,72 @@ PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTy return NULL; } - self = base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) : - (VectorObject *)PyObject_GC_New(VectorObject, &vector_Type); + 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 (type == Py_WRAP) { - self->vec = vec; - self->wrapped = Py_WRAP; + if (vec) { + memcpy(self->vec, vec, size * sizeof(float)); } - else if (type == Py_NEW) { - self->vec = PyMem_Malloc(size * sizeof(float)); - if (vec) { - memcpy(self->vec, vec, size * sizeof(float)); + else { /* new empty */ + fill_vn_fl(self->vec, size, 0.0f); + if (size == 4) { /* do the homogeneous thing */ + self->vec[3] = 1.0f; } - else { /* new empty */ - fill_vn_fl(self->vec, size, 0.0f); - if (size == 4) { /* do the homogeneous thing */ - self->vec[3] = 1.0f; - } - } - self->wrapped = Py_NEW; - } - else { - Py_FatalError("Vector(): invalid type!"); } + self->flag = BASE_MATH_FLAG_DEFAULT; + } + else { + PyMem_Free(vec_alloc); + } + + return (PyObject *)self; +} + +PyObject *Vector_CreatePyObject_wrap( + float *vec, const int size, + PyTypeObject *base_type) +{ + VectorObject *self; + + 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; + + /* 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; } -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) { - float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ - VectorObject *self = (VectorObject *)Vector_CreatePyObject(dummy, size, Py_NEW, NULL); + VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL); if (self) { Py_INCREF(cb_user); self->cb_user = cb_user; @@ -3059,11 +3081,15 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, unsigned char cb return (PyObject *)self; } -PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type) +PyObject *Vector_CreatePyObject_alloc( + float *vec, const int size, + PyTypeObject *base_type) { - VectorObject *vect_ob; - vect_ob = (VectorObject *)Vector_CreatePyObject((float *)vec, size, Py_WRAP, base_type); - vect_ob->wrapped = Py_NEW; + VectorObject *self; + self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type); + if (self) { + self->flag = BASE_MATH_FLAG_DEFAULT; + } - return (PyObject *)vect_ob; + return (PyObject *)self; } diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h index 2074270670a..74ca3336f4b 100644 --- a/source/blender/python/mathutils/mathutils_Vector.h +++ b/source/blender/python/mathutils/mathutils_Vector.h @@ -34,13 +34,25 @@ extern PyTypeObject vector_Type; typedef struct { BASE_MATH_MEMBERS(vec); - int size; /* vec size 2,3 or 4 */ + int size; /* vec size 2 or more */ } VectorObject; /*prototypes*/ -PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type); -PyObject *Vector_CreatePyObject_cb(PyObject *user, int size, - unsigned char cb_type, unsigned char subtype); -PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type); +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_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 67e48253726..2bf596bbfba 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -146,7 +146,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject * mul_v3_fl(dir, t); add_v3_v3v3(pvec, orig, dir); - return Vector_CreatePyObject(pvec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(pvec, 3, NULL); } /* Line-Line intersection using algorithm from mathworld.wolfram.com */ @@ -207,8 +207,8 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject } else { tuple = PyTuple_New(2); - PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, len, Py_NEW, NULL)); - PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, len, Py_NEW, NULL)); + PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, len, NULL)); + PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, len, NULL)); return tuple; } } @@ -285,8 +285,8 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P i2[0] = i_cent[0] - h * v_ab[1] / dist; i2[1] = i_cent[1] + h * v_ab[0] / dist; - PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(i1, 2, Py_NEW, NULL)); - PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(i2, 2, Py_NEW, NULL)); + PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(i1, 2, NULL)); + PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(i2, 2, NULL)); } return ret; @@ -324,7 +324,7 @@ static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args) } normal_poly_v3(n, (const float (*)[3])coords, coords_len); - ret = Vector_CreatePyObject(n, 3, Py_NEW, NULL); + ret = Vector_CreatePyObject(n, 3, NULL); finally: PyMem_Free(coords); @@ -446,7 +446,7 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj } if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) { - return Vector_CreatePyObject(vi, 2, Py_NEW, NULL); + return Vector_CreatePyObject(vi, 2, NULL); } else { Py_RETURN_NONE; @@ -497,7 +497,7 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec /* TODO: implements no_flip */ if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) { - return Vector_CreatePyObject(isect, 3, Py_NEW, NULL); + return Vector_CreatePyObject(isect, 3, NULL); } else { Py_RETURN_NONE; @@ -551,8 +551,8 @@ static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObje { normalize_v3(isect_no); - ret_co = Vector_CreatePyObject(isect_co, 3, Py_NEW, NULL); - ret_no = Vector_CreatePyObject(isect_no, 3, Py_NEW, NULL); + ret_co = Vector_CreatePyObject(isect_co, 3, NULL); + ret_no = Vector_CreatePyObject(isect_no, 3, NULL); } else { ret_co = Py_None; @@ -631,10 +631,10 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje break; } - if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 3, Py_NEW, NULL)); } + if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 3, NULL)); } else { PyTuple_SET_ITEM(ret, 0, Py_None); Py_INCREF(Py_None); } - if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 3, Py_NEW, NULL)); } + if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 3, NULL)); } else { PyTuple_SET_ITEM(ret, 1, Py_None); Py_INCREF(Py_None); } return ret; @@ -705,10 +705,10 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO break; } - if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 2, Py_NEW, NULL)); } + if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 2, NULL)); } else { PyTuple_SET_ITEM(ret, 0, Py_None); Py_INCREF(Py_None); } - if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 2, Py_NEW, NULL)); } + if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 2, NULL)); } else { PyTuple_SET_ITEM(ret, 1, Py_None); Py_INCREF(Py_None); } return ret; @@ -756,7 +756,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec lambda = closest_to_line_v3(pt_out, pt, line_a, line_b); ret = PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, size, Py_NEW, NULL)); + PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, size, NULL)); PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda)); return ret; } @@ -802,7 +802,7 @@ static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject } if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) { - return Vector_CreatePyObject(vi, 3, Py_NEW, NULL); + return Vector_CreatePyObject(vi, 3, NULL); } else { Py_RETURN_NONE; @@ -988,7 +988,7 @@ static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObje UNPACK3(tri_dst), UNPACK3(tri_src)); - return Vector_CreatePyObject(pt_dst, 3, Py_NEW, NULL); + return Vector_CreatePyObject(pt_dst, 3, NULL); } PyDoc_STRVAR(M_Geometry_points_in_planes_doc, @@ -1062,7 +1062,7 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a if (l == len) { /* ok */ /* python */ - PyObject *item = Vector_CreatePyObject(potentialVertex, 3, Py_NEW, NULL); + PyObject *item = Vector_CreatePyObject(potentialVertex, 3, NULL); PyList_Append(py_verts, item); Py_DECREF(item); @@ -1157,7 +1157,7 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject 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, Py_NEW, NULL)); + PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, NULL)); } MEM_freeN(coord_array); return list; diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c index 9dc246f0f37..677fa9830f1 100644 --- a/source/blender/python/mathutils/mathutils_kdtree.c +++ b/source/blender/python/mathutils/mathutils_kdtree.c @@ -58,7 +58,7 @@ static void kdtree_nearest_to_py_tuple(const KDTreeNearest *nearest, PyObject *p BLI_assert(nearest->index >= 0); BLI_assert(PyTuple_GET_SIZE(py_retval) == 3); - PyTuple_SET_ITEM(py_retval, 0, Vector_CreatePyObject((float *)nearest->co, 3, Py_NEW, NULL)); + PyTuple_SET_ITEM(py_retval, 0, Vector_CreatePyObject((float *)nearest->co, 3, NULL)); PyTuple_SET_ITEM(py_retval, 1, PyLong_FromLong(nearest->index)); PyTuple_SET_ITEM(py_retval, 2, PyFloat_FromDouble(nearest->dist)); } diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index f0837c4ec0a..f0449c23dcd 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -309,7 +309,7 @@ static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *ar norm = normalize_vn(vec, size); } - return Vector_CreatePyObject(vec, size, Py_NEW, NULL); + return Vector_CreatePyObject(vec, size, NULL); } /* This is dumb, most people will want a unit vector anyway, since this doesn't have uniform distribution over a sphere*/ #if 0 @@ -338,7 +338,7 @@ static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args) rand_vn(vec, size); - return Vector_CreatePyObject(vec, size, Py_NEW, NULL); + return Vector_CreatePyObject(vec, size, NULL); } #endif @@ -412,7 +412,7 @@ static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args) noise_vector(vec[0], vec[1], vec[2], nb, r_vec); - return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(r_vec, 3, NULL); } PyDoc_STRVAR(M_Noise_turbulence_doc, @@ -484,7 +484,7 @@ static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *arg return NULL; vTurb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs, r_vec); - return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(r_vec, 3, NULL); } /* F. Kenton Musgrave's fractal functions */ @@ -736,7 +736,7 @@ static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args) voronoi(vec[0], vec[1], vec[2], da, pa, me, dtype); for (i = 0; i < 4; i++) { - PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, Py_NEW, NULL)); + PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, NULL)); } return Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list); @@ -788,7 +788,7 @@ static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args) return NULL; cellNoiseV(vec[0], vec[1], vec[2], r_vec); - return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(r_vec, 3, NULL); } static PyMethodDef M_Noise_methods[] = { diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp index cb33ff0e1e3..2b8dfd8f8d1 100644 --- a/source/gameengine/Converter/BL_ArmatureChannel.cpp +++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp @@ -295,7 +295,7 @@ PyObject *BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const str mul_v3_fl(joints,norm); break; } - return Vector_CreatePyObject(joints, 3, Py_NEW, NULL); + return Vector_CreatePyObject(joints, 3, NULL); } int BL_ArmatureChannel::py_attr_set_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index c025d439fc0..a65d61bc98b 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -418,7 +418,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef * return NULL; } #ifdef USE_MATHUTILS - return Vector_CreatePyObject(val, attrdef->m_imax, Py_NEW, NULL); + return Vector_CreatePyObject(val, attrdef->m_imax, NULL); #else PyObject *resultlist = PyList_New(attrdef->m_imax); for (unsigned int i=0; im_imax; i++) @@ -435,7 +435,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef * return NULL; } #ifdef USE_MATHUTILS - return Matrix_CreatePyObject(val, attrdef->m_imin, attrdef->m_imax, Py_WRAP, NULL); + return Matrix_CreatePyObject_wrap(val, attrdef->m_imin, attrdef->m_imax, NULL); #else PyObject *collist = PyList_New(attrdef->m_imin); for (unsigned int i=0; im_imin; i++) @@ -458,7 +458,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef * #ifdef USE_MATHUTILS float fval[3]; val->getValue(fval); - return Vector_CreatePyObject(fval, 3, Py_NEW, NULL); + return Vector_CreatePyObject(fval, 3, NULL); #else PyObject *resultlist = PyList_New(3); for (unsigned int i=0; i<3; i++) diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index 0c661cf2c87..cfc6ded4e65 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ../../GameLogic ../../Network ../../SceneGraph + ../../../blender/blenlib ../../../../intern/container ../../../../intern/string ) diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 355dcc4f78f..ab03e03e74d 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -39,6 +39,7 @@ incs = [ '#source/gameengine/Ketsji', '#source/gameengine/Network', '#source/gameengine/SceneGraph', + '../../../blender/blenlib', ] incs = ' '.join(incs) diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index 804e8de2ad1..76332e75204 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -100,7 +100,7 @@ PyObject *PyObjectFrom(const MT_Matrix4x4 &mat) #ifdef USE_MATHUTILS float fmat[16]; mat.getValue(fmat); - return Matrix_CreatePyObject(fmat, 4, 4, Py_NEW, NULL); + return Matrix_CreatePyObject(fmat, 4, 4, NULL); #else PyObject *collist = PyList_New(4); PyObject *col; @@ -124,7 +124,7 @@ PyObject *PyObjectFrom(const MT_Matrix3x3 &mat) #ifdef USE_MATHUTILS float fmat[9]; mat.getValue3x3(fmat); - return Matrix_CreatePyObject(fmat, 3, 3, Py_NEW, NULL); + return Matrix_CreatePyObject(fmat, 3, 3, NULL); #else PyObject *collist = PyList_New(3); PyObject *col; @@ -148,7 +148,7 @@ PyObject *PyObjectFrom(const MT_Quaternion &qrot) /* NOTE, were re-ordering here for Mathutils compat */ float fvec[4]; qrot.getValue(fvec); - return Quaternion_CreatePyObject(fvec, Py_NEW, NULL); + return Quaternion_CreatePyObject(fvec, NULL); } #endif @@ -157,7 +157,7 @@ PyObject *PyObjectFrom(const MT_Tuple4 &vec) #ifdef USE_MATHUTILS float fvec[4]; vec.getValue(fvec); - return Vector_CreatePyObject(fvec, 4, Py_NEW, NULL); + return Vector_CreatePyObject(fvec, 4, NULL); #else PyObject *list = PyList_New(4); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -173,7 +173,7 @@ PyObject *PyObjectFrom(const MT_Tuple3 &vec) #ifdef USE_MATHUTILS float fvec[3]; vec.getValue(fvec); - return Vector_CreatePyObject(fvec, 3, Py_NEW, NULL); + return Vector_CreatePyObject(fvec, 3, NULL); #else PyObject *list = PyList_New(3); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -188,7 +188,7 @@ PyObject *PyObjectFrom(const MT_Tuple2 &vec) #ifdef USE_MATHUTILS float fvec[2]; vec.getValue(fvec); - return Vector_CreatePyObject(fvec, 2, Py_NEW, NULL); + return Vector_CreatePyObject(fvec, 2, NULL); #else PyObject *list = PyList_New(2); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); diff --git a/source/gameengine/Network/CMakeLists.txt b/source/gameengine/Network/CMakeLists.txt index bae00c464f2..019fc3e6032 100644 --- a/source/gameengine/Network/CMakeLists.txt +++ b/source/gameengine/Network/CMakeLists.txt @@ -27,6 +27,7 @@ set(INC . ../../../intern/container ../../../intern/string + ../../blender/blenlib ) set(INC_SYS diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index 1d78cdba174..feb14e29552 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -31,6 +31,7 @@ sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_Netw incs = [ '.', + '../../blender/blenlib', '#intern/container', '#intern/string', '#intern/moto/include', -- cgit v1.2.3