pose mode: extend selection flipping to use the same method as editmode.
adds extend and active only opton.
This commit is contained in:
@@ -255,7 +255,8 @@ kmi.properties.direction = 'CHILD'
|
||||
kmi.properties.extend = True
|
||||
kmi = km.keymap_items.new('pose.select_linked', 'L', 'PRESS', alt=True)
|
||||
kmi = km.keymap_items.new('pose.select_grouped', 'G', 'PRESS', shift=True)
|
||||
kmi = km.keymap_items.new('pose.select_flip_active', 'F', 'PRESS', shift=True)
|
||||
kmi = km.keymap_items.new('pose.select_mirror', 'F', 'PRESS', shift=True)
|
||||
kmi.properties.only_active = True
|
||||
kmi = km.keymap_items.new('pose.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.keymap_items.new('pose.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.keymap_items.new('pose.ik_add', 'I', 'PRESS', shift=True)
|
||||
|
@@ -315,7 +315,8 @@ kmi.properties.direction = 'CHILD'
|
||||
kmi.properties.extend = True
|
||||
kmi = km.keymap_items.new('pose.select_linked', 'L', 'PRESS')
|
||||
kmi = km.keymap_items.new('pose.select_grouped', 'G', 'PRESS', shift=True)
|
||||
kmi = km.keymap_items.new('pose.select_flip_active', 'F', 'PRESS', shift=True)
|
||||
kmi = km.keymap_items.new('pose.select_mirror', 'F', 'PRESS', shift=True)
|
||||
kmi.properties.only_active = True
|
||||
kmi = km.keymap_items.new('pose.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.keymap_items.new('pose.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.keymap_items.new('pose.ik_add', 'I', 'PRESS', shift=True)
|
||||
|
@@ -532,7 +532,7 @@ class VIEW3D_MT_select_pose(Menu):
|
||||
|
||||
layout.operator("pose.select_all").action = 'TOGGLE'
|
||||
layout.operator("pose.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("pose.select_flip_active", text="Flip Active")
|
||||
layout.operator("pose.select_mirror", text="Flip Active")
|
||||
layout.operator("pose.select_constraint_target", text="Constraint Target")
|
||||
layout.operator("pose.select_linked", text="Linked")
|
||||
|
||||
|
@@ -110,7 +110,7 @@ void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_linked(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_constraint_target(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_grouped(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_flip_active(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_mirror(struct wmOperatorType *ot);
|
||||
|
||||
void POSE_OT_group_add(struct wmOperatorType *ot);
|
||||
void POSE_OT_group_remove(struct wmOperatorType *ot);
|
||||
|
@@ -116,7 +116,7 @@ void ED_operatortypes_armature(void)
|
||||
WM_operatortype_append(POSE_OT_select_linked);
|
||||
WM_operatortype_append(POSE_OT_select_constraint_target);
|
||||
WM_operatortype_append(POSE_OT_select_grouped);
|
||||
WM_operatortype_append(POSE_OT_select_flip_active);
|
||||
WM_operatortype_append(POSE_OT_select_mirror);
|
||||
|
||||
WM_operatortype_append(POSE_OT_group_add);
|
||||
WM_operatortype_append(POSE_OT_group_remove);
|
||||
@@ -363,7 +363,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
|
||||
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_flip_active", FKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_mirror", FKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "POSE_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
|
||||
|
@@ -1050,6 +1050,9 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
|
||||
|
||||
/****************** Mirror Select ****************/
|
||||
|
||||
/**
|
||||
* \note clone of #pose_select_mirror_exec keep in sync
|
||||
*/
|
||||
static int armature_select_mirror_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -1102,7 +1105,7 @@ static int armature_select_mirror_exec(bContext *C, wmOperator *op)
|
||||
void ARMATURE_OT_select_mirror(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Mirror Select";
|
||||
ot->name = "Flip Active/Selected Bone";
|
||||
ot->idname = "ARMATURE_OT_select_mirror";
|
||||
ot->description = "Mirror the bone selection";
|
||||
|
||||
|
@@ -62,6 +62,11 @@
|
||||
|
||||
#include "armature_intern.h"
|
||||
|
||||
/* utility macros fro storing a temp int in the bone (selection flag) */
|
||||
#define PBONE_PREV_FLAG_GET(pchan) ((void)0, (GET_INT_FROM_POINTER((pchan)->temp)))
|
||||
#define PBONE_PREV_FLAG_SET(pchan, val) ((pchan)->temp = SET_INT_IN_POINTER(val))
|
||||
|
||||
|
||||
/* ***************** Pose Select Utilities ********************* */
|
||||
|
||||
/* Utility method for changing the selection status of a bone */
|
||||
@@ -837,52 +842,78 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
|
||||
|
||||
/* -------------------------------------- */
|
||||
|
||||
/* context active object, or weightpainted object with armature in posemode */
|
||||
static int pose_bone_flip_active_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
/**
|
||||
* \note clone of #armature_select_mirror_exec keep in sync
|
||||
*/
|
||||
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob_act = CTX_data_active_object(C);
|
||||
Object *ob = BKE_object_pose_armature_get(ob_act);
|
||||
|
||||
if (ob && (ob->mode & OB_MODE_POSE)) {
|
||||
bArmature *arm = ob->data;
|
||||
|
||||
if (arm->act_bone) {
|
||||
bPoseChannel *pchanf;
|
||||
char name_flip[MAXBONENAME];
|
||||
BKE_deform_flip_side_name(name_flip, arm->act_bone->name, true);
|
||||
|
||||
pchanf = BKE_pose_channel_find_name(ob->pose, name_flip);
|
||||
if (pchanf && pchanf->bone != arm->act_bone) {
|
||||
arm->act_bone->flag &= ~BONE_SELECTED;
|
||||
pchanf->bone->flag |= BONE_SELECTED;
|
||||
|
||||
arm->act_bone = pchanf->bone;
|
||||
|
||||
/* in weightpaint we select the associated vertex group too */
|
||||
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
ED_vgroup_select_by_name(ob_act, name_flip);
|
||||
DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan, *pchan_mirror_act = NULL;
|
||||
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
|
||||
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
|
||||
if ((ob && (ob->mode & OB_MODE_POSE)) == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
arm = ob->data;
|
||||
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
const int flag = (pchan->bone->flag & BONE_SELECTED);
|
||||
PBONE_PREV_FLAG_SET(pchan, flag);
|
||||
}
|
||||
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (PBONE_SELECTABLE(arm, pchan->bone)) {
|
||||
bPoseChannel *pchan_mirror;
|
||||
int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
|
||||
|
||||
if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
|
||||
(PBONE_VISIBLE(arm, pchan_mirror->bone)))
|
||||
{
|
||||
const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
|
||||
flag_new |= flag_mirror;
|
||||
|
||||
if (pchan->bone == arm->act_bone) {
|
||||
pchan_mirror_act = pchan_mirror;
|
||||
}
|
||||
|
||||
/* skip all but the active or its mirror */
|
||||
if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (pchan_mirror_act) {
|
||||
arm->act_bone = pchan_mirror_act->bone;
|
||||
|
||||
/* in weightpaint we select the associated vertex group too */
|
||||
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
|
||||
DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void POSE_OT_select_flip_active(wmOperatorType *ot)
|
||||
void POSE_OT_select_mirror(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Flip Selected Active Bone";
|
||||
ot->idname = "POSE_OT_select_flip_active";
|
||||
ot->description = "Activate the bone with a flipped name";
|
||||
ot->name = "Flip Active/Selected Bone";
|
||||
ot->idname = "POSE_OT_select_mirror";
|
||||
ot->description = "Mirror the bone selection";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = pose_bone_flip_active_exec;
|
||||
ot->exec = pose_select_mirror_exec;
|
||||
ot->poll = ED_operator_posemode;
|
||||
|
||||
/* flags */
|
||||
|
Reference in New Issue
Block a user