From e07b245fe1f41cab13d772c3e26adc2521126324 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 27 Apr 2020 15:41:22 +0200 Subject: 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 --- source/blender/editors/armature/pose_select.c | 66 +++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) (limited to 'source/blender/editors/armature/pose_select.c') diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 41ad5433931..ce652b0eaf4 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -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) -- cgit v1.2.3