Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_animsys.h10
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c156
-rw-r--r--source/blender/editors/armature/editarmature.c11
-rw-r--r--source/blender/makesrna/RNA_access.h2
-rw-r--r--source/blender/makesrna/intern/rna_access.c75
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c7
-rw-r--r--source/blender/makesrna/intern/rna_key.c24
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c7
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)