forked from bartvdbraak/blender
patch [#35789] Quick hack select more/less tool for armatures
by Pedro Riera (priera), Andrey Dubravin and parts rewritten by myself.
This commit is contained in:
parent
80f3b32e06
commit
2dc6b22382
@ -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'
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user