Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-01-19 14:45:15 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-01-19 14:50:56 +0300
commite2d02fee3010771abd88bba5481a5867f4f4197f (patch)
tree3b21225650b315c70690a2f76f33bd42872e01db /source
parentb76dbf5e65b89b1f276a6c007c6c9541910c3f5c (diff)
BMesh: improve hide-flush internal logic
- flushing hidden state ran when it didn't need to. - flushing checks didn't early exit when first visible element found. - low level BM_*_hide API calls like this can use skip iterators can loop over struct members directly. No user-visible changes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c125
1 files changed, 81 insertions, 44 deletions
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 7178a8132d2..93e743b6cd1 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -70,7 +70,7 @@ static void recount_totsels(BMesh *bm)
}
}
-/** \name BMesh helper functions for selection flushing.
+/** \name BMesh helper functions for selection & hide flushing.
* \{ */
static bool bm_vert_is_edge_select_any_other(const BMVert *v, const BMEdge *e_first)
@@ -102,6 +102,20 @@ static bool bm_vert_is_edge_select_any(const BMVert *v)
}
#endif
+static bool bm_vert_is_edge_visible_any(const BMVert *v)
+{
+ if (v->e) {
+ const BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
+}
+
static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
{
const BMLoop *l_iter = l_first;
@@ -131,6 +145,20 @@ static bool bm_edge_is_face_select_any(const BMEdge *e)
}
#endif
+static bool bm_edge_is_face_visible_any(const BMEdge *e)
+{
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return false;
+}
+
/** \} */
/**
@@ -1198,87 +1226,96 @@ void BM_mesh_elem_hflag_enable_all(
/***************** Mesh Hiding stuff *********** */
+/* Hide unless any connected elements are visible */
+
static void vert_flush_hide_set(BMVert *v)
{
- BMIter iter;
- BMEdge *e;
- bool hide = true;
-
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- hide = hide && BM_elem_flag_test(e, BM_ELEM_HIDDEN);
- }
-
- BM_elem_flag_set(v, BM_ELEM_HIDDEN, hide);
+ BM_elem_flag_set(v, BM_ELEM_HIDDEN, !bm_vert_is_edge_visible_any(v));
}
static void edge_flush_hide(BMEdge *e)
{
- BMIter iter;
- BMFace *f;
- bool hide = true;
-
- BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
- hide = hide && BM_elem_flag_test(f, BM_ELEM_HIDDEN);
- }
-
- BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
+ BM_elem_flag_set(e, BM_ELEM_HIDDEN, !bm_edge_is_face_visible_any(e));
}
void BM_vert_hide_set(BMVert *v, const bool hide)
{
/* vert hiding: vert + surrounding edges and faces */
- BMIter iter, fiter;
- BMEdge *e;
- BMFace *f;
-
BLI_assert(v->head.htype == BM_VERT);
BM_elem_flag_set(v, BM_ELEM_HIDDEN, hide);
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
-
- BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
- BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
- }
+ if (v->e) {
+ BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ BM_elem_flag_set(e_iter, BM_ELEM_HIDDEN, hide);
+ if (e_iter->l) {
+ const BMLoop *l_radial_iter, *l_radial_first;
+ l_radial_iter = l_radial_first = e_iter->l;
+ do {
+ BM_elem_flag_set(l_radial_iter->f, BM_ELEM_HIDDEN, hide);
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
}
}
void BM_edge_hide_set(BMEdge *e, const bool hide)
{
- BMIter iter;
- BMFace *f;
- /* BMVert *v; */
-
BLI_assert(e->head.htype == BM_EDGE);
/* edge hiding: faces around the edge */
- BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
- BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ BM_elem_flag_set(l_iter->f, BM_ELEM_HIDDEN, hide);
+ } while ((l_iter = l_iter->radial_next) != l_first);
}
BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
/* hide vertices if necessary */
- vert_flush_hide_set(e->v1);
- vert_flush_hide_set(e->v2);
+ if (hide) {
+ vert_flush_hide_set(e->v1);
+ vert_flush_hide_set(e->v2);
+ }
+ else {
+ BM_elem_flag_disable(e->v1, BM_ELEM_HIDDEN);
+ BM_elem_flag_disable(e->v2, BM_ELEM_HIDDEN);
+ }
}
void BM_face_hide_set(BMFace *f, const bool hide)
{
- BMIter iter;
- BMLoop *l;
-
BLI_assert(f->head.htype == BM_FACE);
BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
- BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
- edge_flush_hide(l->e);
+ if (hide) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ edge_flush_hide(l_iter->e);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ l_iter = l_first;
+ do {
+ vert_flush_hide_set(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
}
+ else {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
- BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
- vert_flush_hide_set(l->v);
+ l_iter = l_first;
+ do {
+ BM_elem_flag_disable(l_iter->e, BM_ELEM_HIDDEN);
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_HIDDEN);
+ } while ((l_iter = l_iter->next) != l_first);
}
}