diff options
m--------- | release/datafiles/locale | 0 | ||||
m--------- | release/scripts/addons | 0 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 108 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.h | 12 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 6 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_path.c | 2 |
7 files changed, 83 insertions, 47 deletions
diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject 4833954c0ac85cc407e1d5a153aa11b1d1823ec +Subproject ab283053ab455f76f5620b59b823e73bd9f601c diff --git a/release/scripts/addons b/release/scripts/addons -Subproject f86f25e62217264495d05f116ccb09d575fe984 +Subproject ec07ed4c2e0495bea7fbe0b546d25e35211506a diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index d479a555a58..0bb86471cbd 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -40,31 +40,50 @@ /* For '_FLAG_OVERLAP'. */ #include "bmesh_private.h" -static void recount_totsels(BMesh *bm) +static int recount_totsel(BMesh *bm, BMIterType iter_type) { - const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH}; - int *tots[3]; - int i; - - /* Recount total selection variables. */ - bm->totvertsel = bm->totedgesel = bm->totfacesel = 0; - tots[0] = &bm->totvertsel; - tots[1] = &bm->totedgesel; - tots[2] = &bm->totfacesel; - - for (i = 0; i < 3; i++) { - BMIter iter; - BMElem *ele; - int count = 0; + BMIter iter; + BMElem *ele; + int count = 0; - BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - count += 1; - } + BM_ITER_MESH (ele, &iter, bm, iter_type) { + if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { + count += 1; } - *tots[i] = count; } + return count; +} + +static void recount_totvertsel(BMesh *bm) +{ + bm->totvertsel = recount_totsel(bm, BM_VERTS_OF_MESH); +} + +static void recount_totedgesel(BMesh *bm) +{ + bm->totedgesel = recount_totsel(bm, BM_EDGES_OF_MESH); +} + +static void recount_totfacesel(BMesh *bm) +{ + bm->totfacesel = recount_totsel(bm, BM_FACES_OF_MESH); +} + +static void recount_totsels(BMesh *bm) +{ + recount_totvertsel(bm); + recount_totedgesel(bm); + recount_totfacesel(bm); +} + +#ifndef NDEBUG +static bool recount_totsels_are_ok(BMesh *bm) +{ + return bm->totvertsel == recount_totsel(bm, BM_VERTS_OF_MESH) && + bm->totedgesel == recount_totsel(bm, BM_EDGES_OF_MESH) && + bm->totfacesel == recount_totsel(bm, BM_FACES_OF_MESH); } +#endif /* -------------------------------------------------------------------- */ /** \name BMesh helper functions for selection & hide flushing. @@ -238,7 +257,7 @@ void BM_mesh_select_mode_clean(BMesh *bm) * (ie: all verts of an edge selects the edge and so on). * This should only be called by system and not tool authors. */ -void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode) +void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode, eBMSelectionFlushFLags flags) { BMEdge *e; BMLoop *l_iter; @@ -251,34 +270,22 @@ void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode) if (selectmode & SCE_SELECT_VERTEX) { /* both loops only set edge/face flags and read off verts */ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && - !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { + const bool is_selected = BM_elem_flag_test(e, BM_ELEM_SELECT); + if (!is_selected && + (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && BM_elem_flag_test(e->v2, BM_ELEM_SELECT))) { BM_elem_flag_enable(e, BM_ELEM_SELECT); + bm->totedgesel += 1; } else { BM_elem_flag_disable(e, BM_ELEM_SELECT); + bm->totedgesel += is_selected ? -1 : 0; } } - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - bool ok = true; - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { - ok = false; - break; - } - } while ((l_iter = l_iter->next) != l_first); - } - else { - ok = false; - } - - BM_elem_flag_set(f, BM_ELEM_SELECT, ok); - } } - else if (selectmode & SCE_SELECT_EDGE) { + + if (selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + const bool is_selected = BM_elem_flag_test(f, BM_ELEM_SELECT); bool ok = true; if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { l_iter = l_first = BM_FACE_FIRST_LOOP(f); @@ -294,18 +301,33 @@ void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode) } BM_elem_flag_set(f, BM_ELEM_SELECT, ok); + if (is_selected && !ok) { + bm->totfacesel -= 1; + } + else if (ok && !is_selected) { + bm->totfacesel += 1; + } } } /* Remove any deselected elements from the BMEditSelection */ BM_select_history_validate(bm); - recount_totsels(bm); + if (flags & BM_SELECT_LEN_FLUSH_RECALC_VERT) { + recount_totvertsel(bm); + } + if (flags & BM_SELECT_LEN_FLUSH_RECALC_EDGE) { + recount_totedgesel(bm); + } + if (flags & BM_SELECT_LEN_FLUSH_RECALC_FACE) { + recount_totfacesel(bm); + } + BLI_assert(recount_totsels_are_ok(bm)); } void BM_mesh_select_mode_flush(BMesh *bm) { - BM_mesh_select_mode_flush_ex(bm, bm->selectmode); + BM_mesh_select_mode_flush_ex(bm, bm->selectmode, BM_SELECT_LEN_FLUSH_RECALC_ALL); } /** diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h index 04a49e24757..ff6c359138a 100644 --- a/source/blender/bmesh/intern/bmesh_marking.h +++ b/source/blender/bmesh/intern/bmesh_marking.h @@ -26,6 +26,16 @@ typedef struct BMEditSelection { char htype; } BMEditSelection; +typedef enum eBMSelectionFlushFLags { + BM_SELECT_LEN_FLUSH_RECALC_NOTHING = 0, + BM_SELECT_LEN_FLUSH_RECALC_VERT = (1 << 0), + BM_SELECT_LEN_FLUSH_RECALC_EDGE = (1 << 1), + BM_SELECT_LEN_FLUSH_RECALC_FACE = (1 << 2), + BM_SELECT_LEN_FLUSH_RECALC_ALL = (BM_SELECT_LEN_FLUSH_RECALC_VERT | + BM_SELECT_LEN_FLUSH_RECALC_EDGE | + BM_SELECT_LEN_FLUSH_RECALC_FACE), +} eBMSelectionFlushFLags; + /* geometry hiding code */ #define BM_elem_hide_set(bm, ele, hide) _bm_elem_hide_set(bm, &(ele)->head, hide) void _bm_elem_hide_set(BMesh *bm, BMHeader *head, const bool hide); @@ -72,7 +82,7 @@ void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode); void BM_mesh_select_mode_clean(BMesh *bm); void BM_mesh_select_mode_set(BMesh *bm, int selectmode); -void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode); +void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode, eBMSelectionFlushFLags flags); void BM_mesh_select_mode_flush(BMesh *bm); void BM_mesh_deselect_flush(BMesh *bm); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 071ca818120..f70d9b044ac 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -438,7 +438,7 @@ void EDBM_selectmode_to_scene(bContext *C) void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) { - BM_mesh_select_mode_flush_ex(em->bm, selectmode); + BM_mesh_select_mode_flush_ex(em->bm, selectmode, BM_SELECT_LEN_FLUSH_RECALC_ALL); } void EDBM_selectmode_flush(BMEditMesh *em) diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 757ed13ac28..6a7ee46f719 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -3725,6 +3725,9 @@ static bool mesh_circle_select(ViewContext *vc, if (SEL_OP_USE_PRE_DESELECT(sel_op)) { if (vc->em->bm->totvertsel) { EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT); + vc->em->bm->totvertsel = 0; + vc->em->bm->totedgesel = 0; + vc->em->bm->totfacesel = 0; changed = true; } } @@ -3790,7 +3793,8 @@ static bool mesh_circle_select(ViewContext *vc, changed |= data.is_changed; if (changed) { - EDBM_selectmode_flush(vc->em); + BM_mesh_select_mode_flush_ex( + vc->em->bm, vc->em->selectmode, BM_SELECT_LEN_FLUSH_RECALC_NOTHING); } return changed; } diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 016a054cf21..2613c5b23a0 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -552,7 +552,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima, if (uv_selectmode & UV_SELECT_EDGE) { /* Special case as we don't use true edge selection, * flush the selection from the vertices. */ - BM_mesh_select_mode_flush_ex(em->bm, SCE_SELECT_VERTEX); + BM_mesh_select_mode_flush_ex(em->bm, SCE_SELECT_VERTEX, BM_SELECT_LEN_FLUSH_RECALC_ALL); } } ED_uvedit_select_sync_flush(scene->toolsettings, em, select); |