Commit: 3c10de2c9b49589d2943ffb5b235e7930f3a4d17
Author: Campbell Barton
Date:   Fri Mar 1 23:09:22 2019 +1100
Branches: master
https://developer.blender.org/rB3c10de2c9b49589d2943ffb5b235e7930f3a4d17

3D View: avoid redundant circle select updates

This refreshes on cursor motion so it's worth avoiding redundant
updates, especially for multi-object edit-modes where many objects
aren't even near the object being selected.

This commit also moves to passing eSelectOp to circle select functions
in preparation for adding a select mode tool option.

===================================================================

M       source/blender/editors/include/ED_particle.h
M       source/blender/editors/physics/particle_edit.c
M       source/blender/editors/space_view3d/view3d_select.c

===================================================================

diff --git a/source/blender/editors/include/ED_particle.h 
b/source/blender/editors/include/ED_particle.h
index 7a612d1f4d9..bbecffee9c0 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -55,7 +55,7 @@ void PE_update_object(
 /* selection tools */
 int PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, 
bool deselect, bool toggle);
 int PE_box_select(struct bContext *C, const struct rcti *rect, const int 
sel_op);
-int PE_circle_select(struct bContext *C, int selecting, const int mval[2], 
float rad);
+bool PE_circle_select(struct bContext *C, int sel_op, const int mval[2], float 
rad);
 int PE_lasso_select(struct bContext *C, const int mcords[][2], const short 
moves, const int sel_op);
 void PE_deselect_all_visible(struct PTCacheEdit *edit);
 
diff --git a/source/blender/editors/physics/particle_edit.c 
b/source/blender/editors/physics/particle_edit.c
index cc96fba6ba8..f9b30de5dc5 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -425,6 +425,7 @@ typedef struct PEData {
 
        int select_action;
        int select_toggle_action;
+       bool is_changed;
 } PEData;
 
 static void PE_set_data(bContext *C, PEData *data)
@@ -1516,6 +1517,7 @@ static void select_key(PEData *data, int point_index, int 
key_index, bool UNUSED
                key->flag &= ~PEK_SELECT;
 
        point->flag |= PEP_EDIT_RECALC;
+       data->is_changed = true;
 }
 
 static void select_key_op(PEData *data, int point_index, int key_index, bool 
is_inside)
@@ -1998,27 +2000,38 @@ int PE_box_select(bContext *C, const rcti *rect, const 
int sel_op)
 
 /************************ circle select operator ************************/
 
-int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
+bool PE_circle_select(bContext *C, const int sel_op, const int mval[2], float 
rad)
 {
+       BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        PTCacheEdit *edit = PE_get_current(scene, ob);
        PEData data;
 
-       if (!PE_start_edit(edit))
-               return OPERATOR_FINISHED;
+       if (!PE_start_edit(edit)) {
+               return false;
+       }
+
+       bool changed = false;
+       if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+               PE_deselect_all_visible(edit);
+               changed = true;
+       }
+       const bool select = (sel_op != SEL_OP_SUB);
 
        PE_set_view3d_data(C, &data);
        data.mval = mval;
        data.rad = rad;
-       data.select = selecting;
+       data.select = select;
 
        for_mouse_hit_keys(&data, select_key, 0);
+       changed |= data.is_changed;
 
-       PE_update_selection(data.depsgraph, scene, ob, 1);
-       WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
-
-       return OPERATOR_FINISHED;
+       if (changed) {
+               PE_update_selection(data.depsgraph, scene, ob, 1);
+               WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, 
ob);
+       }
+       return changed;
 }
 
 /************************ lasso select operator ************************/
diff --git a/source/blender/editors/space_view3d/view3d_select.c 
b/source/blender/editors/space_view3d/view3d_select.c
index 7efafea8725..70ff6065007 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -186,11 +186,12 @@ static bool object_deselect_all_except(ViewLayer 
*view_layer, Base *b)
 /** \name Internal Edit-Mesh Utilities
  * \{ */
 
-static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const 
eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_verts(BMEditMesh *em, const 
eSelectOp sel_op)
 {
        BMVert *eve;
        BMIter iter;
        unsigned int index = bm_wireoffs;
+       bool changed = false;
 
        BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
                if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
@@ -199,17 +200,20 @@ static void 
edbm_backbuf_check_and_select_verts(BMEditMesh *em, const eSelectOp
                        const int sel_op_result = 
ED_select_op_action_deselected(sel_op, is_select, is_inside);
                        if (sel_op_result != -1) {
                                BM_vert_select_set(em->bm, eve, sel_op_result);
+                               changed = true;
                        }
                }
                index++;
        }
+       return changed;
 }
 
-static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const 
eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_edges(BMEditMesh *em, const 
eSelectOp sel_op)
 {
        BMEdge *eed;
        BMIter iter;
        unsigned int index = bm_solidoffs;
+       bool changed = false;
 
        BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
                if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -218,17 +222,20 @@ static void 
edbm_backbuf_check_and_select_edges(BMEditMesh *em, const eSelectOp
                        const int sel_op_result = 
ED_select_op_action_deselected(sel_op, is_select, is_inside);
                        if (sel_op_result != -1) {
                                BM_edge_select_set(em->bm, eed, sel_op_result);
+                               changed = true;
                        }
                }
                index++;
        }
+       return changed;
 }
 
