[Bf-blender-cvs] [d13970de862] master: Fix T92930: Outliner "Show Active" bone fails in certain situations

Philipp Oeser noreply at git.blender.org
Tue Dec 21 14:12:00 CET 2021


Commit: d13970de8627bab29458a6eef951a84a7962b38a
Author: Philipp Oeser
Date:   Tue Nov 9 12:22:06 2021 +0100
Branches: master
https://developer.blender.org/rBd13970de8627bab29458a6eef951a84a7962b38a

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

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

M	source/blender/blenkernel/BKE_action.h
M	source/blender/blenkernel/intern/action.c
M	source/blender/editors/armature/pose_select.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/object/object_constraint.c
M	source/blender/editors/object/object_hook.c
M	source/blender/editors/object/object_relations.c
M	source/blender/editors/object/object_utils.c
M	source/blender/editors/screen/screen_context.c
M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_view3d/view3d_buttons.c
M	source/blender/editors/space_view3d/view3d_edit.c
M	source/blender/editors/space_view3d/view3d_gizmo_armature.c
M	source/blender/editors/transform/transform_orientations.c

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

diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index ea8ee3f93b1..5dd98dbb9a3 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -252,13 +252,29 @@ void BKE_pose_channel_session_uuid_generate(struct bPoseChannel *pchan);
  * from this pose.
  */
 struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
+/**
+ * Checks if the bone is on a visible armature layer
+ *
+ * \return true if on a visible layer, false otherwise.
+ */
+bool BKE_pose_is_layer_visible(const struct bArmature *arm, const struct bPoseChannel *pchan);
 /**
  * Find the active pose-channel for an object
- * (we can't just use pose, as layer info is in armature)
  *
- * \note #Object, not #bPose is used here, as we need layer info from Armature.
+ * \param check_arm_layer: checks if the bone is on a visible armature layer (this might be skipped
+ * (e.g. for "Show Active" from the Outliner).
+ * \return #bPoseChannel if found or NULL.
+ * \note #Object, not #bPose is used here, as we need info (layer/active bone) from Armature.
+ */
+struct bPoseChannel *BKE_pose_channel_active(struct Object *ob, const bool check_arm_layer);
+/**
+ * Find the active pose-channel for an object if it is on a visible armature layer
+ * (calls #BKE_pose_channel_active with check_arm_layer set to true)
+ *
+ * \return #bPoseChannel if found or NULL.
+ * \note #Object, not #bPose is used here, as we need info (layer/active bone) from Armature.
  */
-struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
+struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob);
 /**
  * Use this when detecting the "other selected bone",
  * when we have multiple armatures in pose mode.
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;
   }
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 17347aa57fe..0b889149f9d 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -746,7 +746,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
   const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
   bool changed = false;
 
-  pchan_act = BKE_pose_channel_active(ob);
+  pchan_act = BKE_pose_channel_active_if_layer_visible(ob);
   if (pchan_act == NULL) {
     return OPERATOR_CANCELLED;
   }
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index b8026cbb40c..6bf0e36a3cc 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2672,7 +2672,7 @@ static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v
 
 static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
 {
-  bPoseChannel *pchan = BKE_pose_channel_active(ob);
+  bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
   short proxy_protected, xco = 0, yco = 0;
   // int rb_col; // UNUSED
 
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 5c3a8fc2277..91a512ae8e9 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -89,7 +89,7 @@ ListBase *ED_object_constraint_active_list(Object *ob)
   if (ob->mode & OB_MODE_POSE) {
     bPoseChannel *pchan;
 
-    pchan = BKE_pose_channel_active(ob);
+    pchan = BKE_pose_channel_active_if_layer_visible(ob);
     if (pchan) {
       return &pchan->constraints;
     }
@@ -2215,7 +2215,7 @@ static bool get_new_constraint_target(
     bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, bool add)
 {
   Object *obact = ED_object_active_context(C);
-  bPoseChannel *pchanact = BKE_pose_channel_active(obact);
+  bPoseChannel *pchanact = BKE_pose_channel_active_if_layer_visible(obact);
   bool only_curve = false, only_mesh = false, only_ob = false;
   bool found = false;
 
@@ -2370,7 +2370,7 @@ static int constraint_add_exec(
     pchan = NULL;
   }
   else {
-    pchan = BKE_pose_channel_active(ob);
+    pchan = BKE_pose_channel_active_if_layer_visible(ob);
 
     /* ensure not to confuse object/pose adding */
     if (pchan == NULL) {
@@ -2650,7 +2650,7 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
 static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-  bPoseChannel *pchan = BKE_pose_channel_active(ob);
+  bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
   bConstraint *con = NULL;
 
   uiPopupMenu *pup;
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 5065a2c00f0..51967ff35c7 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -582,7 +582,7 @@ static int add_hook_object(const bContext *C,
 
       BLI_strncpy(hmd->subtarget, arm->act_bone->name, sizeof(hmd->subtarget));
 
-      pchan_act = BKE_pose_channel_active(ob);
+      pchan_act = BKE_pose_channel_active_if_layer_visible(ob);
       if (LIKELY(pchan_act)) {
         invert_m4_m4(pose_mat, pchan_act->pose_mat);
         mul_v3_m4v3(cent, ob->obmat, pchan_act->pose_mat[3]);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 811f20e82be..71d9482597d 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -583,8 +583,8 @@ bool ED_object_parent_set(ReportList *reports,
     }
     case PAR_BONE:
     case PAR_BONE_RELATIVE:
-      pchan = BKE_pose_channel_active(par);
-      pchan_eval = BKE_pose_channel_active(parent_eval);
+      pchan = BKE_pose_channel_active_if_layer_visible(par);
+      pchan_eval = BKE_pose_channel_active_if_layer_visible(parent_eval);
 
       if (pchan == NULL) {
         BKE_report(reports, RPT_ERROR, "No active bone");
diff --git a/source/blender/editors/object/object_utils.c b/source/blender/editors/object/object_utils.c
index 5f85f6ea0eb..df44d840ad3 100644
--- a/source/blender/editors/object/object_utils.c
+++ b/source/blender/editors/object/object_utils.c
@@ -115,7 +115,7 @@ bool ED_object_calc_active_center_for_posemode(Object *ob,
                                                const bool select_only,
                                                float r_center[3])
 {
-  bPoseChannel *pchan = BKE_pose_channel_active(ob);
+  bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
   if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
     copy_v3_v3(r_center, pchan->pose_head);
     return true;
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 304205d0cc4..04df90bf912 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -501,7 +501,7 @@ static eContextResult screen_ctx_active_pose_bone(const bContext *C, bContextDat
   Object *obact = view_layer->basact ? view_layer->basact->object : NULL;
   Object *obpose = BKE_object_pose_armature_get(obact);
 
-  bPoseChannel *pchan = BKE_pose_channel_active(obpose);
+  bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(obpose);
   if (pchan) {
     CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
     return CTX_RESULT_OK;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 34f442eb2f7..282ded43ac1 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -38,6 +38,7 @@
 
 #include "BLT_translation.h"
 
+#include "BKE_action.h"
 #include "BKE_animsys.h"
 #include "BKE_appdir.h"
 #include "BKE_armature.h"
@@ -48,6 +49,7 @@
 #include "BKE_lib_query.h"
 #include "BKE_lib_remap.h"
 #include "BKE_main.h"
+#include "BKE_object.h"
 #include "BKE_report.h"
 #include "BKE_workspace.h"
 
@@ -1264,7 +1266,8 @@ static TreeElement *outliner_show_active_get_element(bContext *C,
     TreeElement *te_obact = te;
 
     if (obact->mode & OB_MODE_POSE) {
-      bPoseChannel *pchan = CTX_data_active_pose_bone(C);
+      Object *obpose = BKE_object_pose_armature_get(obact);
+      bPoseChan

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list