fix for circle select ignoring lock selection option for pose and edit modes, added macros PBONE_SELECTABLE, EBONE_SELECTABLE

This commit is contained in:
Campbell Barton 2012-10-05 05:27:51 +00:00
parent 6e65c7842b
commit 07a0463ac5
6 changed files with 74 additions and 74 deletions

@ -132,6 +132,7 @@ Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest);
/* like EBONE_VISIBLE */
#define PBONE_VISIBLE(arm, bone) (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P))
#define PBONE_SELECTABLE(arm, bone) (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE))
#ifdef __cplusplus
}

@ -1831,7 +1831,7 @@ void ED_armature_deselect_all_visible(Object *obedit)
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
/* first and foremost, bone must be visible and selected */
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, ebone)) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
}
@ -4106,7 +4106,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo
const float len_max = ebone_act->length * (1.0f + thresh);
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, ebone)) {
if ((ebone->length >= len_min) &&
(ebone->length <= len_max))
{
@ -4123,7 +4123,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const
sub_v3_v3v3(dir_act, ebone_act->head, ebone_act->tail);
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, ebone)) {
float dir[3];
sub_v3_v3v3(dir, ebone->head, ebone->tail);
@ -4139,7 +4139,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act)
EditBone *ebone;
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, ebone)) {
if (ebone->layer & ebone_act->layer) {
ED_armature_edit_bone_select(ebone);
}
@ -4161,7 +4161,7 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act)
/* Find matches */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
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)) {
@ -4185,7 +4185,7 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act)
/* Find matches */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
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)) {
@ -4270,7 +4270,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
for (curbone = arm->edbo->first; curbone; curbone = curbone->next) {
/* only work on bone if it is visible and its selection can change */
if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, curbone)) {
if (curbone == arm->act_edbone) {
if (direction == BONE_SELECT_PARENT) {
if (curbone->parent == NULL) continue;
@ -4290,7 +4290,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
chbone = editbone_get_child(arm, curbone, 1);
if (chbone == NULL) continue;
if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, chbone)) {
chbone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
arm->act_edbone = chbone;

@ -492,7 +492,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
if (pchan->parent == NULL) continue;
else pabone = pchan->parent->bone;
if (PBONE_VISIBLE(arm, pabone)) {
if (PBONE_SELECTABLE(arm, pabone)) {
if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
pabone->flag |= BONE_SELECTED;
arm->act_bone = pabone;
@ -514,7 +514,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
for (pchan_child = ob->pose->chanbase.first; pchan_child; pchan_child = pchan_child->next) {
/* possible we have multiple children, some invisible */
if (PBONE_VISIBLE(arm, pchan_child->bone)) {
if (PBONE_SELECTABLE(arm, pchan_child->bone)) {
if (pchan_child->parent == pchan) {
chbone = pchan_child->bone;
break;
@ -526,7 +526,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
if (chbone == NULL) continue;
#endif
if (PBONE_VISIBLE(arm, chbone)) {
if (PBONE_SELECTABLE(arm, chbone)) {
if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
chbone->flag |= BONE_SELECTED;
arm->act_bone = chbone;
@ -719,9 +719,7 @@ static int pose_select_same_keyingset(bContext *C, Object *ob, short extend)
if (pchan) {
/* select if bone is visible and can be affected */
if ((PBONE_VISIBLE(arm, pchan->bone)) &&
(pchan->bone->flag & BONE_UNSELECTABLE) == 0)
{
if (PBONE_SELECTABLE(arm, pchan->bone)) {
pchan->bone->flag |= BONE_SELECTED;
changed = 1;
}

@ -94,6 +94,7 @@ typedef struct EditBone {
/* useful macros */
#define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A))
#define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE))
#define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED))
/* used in bone_select_hierachy() */

@ -398,7 +398,7 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
/*************************** selection utilities *******************************/
static int key_test_depth(PEData *data, const float co[3], int screen_co[2])
static int key_test_depth(PEData *data, const float co[3], const int screen_co[2])
{
View3D *v3d= data->vc.v3d;
double ux, uy, uz;

@ -333,7 +333,7 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, int mcords[][2], s
if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) return;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (PBONE_VISIBLE(arm, pchan->bone) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
if (PBONE_SELECTABLE(arm, pchan->bone)) {
/* XXX, todo, use ED_view3d_project_int_object */
sco1[0] = sco2[0] = IS_CLIPPED;
@ -581,7 +581,7 @@ static void do_lasso_select_armature(ViewContext *vc, int mcords[][2], short mov
/* set editdata in vc */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE) == 0) {
if (EBONE_SELECTABLE(arm, ebone)) {
/* XXX, TODO, use ED_view3d_project_short_object here */
sco1[0] = sco2[0] = IS_CLIPPED;
@ -2380,33 +2380,31 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f
/* check each PoseChannel... */
/* TODO: could be optimized at some point */
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
short sco1[2], sco2[2], didpoint = 0;
float vec[3];
/* skip invisible bones */
if (PBONE_VISIBLE(arm, pchan->bone) == 0)
continue;
if (PBONE_SELECTABLE(arm, pchan->bone)) {
short sco1[2], sco2[2], didpoint = 0;
float vec[3];
/* XXX, TODO, center check does not check for clipping! */
/* XXX, TODO, use ED_view3d_project_short_object here */
/* project head location to screenspace */
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head);
ED_view3d_project_short_global(vc->ar, vec, sco1, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* project tail location to screenspace */
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail);
ED_view3d_project_short_global(vc->ar, vec, sco2, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* check if the head and/or tail is in the circle
* - the call to check also does the selection already
*/
if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1]))
didpoint = 1;
if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1]))
didpoint = 1;
change |= didpoint;
/* XXX, TODO, center check does not check for clipping! */
/* XXX, TODO, use ED_view3d_project_short_object here */
/* project head location to screenspace */
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head);
ED_view3d_project_short_global(vc->ar, vec, sco1, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* project tail location to screenspace */
mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail);
ED_view3d_project_short_global(vc->ar, vec, sco2, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* check if the head and/or tail is in the circle
* - the call to check also does the selection already
*/
if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1]))
didpoint = 1;
if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1]))
didpoint = 1;
change |= didpoint;
}
}
if (change) {
@ -2455,39 +2453,41 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2
/* check each EditBone... */
/* TODO: could be optimized at some point */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
short sco1[2], sco2[2], didpoint = 0;
float vec[3];
/* XXX, TODO, center check does not check for clipping! */
/* XXX, TODO, use ED_view3d_project_short_object here */
if (EBONE_SELECTABLE(arm, ebone)) {
short sco1[2], sco2[2], didpoint = 0;
float vec[3];
/* project head location to screenspace */
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head);
ED_view3d_project_short_global(vc->ar, vec, sco1, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* project tail location to screenspace */
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail);
ED_view3d_project_short_global(vc->ar, vec, sco2, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* check if the head and/or tail is in the circle
* - the call to check also does the selection already
*/
if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1))
didpoint = 1;
if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0))
didpoint = 1;
/* only if the endpoints didn't get selected, deal with the middle of the bone too */
/* XXX should we just do this always? */
if ((didpoint == 0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1])) {
if (select)
ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED;
else
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
change = TRUE;
/* XXX, TODO, center check does not check for clipping! */
/* XXX, TODO, use ED_view3d_project_short_object here */
/* project head location to screenspace */
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->head);
ED_view3d_project_short_global(vc->ar, vec, sco1, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* project tail location to screenspace */
mul_v3_m4v3(vec, vc->obedit->obmat, ebone->tail);
ED_view3d_project_short_global(vc->ar, vec, sco2, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
/* check if the head and/or tail is in the circle
* - the call to check also does the selection already
*/
if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1))
didpoint = 1;
if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0))
didpoint = 1;
/* only if the endpoints didn't get selected, deal with the middle of the bone too */
/* XXX should we just do this always? */
if ((didpoint == 0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1])) {
if (select)
ebone->flag |= BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED;
else
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
change = TRUE;
}
change |= didpoint;
}
change |= didpoint;
}
if (change) {