From dfb8c5974e6f937c3404d0dd59f0e6424de455db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2010 11:31:21 +0000 Subject: rna support for passing dynamic sized arrays to rna functions using this for object.vertex_groups.assign([index list ...], group, weight, mode) --- release/scripts/io/import_scene_obj.py | 3 +-- source/blender/editors/animation/anim_draw.c | 1 + source/blender/editors/animation/anim_ops.c | 2 ++ source/blender/editors/armature/armature_ops.c | 2 +- source/blender/editors/gpencil/drawgpencil.c | 1 + source/blender/editors/gpencil/gpencil_ops.c | 3 ++- source/blender/makesrna/RNA_types.h | 8 ++++++ source/blender/makesrna/intern/makesrna.c | 31 +++++++++++++--------- source/blender/makesrna/intern/rna_access.c | 23 ++++++++++------- source/blender/makesrna/intern/rna_define.c | 2 +- source/blender/makesrna/intern/rna_object.c | 11 ++++---- source/blender/python/intern/bpy_array.c | 33 ++++++++++++++---------- source/blender/python/intern/bpy_rna.c | 10 +++---- source/blender/python/intern/bpy_rna.h | 1 - source/blender/windowmanager/intern/wm.c | 2 ++ source/blender/windowmanager/intern/wm_cursors.c | 2 ++ 16 files changed, 83 insertions(+), 52 deletions(-) diff --git a/release/scripts/io/import_scene_obj.py b/release/scripts/io/import_scene_obj.py index 3a92ec8c5ae..3ffbb36bb6f 100644 --- a/release/scripts/io/import_scene_obj.py +++ b/release/scripts/io/import_scene_obj.py @@ -768,8 +768,7 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v # the following test will never run for group_name, group_indicies in vertex_groups.items(): group= ob.vertex_groups.new(group_name) - for vertex_index in group_indicies: - ob.vertex_groups.assign(vertex_index, group, 1.0, 'REPLACE') + ob.vertex_groups.assign(group_indicies, group, 1.0, 'REPLACE') def create_nurbs(context_nurbs, vert_loc, new_objects): diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index f5f50e10bcb..b564780f6c0 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -25,6 +25,7 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include "BLO_sys_types.h" #include "DNA_anim_types.h" #include "DNA_object_types.h" diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 9570fd64433..9b9c9435518 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -29,6 +29,8 @@ #include #include +#include "BLO_sys_types.h" + #include "DNA_anim_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index d5bd09cc8f1..908aa5bb432 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -29,7 +29,7 @@ #include #include - +#include "BLO_sys_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 4867c5233bb..4b8c58a5308 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -32,6 +32,7 @@ #include #include +#include "BLO_sys_types.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index d9bd43cc851..b6b2675e6c8 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -29,8 +29,9 @@ #include #include -#include "BLI_blenlib.h" +#include "BLO_sys_types.h" +#include "BLI_blenlib.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 887069d6c00..5caae56010f 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -22,6 +22,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "BLO_sys_types.h" + #ifndef RNA_TYPES #define RNA_TYPES @@ -265,6 +267,12 @@ typedef struct ParameterIterator { int valid; } ParameterIterator; +/* mainly to avoid confusing casts */ +typedef struct ParameterDynAlloc { + intptr_t array_tot; /* important, this breaks when set to an int */ + void *array; +} ParameterDynAlloc; + /* Function */ typedef enum FunctionFlag { diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index af0faf5a165..9ebf625946c 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -49,6 +49,7 @@ static int replace_if_different(char *tmpfile) { + // return 0; // use for testing had edited rna #define REN_IF_DIFF \ remove(orgfile); \ @@ -1441,11 +1442,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA else ptrstr= pout ? "*" : ""; - fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); - /* for dynamic parameters we pass an additional int for the length of the parameter */ if (flag & PROP_DYNAMIC) fprintf(f, "\tint %s%s_len;\n", pout ? "*" : "", dparm->prop->identifier); + + fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); } fprintf(f, "\tchar *_data"); @@ -1474,6 +1475,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if(dparm->prop==func->c_ret) fprintf(f, "\t_retdata= _data;\n"); else { + char *data_str; if (cptr || (flag & PROP_DYNAMIC)) { ptrstr= "**"; valstr= "*"; @@ -1491,16 +1493,20 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA valstr= "*"; } + /* this must be kept in sync with RNA_parameter_length_get_data, we could just call the function directly, but this is faster */ + if (flag & PROP_DYNAMIC) { + fprintf(f, "\t%s_len= %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*"); + data_str= "(&(((char *)_data)[sizeof(void *)]))"; + } + else { + data_str= "_data"; + } fprintf(f, "\t%s= ", dparm->prop->identifier); if (!pout) fprintf(f, "%s", valstr); - fprintf(f, "((%s%s%s)_data);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr); - - /* this must be kept in sync with RNA_parameter_length_get_data, we could just call the function directly, but this is faster */ - if (flag & PROP_DYNAMIC) - fprintf(f, "\t%s_len= %s((int *)(_data+%d));\n", dparm->prop->identifier, pout ? "" : "*", rna_parameter_size(dparm->prop)); + fprintf(f, "((%s%s%s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, data_str); } if(dparm->next) @@ -1543,10 +1549,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if(!first) fprintf(f, ", "); first= 0; - fprintf(f, "%s", dparm->prop->identifier); - if (dparm->prop->flag & PROP_DYNAMIC) - fprintf(f, ", %s_len", dparm->prop->identifier); + fprintf(f, "%s_len, %s", dparm->prop->identifier, dparm->prop->identifier); + else + fprintf(f, "%s", dparm->prop->identifier); } fprintf(f, ");\n"); @@ -1863,13 +1869,14 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA if(!first) fprintf(f, ", "); first= 0; + if (flag & PROP_DYNAMIC) + fprintf(f, "int %s%s_len, ", pout ? "*" : "", dparm->prop->identifier); + if(!(flag & PROP_DYNAMIC) && dparm->prop->arraydimension) fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->totarraylength); else fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); - if (flag & PROP_DYNAMIC) - fprintf(f, ", int %s%s_len", pout ? "*" : "", dparm->prop->identifier); } fprintf(f, ");\n"); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index ce3ace0ae1f..4be9502d79a 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3839,7 +3839,14 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, for(parm= func->cont.properties.first; parm; parm= parm->next) { size= rna_parameter_size(parm); - if(!(parm->flag & PROP_REQUIRED)) { + /* set length to 0, these need to be set later, see bpy_array.c's py_to_array */ + if (parm->flag & PROP_DYNAMIC) { + ParameterDynAlloc *data_alloc= data; + data_alloc->array_tot= 0; + data_alloc->array= NULL; + } + + if(!(parm->flag & PROP_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) { switch(parm->type) { case PROP_BOOLEAN: if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size); @@ -3868,10 +3875,6 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, } } - /* set length to 0 */ - if (parm->flag & PROP_DYNAMIC) - *((int *)(((char *)data) + size))= 0; - data= ((char*)data) + rna_parameter_size_alloc(parm); } @@ -3889,9 +3892,9 @@ void RNA_parameter_list_free(ParameterList *parms) BLI_freelistN((ListBase*)((char*)parms->data+tot)); else if (parm->flag & PROP_DYNAMIC) { /* for dynamic arrays and strings, data is a pointer to an array */ - char *array= *(char**)((char*)parms->data+tot); - if(array) - MEM_freeN(array); + ParameterDynAlloc *data_alloc= (void *)(((char *)parms->data) + tot); + if(data_alloc->array) + MEM_freeN(data_alloc->array); } tot+= rna_parameter_size_alloc(parm); @@ -4053,12 +4056,12 @@ void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int lengt int RNA_parameter_length_get_data(ParameterList *parms, PropertyRNA *parm, void *data) { - return *((int *)(((char *)data) + rna_parameter_size(parm))); + return *((int *)((char *)data)); } void RNA_parameter_length_set_data(ParameterList *parms, PropertyRNA *parm, void *data, int length) { - *((int *)(((char *)data) + rna_parameter_size(parm)))= length; + *((int *)data)= length; } int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 0ac77382c04..a1c17ff02c9 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2525,7 +2525,7 @@ int rna_parameter_size_alloc(PropertyRNA *parm) int size = rna_parameter_size(parm); if (parm->flag & PROP_DYNAMIC) - size+= sizeof(int); + size+= sizeof(((ParameterDynAlloc *)NULL)->array_tot); return size; } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index a6f99d01936..3777005aaad 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1064,10 +1064,10 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values) } -static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeformGroup *def, float weight, int assignmode) +static void rna_Object_add_vertex_to_group(Object *ob, int index_len, int *index, bDeformGroup *def, float weight, int assignmode) { - /* creates dverts if needed */ - ED_vgroup_vert_add(ob, def, vertex_index, weight, assignmode); + while(index_len--) + ED_vgroup_vert_add(ob, def, *index++, weight, assignmode); } /* generic poll functions */ @@ -1530,10 +1530,11 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop) parm= RNA_def_pointer(func, "group", "VertexGroup", "", "New vertex group."); RNA_def_function_return(func, parm); - // XXX, this will be very slow, bad API design! :S func= RNA_def_function(srna, "assign", "rna_Object_add_vertex_to_group"); RNA_def_function_ui_description(func, "Add vertex to a vertex group."); - parm= RNA_def_int(func, "index", 0, 0, 0, "", "Vertex index.", 0, 0); + /* TODO, see how array size of 0 works, this shouldnt be used */ + parm= RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "Index List.", 0, 0); + RNA_def_property_flag(parm, PROP_DYNAMIC); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "group", "VertexGroup", "", "Vertex group to add vertex to."); RNA_def_property_flag(parm, PROP_REQUIRED); diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index 9ceba4ae004..ec5cc2e8809 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -24,6 +24,7 @@ #include "bpy_rna.h" #include "BKE_global.h" +#include "MEM_guardedalloc.h" #define MAX_ARRAY_DIMENSION 10 @@ -144,8 +145,9 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA return 0; } #else - PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); - return 0; + *totitem= tot; + return 1; + #endif } @@ -248,22 +250,25 @@ static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, Paramet } if (totitem) { - if (!param_data || RNA_property_flag(prop) & PROP_DYNAMIC) - data= PyMem_MALLOC(item_size * totitem); - else + /* note: this code is confusing */ + if(param_data && RNA_property_flag(prop) & PROP_DYNAMIC) { + /* not freeing allocated mem, RNA_parameter_list_free() will do this */ + ParameterDynAlloc *param_alloc= (ParameterDynAlloc *)param_data; + param_alloc->array_tot= (int)totitem; + param_alloc->array= MEM_callocN(item_size * totitem, "py_to_array dyn"); /* freeing param list will free */ + + data= param_alloc->array; + } + else if (param_data) { data= param_data; + } + else { + data= PyMem_MALLOC(item_size * totitem); + } copy_values(py, ptr, prop, 0, data, item_size, NULL, convert_item, NULL); - if (param_data) { - if (RNA_property_flag(prop) & PROP_DYNAMIC) { - /* not freeing allocated mem, RNA_parameter_list_free will do this */ - *(char**)param_data= data; - - RNA_parameter_length_set_data(parms, prop, param_data, totitem); - } - } - else { + if (param_data==NULL) { /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */ rna_set_array(ptr, prop, data); PyMem_FREE(data); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 5cb6dfca0b2..6133a1da616 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -55,7 +55,7 @@ #include "../generic/mathutils.h" /* so we can have mathutils callbacks */ #include "../generic/IDProp.h" /* for IDprop lookups */ - +static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix); static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length); static Py_ssize_t pyrna_prop_array_length(BPy_PropertyRNA *self); static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self); @@ -972,7 +972,7 @@ static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func) -int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix) +static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix) { /* XXX hard limits should be checked here */ int type = RNA_property_type(prop); @@ -3412,9 +3412,9 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, ParameterList *parms, PropertyRNA * int len; if (flag & PROP_DYNAMIC) { - len= RNA_parameter_length_get_data(parms, prop, data); - - data= *((void **)data); + ParameterDynAlloc *data_alloc= data; + len= data_alloc->array_tot; + data= data_alloc->array; } else len= RNA_property_array_length(ptr, prop); diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 63f6997d82c..514784d5a4c 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -77,7 +77,6 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr ); PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ); /* operators also need this to set args */ -int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix); int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix); PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index afa11616cfd..5f386170c54 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -29,6 +29,8 @@ #include #include +#include "BLO_sys_types.h" + #include "DNA_windowmanager_types.h" #include "GHOST_C-api.h" diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index b16e82726b4..1803a1cee91 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -32,6 +32,8 @@ #include "GHOST_C-api.h" +#include "BLO_sys_types.h" + #include "DNA_listBase.h" #include "DNA_userdef_types.h" -- cgit v1.2.3