patch from Benoit Bolsee (ben2610) for 4 bugs in report [#20527] Several bugs in RNA
authorCampbell Barton <ideasman42@gmail.com>
Mon, 4 Jan 2010 22:30:09 +0000 (22:30 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 4 Jan 2010 22:30:09 +0000 (22:30 +0000)
from the report...

# bug 1. UV properties are not raw editable but are reported
#        as RAW_TYPE_INT by RNA causing wrong conversion
#        internally (bpy_rna.c line 2205)
# bug 2. raw update of UV coordinates crash blender (rna_access.c line 252)
mtfaces.foreach_set("uv", rawuvs)
# workaround:
#for i in range(int(len(faces)/4)):
#   mtfaces[i].uv = uvs[i]

# bug 3. raw update of non-array property fails (rna_access.c line 2270)
mfaces.foreach_set("material_index", mats)
# workaround:
# for i in range(int(len(mfaces))):
#    mfaces[i].material_index = mats[i]

# bug 4. It is not possible to add a vertex color layer using mesh API.
me.add_vertex_color()
# no workaround...

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_mesh.c
source/blender/makesrna/intern/rna_mesh_api.c
source/blender/python/intern/bpy_rna.c

index 8cc949f..4e60fb4 100644 (file)
@@ -210,6 +210,7 @@ typedef struct CollectionPointerLink {
 } CollectionPointerLink;
 
 typedef enum RawPropertyType {
+       PROP_RAW_UNSET=-1,
        PROP_RAW_INT, // XXX - abused for types that are not set, eg. MFace.verts, needs fixing.
        PROP_RAW_SHORT,
        PROP_RAW_CHAR,
index ca14acb..35515e7 100644 (file)
@@ -1779,7 +1779,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
        fprintf(f, "\t%s%s, %d, %s, %s,\n", (prop->flag & PROP_CONTEXT_UPDATE)? "(UpdateFunc)": "", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable), rna_function_string(prop->itemeditable));
 
        if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
-       else fprintf(f, "\t0, 0");
+       else fprintf(f, "\t0, -1");
 
        /* our own type - collections/arrays only */
        if(prop->srna) fprintf(f, ", &RNA_%s", (char*)prop->srna);
index d8b31f4..61fdbb2 100644 (file)
@@ -249,7 +249,7 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
 {
        if(prop->magic == RNA_MAGIC) {
                int arraylen[RNA_MAX_ARRAY_DIMENSION];
-               return (prop->getlength)? prop->getlength(ptr, arraylen): prop->totarraylength;
+               return (prop->getlength && ptr->data)? prop->getlength(ptr, arraylen): prop->totarraylength;
        }
        else {
                IDProperty *idprop= (IDProperty*)prop;
@@ -2266,8 +2266,9 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
 
                /* try to access as raw array */
                if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
-                       if(in.len != itemlen*out.len) {
-                               BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
+                       int arraylen = (itemlen == 0) ? 1 : itemlen;
+                       if(in.len != arraylen*out.len) {
+                               BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*arraylen, in.len);
                                return 0;
                        }
                        
@@ -2277,8 +2278,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
                                void *outp= out.array;
                                int a, size;
 
-                               itemlen= (itemlen == 0)? 1: itemlen;
-                               size= RNA_raw_type_sizeof(out.type) * itemlen;
+                               size= RNA_raw_type_sizeof(out.type) * arraylen;
 
                                for(a=0; a<out.len; a++) {
                                        if(set) memcpy(outp, inp, size);
@@ -2300,6 +2300,12 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
                void *tmparray= NULL;
                int tmplen= 0;
                int err= 0, j, a= 0;
+               int needconv = 1;
+
+               if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
+                       (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
+                       /* avoid creating temporary buffer if the data type match */
+                       needconv = 0;
 
                /* no item property pointer, can still be id property, or
                 * property of a type derived from the collection pointer type */
@@ -2387,7 +2393,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
                                                }
                                                a++;
                                        }
-                                       else {
+                                       else if (needconv == 1) {
                                                /* allocate temporary array if needed */
                                                if(tmparray && tmplen != itemlen) {
                                                        MEM_freeN(tmparray);
@@ -2448,6 +2454,50 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
                                                        }
                                                }
                                        }
+                                       else {
+                                               if(set) {
+                                                       switch(itemtype) {
+                                                               case PROP_BOOLEAN: {
+                                                                       RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               case PROP_INT: {
+                                                                       RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               case PROP_FLOAT: {
+                                                                       RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               default:
+                                                                       break;
+                                                       }
+                                               }
+                                               else {
+                                                       switch(itemtype) {
+                                                               case PROP_BOOLEAN: {
+                                                                       RNA_property_boolean_get_array(&itemptr, iprop, &((int*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               case PROP_INT: {
+                                                                       RNA_property_int_get_array(&itemptr, iprop, &((int*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               case PROP_FLOAT: {
+                                                                       RNA_property_float_get_array(&itemptr, iprop, &((float*)in.array)[a]);
+                                                                       a += itemlen;
+                                                                       break;
+                                                               }
+                                                               default:
+                                                                       break;
+                                                       }
+                                               }
+                                       }
                                }
                        }
                }
@@ -2462,6 +2512,21 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
 
 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
 {
+       if (prop->rawtype == PROP_RAW_UNSET) {
+               /* this property has no raw access, yet we try to provide a raw type to help building the array */
+               switch (prop->type) {
+               case PROP_BOOLEAN:
+                       return PROP_RAW_INT;
+               case PROP_INT:
+                       return PROP_RAW_INT;
+               case PROP_FLOAT:
+                       return PROP_RAW_FLOAT;
+               case PROP_ENUM:
+                       return PROP_RAW_INT;
+               default:
+                       break;
+               }
+       }
        return prop->rawtype;
 }
 
index 854776e..767752a 100644 (file)
@@ -931,6 +931,8 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
        prop->subtype= subtype;
        prop->name= identifier;
        prop->description= "";
+       /* a priori not raw editable */
+       prop->rawtype = -1;
 
        if(type != PROP_COLLECTION && type != PROP_POINTER) {
                prop->flag= PROP_EDITABLE;
index 56a1b17..9f317ec 100644 (file)
@@ -1358,6 +1358,12 @@ static void rna_def_mtface(BlenderRNA *brna)
        RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL);
        RNA_def_property_ui_text(prop, "UV", "");
        RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+       prop= RNA_def_property(srna, "uv_raw", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_multi_array(prop, 2, uv_dim);
+       RNA_def_property_float_sdna(prop, NULL, "uv");
+       RNA_def_property_ui_text(prop, "UV", "Fixed size UV coordinates array");
+
 }
 
 static void rna_def_msticky(BlenderRNA *brna)
index 52ff98f..4fba65b 100644 (file)
@@ -43,6 +43,11 @@ static void rna_Mesh_uv_texture_add(struct Mesh *me, struct bContext *C)
        ED_mesh_uv_texture_add(C, NULL, NULL, me);
 }
 
+static void rna_Mesh_vertex_color_add(struct Mesh *me, struct bContext *C)
+{
+       ED_mesh_color_add(C, NULL, NULL, me);
+}
+
 #else
 
 void RNA_api_mesh(StructRNA *srna)
@@ -68,6 +73,10 @@ void RNA_api_mesh(StructRNA *srna)
        RNA_def_function_flag(func, FUNC_USE_CONTEXT);
        RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh.");
 
+       func= RNA_def_function(srna, "add_vertex_color", "rna_Mesh_vertex_color_add");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+       RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh.");
+
        func= RNA_def_function(srna, "calc_normals", "ED_mesh_calc_normals");
        RNA_def_function_ui_description(func, "Calculate vertex normals.");
 
@@ -79,6 +88,8 @@ void RNA_api_mesh(StructRNA *srna)
        RNA_def_function_ui_description(func, "Add a new material to Mesh.");
        parm= RNA_def_pointer(func, "material", "Material", "", "Material to add.");
        RNA_def_property_flag(parm, PROP_REQUIRED);
+
+
 }
 
 #endif
index ddc221a..cd60796 100644 (file)
@@ -2237,7 +2237,7 @@ static void foreach_attr_type(    BPy_PropertyRNA *self, char *attr,
                                                                        RawPropertyType *raw_type, int *attr_tot, int *attr_signed )
 {
        PropertyRNA *prop;
-       *raw_type= -1;
+       *raw_type= PROP_RAW_UNSET;
        *attr_tot= 0;
        *attr_signed= FALSE;
 
@@ -2263,7 +2263,8 @@ static int foreach_parse_args(
        int target_tot;
 #endif
 
-       *size= *raw_type= *attr_tot= *attr_signed= FALSE;
+       *size= *attr_tot= *attr_signed= FALSE;
+       *raw_type= PROP_RAW_UNSET;
 
        if(!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
                PyErr_SetString( PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence" );
@@ -2296,6 +2297,10 @@ static int foreach_parse_args(
 #endif
        }
 
+       if (*size == 0) {
+               PyErr_SetString( PyExc_AttributeError, "attribute does not support foreach method" );
+               return -1;
+       }
        return 0;
 }