RNA
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Jun 2009 01:10:39 +0000 (01:10 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Jun 2009 01:10:39 +0000 (01:10 +0000)
* Added support for passing collections to/from RNA functions,
  this is done using a ListBase of CollectionPointerLink, which
  is a standard ListBase link + PointerRNA.

* Added editable active uv/vcol layer to Mesh.
* Armature.bones now includes all bones, not only the ones without
  parents.
* Modifier UV layer fields now are allowed to be empty, previously
  this would set the name during modifier evaluation if there was
  none.

source/blender/blenkernel/intern/modifier.c
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/python/intern/bpy_rna.c

index bf3d27cafbfb2efc664bb9c3abffda62ab243391..1a6f57e75c421f457e953fe2aad38c1b0de1a2aa 100644 (file)
@@ -3543,7 +3543,7 @@ static void displaceModifier_updateDepgraph(
        }
 }
 
-static void validate_layer_name(const CustomData *data, int type, char *name)
+static void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
 {
        int index = -1;
 
@@ -3556,8 +3556,10 @@ static void validate_layer_name(const CustomData *data, int type, char *name)
                * deleted, so assign the active layer to name
                */
                index = CustomData_get_active_layer_index(data, CD_MTFACE);
-               strcpy(name, data->layers[index].name);
+               strcpy(outname, data->layers[index].name);
        }
+       else
+               strcpy(outname, name);
 }
 
 static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
@@ -3583,12 +3585,11 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
                        char *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
-                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name);
-
-                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-                                       dmd->uvlayer_name);
+                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -3884,6 +3885,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
        int num_projectors = 0;
        float aspect;
+       char uvname[32];
        
        if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
        else aspect = 1.0f;
@@ -3898,12 +3900,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        if(!dm->getFaceDataArray(dm, CD_MTFACE)) return dm;
 
        /* make sure we're using an existing layer */
-       validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name);
+       validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
 
        /* make sure we are not modifying the original UV layer */
        tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-                       CD_MTFACE,
-   umd->uvlayer_name);
+                       CD_MTFACE, uvname);
 
        numVerts = dm->getNumVerts(dm);
 
@@ -5185,12 +5186,11 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
                        char *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
-                       validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name);
-
-                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-                                       wmd->uvlayer_name);
+                       validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
index e7ca3fc59321946b23675ea91fcb37a2cedef9d9..475db3955b6fef41b2bcd687488084ff480350f5 100644 (file)
@@ -248,8 +248,7 @@ static const char *rna_parameter_type_name(PropertyRNA *parm)
                                return rna_find_dna_type((const char *)pparm->type);
                }
                case PROP_COLLECTION: {
-                       CollectionPropertyRNA *cparm= (CollectionPropertyRNA*)parm;
-                       return rna_find_dna_type((const char *)cparm->type);
+                       return "ListBase";
                }
                default:
                        return "<error, no type specified>";
@@ -1116,9 +1115,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
 
        funcname= rna_alloc_function_name(srna->identifier, func->identifier, "call");
 
+       /* function definition */
        fprintf(f, "void %s(bContext *C, ReportList *reports, PointerRNA *_ptr, ParameterList *_parms)", funcname);
        fprintf(f, "\n{\n");
 