-static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, const 
eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_faces(BMEditMesh *em, const 
eSelectOp sel_op)
 {
        BMFace *efa;
        BMIter iter;
        unsigned int index = 1;
+       bool changed = false;
 
        BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
@@ -237,17 +244,20 @@ static void 
edbm_backbuf_check_and_select_faces(BMEditMesh *em, const eSelectOp
                        const int sel_op_result = 
ED_select_op_action_deselected(sel_op, is_select, is_inside);
                        if (sel_op_result != -1) {
                                BM_face_select_set(em->bm, efa, sel_op_result);
+                               changed = true;
                        }
                }
                index++;
        }
+       return changed;
 }
 
 /* object mode, edbm_ prefix is confusing here, rename? */
-static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const 
eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const 
eSelectOp sel_op)
 {
        MVert *mv = me->mvert;
        unsigned int index;
+       bool changed = false;
 
        if (mv) {
                for (index = 1; index <= me->totvert; index++, mv++) {
@@ -257,17 +267,20 @@ static void 
edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const eSelectOp
                                const int sel_op_result = 
ED_select_op_action_deselected(sel_op, is_select, is_inside);
                                if (sel_op_result != -1) {
                                        SET_FLAG_FROM_TEST(mv->flag, 
sel_op_result, SELECT);
+                                       changed = true;
                                }
                        }
                }
        }
+       return changed;
 }
 
 /* object mode, edbm_ prefix is confusing here, rename? */
-static void edbm_backbuf_check_and_select_tfaces(Mesh *me, const eSelectOp 
sel_op)
+static bool edbm_backbuf_check_and_select_tfaces(Mesh *me, const eSelectOp 
sel_op)
 {
        MPoly *mpoly = me->mpoly;
        unsigned int index;
+       bool changed = false;
 
        if (mpoly) {
                for (index = 1; index <= me->totpoly; index++, mpoly++) {
@@ -277,10 +290,12 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh 
*me, const eSelectOp sel_o
                                const int sel_op_result = 
ED_select_op_action_deselected(sel_op, is_select, is_inside);
                                if (sel_op_result != -1) {
                                        SET_FLAG_FROM_TEST(mpoly->flag, 
sel_op_result, ME_FACE_SEL);
+                                       changed = true;
                                }
                        }
                }
        }
+       return changed;
 }
 
 /** \} */
@@ -2828,6 +2843,7 @@ static void mesh_circle_doSelectVert(void *userData, 
BMVert *eve, const float sc
 
        if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) 
{
                BM_vert_select_set(data->vc->em->bm, eve, data->select);
+               data->is_changed = true;
        }
 }
 static void mesh_circle_doSelectEdge(
@@ -2837,6 +2853,7 @@ static void mesh_circle_doSelectEdge(
 
        if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, 
screen_co_b)) {
                BM_edge_select_set(data->vc->em->bm, eed, data->select);
+               data->is_changed = true;
        }
 }
 static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float 
screen_co[2], int UNUSED(index))
@@ -2845,25 +2862,32 @@ static void mesh_circle_doSelectFace(void *userData, 
BMFace *efa, const float sc
 
        if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) 
{
                BM_face_select_set(data->vc->em->bm, efa, data->select);
+               data->is_changed = true;
        }
 }
 
-static void mesh_circle_select(ViewContext *vc, const bool select, const int 
mval[2], float rad)
+static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int 
mval[2], float rad)
 {
        ToolSettings *ts = vc->scene->toolsettings;
        int bbsel;
        CircleSelectUserData data;
+       vc->em = BKE_editmesh_from_object(vc->obedit);
+
+       bool changed = false;
+       if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+               EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
+               changed = true;
+       }
+       const bool select = (sel_op != SEL_OP_SUB);
 
        bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 
1.0f));
        ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's 
screen/vert projection */
 
-       vc->em = BKE_editmesh_from_object(vc->obedit);
-
        view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
 
        if (ts->selectmode & SCE_SELECT_VERTEX) {
                if (bbsel) {
-                       edbm_backbuf_check_and_select_verts(vc->em, select ? 
SEL_OP_ADD : SEL_OP_SUB);
+                       changed |= edbm_backbuf_check_and_select_verts(vc->em, 
select ? SEL_OP_ADD : SEL_OP_SUB);
                }
                else {
                        mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, 
&data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -2872,7 +2896,7 @@ static void mesh_circle_select(ViewContext *vc, const 
bool select, const int mva
 
        if (ts->selectmode & SCE_SELECT_EDGE) {
                if (bbsel) {
-                       edbm_backbuf_check_and_select_edges(vc->em, select ? 
SEL_OP_ADD : SEL_OP_SUB);
+                       changed |= edbm_backbuf_check_and_select_edges(vc->em, 
select ? SEL_OP_ADD : SEL_OP_SUB);
                }
                else {
                        mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, 
&data, V3D_PROJ_TEST_CLIP_NEAR);
@@ -2881,31 +2905,48 @@ static void mesh_circle_select(ViewContext *vc, const 
bool select, const int mva
 
        if (ts->selectmode & SCE_SELECT_FACE) {
                if (bbsel) {
-                       edbm_backbuf_check_and_select_faces(vc->em, select ? 
SEL_OP_ADD : SEL_OP_SUB);
+                       changed |= edbm_backbuf_check_and_select_faces(vc->em, 
select ? SEL_OP_ADD : SEL_OP_SUB);
                }
                else {
                        mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, 
&data, V3D_PROJ_TEST_CLIP_DEFAULT);
                }
        }
 
+       changed |= data.is_changed;
+
        EDBM_backbuf_free();
-       EDBM_selectmode_flush(vc->em);
+
+       if (changed) {
+               EDBM_selectmode_flush(vc->em);
+       }
+
+       return cha

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to