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.
This commit is contained in:
parent
40e62f271c
commit
14e7ba0c8a
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue