256
259
} while ((l_iter = l_iter->next) != l_first);
258
f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD);
261
f_copy = BM_face_create(bm_dst, verts, edges, f->len, BM_CREATE_SKIP_CD);
260
BM_elem_attrs_copy(bm, bm, f, f_copy);
263
BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
262
265
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
263
266
l_copy = BM_FACE_FIRST_LOOP(f_copy);
265
BM_elem_attrs_copy(bm, bm, l_iter, l_copy);
268
BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy);
266
269
l_copy = l_copy->next;
267
270
} while ((l_iter = l_iter->next) != l_first);
1038
1053
/* create region face */
1039
newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
1040
if (UNLIKELY(!newf || BMO_error_occurred(bm))) {
1054
f_new = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
1055
if (UNLIKELY(!f_new || BMO_error_occurred(bm))) {
1041
1056
if (!BMO_error_occurred(bm))
1042
1057
err = N_("Invalid boundary region to join faces");
1046
1061
/* copy over loop data */
1047
l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
1062
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
1049
1064
BMLoop *l2 = l_iter->radial_next;
1065
1080
} while ((l_iter = l_iter->next) != l_first);
1067
BM_elem_attrs_copy(bm, bm, faces[0], newf);
1082
BM_elem_attrs_copy(bm, bm, faces[0], f_new);
1069
1084
#ifdef USE_BMESH_HOLES
1070
1085
/* add holes */
1071
BLI_movelisttolist(&newf->loops, &holes);
1086
BLI_movelisttolist(&f_new->loops, &holes);
1074
1089
/* update loop face pointer */
1075
1090
#ifdef USE_BMESH_HOLES
1076
for (lst = newf->loops.first; lst; lst = lst->next)
1091
for (lst = f_new->loops.first; lst; lst = lst->next)
1079
1094
#ifdef USE_BMESH_HOLES
1080
1095
l_iter = l_first = lst->first;
1082
l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
1097
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
1086
1101
} while ((l_iter = l_iter->next) != l_first);
1089
1104
bm_elements_systag_disable(faces, totface, _FLAG_JF);
1090
BM_ELEM_API_FLAG_DISABLE(newf, _FLAG_JF);
1105
BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF);
1092
1107
/* handle multi-res data */
1093
1108
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
1094
l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
1109
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
1096
1111
for (i = 0; i < totface; i++) {
1097
1112
BM_loop_interp_multires(bm, l_iter, faces[i]);
1212
1227
BMLoop *l_iter, *l_first;
1213
BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL;
1228
BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL;
1215
1230
int i, len, f1len, f2len;
1217
1232
/* verify that v1 and v2 are in face */
1219
1234
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < len; i++, l_iter = l_iter->next) {
1220
if (l_iter->v == v1) v1loop = l_iter;
1221
else if (l_iter->v == v2) v2loop = l_iter;
1235
if (l_iter->v == v1) l_v1 = l_iter;
1236
else if (l_iter->v == v2) l_v2 = l_iter;
1224
if (!v1loop || !v2loop) {
1239
if (!l_v1 || !l_v2) {
1229
1244
e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0);
1231
1246
f2 = bm_face_create__sfme(bm, f);
1232
f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
1233
f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0);
1235
f1loop->prev = v2loop->prev;
1236
f2loop->prev = v1loop->prev;
1237
v2loop->prev->next = f1loop;
1238
v1loop->prev->next = f2loop;
1240
f1loop->next = v1loop;
1241
f2loop->next = v2loop;
1242
v1loop->prev = f1loop;
1243
v2loop->prev = f2loop;
1247
l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0);
1248
l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0);
1250
l_f1->prev = l_v2->prev;
1251
l_f2->prev = l_v1->prev;
1252
l_v2->prev->next = l_f1;
1253
l_v1->prev->next = l_f2;
1245
1260
#ifdef USE_BMESH_HOLES
1246
1261
lst = f->loops.first;
1247
1262
lst2 = f2->loops.first;
1249
lst2->first = lst2->last = f2loop;
1250
lst->first = lst->last = f1loop;
1264
lst2->first = lst2->last = l_f2;
1265
lst->first = lst->last = l_f1;
1252
1267
/* find which of the faces the original first loop is in */
1253
l_iter = l_first = f1loop;
1268
l_iter = l_first = l_f1;
1254
1269
first_loop_f1 = 0;
1256
1271
if (l_iter == f->l_first)
1261
1276
/* original first loop was in f1, find a suitable first loop for f2
1262
1277
* which is as similar as possible to f1. the order matters for tools
1263
1278
* such as duplifaces. */
1264
if (f->l_first->prev == f1loop)
1265
f2->l_first = f2loop->prev;
1266
else if (f->l_first->next == f1loop)
1267
f2->l_first = f2loop->next;
1279
if (f->l_first->prev == l_f1)
1280
f2->l_first = l_f2->prev;
1281
else if (f->l_first->next == l_f1)
1282
f2->l_first = l_f2->next;
1269
f2->l_first = f2loop;
1272
1287
/* original first loop was in f2, further do same as above */
1273
1288
f2->l_first = f->l_first;
1275
if (f->l_first->prev == f2loop)
1276
f->l_first = f1loop->prev;
1277
else if (f->l_first->next == f2loop)
1278
f->l_first = f1loop->next;
1290
if (f->l_first->prev == l_f2)
1291
f->l_first = l_f1->prev;
1292
else if (f->l_first->next == l_f2)
1293
f->l_first = l_f1->next;
1280
f->l_first = f1loop;
1350
1365
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
1369
BMVert *v_new, *v_old;
1355
1370
int i, valence1 = 0, valence2 = 0;
1358
1373
BLI_assert(bmesh_vert_in_edge(e, tv) != false);
1360
ov = bmesh_edge_other_vert_get(e, tv);
1375
v_old = bmesh_edge_other_vert_get(e, tv);
1362
valence1 = bmesh_disk_count(ov);
1377
valence1 = bmesh_disk_count(v_old);
1364
1379
valence2 = bmesh_disk_count(tv);
1366
nv = BM_vert_create(bm, tv->co, tv, 0);
1367
ne = BM_edge_create(bm, nv, tv, e, 0);
1381
v_new = BM_vert_create(bm, tv->co, tv, 0);
1382
e_new = BM_edge_create(bm, v_new, tv, e, 0);
1369
bmesh_disk_edge_remove(ne, tv);
1370
bmesh_disk_edge_remove(ne, nv);
1384
bmesh_disk_edge_remove(e_new, tv);
1385
bmesh_disk_edge_remove(e_new, v_new);
1372
1387
/* remove e from tv's disk cycle */
1373
1388
bmesh_disk_edge_remove(e, tv);
1375
/* swap out tv for nv in e */
1376
bmesh_edge_swapverts(e, tv, nv);
1378
/* add e to nv's disk cycle */
1379
bmesh_disk_edge_append(e, nv);
1381
/* add ne to nv's disk cycle */
1382
bmesh_disk_edge_append(ne, nv);
1384
/* add ne to tv's disk cycle */
1385
bmesh_disk_edge_append(ne, tv);
1390
/* swap out tv for v_new in e */
1391
bmesh_edge_swapverts(e, tv, v_new);
1393
/* add e to v_new's disk cycle */
1394
bmesh_disk_edge_append(e, v_new);
1396
/* add e_new to v_new's disk cycle */
1397
bmesh_disk_edge_append(e_new, v_new);
1399
/* add e_new to tv's disk cycle */
1400
bmesh_disk_edge_append(e_new, tv);
1387
1402
/* verify disk cycles */
1388
edok = bmesh_disk_validate(valence1, ov->e, ov);
1403
edok = bmesh_disk_validate(valence1, v_old->e, v_old);
1389
1404
BMESH_ASSERT(edok != false);
1390
1405
edok = bmesh_disk_validate(valence2, tv->e, tv);
1391
1406
BMESH_ASSERT(edok != false);
1392
edok = bmesh_disk_validate(2, nv->e, nv);
1407
edok = bmesh_disk_validate(2, v_new->e, v_new);
1393
1408
BMESH_ASSERT(edok != false);
1395
1410
/* Split the radial cycle if present */
1400
int radlen = bmesh_radial_length(nextl);
1415
int radlen = bmesh_radial_length(l_next);
1401
1416
int first1 = 0, first2 = 0;
1403
1418
/* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
1407
nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL;
1422
l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
1408
1423
bmesh_radial_loop_remove(l, NULL);
1410
nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
1412
nl->next = (l->next);
1413
nl->prev->next = nl;
1414
nl->next->prev = nl;
1425
l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
1427
l_new->next = (l->next);
1428
l_new->prev->next = l_new;
1429
l_new->next->prev = l_new;
1417
1432
/* assign the correct edge to the correct loop */
1418
if (bmesh_verts_in_edge(nl->v, nl->next->v, e)) {
1433
if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e)) {
1422
/* append l into ne's rad cycle */
1437
/* append l into e_new's rad cycle */
1425
1440
l->radial_next = l->radial_prev = NULL;
1457
1472
/* verify length of radial cycle */
1458
1473
edok = bmesh_radial_validate(radlen, e->l);
1459
1474
BMESH_ASSERT(edok != false);
1460
edok = bmesh_radial_validate(radlen, ne->l);
1475
edok = bmesh_radial_validate(radlen, e_new->l);
1461
1476
BMESH_ASSERT(edok != false);
1463
1478
/* verify loop->v and loop->next->v pointers for e */
1464
1479
for (i = 0, l = e->l; i < radlen; i++, l = l->radial_next) {
1465
1480
BMESH_ASSERT(l->e == e);
1466
1481
//BMESH_ASSERT(l->radial_next == l);
1467
BMESH_ASSERT(!(l->prev->e != ne && l->next->e != ne));
1482
BMESH_ASSERT(!(l->prev->e != e_new && l->next->e != e_new));
1469
1484
edok = bmesh_verts_in_edge(l->v, l->next->v, e);
1470
1485
BMESH_ASSERT(edok != false);
1477
1492
BM_CHECK_ELEMENT(l->e);
1478
1493
BM_CHECK_ELEMENT(l->f);
1480
/* verify loop->v and loop->next->v pointers for ne */
1481
for (i = 0, l = ne->l; i < radlen; i++, l = l->radial_next) {
1482
BMESH_ASSERT(l->e == ne);
1495
/* verify loop->v and loop->next->v pointers for e_new */
1496
for (i = 0, l = e_new->l; i < radlen; i++, l = l->radial_next) {
1497
BMESH_ASSERT(l->e == e_new);
1483
1498
// BMESH_ASSERT(l->radial_next == l);
1484
1499
BMESH_ASSERT(!(l->prev->e != e && l->next->e != e));
1485
edok = bmesh_verts_in_edge(l->v, l->next->v, ne);
1500
edok = bmesh_verts_in_edge(l->v, l->next->v, e_new);
1486
1501
BMESH_ASSERT(edok != false);
1487
1502
BMESH_ASSERT(l->v != l->next->v);
1488
1503
BMESH_ASSERT(l->e != l->next->e);
1535
1550
* faces with just 2 edges. It is up to the caller to decide what to do with
1538
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_double)
1553
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_double)
1542
BMLoop *killoop, *l;
1543
1558
int len, radlen = 0, i, valence1, valence2;
1544
1559
bool edok, halt = false;
1546
if (bmesh_vert_in_edge(ke, kv) == 0) {
1561
if (bmesh_vert_in_edge(e_kill, v_kill) == 0) {
1550
len = bmesh_disk_count(kv);
1565
len = bmesh_disk_count(v_kill);
1552
1567
if (len == 2) {
1553
oe = bmesh_disk_edge_next(ke, kv);
1554
tv = bmesh_edge_other_vert_get(ke, kv);
1555
ov = bmesh_edge_other_vert_get(oe, kv);
1556
halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */
1568
e_old = bmesh_disk_edge_next(e_kill, v_kill);
1569
tv = bmesh_edge_other_vert_get(e_kill, v_kill);
1570
v_old = bmesh_edge_other_vert_get(e_old, v_kill);
1571
halt = bmesh_verts_in_edge(v_kill, tv, e_old); /* check for double edges */
1562
1577
BMEdge *e_splice;
1564
/* For verification later, count valence of ov and tv */
1565
valence1 = bmesh_disk_count(ov);
1579
/* For verification later, count valence of v_old and tv */
1580
valence1 = bmesh_disk_count(v_old);
1566
1581
valence2 = bmesh_disk_count(tv);
1568
1583
if (check_edge_double) {
1569
e_splice = BM_edge_exists(tv, ov);
1584
e_splice = BM_edge_exists(tv, v_old);
1572
/* remove oe from kv's disk cycle */
1573
bmesh_disk_edge_remove(oe, kv);
1574
/* relink oe->kv to be oe->tv */
1575
bmesh_edge_swapverts(oe, kv, tv);
1576
/* append oe to tv's disk cycle */
1577
bmesh_disk_edge_append(oe, tv);
1578
/* remove ke from tv's disk cycle */
1579
bmesh_disk_edge_remove(ke, tv);
1587
/* remove e_old from v_kill's disk cycle */
1588
bmesh_disk_edge_remove(e_old, v_kill);
1589
/* relink e_old->v_kill to be e_old->tv */
1590
bmesh_edge_swapverts(e_old, v_kill, tv);
1591
/* append e_old to tv's disk cycle */
1592
bmesh_disk_edge_append(e_old, tv);
1593
/* remove e_kill from tv's disk cycle */
1594
bmesh_disk_edge_remove(e_kill, tv);
1581
/* deal with radial cycle of ke */
1582
radlen = bmesh_radial_length(ke->l);
1584
/* first step, fix the neighboring loops of all loops in ke's radial cycle */
1585
for (i = 0, killoop = ke->l; i < radlen; i++, killoop = killoop->radial_next) {
1596
/* deal with radial cycle of e_kill */
1597
radlen = bmesh_radial_length(e_kill->l);
1599
/* first step, fix the neighboring loops of all loops in e_kill's radial cycle */
1600
for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) {
1586
1601
/* relink loops and fix vertex pointer */
1587
if (killoop->next->v == kv) {
1588
killoop->next->v = tv;
1602
if (l_kill->next->v == v_kill) {
1603
l_kill->next->v = tv;
1591
killoop->next->prev = killoop->prev;
1592
killoop->prev->next = killoop->next;
1593
if (BM_FACE_FIRST_LOOP(killoop->f) == killoop) {
1594
BM_FACE_FIRST_LOOP(killoop->f) = killoop->next;
1606
l_kill->next->prev = l_kill->prev;
1607
l_kill->prev->next = l_kill->next;
1608
if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
1609
BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
1596
killoop->next = NULL;
1597
killoop->prev = NULL;
1611
l_kill->next = NULL;
1612
l_kill->prev = NULL;
1599
1614
/* fix len attribute of face */
1602
/* second step, remove all the hanging loops attached to ke */
1603
radlen = bmesh_radial_length(ke->l);
1617
/* second step, remove all the hanging loops attached to e_kill */
1618
radlen = bmesh_radial_length(e_kill->l);
1605
1620
if (LIKELY(radlen)) {
1606
1621
BMLoop **loops = BLI_array_alloca(loops, radlen);
1610
1625
/* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */
1611
1626
for (i = 0; i < radlen; i++) {
1613
killoop = killoop->radial_next;
1628
l_kill = l_kill->radial_next;
1615
1630
for (i = 0; i < radlen; i++) {
1621
/* Validate radial cycle of oe */
1622
edok = bmesh_radial_validate(radlen, oe->l);
1636
/* Validate radial cycle of e_old */
1637
edok = bmesh_radial_validate(radlen, e_old->l);
1623
1638
BMESH_ASSERT(edok != false);
1626
1641
/* deallocate edge */
1627
bm_kill_only_edge(bm, ke);
1642
bm_kill_only_edge(bm, e_kill);
1629
1644
/* deallocate vertex */
1630
bm_kill_only_vert(bm, kv);
1645
bm_kill_only_vert(bm, v_kill);
1632
/* Validate disk cycle lengths of ov, tv are unchanged */
1633
edok = bmesh_disk_validate(valence1, ov->e, ov);
1647
/* Validate disk cycle lengths of v_old, tv are unchanged */
1648
edok = bmesh_disk_validate(valence1, v_old->e, v_old);
1634
1649
BMESH_ASSERT(edok != false);
1635
1650
edok = bmesh_disk_validate(valence2, tv->e, tv);
1636
1651
BMESH_ASSERT(edok != false);
1638
/* Validate loop cycle of all faces attached to 'oe' */
1639
for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) {
1640
BMESH_ASSERT(l->e == oe);
1641
edok = bmesh_verts_in_edge(l->v, l->next->v, oe);
1653
/* Validate loop cycle of all faces attached to 'e_old' */
1654
for (i = 0, l = e_old->l; i < radlen; i++, l = l->radial_next) {
1655
BMESH_ASSERT(l->e == e_old);
1656
edok = bmesh_verts_in_edge(l->v, l->next->v, e_old);
1642
1657
BMESH_ASSERT(edok != false);
1643
1658
edok = bmesh_loop_validate(l->f);
1644
1659
BMESH_ASSERT(edok != false);
1716
1731
f1len = f1->len;
1717
1732
f2len = f2->len;
1719
if (!((f1loop = BM_face_edge_share_loop(f1, e)) &&
1720
(f2loop = BM_face_edge_share_loop(f2, e))))
1734
if (!((l_f1 = BM_face_edge_share_loop(f1, e)) &&
1735
(l_f2 = BM_face_edge_share_loop(f2, e))))
1725
1740
/* validate direction of f2's loop cycle is compatible */
1726
if (f1loop->v == f2loop->v) {
1741
if (l_f1->v == l_f2->v) {
1730
1745
/* validate that for each face, each vertex has another edge in its disk cycle that is
1731
1746
* not e, and not shared. */
1732
if (bmesh_radial_face_find(f1loop->next->e, f2) ||
1733
bmesh_radial_face_find(f1loop->prev->e, f2) ||
1734
bmesh_radial_face_find(f2loop->next->e, f1) ||
1735
bmesh_radial_face_find(f2loop->prev->e, f1) )
1747
if (bmesh_radial_face_find(l_f1->next->e, f2) ||
1748
bmesh_radial_face_find(l_f1->prev->e, f2) ||
1749
bmesh_radial_face_find(l_f2->next->e, f1) ||
1750
bmesh_radial_face_find(l_f2->prev->e, f1) )
1767
1782
/* join the two loop */
1768
f1loop->prev->next = f2loop->next;
1769
f2loop->next->prev = f1loop->prev;
1771
f1loop->next->prev = f2loop->prev;
1772
f2loop->prev->next = f1loop->next;
1774
/* if f1loop was baseloop, make f1loop->next the base. */
1775
if (BM_FACE_FIRST_LOOP(f1) == f1loop)
1776
BM_FACE_FIRST_LOOP(f1) = f1loop->next;
1783
l_f1->prev->next = l_f2->next;
1784
l_f2->next->prev = l_f1->prev;
1786
l_f1->next->prev = l_f2->prev;
1787
l_f2->prev->next = l_f1->next;
1789
/* if l_f1 was baseloop, make l_f1->next the base. */
1790
if (BM_FACE_FIRST_LOOP(f1) == l_f1)
1791
BM_FACE_FIRST_LOOP(f1) = l_f1->next;
1778
1793
/* increase length of f1 */
1779
1794
f1->len += (f2->len - 2);
1784
1799
l_iter->f = f1;
1786
1801
/* remove edge from the disk cycle of its two vertices */
1787
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v1);
1788
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
1802
bmesh_disk_edge_remove(l_f1->e, l_f1->e->v1);
1803
bmesh_disk_edge_remove(l_f1->e, l_f1->e->v2);
1790
1805
/* deallocate edge and its two loops as well as f2 */
1791
1806
if (bm->etoolflagpool) {
1792
BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
1807
BLI_mempool_free(bm->etoolflagpool, l_f1->e->oflags);
1794
BLI_mempool_free(bm->epool, f1loop->e);
1809
BLI_mempool_free(bm->epool, l_f1->e);
1796
BLI_mempool_free(bm->lpool, f1loop);
1811
BLI_mempool_free(bm->lpool, l_f1);
1798
BLI_mempool_free(bm->lpool, f2loop);
1813
BLI_mempool_free(bm->lpool, l_f2);
1800
1815
if (bm->ftoolflagpool) {
1801
1816
BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
1882
1897
bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
1884
BMEdge **stack = NULL;
1885
BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE);
1899
const int v_edgetot = BM_vert_face_count(v);
1900
BMEdge **stack = BLI_array_alloca(stack, v_edgetot);
1901
STACK_DECLARE(stack);
1903
SmallHash visithash;
1886
1904
BMVert **verts = NULL;
1888
1905
BMIter eiter, liter;
1891
1908
int i, maxindex;
1894
visithash = BLI_ghash_ptr_new(__func__);
1911
BLI_smallhash_init(&visithash);
1897
1916
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
1898
if (BLI_ghash_haskey(visithash, e)) {
1917
if (BLI_smallhash_haskey(&visithash, (uintptr_t)e)) {
1902
/* Prime the stack with this unvisited edge */
1903
BLI_array_append(stack, e);
1905
1921
/* Considering only edges and faces incident on vertex v, walk
1906
1922
* the edges & faces and assign an index to each connected set */
1907
while ((e = BLI_array_pop(stack))) {
1908
BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex));
1924
BLI_smallhash_insert(&visithash, (uintptr_t)e, SET_INT_IN_POINTER(maxindex));
1910
BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
1911
nl = (l->v == v) ? l->prev : l->next;
1912
if (!BLI_ghash_haskey(visithash, nl->e)) {
1913
BLI_array_append(stack, nl->e);
1927
BMLoop *l_iter, *l_first;
1928
l_iter = l_first = e->l;
1930
l_new = (l_iter->v == v) ? l_iter->prev : l_iter->next;
1931
if (!BLI_smallhash_haskey(&visithash, (uintptr_t)l_new->e)) {
1932
STACK_PUSH(stack, l_new->e);
1934
} while ((l_iter = l_iter->radial_next) != l_first);
1936
} while ((e = STACK_POP(stack)));
1921
1941
/* Make enough verts to split v for each group */
1922
verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
1942
if (r_vout != NULL) {
1943
verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
1946
verts = BLI_array_alloca(verts, maxindex);
1924
1950
for (i = 1; i < maxindex; i++) {
1925
1951
verts[i] = BM_vert_create(bm, v->co, v, 0);
1952
1978
* by modifying data it loops over [#30632], this re-uses the 'stack' variable which is a bit
1953
1979
* bad practice but save alloc'ing a new array - note, the comment above is useful, keep it
1954
1980
* if you are tidying up code - campbell */
1955
BLI_array_empty(stack);
1956
1982
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
1957
1983
if (l->v == v) {
1958
BLI_array_append(stack, (BMEdge *)l);
1984
STACK_PUSH(stack, (BMEdge *)l);
1961
while ((l = (BMLoop *)(BLI_array_pop(stack)))) {
1962
if ((i = GET_INT_FROM_POINTER(BLI_ghash_lookup(visithash, l->e)))) {
1987
while ((l = (BMLoop *)(STACK_POP(stack)))) {
1988
if ((i = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&visithash, (uintptr_t)l->e)))) {
1963
1989
l->v = verts[i];
1968
BLI_array_free(stack);
1970
1996
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
1971
i = GET_INT_FROM_POINTER(BLI_ghash_lookup(visithash, e));
1997
i = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&visithash, (uintptr_t)e));
2106
2129
* \brief Un-glue Region Make Vert (URMV)
2108
* Disconnects a face from its vertex fan at loop \a sl
2131
* Disconnects a face from its vertex fan at loop \a l_sep
2110
2133
* \return The newly created BMVert
2112
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
2135
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
2139
BMVert *v_new = NULL;
2140
BMVert *v_sep = l_sep->v;
2119
2142
/* peel the face from the edge radials on both sides of the
2120
2143
* loop vert, disconnecting the face from its fan */
2121
bmesh_edge_separate(bm, sl->e, sl);
2122
bmesh_edge_separate(bm, sl->prev->e, sl->prev);
2144
bmesh_edge_separate(bm, l_sep->e, l_sep);
2145
bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev);
2124
if (bmesh_disk_count(sv) == 2) {
2125
/* If there are still only two edges out of sv, then
2147
if (bmesh_disk_count(v_sep) == 2) {
2148
/* If there are still only two edges out of v_sep, then
2126
2149
* this whole URMV was just a no-op, so exit now. */
2130
2153
/* Update the disk start, so that v->e points to an edge
2131
2154
* not touching the split loop. This is so that BM_vert_split
2132
* will leave the original sv on some *other* fan (not the
2155
* will leave the original v_sep on some *other* fan (not the
2133
2156
* one-face fan that holds the unglue face). */
2134
while (sv->e == sl->e || sv->e == sl->prev->e) {
2135
sv->e = bmesh_disk_edge_next(sv->e, sv);
2157
while (v_sep->e == l_sep->e || v_sep->e == l_sep->prev->e) {
2158
v_sep->e = bmesh_disk_edge_next(v_sep->e, v_sep);
2138
2161
/* Split all fans connected to the vert, duplicating it for
2139
2162
* each fans. */
2140
bmesh_vert_separate(bm, sv, &vtar, &len);
2163
bmesh_vert_separate(bm, v_sep, &vtar, &len);
2142
2165
/* There should have been at least two fans cut apart here,
2143
2166
* otherwise the early exit would have kicked in. */
2144
2167
BLI_assert(len >= 2);
2148
2171
/* Desired result here is that a new vert should always be
2149
2172
* created for the unglue face. This is so we can glue any
2150
2173
* extras back into the original vert. */
2151
BLI_assert(nv != sv);
2152
BLI_assert(sv == vtar[0]);
2174
BLI_assert(v_new != v_sep);
2175
BLI_assert(v_sep == vtar[0]);
2154
2177
/* If there are more than two verts as a result, glue together
2155
2178
* all the verts except the one this URMV intended to create */
2157
2180
for (i = 0; i < len; i++) {
2158
if (vtar[i] == nv) {
2181
if (vtar[i] == v_new) {