From 2dc6b22382279deef21df3e36ae04019e3581ef8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Jul 2013 10:51:54 +0000 Subject: patch [#35789] Quick hack select more/less tool for armatures by Pedro Riera (priera), Andrey Dubravin and parts rewritten by myself. --- release/scripts/startup/bl_ui/space_view3d.py | 5 + source/blender/editors/armature/armature_intern.h | 2 + source/blender/editors/armature/armature_ops.c | 5 + source/blender/editors/armature/armature_select.c | 139 ++++++++++++++++++++++ 4 files changed, 151 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 4eb4ae380cd..2bbfd26f5f3 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -748,6 +748,11 @@ class VIEW3D_MT_select_edit_armature(Menu): layout.separator() + layout.operator("armature.select_more", text="More") + layout.operator("armature.select_less", text="Less") + + layout.separator() + layout.operator("armature.select_hierarchy", text="Parent").direction = 'PARENT' layout.operator("armature.select_hierarchy", text="Child").direction = 'CHILD' diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index bfebc68ea46..e58d8fd2380 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -63,6 +63,8 @@ void ARMATURE_OT_parent_clear(struct wmOperatorType *ot); void ARMATURE_OT_select_all(struct wmOperatorType *ot); void ARMATURE_OT_select_inverse(struct wmOperatorType *ot); +void ARMATURE_OT_select_more(struct wmOperatorType *ot); +void ARMATURE_OT_select_less(struct wmOperatorType *ot); void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot); void ARMATURE_OT_select_linked(struct wmOperatorType *ot); void ARMATURE_OT_select_similar(struct wmOperatorType *ot); diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 568178802bd..0090522d1e1 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -59,6 +59,8 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_select_all); WM_operatortype_append(ARMATURE_OT_select_inverse); + WM_operatortype_append(ARMATURE_OT_select_more); + WM_operatortype_append(ARMATURE_OT_select_less); WM_operatortype_append(ARMATURE_OT_select_hierarchy); WM_operatortype_append(ARMATURE_OT_select_linked); WM_operatortype_append(ARMATURE_OT_select_similar); @@ -258,6 +260,9 @@ void ED_keymap_armature(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); RNA_boolean_set(kmi->ptr, "extend", TRUE); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 53d561c7736..d05d309b201 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -665,6 +665,145 @@ void ARMATURE_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/**************** Select more/less **************/ + +#define EBONE_PREV_FLAG_GET(ebone) ((void)0, (GET_INT_FROM_POINTER(ebone->temp))) +#define EBONE_PREV_FLAG_SET(ebone, val) (ebone->temp = SET_INT_IN_POINTER(val)) + +static void armature_select_more(bArmature *arm, EditBone *ebone) +{ + if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != 0) { + if (EBONE_SELECTABLE(arm, ebone)) { + ED_armature_ebone_select_set(ebone, true); + } + } + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + /* to parent */ + if ((EBONE_PREV_FLAG_GET(ebone) & BONE_ROOTSEL) != 0) { + if (EBONE_SELECTABLE(arm, ebone->parent)) { + ED_armature_ebone_selectflag_enable(ebone->parent, (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)); + } + } + + /* from parent (difference from select less) */ + if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_TIPSEL) != 0) { + if (EBONE_SELECTABLE(arm, ebone)) { + ED_armature_ebone_selectflag_enable(ebone, (BONE_SELECTED | BONE_ROOTSEL)); + } + } + } +} + +static void armature_select_less(bArmature *UNUSED(arm), EditBone *ebone) +{ + if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != (BONE_ROOTSEL | BONE_TIPSEL)) { + ED_armature_ebone_select_set(ebone, false); + } + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + /* to parent */ + if ((EBONE_PREV_FLAG_GET(ebone) & BONE_SELECTED) == 0) { + ED_armature_ebone_selectflag_disable(ebone->parent, (BONE_SELECTED | BONE_TIPSEL)); + } + + /* from parent (difference from select more) */ + if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_SELECTED) == 0) { + ED_armature_ebone_selectflag_disable(ebone, (BONE_SELECTED | BONE_ROOTSEL)); + } + } +} + +static void armature_select_more_less(Object* ob, bool more) +{ + bArmature* arm = (bArmature *)ob->data; + EditBone* ebone; + + /* XXX, eventually we shouldn't need this - campbell */ + ED_armature_sync_selection(arm->edbo); + + /* count bones & store selection state */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + EBONE_PREV_FLAG_SET(ebone, ED_armature_ebone_selectflag_get(ebone)); + } + + /* do selection */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + if (more) { + armature_select_more(arm, ebone); + } + else { + armature_select_less(arm, ebone); + } + } + } + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + if (more == false) { + if (ebone->flag & BONE_SELECTED) { + ED_armature_ebone_select_set(ebone, true); + } + } + } + ebone->temp = NULL; + } + + ED_armature_sync_selection(arm->edbo); +} + +#undef EBONE_PREV_FLAG_GET +#undef EBONE_PREV_FLAG_SET + +static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + armature_select_more_less(obedit, true); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "ARMATURE_OT_select_more"; + ot->description = "Select those bones connected to the initial selection"; + + /* api callbacks */ + ot->exec = armature_de_select_more_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int armature_de_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + armature_select_more_less(obedit, false); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "ARMATURE_OT_select_less"; + ot->description = "Deselect those bones at the boundary of each selection region"; + + /* api callbacks */ + ot->exec = armature_de_select_less_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + enum { SIMEDBONE_LENGTH = 1, SIMEDBONE_DIRECTION, -- cgit v1.2.3