Anim: Remove PBONE_SELECTABLE macro

This patch replaces the `PBONE_SELECTABLE` macro with functions.
There is a slight functional change in that for pose bones: the visibility
is now correctly accounted for. Before this change it would always look
at the `Bone` visibility. This is no longer the correct way to
check for that since a43359eb88
moved that to the pose bone

Part of #138482

Pull Request: https://projects.blender.org/blender/blender/pulls/145974
This commit is contained in:
Christoph Lendenfeld
2025-09-11 10:00:13 +02:00
committed by Christoph Lendenfeld
parent 1517aa4416
commit baafbd8e95
6 changed files with 23 additions and 16 deletions

View File

@@ -56,6 +56,16 @@ inline bool bone_is_selected(const bArmature *armature, const EditBone *ebone)
return (ebone->flag & BONE_SELECTED) && bone_is_visible(armature, ebone);
}
inline bool bone_is_selectable(const bArmature *armature, const bPoseChannel *pchan)
{
return bone_is_visible(armature, pchan) && !(pchan->bone->flag & BONE_UNSELECTABLE);
}
inline bool bone_is_selectable(const bArmature *armature, const Bone *bone)
{
return bone_is_visible(armature, bone) && !(bone->flag & BONE_UNSELECTABLE);
}
/**
* Iterates all descendents of the given pose bone including the bone itself. Iterates breadth
* first.

View File

@@ -568,9 +568,6 @@ void BKE_pchan_bbone_deform_segment_index(const bPoseChannel *pchan,
int *r_index,
float *r_blend_next);
#define PBONE_SELECTABLE(arm, bone) \
(blender::animrig::bone_is_visible(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE))
/* context.selected_pose_bones */
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan) \
for (bPoseChannel *_pchan = (bPoseChannel *)(_ob)->pose->chanbase.first; _pchan; \

View File

@@ -109,7 +109,7 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select, bool chan
arm = static_cast<bArmature *>(ob->data);
/* can only change selection state if bone can be modified */
if (PBONE_SELECTABLE(arm, pchan->bone)) {
if (blender::animrig::bone_is_selectable(arm, pchan)) {
/* change selection state - activate too if selected */
if (select) {
pchan->bone->flag |= BONE_SELECTED;
@@ -513,7 +513,7 @@ static wmOperatorStatus pose_select_linked_exec(bContext *C, wmOperator * /*op*/
/* Select parents */
for (curBone = pchan->bone; curBone; curBone = next) {
if (PBONE_SELECTABLE(arm, curBone)) {
if (blender::animrig::bone_is_selectable(arm, curBone)) {
curBone->flag |= BONE_SELECTED;
if (curBone->flag & BONE_CONNECTED) {
@@ -740,7 +740,7 @@ static wmOperatorStatus pose_select_hierarchy_exec(bContext *C, wmOperator *op)
Bone *bone_parent;
bone_parent = pchan_act->parent->bone;
if (PBONE_SELECTABLE(arm, bone_parent)) {
if (blender::animrig::bone_is_selectable(arm, bone_parent)) {
if (!add_to_sel) {
pchan_act->bone->flag &= ~BONE_SELECTED;
}
@@ -759,7 +759,7 @@ static wmOperatorStatus pose_select_hierarchy_exec(bContext *C, wmOperator *op)
for (pass = 0; pass < 2 && (bone_child == nullptr); pass++) {
LISTBASE_FOREACH (bPoseChannel *, pchan_iter, &ob->pose->chanbase) {
/* possible we have multiple children, some invisible */
if (PBONE_SELECTABLE(arm, pchan_iter->bone)) {
if (blender::animrig::bone_is_selectable(arm, pchan_iter)) {
if (pchan_iter->parent == pchan_act) {
if ((pass == 1) || (pchan_iter->bone->flag & BONE_CONNECTED)) {
bone_child = pchan_iter->bone;
@@ -1001,7 +1001,7 @@ static bool pose_select_children(bContext *C, const bool all, const bool extend)
deselect_pose_bones(selected_pose_bones);
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose_object->pose->chanbase) {
if (!PBONE_SELECTABLE(arm, pchan->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan)) {
continue;
}
if (all) {
@@ -1040,7 +1040,7 @@ static bool pose_select_parents(bContext *C, const bool extend)
if (!pchan->parent) {
continue;
}
if (!PBONE_SELECTABLE(arm, pchan->parent->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan->parent->bone)) {
continue;
}
pose_do_bone_select(pchan->parent, SEL_SELECT);
@@ -1070,7 +1070,7 @@ static bool pose_select_siblings(bContext *C, const bool extend)
deselect_pose_bones(parents_of_selected);
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose_object->pose->chanbase) {
if (!PBONE_SELECTABLE(arm, pchan->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan)) {
continue;
}
/* Checking if the bone is already selected so `changed_any_selection` stays true to its
@@ -1153,7 +1153,7 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
if (pchan) {
/* select if bone is visible and can be affected */
if (PBONE_SELECTABLE(arm, pchan->bone)) {
if (blender::animrig::bone_is_selectable(arm, pchan)) {
pchan->bone->flag |= BONE_SELECTED;
changed = true;
}
@@ -1331,7 +1331,7 @@ static wmOperatorStatus pose_select_mirror_exec(bContext *C, wmOperator *op)
}
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
if (!PBONE_SELECTABLE(arm, pchan->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan)) {
continue;
}

View File

@@ -259,7 +259,7 @@ static void do_outliner_object_select_recursive(const Scene *scene,
static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
{
LISTBASE_FOREACH (Bone *, bone, &bone_parent->childbase) {
if (select && PBONE_SELECTABLE(arm, bone)) {
if (select && blender::animrig::bone_is_selectable(arm, bone)) {
bone->flag |= BONE_SELECTED;
}
else {

View File

@@ -229,7 +229,7 @@ static void outliner_select_sync_to_pose_bone(TreeElement *te,
short bone_flag = pchan->bone->flag;
if (PBONE_SELECTABLE(arm, pchan->bone)) {
if (blender::animrig::bone_is_selectable(arm, pchan)) {
if (tselem->flag & TSE_SELECTED) {
pchan->bone->flag |= BONE_SELECTED;

View File

@@ -520,7 +520,7 @@ static void do_lasso_select_pose__do_tag(void *user_data,
{
LassoSelectUserData *data = static_cast<LassoSelectUserData *>(user_data);
const bArmature *arm = static_cast<bArmature *>(data->vc->obact->data);
if (!PBONE_SELECTABLE(arm, pchan->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan)) {
return;
}
@@ -5040,7 +5040,7 @@ static void do_circle_select_pose__doSelectBone(void *user_data,
{
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(user_data);
bArmature *arm = static_cast<bArmature *>(data->vc->obact->data);
if (!PBONE_SELECTABLE(arm, pchan->bone)) {
if (!blender::animrig::bone_is_selectable(arm, pchan)) {
return;
}