From cf20aa834484269eef39912162a91f4d198c0c7e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Jul 2013 01:49:20 +0000 Subject: move ED_armature_edit_bone_select() into a more general utility function so view3d-select bone operators can use it and get matching selection behavior when entering editmode. - specifically - write to the connected parents tipsel flag when setting the rootsel flag. --- source/blender/editors/armature/armature_select.c | 24 +++------ source/blender/editors/armature/armature_utils.c | 59 ++++++++++++++++++++++ source/blender/editors/include/ED_armature.h | 7 +++ .../blender/editors/space_view3d/view3d_select.c | 39 ++++++-------- 4 files changed, 88 insertions(+), 41 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index d2d13ec8598..53d561c7736 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -682,16 +682,6 @@ static EnumPropertyItem prop_similar_types[] = { {0, NULL, 0, NULL, NULL} }; -/* could be used in more places */ -static void ED_armature_edit_bone_select(EditBone *ebone) -{ - BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); - ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - if ((ebone->flag & BONE_CONNECTED) && (ebone->parent != NULL)) { - ebone->parent->flag |= BONE_TIPSEL; - } -} static void select_similar_length(bArmature *arm, EditBone *ebone_act, const float thresh) { @@ -706,7 +696,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo if ((ebone->length >= len_min) && (ebone->length <= len_max)) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -724,7 +714,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const sub_v3_v3v3(dir, ebone->head, ebone->tail); if (angle_v3v3(dir_act, dir) / (float)M_PI < thresh) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -737,7 +727,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_SELECTABLE(arm, ebone)) { if (ebone->layer & ebone_act->layer) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -760,8 +750,8 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char prefix_other[MAX_VGROUP_NAME]; BKE_deform_split_prefix(ebone->name, prefix_other, body_tmp); - if (!strcmp(prefix_act, prefix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(prefix_act, prefix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } @@ -784,8 +774,8 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char suffix_other[MAX_VGROUP_NAME]; BKE_deform_split_suffix(ebone->name, body_tmp, suffix_other); - if (!strcmp(suffix_act, suffix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(suffix_act, suffix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 5173bc66e99..0e93a00b01d 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -704,3 +704,62 @@ void undo_push_armature(bContext *C, const char *name) // XXX solve getdata() undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); } + +/* *************************************************************** */ +/* Low level selection functions which hide connected-parent + * flag behavior which gets tricky to handle in selection operators. + * (no flushing in ED_armature_ebone_select.*, that should be explicit) */ + +int ED_armature_ebone_selectflag_get(const EditBone *ebone) +{ + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + return ((ebone->flag & (BONE_SELECTED | BONE_TIPSEL)) | + ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0)); + } + else { + return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)); + } +} + +void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag) +{ + flag = flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->parent->flag &= ~BONE_TIPSEL; + + ebone->flag |= flag; + ebone->parent->flag |= (flag & BONE_ROOTSEL) ? BONE_TIPSEL : 0; + } + else { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->flag |= flag; + } +} + +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag | flag); +} + +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag & ~flag); +} + +/* could be used in more places */ +void ED_armature_ebone_select_set(EditBone *ebone, bool select) +{ + int flag; + if (select) { + BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); + flag = (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + flag = 0; + } + ED_armature_ebone_selectflag_set(ebone, flag); +} diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 801fa12d444..32436ebae2d 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -153,6 +153,13 @@ void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const void undo_push_armature(struct bContext *C, const char *name); +/* low level selection functions which handle */ +int ED_armature_ebone_selectflag_get(const EditBone *ebone); +void ED_armature_ebone_selectflag_set(EditBone *ebone, const int flag); +void ED_armature_ebone_select_set(EditBone *ebone, bool select); +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag); +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); + /* poseobject.c */ void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 96cd5a22f58..3fd0f79b2f0 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -625,8 +625,8 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, INT_MAX)) { is_point_done = true; - if (data->select) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; + if (data->select) ED_armature_ebone_selectflag_enable(ebone, BONE_ROOTSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_ROOTSEL); } } @@ -637,8 +637,8 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, INT_MAX)) { is_point_done = true; - if (data->select) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; + if (data->select) ED_armature_ebone_selectflag_enable(ebone, BONE_TIPSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_TIPSEL); } } @@ -646,8 +646,7 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo if ((is_point_done == false) && (points_proj_tot == 2) && BLI_lasso_is_edge_inside(data->mcords, data->moves, x0, y0, x1, y1, INT_MAX)) { - if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + ED_armature_ebone_select_set(ebone, data->select); data->is_change = true; } @@ -1910,14 +1909,14 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (index & BONESEL_TIP) { ebone->flag |= BONE_DONE; - if (select) ebone->flag |= BONE_TIPSEL; - else ebone->flag &= ~BONE_TIPSEL; + if (select) ED_armature_ebone_selectflag_enable(ebone, BONE_TIPSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_TIPSEL); } if (index & BONESEL_ROOT) { ebone->flag |= BONE_DONE; - if (select) ebone->flag |= BONE_ROOTSEL; - else ebone->flag &= ~BONE_ROOTSEL; + if (select) ED_armature_ebone_selectflag_enable(ebone, BONE_ROOTSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_ROOTSEL); } } } @@ -1939,10 +1938,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool if (index & BONESEL_BONE) { if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (!(ebone->flag & BONE_DONE)) { - if (select) - ebone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED); - else - ebone->flag &= ~(BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED); + ED_armature_ebone_select_set(ebone, select); } } } @@ -2602,16 +2598,12 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, cons if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (head) { - if (data->select) - ebone->flag |= BONE_ROOTSEL; - else - ebone->flag &= ~BONE_ROOTSEL; + if (data->select) ED_armature_ebone_selectflag_enable(ebone, BONE_ROOTSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_ROOTSEL); } else { - if (data->select) - ebone->flag |= BONE_TIPSEL; - else - ebone->flag &= ~BONE_TIPSEL; + if (data->select) ED_armature_ebone_selectflag_enable(ebone, BONE_TIPSEL); + else ED_armature_ebone_selectflag_disable(ebone, BONE_TIPSEL); } return 1; } @@ -2652,8 +2644,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB if ((is_point_done == false) && (points_proj_tot == 2) && edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { - if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + ED_armature_ebone_select_set(ebone, data->select); data->is_change = true; } -- cgit v1.2.3