[Bf-blender-cvs] [14e7ba0c8ac] master: Fix Pose Lib: pose is applied when selected bones don't overlap with pose

Sybren A. Stüvel noreply at git.blender.org
Fri Mar 9 19:09:46 CET 2018


Commit: 14e7ba0c8ac7f229a1b025103a786f267dfb9387
Author: Sybren A. Stüvel
Date:   Fri Mar 9 19:03:29 2018 +0100
Branches: master
https://developer.blender.org/rB14e7ba0c8ac7f229a1b025103a786f267dfb9387

Fix Pose Lib: pose is applied when selected bones don't overlap with pose

Premise: When pose bones are selected, applying a pose library should
only affect the selected bones.

This commit fixes a bug where the pose was also applied when there was
no overlap between the selected bones and the bones in the pose. For
example, applying a pose which contains only keyframes for the left
hand, while only right-hand bones are selected, would apply the pose
to the left hand anyway.

The code is now also slightly more efficient; the removed 'selcount'
counter was only used as a binary (i.e. zero or non-zero). It's now
stored as a bitflag instead.

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

M	source/blender/editors/armature/pose_lib.c

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

diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 587ae6991a2..d9d5fa395d6 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -833,7 +833,6 @@ typedef struct tPoseLib_PreviewData {
 	bAction *act;           /* poselib to use */
 	TimeMarker *marker;     /* 'active' pose */
 
-	int selcount;           /* number of selected elements to work on */
 	int totcount;           /* total number of elements to work on */
 
 	short state;            /* state of main loop */
@@ -866,7 +865,8 @@ enum {
 /* defines for tPoseLib_PreviewData->flag values */
 enum {
 	PL_PREVIEW_FIRSTTIME    = (1 << 0),
-	PL_PREVIEW_SHOWORIGINAL = (1 << 1)
+	PL_PREVIEW_SHOWORIGINAL = (1 << 1),
+	PL_PREVIEW_ANY_BONE_SELECTED = (1 << 2),
 };
 
 /* ---------------------------- */
@@ -886,7 +886,20 @@ static void poselib_backup_posecopy(tPoseLib_PreviewData *pld)
 {
 	bActionGroup *agrp;
 	bPoseChannel *pchan;
-	
+	bool selected = false;
+
+	/* determine whether any bone is selected. */
+	LISTBASE_FOREACH (bPoseChannel *, bchan, &pld->pose->chanbase) {
+		selected = bchan->bone != NULL && bchan->bone->flag & BONE_SELECTED;
+		if (selected) {
+			pld->flag |= PL_PREVIEW_ANY_BONE_SELECTED;
+			break;
+		}
+	}
+	if (!selected) {
+		pld->flag &= ~PL_PREVIEW_ANY_BONE_SELECTED;
+	}
+
 	/* for each posechannel that has an actionchannel in */
 	for (agrp = pld->act->groups.first; agrp; agrp = agrp->next) {
 		/* try to find posechannel */
@@ -908,8 +921,6 @@ static void poselib_backup_posecopy(tPoseLib_PreviewData *pld)
 			BLI_addtail(&pld->backups, plb);
 			
 			/* mark as being affected */
-			if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
-				pld->selcount++;
 			pld->totcount++;
 		}
 	}
@@ -970,6 +981,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
 	KeyframeEditData ked = {{NULL}};
 	KeyframeEditFunc group_ok_cb;
 	int frame = 1;
+	const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
 	
 	/* get the frame */
 	if (pld->marker)
@@ -982,8 +994,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
 	group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
 	ked.f1 = ((float)frame) - 0.5f;
 	ked.f2 = ((float)frame) + 0.5f;
-	
-	
+
 	/* start applying - only those channels which have a key at this point in time! */
 	for (agrp = act->groups.first; agrp; agrp = agrp->next) {
 		/* check if group has any keyframes */
@@ -995,7 +1006,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
 				bool ok = 0;
 				
 				/* check if this bone should get any animation applied */
-				if (pld->selcount == 0) {
+				if (!any_bone_selected) {
 					/* if no bones are selected, then any bone is ok */
 					ok = 1;
 				}
@@ -1008,7 +1019,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
 						ok = 1;
 					}
 				}
-				
+
 				if (ok) 
 					animsys_evaluate_action_group(ptr, act, agrp, NULL, (float)frame);
 			}
@@ -1027,14 +1038,15 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
 	KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
 	ListBase dsources = {NULL, NULL};
 	bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
-	
+	const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
+
 	/* start tagging/keying */
 	for (agrp = act->groups.first; agrp; agrp = agrp->next) {
 		/* only for selected bones unless there aren't any selected, in which case all are included  */
 		pchan = BKE_pose_channel_find_name(pose, agrp->name);
 		
 		if (pchan) {
-			if ((pld->selcount == 0) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
+			if (!any_bone_selected || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
 				if (autokey) {
 					/* add datasource override for the PoseChannel, to be used later */
 					ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);



More information about the Bf-blender-cvs mailing list