diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-10-06 07:02:14 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-10-06 07:02:14 +0400 |
commit | c4472bbab678cfc826fc40fe9272db38cbb6a1cd (patch) | |
tree | b9a8427e12a0bc4f7e6ab576c05ad0bcc547c3be /source/blender/editors | |
parent | f84f2c703378284cb72de3bb07b7a8f4b5de31c9 (diff) |
add mball_foreachScreenElem() and use for lasso & circle selection, also utility metaball functions to (de)select all.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 2 | ||||
-rw-r--r-- | source/blender/editors/metaball/mball_edit.c | 79 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 19 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 82 |
4 files changed, 98 insertions, 84 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index ebf93baeabc..b81e08ed7ef 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -44,6 +44,7 @@ struct EditBone; struct ImBuf; struct MVert; struct Main; +struct MetaElem; struct Nurb; struct Nurb; struct Object; @@ -170,6 +171,7 @@ void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts); void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData); void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData); +void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, int x, int y), void *userData); void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData); void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData); void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData); diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 22ccd7bbed8..e9063687506 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -129,37 +129,33 @@ static int mball_select_all_exec(bContext *C, wmOperator *op) MetaElem *ml; int action = RNA_enum_get(op->ptr, "action"); - ml = mb->editelems->first; - if (ml) { - if (action == SEL_TOGGLE) { - action = SEL_SELECT; - while (ml) { - if (ml->flag & SELECT) { - action = SEL_DESELECT; - break; - } - ml = ml->next; - } - } + if (mb->editelems->first == NULL) + return OPERATOR_CANCELLED; - ml = mb->editelems->first; - while (ml) { - switch (action) { - case SEL_SELECT: - ml->flag |= SELECT; - break; - case SEL_DESELECT: - ml->flag &= ~SELECT; - break; - case SEL_INVERT: - ml->flag ^= SELECT; - break; + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + for (ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & SELECT) { + action = SEL_DESELECT; + break; } - ml = ml->next; } - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); } + switch (action) { + case SEL_SELECT: + BKE_mball_select_all(mb); + break; + case SEL_DESELECT: + BKE_mball_deselect_all(mb); + break; + case SEL_INVERT: + BKE_mball_select_swap(mb); + break; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); + return OPERATOR_FINISHED; } @@ -421,7 +417,7 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to Object *obedit = CTX_data_edit_object(C); ViewContext vc; MetaBall *mb = (MetaBall *)obedit->data; - MetaElem *ml, *act = NULL; + MetaElem *ml, *ml_act = NULL; int a, hits; unsigned int buffer[4 * MAXPICKBUF]; rcti rect; @@ -451,14 +447,14 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to /* index converted for gl stuff */ if (ml->selcol1 == buffer[4 * a + 3]) { ml->flag |= MB_SCALE_RAD; - act = ml; + ml_act = ml; } if (ml->selcol2 == buffer[4 * a + 3]) { ml->flag &= ~MB_SCALE_RAD; - act = ml; + ml_act = ml; } } - if (act) break; + if (ml_act) break; ml = ml->next; if (ml == NULL) ml = mb->editelems->first; if (ml == startelem) break; @@ -466,31 +462,28 @@ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int to /* When some metaelem was found, then it is necessary to select or * deselect it. */ - if (act) { + if (ml_act) { if (extend) { - act->flag |= SELECT; + ml_act->flag |= SELECT; } else if (deselect) { - act->flag &= ~SELECT; + ml_act->flag &= ~SELECT; } else if (toggle) { - if (act->flag & SELECT) - act->flag &= ~SELECT; + if (ml_act->flag & SELECT) + ml_act->flag &= ~SELECT; else - act->flag |= SELECT; + ml_act->flag |= SELECT; } else { /* Deselect all existing metaelems */ - ml = mb->editelems->first; - while (ml) { - ml->flag &= ~SELECT; - ml = ml->next; - } + BKE_mball_deselect_all(mb); + /* Select only metaelem clicked on */ - act->flag |= SELECT; + ml_act->flag |= SELECT; } - mb->lastelem = act; + mb->lastelem = ml_act; WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 40207ce806c..a6f4527cf98 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2221,6 +2221,25 @@ void nurbs_foreachScreenVert( } /* ED_view3d_init_mats_rv3d must be called first */ +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, int x, int y), + void *userData) +{ + MetaBall *mb = (MetaBall *)vc->obedit->data; + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + int screen_co[2]; + if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + { + func(userData, ml, screen_co[0], screen_co[1]); + } + } +} + +/* ED_view3d_init_mats_rv3d must be called first */ void armature_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c4639fc2c56..53f2c2e9f5e 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -61,13 +61,14 @@ #include "IMB_imbuf.h" #include "BKE_global.h" -#include "BKE_context.h" -#include "BKE_paint.h" #include "BKE_armature.h" +#include "BKE_context.h" #include "BKE_depsgraph.h" -#include "BKE_tessmesh.h" +#include "BKE_mball.h" #include "BKE_movieclip.h" #include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_tessmesh.h" #include "BKE_tracking.h" @@ -678,32 +679,34 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho } } +static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +{ + LassoSelectUserData *data = userData; + if (BLI_rcti_isect_pt(data->rect, x, y) && + BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) { + if (data->select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + data->is_change = TRUE; + } +} static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { + LassoSelectUserData data; + rcti rect; + MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - if (extend == 0 && select) { - /* XXX, make an editor function as is done elsewhere */ - for (ml = mb->editelems->first; ml; ml = ml->next) { - ml->flag &= ~SELECT; - } - } + if (extend == 0 && select) + BKE_mball_deselect_all(mb); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - for (ml = mb->editelems->first; ml; ml = ml->next) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - if (BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) { - if (select) ml->flag |= SELECT; - else ml->flag &= ~SELECT; - } - } - } + BLI_lasso_boundbox(&rect, mcords, moves); + + mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data); } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) @@ -1792,11 +1795,8 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, int select, int exten hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect); - if (extend == 0 && select) { - for (ml = mb->editelems->first; ml; ml = ml->next) { - ml->flag &= ~SELECT; - } - } + if (extend == 0 && select) + BKE_mball_deselect_all(mb); for (ml = mb->editelems->first; ml; ml = ml->next) { for (a = 0; a < hits; a++) { @@ -2577,27 +2577,27 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 } } +static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +{ + CircleSelectUserData *data = userData; + const float delta[2] = {(float)(x - data->mval[0]), + (float)(y - data->mval[1])}; + + if (len_squared_v2(delta) <= data->radius_squared) { + if (data->select) ml->flag |= SELECT; + else ml->flag &= ~SELECT; + data->is_change = TRUE; + } +} static void mball_circle_select(ViewContext *vc, int select, const int mval[2], float rad) { - const float radius_squared = rad * rad; - const float mval_fl[2] = {mval[0], mval[1]}; + CircleSelectUserData data; - MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; + view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - for (ml = mb->editelems->first; ml; ml = ml->next) { - float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) - { - if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { - if (select) ml->flag |= SELECT; - else ml->flag &= ~SELECT; - } - } - } + mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data); } /** Callbacks for circle selection in Editmode */ |