[Bf-blender-cvs] [414ebc68c2c] master: Fix T60686: Renaming an animated bone breaks its animation

Sergey Sharybin noreply at git.blender.org
Tue Jan 22 14:53:37 CET 2019


Commit: 414ebc68c2cccabc20eb9b966c8235d222874d56
Author: Sergey Sharybin
Date:   Tue Jan 22 14:50:58 2019 +0100
Branches: master
https://developer.blender.org/rB414ebc68c2cccabc20eb9b966c8235d222874d56

Fix T60686: Renaming an animated bone breaks its animation

After rename is done we need to make sure all copies of
corresponding datablocks are updated in all dependency
graphs: otherwise bone will have a new name, but animation
will still be using an old one.

===================================================================

M	source/blender/blenkernel/intern/anim_sys.c

===================================================================

diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 2a11fba8eab..9aff54ea3bc 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -709,90 +709,97 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o
 }
 
 /* Check RNA-Paths for a list of F-Curves */
-static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+static bool fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
                                     const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
 {
 	FCurve *fcu;
-
-	/* we need to check every curve... */
+	bool is_changed = false;
+	/* We need to check every curve. */
 	for (fcu = curves->first; fcu; fcu = fcu->next) {
-		if (fcu->rna_path) {
-			const char *old_path = fcu->rna_path;
-
-			/* firstly, handle the F-Curve's own path */
-			fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
-
-			/* if path changed and the F-Curve is grouped, check if its group also needs renaming
-			 * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename)
-			 */
-			if (fcu->rna_path != old_path) {
-				bActionGroup *agrp = fcu->grp;
-
-				if ((agrp) && STREQ(oldName, agrp->name)) {
-					BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
-				}
+		if (fcu->rna_path == NULL) {
+			continue;
+		}
+		const char *old_path = fcu->rna_path;
+		/* Firstly, handle the F-Curve's own path. */
+		fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
+		/* if path changed and the F-Curve is grouped, check if its group also needs renaming
+		 * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename) */
+		if (fcu->rna_path != old_path) {
+			bActionGroup *agrp = fcu->grp;
+			is_changed = true;
+			if ((agrp != NULL) && STREQ(oldName, agrp->name)) {
+				BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
 			}
 		}
 	}
+	return is_changed;
 }
 
 /* Check RNA-Paths for a list of Drivers */
-static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName,
+static bool drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName,
                                     const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
 {
+	bool is_changed = false;
 	FCurve *fcu;
-
-	/* we need to check every curve - drivers are F-Curves too! */
+	/* We need to check every curve - drivers are F-Curves too. */
 	for (fcu = curves->first; fcu; fcu = fcu->next) {
 		/* firstly, handle the F-Curve's own path */
-		if (fcu->rna_path)
+		if (fcu->rna_path != NULL) {
+			const char *old_rna_path = fcu->rna_path;
 			fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
-
-		/* driver? */
-		if (fcu->driver) {
-			ChannelDriver *driver = fcu->driver;
-			DriverVar *dvar;
-
-			/* driver variables */
-			for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
-				/* only change the used targets, since the others will need fixing manually anyway */
-				DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
-				{
-					/* rename RNA path */
-					if (dtar->rna_path && dtar->id)
-						dtar->rna_path = rna_path_rename_fix(dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
-
-					/* also fix the bone-name (if applicable) */
-					if (strstr(prefix, "bones")) {
-						if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB) && (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
-						     (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name) )
-						{
-							BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
-						}
+			is_changed |= (fcu->rna_path != old_rna_path);
+		}
+		if (fcu->driver == NULL) {
+			continue;
+		}
+		ChannelDriver *driver = fcu->driver;
+		DriverVar *dvar;
+		/* driver variables */
+		for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+			/* only change the used targets, since the others will need fixing manually anyway */
+			DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
+			{
+				/* rename RNA path */
+				if (dtar->rna_path && dtar->id) {
+					const char *old_rna_path = dtar->rna_path;
+					dtar->rna_path = rna_path_rename_fix(dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
+					is_changed |= (dtar->rna_path != old_rna_path);
+				}
+				/* also fix the bone-name (if applicable) */
+				if (strstr(prefix, "bones")) {
+					if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB) && (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
+					     (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name) )
+					{
+						is_changed = true;
+						BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
 					}
 				}
-				DRIVER_TARGETS_LOOPER_END;
 			}
+			DRIVER_TARGETS_LOOPER_END;
 		}
 	}
+	return is_changed;
 }
 
 /* Fix all RNA-Paths for Actions linked to NLA Strips */
-static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+static bool nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
                                       const char *oldKey, const char *newKey, ListBase *strips, bool verify_paths)
 {
 	NlaStrip *strip;
-
-	/* recursively check strips, fixing only actions... */
+	bool is_changed = false;
+	/* Recursively check strips, fixing only actions. */
 	for (strip = strips->first; strip; strip = strip->next) {
 		/* fix strip's action */
-		if (strip->act)
-			fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
-		/* ignore own F-Curves, since those are local...  */
-
-		/* check sub-strips (if metas) */
-		nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
+		if (strip->act != NULL) {
+			is_changed |= fcurves_path_rename_fix(
+			        owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
+		}
+		/* Ignore own F-Curves, since those are local.  */
+		/* Check sub-strips (if metas) */
+		is_changed |= nlastrips_path_rename_fix(
+		        owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
 	}
+	return is_changed;
 }
 
 /* Rename Sub-ID Entities in RNA Paths ----------------------- */
@@ -900,14 +907,14 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons
 {
 	NlaTrack *nlt;
 	char *oldN, *newN;
-
-	/* if no AnimData, no need to proceed */
-	if (ELEM(NULL, owner_id, adt))
+	/* If no AnimData, no need to proceed. */
+	if (ELEM(NULL, owner_id, adt)) {
 		return;
-
-	/* Name sanitation logic - shared with BKE_action_fix_paths_rename() */
+	}
+	bool is_self_changed = false;
+	/* Name sanitation logic - shared with BKE_action_fix_paths_rename(). */
 	if ((oldName != NULL) && (newName != NULL)) {
-		/* pad the names with [" "] so that only exact matches are made */
+		/* Pad the names with [" "] so that only exact matches are made. */
 		const size_t name_old_len = strlen(oldName);
 		const size_t name_new_len = strlen(newName);
 		char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
@@ -922,20 +929,33 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons
 		oldN = BLI_sprintfN("[%d]", oldSubscript);
 		newN = BLI_sprintfN("[%d]", newSubscript);
 	}
-
-	/* Active action and temp action */
-	if (adt->action)
-		fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths);
-	if (adt->tmpact)
-		fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths);
-
+	/* Active action and temp action. */
+	if (adt->action != NULL) {
+		if (fcurves_path_rename_fix(owner_id, prefix, oldName, newName,
+		                            oldN, newN, &adt->action->curves, verify_paths))
+		{
+			DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+		}
+	}
+	if (adt->tmpact) {
+		if (fcurves_path_rename_fix(owner_id, prefix, oldName, newName,
+		                            oldN, newN, &adt->tmpact->curves, verify_paths))
+		{
+			DEG_id_tag_update(&adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
+		}
+	}
 	/* Drivers - Drivers are really F-Curves */
-	drivers_path_rename_fix(owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
-
+	is_self_changed |= drivers_path_rename_fix(
+	         owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
 	/* NLA Data - Animation Data for Strips */
-	for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next)
-		nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
-
+	for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+		is_self_changed |= nlastrips_path_rename_fix(
+		        owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
+	}
+	/* Tag owner ID if it */
+	if (is_self_changed) {
+		DEG_id_tag_update(owner_id, ID_RECALC_COPY_ON_WRITE);
+	}
 	/* free the temp names */
 	MEM_freeN(oldN);
 	MEM_freeN(newN);



More information about the Bf-blender-cvs mailing list