BMesh: support splitting edge-loops when expanding

This commit is contained in:
2015-11-19 22:12:41 +11:00
parent 9c044b4773
commit b1c4d21e2e
3 changed files with 57 additions and 7 deletions

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -284,7 +284,7 @@ static void bridge_loop_pair(
if (el_store_a_len > el_store_b_len) {
el_store_b = BM_edgeloop_copy(el_store_b);
BM_edgeloop_expand(bm, el_store_b, el_store_a_len);
BM_edgeloop_expand(bm, el_store_b, el_store_a_len, false, NULL);
el_store_b_free = true;
}