From d741b3723633f68c960d5fb1ff677f7a72e652ac Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 Dec 2009 22:59:09 +0000 Subject: [PATCH] flag to make rna props 'thick wrapped', so returning a property wont try maintain a reference to the original rna property with callbacks. also needed for functions that return vectors/matrix's --- source/blender/makesrna/RNA_types.h | 4 ++ source/blender/makesrna/intern/rna_armature.c | 1 + source/blender/python/generic/matrix.c | 2 +- source/blender/python/intern/bpy_rna.c | 69 ++++++++++++++----- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 90603f98c7a..8cc949f628e 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -175,6 +175,10 @@ typedef enum PropertyFlag { /* need context for update function */ PROP_CONTEXT_UPDATE = 1<<22, + /* Use for arrays or for any data that should not have a referene kept + * most common case is functions that return arrays where the array */ + PROP_THICK_WRAP = 1<<23, + /* internal flags */ PROP_BUILTIN = 1<<7, PROP_EXPORT = 1<<8, diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 0f36ebda70e..22b16c13630 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -647,6 +647,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) //RNA_def_property_float_sdna(prop, NULL, ""); // doesnt access any real data RNA_def_property_array(prop, 16); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_THICK_WRAP); /* no reference to original data */ RNA_def_property_ui_text(prop, "Editbone Matrix", "Read-only matrix calculated from the roll (armature space)."); RNA_def_property_float_funcs(prop, "rna_EditBone_matrix_get", NULL, NULL); // TODO - this could be made writable also diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index a1ef4b53615..dcd1057f881 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -1136,7 +1136,7 @@ static PyGetSetDef Matrix_getseters[] = { {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL}, {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL}, {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL}, - {"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "", + {"_owner",(getter)BaseMathObject_getOwner, (setter)NULL, "", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 4351f69a44a..7c4e49e93e3 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -145,6 +145,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) #ifdef USE_MATHUTILS int subtype, totdim; int len; + int is_thick; /* disallow dynamic sized arrays to be wrapped since the size could change * to a size mathutils does not support */ @@ -154,9 +155,11 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) len= RNA_property_array_length(ptr, prop); subtype= RNA_property_subtype(prop); totdim= RNA_property_array_dimension(ptr, prop, NULL); + is_thick = (RNA_property_flag(prop) & PROP_THICK_WRAP); if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { - ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */ + if(!is_thick) + ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */ switch(RNA_property_subtype(prop)) { case PROP_TRANSLATION: @@ -166,40 +169,74 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) case PROP_XYZ: case PROP_XYZ|PROP_UNIT_LENGTH: if(len>=2 && len <= 4) { - PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the vector owns now */ - ret= vec_cb; /* return the vector instead */ + if(is_thick) { + ret= newVectorObject(NULL, len, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec); + } + else { + PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the vector owns now */ + ret= vec_cb; /* return the vector instead */ + } } break; case PROP_MATRIX: if(len==16) { - PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ + if(is_thick) { + ret= newMatrixObject(NULL, 4, 4, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + } + else { + PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } } else if (len==9) { - PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ + if(is_thick) { + ret= newMatrixObject(NULL, 3, 3, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + } + else { + PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } } break; case PROP_EULER: case PROP_QUATERNION: if(len==3) { /* euler */ - PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= eul_cb; /* return the matrix instead */ + if(is_thick) { + ret= newEulerObject(NULL, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); + } + else { + PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= eul_cb; /* return the matrix instead */ + } } else if (len==4) { - PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= quat_cb; /* return the matrix instead */ + if(is_thick) { + ret= newQuaternionObject(NULL, Py_NEW, NULL); + RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat); + } + else { + PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= quat_cb; /* return the matrix instead */ + } } break; default: break; } } + + if(ret==NULL) + ret = pyrna_prop_CreatePyObject(ptr, prop); /* TODO, convert to a python list */ + #endif return ret;