Armature posemode: add mouse independent "Select Linked" operator

The current "Select Linked" operator works based on mouse position and
makes no sense to call from the menus and was removed in rB536055e1ee0b.

This patch adds an operator independent from mouse position that just
selects all bones in relation to selected bones (and adds back menu
entries, adds keymap entry CTRL+L).

The original operator is renamed to 'select_linked_pick' internally
(this is now more in line to how "Select Linked" works for meshes,
curves etc)

ref T76071

Maniphest Tasks: T76071

Differential Revision: https://developer.blender.org/D7542
This commit is contained in:
Philipp Oeser 2020-04-27 15:41:22 +02:00
parent afeddd42e6
commit e07b245fe1
Notes: blender-bot 2023-02-14 06:46:23 +01:00
Referenced by commit 18dbc8f5c1, Resolve keymap conflict for poselib
Referenced by issue #76071, Pose: Select Linked does not work from menu
5 changed files with 66 additions and 6 deletions

View File

@ -3859,7 +3859,8 @@ def km_pose(params):
{"properties": [("direction", 'CHILD'), ("extend", False)]}),
("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True},
{"properties": [("direction", 'CHILD'), ("extend", True)]}),
("pose.select_linked", {"type": 'L', "value": 'PRESS'}, None),
("pose.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
("pose.select_linked_pick", {"type": 'L', "value": 'PRESS'}, None),
("pose.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None),
("pose.select_mirror", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None),
("pose.constraint_add_with_targets", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None),

View File

@ -1469,6 +1469,7 @@ class VIEW3D_MT_select_pose(Menu):
layout.separator()
layout.operator("pose.select_constraint_target", text="Constraint Target")
layout.operator("pose.select_linked", text="Linked")
layout.separator()

View File

@ -104,6 +104,7 @@ void POSE_OT_select_all(struct wmOperatorType *ot);
void POSE_OT_select_parent(struct wmOperatorType *ot);
void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
void POSE_OT_select_linked(struct wmOperatorType *ot);
void POSE_OT_select_linked_pick(struct wmOperatorType *ot);
void POSE_OT_select_constraint_target(struct wmOperatorType *ot);
void POSE_OT_select_grouped(struct wmOperatorType *ot);
void POSE_OT_select_mirror(struct wmOperatorType *ot);

View File

@ -100,6 +100,7 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_select_parent);
WM_operatortype_append(POSE_OT_select_hierarchy);
WM_operatortype_append(POSE_OT_select_linked);
WM_operatortype_append(POSE_OT_select_linked_pick);
WM_operatortype_append(POSE_OT_select_constraint_target);
WM_operatortype_append(POSE_OT_select_grouped);
WM_operatortype_append(POSE_OT_select_mirror);

View File

@ -454,22 +454,22 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve
return OPERATOR_FINISHED;
}
static bool pose_select_linked_poll(bContext *C)
static bool pose_select_linked_pick_poll(bContext *C)
{
return (ED_operator_view3d_active(C) && ED_operator_posemode(C));
}
void POSE_OT_select_linked(wmOperatorType *ot)
void POSE_OT_select_linked_pick(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Connected";
ot->idname = "POSE_OT_select_linked";
ot->description = "Select bones related to selected ones by parent/child relationships";
ot->idname = "POSE_OT_select_linked_pick";
ot->description = "Select bones linked by parent/child connections under the mouse cursor";
/* callbacks */
/* leave 'exec' unset */
ot->invoke = pose_select_connected_invoke;
ot->poll = pose_select_linked_poll;
ot->poll = pose_select_linked_pick_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -482,6 +482,62 @@ void POSE_OT_select_linked(wmOperatorType *ot)
"Extend selection instead of deselecting everything first");
}
static int pose_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Bone *curBone, *next = NULL;
CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
if ((pchan->bone->flag & BONE_SELECTED) == 0) {
continue;
}
bArmature *arm = ob->data;
/* Select parents */
for (curBone = pchan->bone; curBone; curBone = next) {
if (PBONE_SELECTABLE(arm, curBone)) {
curBone->flag |= BONE_SELECTED;
if (curBone->flag & BONE_CONNECTED) {
next = curBone->parent;
}
else {
next = NULL;
}
}
else {
next = NULL;
}
}
/* Select children */
for (curBone = pchan->bone->childbase.first; curBone; curBone = curBone->next) {
selectconnected_posebonechildren(ob, curBone, false);
}
ED_pose_bone_select_tag_update(ob);
}
CTX_DATA_END;
ED_outliner_select_sync_from_pose_bone_tag(C);
return OPERATOR_FINISHED;
}
void POSE_OT_select_linked(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Connected";
ot->idname = "POSE_OT_select_linked";
ot->description = "Select all bones linked by parent/child connections to the current selection";
/* callbacks */
ot->exec = pose_select_linked_exec;
ot->poll = ED_operator_posemode;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* -------------------------------------- */
static int pose_de_select_all_exec(bContext *C, wmOperator *op)