rna support for passing dynamic sized arrays to rna functions
authorCampbell Barton <ideasman42@gmail.com>
Tue, 31 Aug 2010 11:31:21 +0000 (11:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 31 Aug 2010 11:31:21 +0000 (11:31 +0000)
using this for object.vertex_groups.assign([index list ...], group, weight, mode)

16 files changed:
release/scripts/io/import_scene_obj.py
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_ops.c
source/blender/editors/armature/armature_ops.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_ops.c
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_object.c
source/blender/python/intern/bpy_array.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_cursors.c

index 3a92ec8c5ae4cabca8f83fa5ab91ab0d1cad28f8..3ffbb36bb6fb1fd76aea039ac2d91c0e473bf4fa 100644 (file)
@@ -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):
index f5f50e10bcb81bfc3b95154e7c080b2470108cdc..b564780f6c0d199e7d630a35ac4792a9f0445c2a 100644 (file)
@@ -25,6 +25,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+#include "BLO_sys_types.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_object_types.h"
index 9570fd644335b9ccf041021612a8e65f8548f1f5..9b9c943551813e630655cf28dbaf73dcac0365de 100644 (file)
@@ -29,6 +29,8 @@
 #include <stdlib.h>
 #include <math.h>
 
+#include "BLO_sys_types.h"
+
 #include "DNA_anim_types.h"
 #include "DNA_scene_types.h"
 
index d5bd09cc8f1ebaf06b32e56139f92f753d058fbb..908aa5bb432aa3b44094e8ad75b0aea705a44e59 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include <math.h>
 
-
+#include "BLO_sys_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
index 4867c5233bb07c880ddb2a933fd169464973079e..4b8c58a53089365747d15049810e33674fc58aff 100644 (file)
@@ -32,6 +32,7 @@
 #include <math.h>
 #include <float.h>
 
+#include "BLO_sys_types.h"
 
 #include "IMB_imbuf_types.h"
 
index d9bd43cc8517d77b3c2fcb6e0d6fa6613639eda9..b6b2675e6c8ed70421829dd39b5037cc34c779d0 100644 (file)
@@ -29,8 +29,9 @@
 #include <stddef.h>
 #include <stdio.h>
 
-#include "BLI_blenlib.h"
+#include "BLO_sys_types.h"
 
+#include "BLI_blenlib.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
index 887069d6c00e1352ed84fcf8d27f563c16c1792a..5caae56010f2bb3892da7eeed279d0d0da6512c0 100644 (file)
@@ -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 {
index af0faf5a1656beb0b41408fa8767cc61cf5ac50b..9ebf625946c942da44c91816fdf33c7508a2593f 100644 (file)
@@ -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");
index ce3ace0ae1f43d0c61c3df1ba6e68d4becb91ef0..4be9502d79a6edc4909b94fb5a2c21bc73731669 100644 (file)
@@ -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)
index 0ac77382c048fb50e7051d2a184c2600d18a7649..a1c17ff02c9e0ef7cb4c2385eec1d4f6134f3682 100644 (file)
@@ -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;
 }
index a6f99d0193670ee8b66758f19ffa484eccf1c323..3777005aaada112c9465db12f0f9d226caa9aa70 100644 (file)
@@ -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);
index 9ceba4ae004f0fc7ce331c515040f31a020a239f..ec5cc2e8809d5a99bd26222638dc2f080de86a5b 100644 (file)
@@ -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);
index 5cb6dfca0b23252623ec8af27cca90bba52af1ae..6133a1da616a482dccd1a7336243cdc8120ec052 100644 (file)
@@ -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);
index 63f6997d82c53e58520176bf123378a026c118b6..514784d5a4cfb75922d793ff86dadbf3caf08036 100644 (file)
@@ -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);
 
index afa11616cfde887ee262e6335deae85248bf15bd..5f386170c54da5a9295ecfbb987a271efd353796 100644 (file)
@@ -29,6 +29,8 @@
 #include <string.h>
 #include <stddef.h>
 
+#include "BLO_sys_types.h"
+
 #include "DNA_windowmanager_types.h"
 
 #include "GHOST_C-api.h"
index b16e82726b4708e23cf992f6d21d0d7e8a2ab452..1803a1cee918db2dcd923485c47ee55251cbb14a 100644 (file)
@@ -32,6 +32,8 @@
 
 #include "GHOST_C-api.h"
 
+#include "BLO_sys_types.h"
+
 #include "DNA_listBase.h"
 #include "DNA_userdef_types.h"