+       /* variable definitions */
        if((func->flag & FUNC_NO_SELF)==0) {
                if(dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
                else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
@@ -1135,6 +1136,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
        fprintf(f, ";\n");
        fprintf(f, "\t\n");
 
+       /* assign self */
        if((func->flag & FUNC_NO_SELF)==0) {
                if(dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
                else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
@@ -1405,6 +1407,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
        dsrna= rna_find_struct_def(srna);
        func= dfunc->func;
 
+       /* return type */
        for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
                if(dparm->prop==func->ret) {
                        if(dparm->prop->arraylength)
@@ -1418,13 +1421,16 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
                }
        }
 
+       /* void if nothing to return */
        if(!dparm)
                fprintf(f, "void ");
 
+       /* function name */
        fprintf(f, "%s(", dfunc->call);
 
        first= 1;
 
+       /* self, context and reports parameters */
        if((func->flag & FUNC_NO_SELF)==0) {
                if(dsrna->dnaname) fprintf(f, "struct %s *_self", dsrna->dnaname);
                else fprintf(f, "struct %s *_self", srna->identifier);
@@ -1443,6 +1449,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
                fprintf(f, "ReportList *reports");
        }
 
+       /* defined parameters */
        for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
                if(dparm->prop==func->ret)
                        continue;
index 66127ebc6df3c225640c490aa3decb4f4835116b..7defb0676c6728b578e65372efe0a54066488296 100644 (file)
@@ -2457,6 +2457,17 @@ ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func)
 
 void RNA_parameter_list_free(ParameterList *parms)
 {
+       PropertyRNA *parm;
+       int tot;
+
+       parm= parms->func->cont.properties.first;
+       for(tot= 0; parm; parm= parm->next) {
+               if(parm->type == PROP_COLLECTION)
+                       BLI_freelistN((ListBase*)((char*)parms->data+tot));
+
+               tot+= rna_parameter_size(parm);
+       }
+
        MEM_freeN(parms->data);
        parms->data= NULL;
 
index 0f437f8f1a8c4c908d0dcd4965c000bc19a7c917..caa970eff57acc411647bdd250f9d48ca5fd6d40 100644 (file)
@@ -443,6 +443,30 @@ void rna_EditBone_tail_selected_set(PointerRNA *ptr, int value)
        else data->flag &= ~BONE_TIPSEL;
 }
 
+static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
+{
+       ListBaseIterator *internal= iter->internal;
+       Bone *bone= (Bone*)internal->link;
+
+       if(bone->childbase.first)
+               internal->link= (Link*)bone->childbase.first;
+       else if(bone->next)
+               internal->link= (Link*)bone->next;
+       else {
+               internal->link= NULL;
+
+               do {
+                       bone= bone->parent;
+                       if(bone && bone->next) {
+                               internal->link= (Link*)bone->next;
+                               break;
+                       }
+               } while(bone);
+       }
+
+       iter->valid= (internal->link != NULL);
+}
+
 #else
 
 static void rna_def_bone_common(StructRNA *srna, int editbone)
@@ -660,6 +684,7 @@ void rna_def_armature(BlenderRNA *brna)
        /* Collections */
        prop= RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
+       RNA_def_property_collection_funcs(prop, 0, "rna_Armature_bones_next", 0, 0, 0, 0, 0, 0, 0);
        RNA_def_property_struct_type(prop, "Bone");
        RNA_def_property_ui_text(prop, "Bones", "");
 
index 80c145911b1a67f9abe1de0eb82cbc135174fe42..8200a21f4accd4f4bfad500c0952bf24ed12a25b 100644 (file)
@@ -534,6 +534,14 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
 
        srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
        RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
+
+       RNA_def_struct_sdna(srna, "bConstraint");
+
+       prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
+       RNA_def_property_float_sdna(prop, NULL, "headtail");
+       RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
        RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
 
        prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
@@ -582,13 +590,6 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_OFFSET);
        RNA_def_property_ui_text(prop, "Offset", "Add original location into copied location.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
-       RNA_def_struct_sdna(srna, "bConstraint");
-
-       prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
-       RNA_def_property_float_sdna(prop, NULL, "headtail");
-       RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 }
 
 static void rna_def_constraint_minmax(BlenderRNA *brna)
index 8d98036290ae747a78b8ee5bca571d5cdb9295ba..26fc3c2941e2a7aef5af1522c2f5d534522c3098 100644 (file)
@@ -264,7 +264,7 @@ void RNA_def_main(BlenderRNA *brna)
        {
                prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE);
                RNA_def_property_struct_type(prop, lists[i][1]);
-               RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, "add_mesh", "remove_mesh");
+               RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0, 0);
                RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]);
        }
 
index da90b9f4c76dd153d500302cc2fffad2da84a13d..e56760f5ca3ae9d68b676d62fa5663d38d94cc71 100644 (file)
@@ -234,6 +234,29 @@ static int rna_Mesh_uv_layers_length(PointerRNA *ptr)
        return rna_CustomDataLayer_length(ptr, CD_MTFACE);
 }
 
+static PointerRNA rna_Mesh_active_uv_layer_get(PointerRNA *ptr)
+{
+       Mesh *me= (Mesh*)ptr->data;
+       int index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+       CustomDataLayer *cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+       return rna_pointer_inherit_refine(ptr, &RNA_MeshTextureFaceLayer, cdl);
+}
+
+static void rna_Mesh_active_uv_layer_set(PointerRNA *ptr, PointerRNA value)
+{
+       Mesh *me= (Mesh*)ptr->data;
+       CustomDataLayer *cdl;
+       int a;
+
+       for(cdl=me->fdata.layers, a=0; a<me->fdata.totlayer; cdl++, a++) {
+               if(value.data == cdl) {
+                       CustomData_set_layer_active_index(&me->fdata, CD_MTFACE, a);
+                       return;
+               }
+       }
+}
+
 static void rna_MeshTextureFace_uv1_get(PointerRNA *ptr, float *values)
 {
        MTFace *mtface= (MTFace*)ptr->data;
@@ -348,6 +371,29 @@ static int rna_Mesh_vcol_layers_length(PointerRNA *ptr)
        return rna_CustomDataLayer_length(ptr, CD_MCOL);
 }
 
