From b1c4d21e2e5aa7b5df552fa149dd78d29d0fd7d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Nov 2015 22:12:41 +1100 Subject: BMesh: support splitting edge-loops when expanding --- source/blender/bmesh/intern/bmesh_edgeloop.c | 57 +++++++++++++++++++++++++--- source/blender/bmesh/intern/bmesh_edgeloop.h | 5 ++- 2 files changed, 56 insertions(+), 6 deletions(-) (limited to 'source/blender/bmesh/intern') diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index eaa070151a6..5e1d9c3a98d 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -664,17 +664,47 @@ void BM_edgeloop_flip(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store) BLI_listbase_reverse(&el_store->verts); } -void BM_edgeloop_expand(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, int el_store_len) +void BM_edgeloop_expand( + BMesh *bm, BMEdgeLoopStore *el_store, int el_store_len, + bool split, GSet *split_edges) { + bool split_swap = true; + +#define EDGE_SPLIT(node_copy, node_other) { \ + BMVert *v_split, *v_other = (node_other)->data; \ + BMEdge *e_split, *e_other = BM_edge_exists((node_copy)->data, v_other); \ + v_split = BM_edge_split(bm, e_other, split_swap ? (node_copy)->data : v_other, &e_split, 0.0f); \ + v_split->e = e_split; \ + BLI_assert(v_split == e_split->v2); \ + BLI_gset_insert(split_edges, e_split); \ + (node_copy)->data = v_split; \ + } ((void)0) + /* first double until we are more than half as big */ while ((el_store->len * 2) < el_store_len) { LinkData *node_curr = el_store->verts.first; while (node_curr) { LinkData *node_curr_copy = MEM_dupallocN(node_curr); - BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + if (split == false) { + BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr_copy->next; + } + else { + if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) { + EDGE_SPLIT(node_curr_copy, node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first); + BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr_copy->next; + } + else { + EDGE_SPLIT(node_curr_copy, node_curr->prev); + BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr->next; + } + split_swap = !split_swap; + } el_store->len++; - node_curr = node_curr_copy->next; } + split_swap = !split_swap; } if (el_store->len < el_store_len) { @@ -694,12 +724,29 @@ void BM_edgeloop_expand(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, int el_sto BLI_LISTBASE_CIRCULAR_FORWARD_END (&el_store->verts, node_curr, node_curr_init); node_curr_copy = MEM_dupallocN(node_curr); - BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + if (split == false) { + BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr_copy->next; + } + else { + if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) { + EDGE_SPLIT(node_curr_copy, node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first); + BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr_copy->next; + } + else { + EDGE_SPLIT(node_curr_copy, node_curr->prev); + BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy); + node_curr = node_curr->next; + } + split_swap = !split_swap; + } el_store->len++; - node_curr = node_curr_copy->next; } while (el_store->len < el_store_len); } +#undef EDGE_SPLIT + BLI_assert(el_store->len == el_store_len); } diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h index 5df4ee5848e..68583562888 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.h +++ b/source/blender/bmesh/intern/bmesh_edgeloop.h @@ -30,6 +30,7 @@ struct ListBase; struct BMEdgeLoopStore; +struct GSet; /* multiple edgeloops (ListBase) */ int BM_mesh_edgeloops_find( @@ -66,7 +67,9 @@ bool BM_edgeloop_calc_normal_aligned( BMesh *bm, struct BMEdgeLoopStore *el_store, const float no_align[3]); void BM_edgeloop_flip(BMesh *bm, struct BMEdgeLoopStore *el_store); -void BM_edgeloop_expand(BMesh *bm, struct BMEdgeLoopStore *el_store, int el_store_len); +void BM_edgeloop_expand( + BMesh *bm, struct BMEdgeLoopStore *el_store, int el_store_len, + bool split, struct GSet *split_edges); bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b); -- cgit v1.2.3