From d20128bbbcae252e9b39af14246dfcc6534dc0d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 16:48:04 +0000 Subject: fix for BM_edge_other_loop() not working right (own error in recent commit), and add new function BM_vert_step_fan_loop() for stepping around the loops of a face fan with manifold edges. --- source/blender/bmesh/intern/bmesh_queries.c | 53 ++++++++++++++++++++++++++++- source/blender/bmesh/intern/bmesh_queries.h | 1 + 2 files changed, 53 insertions(+), 1 deletion(-) (limited to 'source/blender/bmesh/intern') diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 9520b0298d8..073e233c0e1 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -346,7 +346,9 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) BLI_assert(BM_edge_is_manifold(e)); BLI_assert(BM_vert_in_edge(e, l->v)); - l_other = (e->l == l) ? l->radial_next : l; + l_other = (l->e == e) ? l : l->prev; + l_other = l_other->radial_next; + BLI_assert(l_other->e == e); if (l_other->v == l->v) { /* pass */ @@ -361,6 +363,55 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) return l_other; } +/** + * Utility function to step around a fan of loops, + * using an edge to mark the previous side. + * + * \note all edges must be manifold, + * once a non manifold edge is hit, return NULL. + * + *
+ *                ,.,-->|
+ *            _,-'      |
+ *          ,'          | (notice how 'e_step'
+ *         /            |  and 'l' define the
+ *        /             |  direction the arrow
+ *       |     return   |  points).
+ *       |     loop --> |
+ * ---------------------+---------------------
+ *         ^      l --> |
+ *         |            |
+ *  assign e_step       |
+ *                      |
+ *   begin e_step ----> |
+ *                      |
+ * 
+ */ + +BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step) +{ + BMEdge *e_prev = *e_step; + BMEdge *e_next; + if (l->e == e_prev) { + e_next = l->prev->e; + } + else if (l->prev->e == e_prev) { + e_next = l->e; + } + else { + BLI_assert(0); + } + + if (BM_edge_is_manifold(e_next)) { + return BM_edge_other_loop((*e_step = e_next), l); + } + else { + return NULL; + } +} + + + /** * The function takes a vertex at the center of a fan and returns the opposite edge in the fan. * All edges in the fan must be manifold, otherwise return NULL. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 166b8a54f8a..34d0747676c 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -44,6 +44,7 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l); BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v); BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); +BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step); BMLoop *BM_vert_find_first_loop(BMVert *v); int BM_vert_edge_count_nonwire(BMVert *v); -- cgit v1.2.3