+static PointerRNA rna_Mesh_active_vcol_layer_get(PointerRNA *ptr)
+{
+       Mesh *me= (Mesh*)ptr->data;
+       int index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
+       CustomDataLayer *cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+       return rna_pointer_inherit_refine(ptr, &RNA_MeshColorLayer, cdl);
+}
+
+static void rna_Mesh_active_vcol_layer_set(PointerRNA *ptr, PointerRNA value)
+{
+       Mesh *me= (Mesh*)ptr->data;
+       CustomDataLayer *cdl;
+       int a;
+
+       for(cdl=me->fdata.layers, a=0; a<me->fdata.totlayer; cdl++, a++) {
+               if(value.data == cdl) {
+                       CustomData_set_layer_active_index(&me->fdata, CD_MCOL, a);
+                       return;
+               }
+       }
+}
+
 static void rna_MeshColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
        Mesh *me= (Mesh*)ptr->id.data;
@@ -1075,18 +1121,34 @@ static void rna_def_mesh(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "MeshSticky");
        RNA_def_property_ui_text(prop, "Sticky", "Sticky texture coordinates.");
 
+       /* UV layers */
+
        prop= RNA_def_property(srna, "uv_layers", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
        RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_layers_begin", 0, 0, 0, "rna_Mesh_uv_layers_length", 0, 0, 0, 0);
        RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
        RNA_def_property_ui_text(prop, "UV Layers", "");
 
+       prop= RNA_def_property(srna, "active_uv_layer", PROP_POINTER, PROP_UNSIGNED);
+       RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
+       RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_uv_layer_get", "rna_Mesh_active_uv_layer_set", NULL);
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Active UV Layer", "Active UV layer.");
+
+       /* VCol layers */
+
        prop= RNA_def_property(srna, "vcol_layers", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
        RNA_def_property_collection_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_length", 0, 0, 0, 0);
        RNA_def_property_struct_type(prop, "MeshColorLayer");
        RNA_def_property_ui_text(prop, "Vertex Color Layers", "");
 
+       prop= RNA_def_property(srna, "active_vcol_layer", PROP_POINTER, PROP_UNSIGNED);
+       RNA_def_property_struct_type(prop, "MeshColorLayer");
+       RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_vcol_layer_get", "rna_Mesh_active_vcol_layer_set", NULL);
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer.");
+
        prop= RNA_def_property(srna, "float_layers", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
        RNA_def_property_collection_funcs(prop, "rna_Mesh_float_layers_begin", 0, 0, 0, "rna_Mesh_float_layers_length", 0, 0, 0, 0);
index 0b8a7df1ae128a3f2c17b1787cc27b975236c036..558722cc5e6af954f0bbecb9a49c29be07d9c37d 100644 (file)
@@ -269,6 +269,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
                                        ret= quat_cb; /* return the matrix instead */
                                }
                                break;
+                       default:
+                               break;
                        }
                }
 
@@ -677,6 +679,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
                        int seq_len, i;
                        PyObject *item;
                        PointerRNA itemptr;
+                       ListBase *lb;
+                       CollectionPointerLink *link;
+
+                       lb= (data)? (ListBase*)data: NULL;
                        
                        /* convert a sequence of dict's into a collection */
                        if(!PySequence_Check(value)) {
@@ -692,8 +698,15 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
                                        Py_XDECREF(item);
                                        return -1;
                                }
-                               
-                               RNA_property_collection_add(ptr, prop, &itemptr);
+
+                               if(lb) {
+                                       link= MEM_callocN(sizeof(CollectionPointerLink), "PyCollectionPointerLink");
+                                       link->ptr= itemptr;
+                                       BLI_addtail(lb, link);
+                               }
+                               else
+                                       RNA_property_collection_add(ptr, prop, &itemptr);
+
                                if(pyrna_pydict_to_props(&itemptr, item, "Converting a python list to an RNA collection")==-1) {
                                        Py_DECREF(item);
                                        return -1;
@@ -1380,10 +1393,21 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
                        break;
                }
                case PROP_COLLECTION:
-                       /* XXX not supported yet
-                        * ret = pyrna_prop_CreatePyObject(ptr, prop); */
-                       ret = NULL;
+               {
+                       ListBase *lb= (ListBase*)data;
+                       CollectionPointerLink *link;
+                       PyObject *linkptr;
+
+                       ret = PyList_New(0);
+
+                       for(link=lb->first; link; link=link->next) {
+                               linkptr= pyrna_struct_CreatePyObject(&link->ptr);
+                               PyList_Append(ret, linkptr);
+                               Py_DECREF(linkptr);
+                       }
+
                        break;
+               }
                default:
                        PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type);
                        ret = NULL;