patch from Benoit Bolsee (ben2610) for 4 bugs in report [#20527] Several bugs in RNA

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...
This commit is contained in:
Campbell Barton 2010-01-04 22:30:09 +00:00
parent 7f03297fc8
commit e90b6eefb1
7 changed files with 99 additions and 9 deletions

View 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,

View 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);

View 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;
}

View 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;

View 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)

View 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

View 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;
}