add mball_foreachScreenElem() and use for lasso & circle selection, also utility...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 6 Oct 2012 03:02:14 +0000 (03:02 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 6 Oct 2012 03:02:14 +0000 (03:02 +0000)
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/intern/mball.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/metaball/mball_edit.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_select.c

index 913e8653b9b777ca50a31e4b358d4f1f56be7398..d591b44e4895cd2c4b722a6b0695ec6ba142b69e 100644 (file)
@@ -63,4 +63,8 @@ void BKE_mball_translate(struct MetaBall *mb, float offset[3]);
 
 struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, const int type);
 
+void BKE_mball_select_all(struct MetaBall *mb);
+void BKE_mball_deselect_all(struct MetaBall *mb);
+void BKE_mball_select_swap(struct MetaBall *mb);
+
 #endif
index 2030ab0f55270bacef8fbe48739333c8696bcb6e..de7fdece7dd69c8d36957a72550c663ad4d864bb 100644 (file)
@@ -2396,3 +2396,32 @@ void BKE_mball_translate(MetaBall *mb, float offset[3])
                add_v3_v3(&ml->x, offset);
        }
 }
+
+/* *** select funcs *** */
+void BKE_mball_select_all(struct MetaBall *mb)
+{
+       MetaElem *ml;
+
+       for (ml = mb->editelems->first; ml; ml = ml->next) {
+               ml->flag |= SELECT;
+       }
+}
+
+void BKE_mball_deselect_all(MetaBall *mb)
+{
+       MetaElem *ml;
+
+       for (ml = mb->editelems->first; ml; ml = ml->next) {
+               ml->flag &= ~SELECT;
+       }
+}
+
+void BKE_mball_select_swap(struct MetaBall *mb)
+{
+       MetaElem *ml;
+
+       for (ml = mb->editelems->first; ml; ml = ml->next) {
+               ml->flag ^= SELECT;
+       }
+}
+
index ebf93baeabc94d3d2a7810ac1fd0b2c8c2467637..b81e08ed7ef7a025dc1752ee0293353b59b877eb 100644 (file)
@@ -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);
index 22ccd7bbed8e3d9e678fd21fb5e0c1bceaea6e64..e9063687506e6ff856a02b417b069110a3e9f402 100644 (file)
@@ -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);
 
index 40207ce806ce685b282c9357db0661288cd2f0ad..a6f4527cf98d46ebee77c086d7aa1bca266de830 100644 (file)
@@ -2220,6 +2220,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,
index c4639fc2c56b41a3307cedbfd4c24fe06d6893ff..53f2c2e9f5e6ff5ab2668b6bccc000b36ccbdbba 100644 (file)
 #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 */