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
This commit is contained in:
parent
fac42e3fa1
commit
d13970de86
Notes:
blender-bot
2024-05-08 11:36:44 +02:00
Referenced by issue #95204, Bone's Custom Properties are invisible in the Bone Properties Editor if bone in hidden layer Referenced by issue #92930, Outliner "Show Active" frames object instead of bone for Bones on hidden layers in Pose Mode.
|
@ -253,12 +253,28 @@ void BKE_pose_channel_session_uuid_generate(struct bPoseChannel *pchan);
|
|||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
|
||||
/**
|
||||
* Find the active pose-channel for an object
|
||||
* (we can't just use pose, as layer info is in armature)
|
||||
* Checks if the bone is on a visible armature layer
|
||||
*
|
||||
* \note #Object, not #bPose is used here, as we need layer info from Armature.
|
||||
* \return true if on a visible layer, false otherwise.
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
|
||||
bool BKE_pose_is_layer_visible(const struct bArmature *arm, const struct bPoseChannel *pchan);
|
||||
/**
|
||||
* Find the active pose-channel for an object
|
||||
*
|
||||
* \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_if_layer_visible(struct Object *ob);
|
||||
/**
|
||||
* Use this when detecting the "other selected bone",
|
||||
* when we have multiple armatures in pose mode.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(obpose, false);
|
||||
if (pchan) {
|
||||
te = outliner_find_posechannel(&te_obact->subtree, pchan);
|
||||
}
|
||||
|
|
|
@ -1552,7 +1552,7 @@ static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
|
|||
PointerRNA pchanptr;
|
||||
uiLayout *col;
|
||||
|
||||
pchan = BKE_pose_channel_active(ob);
|
||||
pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
|
||||
if (!pchan) {
|
||||
uiItemL(layout, IFACE_("No Bone Active"), ICON_NONE);
|
||||
|
|
|
@ -3216,7 +3216,7 @@ static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
if (obact->mode & OB_MODE_POSE) {
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact);
|
||||
bPoseChannel *pcham_act = BKE_pose_channel_active(obact_eval);
|
||||
bPoseChannel *pcham_act = BKE_pose_channel_active_if_layer_visible(obact_eval);
|
||||
if (pcham_act) {
|
||||
BLI_strncpy(v3d->ob_center_bone, pcham_act->name, sizeof(v3d->ob_center_bone));
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType
|
|||
if (ob) {
|
||||
const bArmature *arm = ob->data;
|
||||
if (arm->drawtype == ARM_B_BONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
if (pchan && pchan->bone->segments > 1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *g
|
|||
{
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Object *ob = BKE_object_pose_armature_get(OBACT(view_layer));
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
|
||||
const wmGizmoType *gzt_move = WM_gizmotype_find("GIZMO_GT_move_3d", true);
|
||||
|
||||
|
@ -187,7 +187,7 @@ static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup
|
|||
}
|
||||
|
||||
struct BoneSplineWidgetGroup *bspline_group = gzgroup->customdata;
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
|
||||
/* Handles */
|
||||
for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
|
||||
|
|
|
@ -513,7 +513,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
|
|||
|
||||
if (ob) {
|
||||
if (ob->mode & OB_MODE_POSE) {
|
||||
const bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
const bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob);
|
||||
if (pchan && gimbal_axis_pose(ob, pchan, r_mat)) {
|
||||
break;
|
||||
}
|
||||
|
@ -1224,7 +1224,7 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
|
|||
float imat[3][3], mat[3][3];
|
||||
bool ok = false;
|
||||
|
||||
if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
|
||||
if (activeOnly && (pchan = BKE_pose_channel_active_if_layer_visible(ob))) {
|
||||
add_v3_v3(normal, pchan->pose_mat[2]);
|
||||
add_v3_v3(plane, pchan->pose_mat[1]);
|
||||
ok = true;
|
||||
|
|
Loading…
Reference in New Issue