diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-04-12 08:21:40 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-04-12 10:38:14 +0300 |
commit | 690b90f1e2cb949a3cdfb02678be844c4808f2cb (patch) | |
tree | 770053fda356cc5792a488ea863bbf7bb6e0c634 /source/blender/bmesh | |
parent | 6d2c3a245622fa836ae603666789970a2f83b1c1 (diff) |
BMesh: minor optimization counting adjacent data
add BM_***_count_is_over(), _count_is_equal()
Useful if we only want to know if the count is a smaller value.
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_private.h | 1 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 41 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.h | 10 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.c | 59 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_beautify.c | 6 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.c | 2 |
9 files changed, 115 insertions, 13 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 9e0807710fc..ad35f6e0472 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1111,7 +1111,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) if (!d1 && !d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_JF)) { /* don't remove an edge it makes up the side of another face * else this will remove the face as well - campbell */ - if (BM_edge_face_count(l_iter->e) <= 2) { + if (!BM_edge_face_count_is_over(l_iter->e, 3)) { if (do_del) { BLI_array_append(deledges, l_iter->e); } diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 7b3f64dc5cd..85e9ec3aa24 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -72,7 +72,8 @@ */ bool BM_vert_dissolve(BMesh *bm, BMVert *v) { - const int len = BM_vert_edge_count(v); + /* logic for 3 or more is identical */ + const int len = BM_vert_edge_count_ex(v, 3); if (len == 1) { BM_vert_kill(bm, v); /* will kill edges too */ @@ -97,7 +98,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v) return false; } } - else if (len == 2 && BM_vert_face_count(v) == 1) { + else if (len == 2 && BM_vert_face_count_is_equal(v, 1)) { /* boundary vertex on a face */ return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL); } diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 102a677943b..814015a2a74 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -54,6 +54,7 @@ int bmesh_elem_check(void *element, const char htype); #endif int bmesh_radial_length(const BMLoop *l); +int bmesh_disk_count_ex(const BMVert *v, const int count_max); int bmesh_disk_count(const BMVert *v); /** diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 7c557cb1343..392f8b0bba2 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -750,6 +750,11 @@ int BM_vert_edge_count(const BMVert *v) return bmesh_disk_count(v); } +int BM_vert_edge_count_ex(const BMVert *v, const int count_max) +{ + return bmesh_disk_count_ex(v, count_max); +} + int BM_vert_edge_count_nonwire(const BMVert *v) { int count = 0; @@ -770,13 +775,30 @@ int BM_edge_face_count(const BMEdge *e) int count = 0; if (e->l) { - BMLoop *l_iter; - BMLoop *l_first; + BMLoop *l_iter, *l_first; l_iter = l_first = e->l; + do { + count++; + } while ((l_iter = l_iter->radial_next) != l_first); + } + return count; +} + +int BM_edge_face_count_ex(const BMEdge *e, const int count_max) +{ + int count = 0; + + if (e->l) { + BMLoop *l_iter, *l_first; + + l_iter = l_first = e->l; do { count++; + if (count == count_max) { + break; + } } while ((l_iter = l_iter->radial_next) != l_first); } @@ -792,6 +814,21 @@ int BM_vert_face_count(const BMVert *v) return bmesh_disk_facevert_count(v); } +int BM_vert_face_count_ex(const BMVert *v, int count_max) +{ + return bmesh_disk_facevert_count_ex(v, count_max); +} + +/** + * Return true if the vertex is connected to _any_ faces. + * + * same as ``BM_vert_face_count(v) != 0`` or ``BM_vert_find_first_loop(v) == NULL`` + */ +bool BM_vert_face_check(BMVert *v) +{ + return v->e && (bmesh_disk_faceedge_find_first(v->e, v) != NULL); +} + /** * Tests whether or not the vertex is part of a wire edge. * (ie: has no faces attached to it) diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 4ee5588ba0b..6d25d9fbfec 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -65,12 +65,22 @@ BMFace *BM_vert_pair_share_face_by_angle( const bool allow_adjacent) ATTR_NONNULL(); int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == n) +#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == (n) + 1) +int BM_vert_edge_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_ex(e, (n) + 1) == n) +#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_ex(e, (n) + 1) == (n) + 1) +int BM_edge_face_count_ex(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_ex(v, (n) + 1) == n) +#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_ex(v, (n) + 1) == (n) + 1) +int BM_vert_face_count_ex(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool BM_vert_is_edge_pair(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +bool BM_vert_face_check(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool BM_vert_is_wire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 3e8002c0192..cf56c3b4b83 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -206,6 +206,22 @@ int bmesh_disk_count(const BMVert *v) return count; } +int bmesh_disk_count_ex(const BMVert *v, const int count_max) +{ + int count = 0; + if (v->e) { + BMEdge *e_first, *e_iter; + e_iter = e_first = v->e; + do { + count++; + if (count == count_max) { + break; + } + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + } + return count; +} + bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) { BMEdge *e_iter; @@ -236,9 +252,9 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) int bmesh_disk_facevert_count(const BMVert *v) { /* is there an edge on this vert at all */ + int count = 0; if (v->e) { BMEdge *e_first, *e_iter; - int count = 0; /* first, loop around edge */ e_first = e_iter = v->e; @@ -247,11 +263,29 @@ int bmesh_disk_facevert_count(const BMVert *v) count += bmesh_radial_facevert_count(e_iter->l, v); } } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); - return count; } - else { - return 0; + return count; +} + +int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) +{ + /* is there an edge on this vert at all */ + int count = 0; + if (v->e) { + BMEdge *e_first, *e_iter; + + /* first, loop around edge */ + e_first = e_iter = v->e; + do { + if (e_iter->l) { + count += bmesh_radial_facevert_count_ex(e_iter->l, v, count_max - count); + if (count == count_max) { + break; + } + } + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); } + return count; } /** @@ -456,6 +490,23 @@ int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) return count; } +int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) +{ + const BMLoop *l_iter; + int count = 0; + l_iter = l; + do { + if (l_iter->v == v) { + count++; + if (count == count_max) { + break; + } + } + } while ((l_iter = l_iter->radial_next) != l); + + return count; +} + /** * \brief RADIAL CHECK FACE VERT * diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index 29868194bbf..4a6247d7165 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -49,6 +49,7 @@ BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v) A BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -60,6 +61,7 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e) ATTR_NONNULL(1); * bmesh_radial_loop_next(BMLoop *l) / prev. * just use member access l->radial_next, l->radial_prev now */ +int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index 990a2108bd7..b64c3aab5d7 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -333,7 +333,7 @@ static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_ BLI_assert(e->l->f->len == 3 && e->l->radial_next->f->len == 3); - BLI_assert(BM_edge_face_count(e) == 2); + BLI_assert(BM_edge_face_count_is_equal(e, 2)); for (i = 0; i < 4; i++) { bm_edge_update_beauty_cost_single( @@ -389,11 +389,11 @@ void BM_mesh_beautify_fill( i = BM_elem_index_get(e); eheap_table[i] = NULL; - BLI_assert(BM_edge_face_count(e) == 2); + BLI_assert(BM_edge_face_count_is_equal(e, 2)); e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS); - BLI_assert(e == NULL || BM_edge_face_count(e) == 2); + BLI_assert(e == NULL || BM_edge_face_count_is_equal(e, 2)); if (LIKELY(e)) { GSet *e_state_set = edge_state_arr[i]; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 3c7a86a332f..a2a0f974a79 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -2778,7 +2778,7 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv) copy_mesh_vert(vm, 1, 0, ns - k, 0, 0, k); } - if (BM_vert_face_count(bv->v) == 0) { + if (BM_vert_face_check(bv->v) == false) { e_eg = bv->edges[0].e; BLI_assert(e_eg != NULL); for (k = 0; k < ns; k++) { |