From d13970de8627bab29458a6eef951a84a7962b38a Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 9 Nov 2021 12:22:06 +0100 Subject: Fix T92930: Outliner "Show Active" bone fails in certain situations Outliner would frame the armature object instead of the bone if the bone was on a hidden armature layer. Similar to issues reported in e.g. T58068 and T80464, this is due to the fact that `BKE_pose_channel_active` always checks for the armature layer (and returns NULL if a bone is not on a visible armature layer). Now propose to make this layer check **optional** (and e.g. from the Outliner be more permissive). This also introduces `BKE_pose_channel_active_if_layer_visible` which just wraps `BKE_pose_channel_active` with the check being ON. Maniphest Tasks: T92930 Differential Revision: https://developer.blender.org/D13154 --- source/blender/blenkernel/intern/action.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern/action.c') diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index ddba726ba83..764c043f5ed 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -705,7 +705,12 @@ bool BKE_pose_channels_is_valid(const bPose *pose) #endif -bPoseChannel *BKE_pose_channel_active(Object *ob) +bool BKE_pose_is_layer_visible(const bArmature *arm, const bPoseChannel *pchan) +{ + return (pchan->bone->layer & arm->layer); +} + +bPoseChannel *BKE_pose_channel_active(Object *ob, const bool check_arm_layer) { bArmature *arm = (ob) ? ob->data : NULL; bPoseChannel *pchan; @@ -716,14 +721,21 @@ bPoseChannel *BKE_pose_channel_active(Object *ob) /* find active */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone) && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer)) { - return pchan; + if ((pchan->bone) && (pchan->bone == arm->act_bone)) { + if (!check_arm_layer || BKE_pose_is_layer_visible(arm, pchan)) { + return pchan; + } } } return NULL; } +bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob) +{ + return BKE_pose_channel_active(ob, true); +} + bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob) { bArmature *arm = (ob) ? ob->data : NULL; @@ -732,7 +744,7 @@ bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob) return NULL; } - bPoseChannel *pchan = BKE_pose_channel_active(ob); + bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob); if (pchan && (pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) { return pchan; } -- cgit v1.2.3