diff options
-rw-r--r-- | source/blender/blenkernel/BKE_animsys.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 156 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 11 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 75 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_key.c | 24 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 7 |
8 files changed, 269 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index cc5b4dfdcaf..045095567bc 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -67,6 +67,7 @@ struct KeyingSet *BKE_keyingset_add(struct ListBase *list, const char name[], sh /* Add a destination to a KeyingSet */ void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode); +/* Find the destination matching the criteria given */ struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode); /* Copy all KeyingSets in the given list */ @@ -79,6 +80,15 @@ void BKE_keyingset_free(struct KeyingSet *ks); void BKE_keyingsets_free(struct ListBase *list); /* ************************************* */ +/* Path Fixing API */ + +/* Fix all the paths for the given ID+AnimData */ +void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, char *prefix, char *oldName, char *newName); + +/* Fix all the paths for the entire database... */ +void BKE_all_animdata_fix_paths_rename(char *prefix, char *oldName, char *newName); + +/* ************************************* */ // TODO: overrides, remapping, and path-finding api's /* ************************************* */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 47f5dd116d7..316ac484484 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -238,24 +238,69 @@ void BKE_animdata_make_local(AnimData *adt) /* Path Validation -------------------------------------------- */ -#if 0 -/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */ -static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath) +/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate + * + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.pose_channels["Bone"] + */ +static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldpath) { + char *prefixPtr= strstr(oldpath, prefix); + char *oldNamePtr= strstr(oldpath, oldName); + int prefixLen= strlen(prefix); + int oldNameLen= strlen(oldName); + /* only start fixing the path if the prefix and oldName feature in the path, + * and prefix occurs immediately before oldName (the +2 should take care of any [") + */ + if ( (prefixPtr && oldNamePtr) && (prefixPtr+prefixLen+2 == oldNamePtr) ) { + DynStr *ds= BLI_dynstr_new(); + char *postfixPtr= oldNamePtr+oldNameLen+2; + char *newPath = NULL; + char oldChar; + + /* add the part of the string that goes up to the start of the prefix */ + if (prefixPtr > oldpath) { + oldChar= prefixPtr[0]; + prefixPtr[0]= 0; + BLI_dynstr_append(ds, oldpath); + prefixPtr[0]= oldChar; + } + + /* add the prefix, and opening brackets */ + BLI_dynstr_append(ds, prefix); + BLI_dynstr_append(ds, "[\""); + + /* add the new name */ + BLI_dynstr_append(ds, newName); + + /* add the closing brackets, then the postfix */ + BLI_dynstr_append(ds, "\"]"); + BLI_dynstr_append(ds, postfixPtr); + + /* create new path, and cleanup old data */ + newPath= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + + MEM_freeN(oldpath); + + /* return the new path */ + return newPath; + } - return oldpath; // FIXME!!! + /* the old path doesn't need to be changed */ + return oldpath; } /* Check RNA-Paths for a list of F-Curves */ -static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *curves) +static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *curves) { FCurve *fcu; /* we need to check every curve... */ for (fcu= curves->first; fcu; fcu= fcu->next) { /* firstly, handle the F-Curve's own path */ - fcu->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, fcu->rna_path); + fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path); /* driver? */ if (fcu->driver) { @@ -264,14 +309,14 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new /* driver targets */ for (dtar= driver->targets.first; dtar; dtar=dtar->next) { - dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path); + dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path); } } } } /* Fix all RNA-Paths for Actions linked to NLA Strips */ -static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *strips) +static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *strips) { NlaStrip *strip; @@ -279,42 +324,113 @@ static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *n for (strip= strips->first; strip; strip= strip->next) { /* fix strip's action */ if (strip->act) - fcurves_path_rename_fix(owner_id, modPtr, newName, &strip->act->curves); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves); /* ignore own F-Curves, since those are local... */ /* check sub-strips (if metas) */ - nlastrips_path_rename_fix(owner_id, modPtr, newName, &strip->strips); + nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips); } } /* Fix all RNA-Paths in the AnimData block used by the given ID block - * - the pointer of interest must not have had its new name assigned already, otherwise - * path matching for this will never work + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.pose_channels["Bone"] */ -void BKE_animdata_fix_paths_rename (ID *owner_id, PointerRNA *modPtr, char *newName) +void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, char *prefix, char *oldName, char *newName) { - AnimData *adt= BKE_animdata_from_id(owner_id); NlaTrack *nlt; /* if no AnimData, no need to proceed */ - if (ELEM4(NULL, owner_id, adt, modPtr, newName)) + if (ELEM4(NULL, owner_id, adt, oldName, newName)) return; /* Active action and temp action */ if (adt->action) - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->action->curves); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &adt->action->curves); if (adt->tmpact) - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->tmpact->curves); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &adt->tmpact->curves); /* Drivers - Drivers are really F-Curves */ - fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->drivers); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &adt->drivers); /* NLA Data - Animation Data for Strips */ - for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) + nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &nlt->strips); +} + +/* Fix all RNA-Paths throughout the database (directly access the Global.main version) + * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]> + * i.e. pose.pose_channels["Bone"] + */ +void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newName) +{ + Main *mainptr= G.main; + ID *id; + + /* macro for less typing + * - whether animdata exists is checked for by the main renaming callback, though taking + * this outside of the function may make things slightly faster? + */ +#define RENAMEFIX_ANIM_IDS(first) \ + for (id= first; id; id= id->next) { \ + AnimData *adt= BKE_animdata_from_id(id); \ + BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName);\ + } + + /* nodes */ + RENAMEFIX_ANIM_IDS(mainptr->nodetree.first); + + /* textures */ + RENAMEFIX_ANIM_IDS(mainptr->tex.first); + + /* lamps */ + RENAMEFIX_ANIM_IDS(mainptr->lamp.first); + + /* materials */ + RENAMEFIX_ANIM_IDS(mainptr->mat.first); + + /* cameras */ + RENAMEFIX_ANIM_IDS(mainptr->camera.first); + + /* shapekeys */ + RENAMEFIX_ANIM_IDS(mainptr->key.first); + + /* metaballs */ + RENAMEFIX_ANIM_IDS(mainptr->mball.first); + + /* curves */ + RENAMEFIX_ANIM_IDS(mainptr->curve.first); + + /* armatures */ + RENAMEFIX_ANIM_IDS(mainptr->armature.first); + + /* meshes */ + // TODO... + + /* particles */ + RENAMEFIX_ANIM_IDS(mainptr->particle.first); + + /* objects */ + RENAMEFIX_ANIM_IDS(mainptr->object.first); + + /* worlds */ + RENAMEFIX_ANIM_IDS(mainptr->world.first); + + /* scenes */ + for (id= mainptr->scene.first; id; id= id->next) { + AnimData *adt= BKE_animdata_from_id(id); + Scene *scene= (Scene *)id; + + /* do compositing nodes first (since these aren't included in main tree) */ + if (scene->nodetree) { + AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree); + BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName); + } + /* now fix scene animation data as per normal */ + BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName); } } -#endif /* *********************************** */ /* KeyingSet API */ diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 0343fea5bfb..1c2ec920d41 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5289,9 +5289,8 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) /* now check if we're in editmode, we need to find the unique name */ if (arm->edbo) { - EditBone *eBone; + EditBone *eBone= editbone_name_exists(arm->edbo, oldname); - eBone= editbone_name_exists(arm->edbo, oldname); if (eBone) { unique_editbone_name(arm->edbo, newname, NULL); BLI_strncpy(eBone->name, newname, MAXBONENAME); @@ -5302,7 +5301,7 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) Bone *bone= get_named_bone(arm, oldname); if (bone) { - unique_bone_name (arm, newname); + unique_bone_name(arm, newname); BLI_strncpy(bone->name, newname, MAXBONENAME); } else return; @@ -5379,6 +5378,12 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) BLI_strncpy(dg->name, newname, MAXBONENAME); } } + + /* Fix animation data attached to this object */ + if (ob->adt) { + /* posechannels only... */ + BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.pose_channels", oldname, newname); + } } /* do entire db - ipo's for the drivers */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 810fb110f7a..a3cdf29669f 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -704,6 +704,8 @@ char *RNA_path_back(const char *path); int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop); +int RNA_path_resolve_next(PointerRNA *ptr, char **path, + PointerRNA *r_ptr, PropertyRNA **r_prop); char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 6cf2fd0c60f..a2202b36c0c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2216,6 +2216,81 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int return buf; } +/* Resolve the given RNA path to find the next pointer+property pointed to in the path */ +// NOTE: this is the same as the code below, except that we don't have the while() loop to traverse the entire path +int RNA_path_resolve_next(PointerRNA *ptr, char **path, PointerRNA *r_ptr, PropertyRNA **r_prop) +{ + PropertyRNA *prop; + PointerRNA curptr, nextptr; + char fixedbuf[256], *token; + int len, intkey; + + prop= NULL; + curptr= *ptr; + + if ((path == NULL) || (*path == 0)) + return 0; + + /* look up property name in current struct */ + token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0); + if (!token) + return 0; + + prop= RNA_struct_find_property(&curptr, token); + + if(token != fixedbuf) + MEM_freeN(token); + if (!prop) + return 0; + + /* now look up the value of this property if it is a pointer or + * collection, otherwise return the property rna so that the + * caller can read the value of the property itself */ + if(RNA_property_type(prop) == PROP_POINTER) { + nextptr= RNA_property_pointer_get(&curptr, prop); + + if(nextptr.data) + curptr= nextptr; + else + return 0; + } + else if(RNA_property_type(prop) == PROP_COLLECTION && *path) { + /* resolve the lookup with [] brackets */ + token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1); + + if(!token) + return 0; + + len= strlen(token); + + /* check for "" to see if it is a string */ + if(len >= 2 && token[0] == '"' && token[len-1] == '"') { + /* strip away "" */ + token[len-1]= 0; + RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr); + } + else { + /* otherwise do int lookup */ + intkey= atoi(token); + RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr); + } + + if(token != fixedbuf) + MEM_freeN(token); + + if(nextptr.data) + curptr= nextptr; + else + return 0; + } + + *r_ptr= curptr; + *r_prop= prop; + + return 1; +} + +/* Resolve the given RNA path to find the pointer+property indicated at the end of the path */ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop) { PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 53c8db6ff0f..54097f25b99 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -155,6 +155,10 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr) static void rna_Constraint_name_set(PointerRNA *ptr, const char *value) { bConstraint *con= ptr->data; + char oldname[32]; + + /* make a copy of the old name first */ + BLI_strncpy(oldname, con->name, sizeof(oldname)); /* copy the new name into the name slot */ BLI_strncpy(con->name, value, sizeof(con->name)); @@ -168,6 +172,9 @@ static void rna_Constraint_name_set(PointerRNA *ptr, const char *value) if (list) unique_constraint_name(con, list); } + + /* fix all the animation data which may link to this */ + BKE_all_animdata_fix_paths_rename("constraints", oldname, con->name); } static char *rna_Constraint_path(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index 230ed90c131..1e1eb9b055f 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -37,6 +37,8 @@ #ifdef RNA_RUNTIME +#include <stddef.h> + #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -47,6 +49,27 @@ #include "WM_api.h" #include "WM_types.h" +void rna_ShapeKey_name_set(PointerRNA *ptr, const char *value) +{ + KeyBlock *kb= ptr->data; + char oldname[32]; + + /* make a copy of the old name first */ + BLI_strncpy(oldname, kb->name, sizeof(oldname)); + + /* copy the new name into the name slot */ + BLI_strncpy(kb->name, value, sizeof(kb->name)); + + /* make sure the name is truly unique */ + if (ptr->id.data) { + Key *key= ptr->id.data; + BLI_uniquename(&key->block, kb, "Key", '.', offsetof(KeyBlock, name), 32); + } + + /* fix all the animation data which may link to this */ + BKE_all_animdata_fix_paths_rename("keys", oldname, kb->name); +} + static void rna_ShapeKey_value_set(PointerRNA *ptr, float value) { KeyBlock *data= (KeyBlock*)ptr->data; @@ -353,6 +376,7 @@ static void rna_def_keyblock(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShapeKey_name_set"); RNA_def_struct_name_property(srna, prop); /* keys need to be sorted to edit this */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1be610ee392..91df7800156 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -168,6 +168,10 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr) void rna_Modifier_name_set(PointerRNA *ptr, const char *value) { ModifierData *md= ptr->data; + char oldname[32]; + + /* make a copy of the old name first */ + BLI_strncpy(oldname, md->name, sizeof(oldname)); /* copy the new name into the name slot */ BLI_strncpy(md->name, value, sizeof(md->name)); @@ -177,6 +181,9 @@ void rna_Modifier_name_set(PointerRNA *ptr, const char *value) Object *ob= ptr->id.data; modifier_unique_name(&ob->modifiers, md); } + + /* fix all the animation data which may link to this */ + BKE_all_animdata_fix_paths_rename("modifiers", oldname, md->name); } static char *rna_Modifier_path(PointerRNA *ptr) |