diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_structure.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.c | 115 |
1 files changed, 102 insertions, 13 deletions
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 3e8002c0192..cb302139a4c 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -40,19 +40,56 @@ * MISC utility functions. */ -bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new) +void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) { - if (e->v1 == v_orig) { - e->v1 = v_new; + if (e->v1 == v_src) { + e->v1 = v_dst; e->v1_disk_link.next = e->v1_disk_link.prev = NULL; - return true; } - else if (e->v2 == v_orig) { - e->v2 = v_new; + else if (e->v2 == v_src) { + e->v2 = v_dst; e->v2_disk_link.next = e->v2_disk_link.prev = NULL; - return true; } - return false; + else { + BLI_assert(0); + } +} + +/** + * Handles all connected data, use with care. + * + * Assumes caller has setup correct state before the swap is done. + */ +void bmesh_edge_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) +{ + /* swap out loops */ + if (e->l) { + BMLoop *l_iter, *l_first; + l_iter = l_first = e->l; + do { + if (l_iter->v == v_src) { + l_iter->v = v_dst; + } + else if (l_iter->next->v == v_src) { + l_iter->next->v = v_dst; + } + else { + BLI_assert(l_iter->prev->v != v_src); + } + } while ((l_iter = l_iter->radial_next) != l_first); + } + + /* swap out edges */ + bmesh_disk_vert_replace(e, v_dst, v_src); +} + +void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src) +{ + BLI_assert(e->v1 == v_src || e->v2 == v_src); + bmesh_disk_edge_remove(e, v_src); /* remove e from tv's disk cycle */ + bmesh_disk_vert_swap(e, v_dst, v_src); /* swap out tv for v_new in e */ + bmesh_disk_edge_append(e, v_dst); /* add e to v_dst's disk cycle */ + BLI_assert(e->v1 != e->v2); } /** @@ -88,6 +125,7 @@ bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new) * the disk cycle has no problems dealing with non-manifold conditions involving faces. * * Functions relating to this cycle: + * - #bmesh_disk_vert_replace * - #bmesh_disk_edge_append * - #bmesh_disk_edge_remove * - #bmesh_disk_edge_next @@ -206,13 +244,29 @@ 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; if (!BM_vert_in_edge(e, v)) return false; - if (bmesh_disk_count(v) != len || len == 0) + if (bmesh_disk_count_ex(v, len + 1) != len || len == 0) return false; e_iter = e; @@ -236,9 +290,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 +301,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 +528,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 * |