From 8bc48307bac9755b68297ebc2a6565a4b2343400 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 17 Nov 2013 05:18:10 +1100 Subject: pose mode: extend selection flipping to use the same method as editmode. adds extend and active only opton. --- source/blender/editors/armature/armature_intern.h | 2 +- source/blender/editors/armature/armature_ops.c | 4 +- source/blender/editors/armature/armature_select.c | 5 +- source/blender/editors/armature/pose_select.c | 97 +++++++++++++++-------- 4 files changed, 71 insertions(+), 37 deletions(-) (limited to 'source') diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 3707e13095b..bc7d69d1558 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -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); diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 040b6f33f3b..4c7eb847054 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -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); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 10e77043cca..003f6bf36f3 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -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"; diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index b6786db8cb3..b3277c185d4 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -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 */ -- cgit v1.2.3