diff options
author | Joshua Leung <aligorith@gmail.com> | 2010-12-31 06:35:34 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2010-12-31 06:35:34 +0300 |
commit | d4ea9eb9e73e43589ed0e3ce1f4ad2f8366035d5 (patch) | |
tree | bba953d2064e2fb895b334afb4908aff18f6d163 /source/blender/editors/space_view3d/view3d_select.c | |
parent | 770363376293aeda36fc891faa7c02d7d245ce99 (diff) |
Bugfix [#25415] Circle Selection does not work on bones in Pose mode
Clobbered together some new code to do this based on the code for Edit
Bone circle select as this case doesn't seem to have been implemented
yet.
NOTE: the code in view3d_select.c needs some urgent love and tidying
up (like a room full of flaking paint).
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index bbb26ad09a4..d26137bd115 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -32,6 +32,7 @@ #include <float.h> #include <assert.h> +#include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_meta_types.h" @@ -1688,9 +1689,11 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); if(bone) { if(select) { - bone->flag |= BONE_SELECTED; - bone_selected=1; + if ((bone->flag & BONE_UNSELECTABLE)==0) { + bone->flag |= BONE_SELECTED; + bone_selected=1; // XXX select_actionchannel_by_name(base->object->action, bone->name, 1); + } } else { bArmature *arm= base->object->data; @@ -2053,6 +2056,67 @@ static void lattice_circle_select(ViewContext *vc, int select, short *mval, floa } +// NOTE: pose-bone case is copied from editbone case... +static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) +{ + struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; + int mx = x - data->mval[0], my = y - data->mval[1]; + float r = sqrt(mx*mx + my*my); + + if (r <= data->radius) { + if (data->select) + pchan->bone->flag |= BONE_SELECTED; + else + pchan->bone->flag &= ~BONE_SELECTED; + return 1; + } + return 0; +} +static void pose_circle_select(ViewContext *vc, int select, short *mval, float rad) +{ + struct {ViewContext *vc; short select, mval[2]; float radius; } data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + int change= FALSE; + + /* set vc->edit data */ + data.select = select; + data.mval[0] = mval[0]; + data.mval[1] = mval[1]; + data.radius = rad; + + ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ + + /* check each PoseChannel... */ + // TODO: could be optimised at some point + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + short sco1[2], sco2[2], didpoint=0; + float vec[3]; + + /* project head location to screenspace */ + mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head); + project_short(vc->ar, vec, sco1); + + /* project tail location to screenspace */ + mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail); + project_short(vc->ar, vec, sco2); + + /* 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) { + WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obact); + } +} + static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) { struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData; @@ -2172,8 +2236,9 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) select= (gesture_mode==GESTURE_MODAL_SELECT); - if(CTX_data_edit_object(C) || paint_facesel_test(obact) || - (obact && obact->mode & OB_MODE_PARTICLE_EDIT)) { + if( CTX_data_edit_object(C) || paint_facesel_test(obact) || + (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) ) + { ViewContext vc; short mval[2]; @@ -2191,6 +2256,8 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) paint_facesel_circle_select(&vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); } + else if(obact->mode & OB_MODE_POSE) + pose_circle_select(&vc, select, mval, (float)radius); else return PE_circle_select(C, select, mval, (float)radius); } |