diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_marking.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 188 |
1 files changed, 139 insertions, 49 deletions
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index ee35d8cd1d2..8aa64906019 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -41,6 +41,7 @@ #include "BLI_listbase.h" #include "bmesh.h" +#include "bmesh_structure.h" static void recount_totsels(BMesh *bm) { @@ -69,6 +70,69 @@ static void recount_totsels(BMesh *bm) } } +/** \name BMesh helper functions for selection flushing. + * \{ */ + +static bool bm_vert_is_edge_select_any_other(BMVert *v, BMEdge *e_first) +{ + BMEdge *e_iter = e_first; + + /* start by stepping over the current edge */ + while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first) { + if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) { + return true; + } + } + return false; +} + +#if 0 +static bool bm_vert_is_edge_select_any(BMVert *v) +{ + if (v->e) { + BMEdge *e_iter, *e_first; + e_iter = e_first = v->e; + do { + if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) { + return true; + } + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + } + return false; +} +#endif + +static bool bm_edge_is_face_select_any_other(BMLoop *l_first) +{ + BMLoop *l_iter = l_first; + + /* start by stepping over the current face */ + while ((l_iter = l_iter->radial_next) != l_first) { + if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) { + return true; + } + } + return false; +} + +#if 0 +static bool bm_edge_is_face_select_any(BMEdge *e) +{ + if (e->l) { + BMLoop *l_iter, *l_first; + l_iter = l_first = e->l; + do { + if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) { + return true; + } + } while ((l_iter = l_iter->radial_next) != l_first); + } + return false; +} +#endif + +/** \} */ + /** * \brief Select Mode Clean * @@ -341,8 +405,8 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select) if (select) { if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) { - bm->totvertsel += 1; BM_elem_flag_enable(v, BM_ELEM_SELECT); + bm->totvertsel += 1; } } else { @@ -367,39 +431,27 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select) } if (select) { - if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel += 1; - - BM_elem_flag_enable(e, BM_ELEM_SELECT); + if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_elem_flag_enable(e, BM_ELEM_SELECT); + bm->totedgesel += 1; + } BM_vert_select_set(bm, e->v1, true); BM_vert_select_set(bm, e->v2, true); } else { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel -= 1; - BM_elem_flag_disable(e, BM_ELEM_SELECT); + if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_elem_flag_disable(e, BM_ELEM_SELECT); + bm->totedgesel -= 1; + } if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) { - BMIter iter; - BMVert *verts[2] = {e->v1, e->v2}; - BMEdge *e2; int i; /* check if the vert is used by a selected edge */ for (i = 0; i < 2; i++) { - bool deselect = true; - - for (e2 = BM_iter_new(&iter, bm, BM_EDGES_OF_VERT, verts[i]); e2; e2 = BM_iter_step(&iter)) { - if (e2 == e) { - continue; - } - - if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) { - deselect = false; - break; - } - } - - if (deselect) { - BM_vert_select_set(bm, verts[i], false); + BMVert *v = *((&e->v1) + i); + if (bm_vert_is_edge_select_any_other(v, e) == false) { + BM_vert_select_set(bm, v, false); } } } @@ -430,10 +482,10 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select) if (select) { if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) { - bm->totfacesel++; + BM_elem_flag_enable(f, BM_ELEM_SELECT); + bm->totfacesel += 1; } - BM_elem_flag_enable(f, BM_ELEM_SELECT); l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { BM_vert_select_set(bm, l_iter->v, true); @@ -441,42 +493,80 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select) } while ((l_iter = l_iter->next) != l_first); } else { - BMIter liter; - BMLoop *l; - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) bm->totfacesel -= 1; - BM_elem_flag_disable(f, BM_ELEM_SELECT); + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BM_elem_flag_disable(f, BM_ELEM_SELECT); + bm->totfacesel -= 1; + } /* flush down to edges */ - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BMIter fiter; - BMFace *f2; - BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) { - if (BM_elem_flag_test(f2, BM_ELEM_SELECT)) - break; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + /* vertex flushing is handled below */ + if (bm_edge_is_face_select_any_other(l_iter) == false) { + BM_edge_select_set_noflush(bm, l_iter->e, false); } + } while ((l_iter = l_iter->next) != l_first); - if (!f2) { - BM_edge_select_set(bm, l->e, false); + /* flush down to verts */ + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (bm_vert_is_edge_select_any_other(l_iter->v, l_iter->e) == false) { + BM_vert_select_set(bm, l_iter->v, false); } + } while ((l_iter = l_iter->next) != l_first); + } +} + +/** \name Non flushing versions element selection. + * \{ */ + +void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select) +{ + BLI_assert(e->head.htype == BM_EDGE); + + if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { + return; + } + + if (select) { + if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_elem_flag_enable(e, BM_ELEM_SELECT); + bm->totedgesel += 1; } + } + else { + if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_elem_flag_disable(e, BM_ELEM_SELECT); + bm->totedgesel -= 1; + } + } +} - /* flush down to verts */ - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BMIter eiter; - BMEdge *e; - BM_ITER_ELEM (e, &eiter, l->v, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) - break; - } +void BM_face_select_set_noflush(BMesh *bm, BMFace *f, const bool select) +{ + BLI_assert(f->head.htype == BM_FACE); - if (!e) { - BM_vert_select_set(bm, l->v, false); - } + if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + return; + } + + if (select) { + if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BM_elem_flag_enable(f, BM_ELEM_SELECT); + bm->totfacesel += 1; + } + } + else { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BM_elem_flag_disable(f, BM_ELEM_SELECT); + bm->totfacesel -= 1; } } } +/** \} */ + /** * Select Mode Set * |