~ubuntu-branches/ubuntu/trusty/blender/trusty-proposed

« back to all changes in this revision

Viewing changes to source/blender/bmesh/intern/bmesh_core.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2013-08-14 10:43:49 UTC
  • mfrom: (14.2.19 sid)
  • Revision ID: package-import@ubuntu.com-20130814104349-t1d5mtwkphp12dyj
Tags: 2.68a-3
* Upload to unstable
* debian/: python3.3 Depends simplified
  - debian/control: python3.3 Depends dropped
    for blender-data package
  - 0001-blender_thumbnailer.patch refreshed
* debian/control: libavcodec b-dep versioning dropped

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include "BLI_math_vector.h"
31
31
#include "BLI_listbase.h"
32
32
#include "BLI_array.h"
 
33
#include "BLI_smallhash.h"
33
34
 
34
35
#include "BLF_translation.h"
35
36
 
209
210
        return l;
210
211
}
211
212
 
212
 
BMFace *BM_face_copy(BMesh *bm, BMFace *f,
 
213
BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
213
214
                     const bool copy_verts, const bool copy_edges)
214
215
{
215
216
        BMVert **verts = BLI_array_alloca(verts, f->len);
220
221
        BMFace *f_copy;
221
222
        int i;
222
223
 
 
224
        BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges));
 
225
 
223
226
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
224
227
        i = 0;
225
228
        do {
226
229
                if (copy_verts) {
227
 
                        verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
 
230
                        verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, 0);
228
231
                }
229
232
                else {
230
233
                        verts[i] = l_iter->v;
247
250
                                v1 = verts[(i + 1) % f->len];
248
251
                        }
249
252
                        
250
 
                        edges[i] = BM_edge_create(bm,  v1, v2, l_iter->e, 0);
 
253
                        edges[i] = BM_edge_create(bm_dst,  v1, v2, l_iter->e, 0);
251
254
                }
252
255
                else {
253
256
                        edges[i] = l_iter->e;
255
258
                i++;
256
259
        } while ((l_iter = l_iter->next) != l_first);
257
260
        
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);
259
262
        
260
 
        BM_elem_attrs_copy(bm, bm, f, f_copy);
 
263
        BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
261
264
        
262
265
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
263
266
        l_copy = BM_FACE_FIRST_LOOP(f_copy);
264
267
        do {
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);
268
271
 
308
311
}
309
312
 
310
313
/**
311
 
 * \brief Main face creation function
 
314
 * Main face creation function
 
315
 *
 
316
 * \param bm  The mesh
 
317
 * \param verts  A sorted array of verts size of len
 
318
 * \param edges  A sorted array of edges size of len
 
319
 * \param len  Length of the face
 
320
 * \param create_flag  Options for creating the face
312
321
 */
313
322
BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag)
314
323
{
489
498
 
490
499
                        if (len != f->len)
491
500
                                err |= (1 << 23);
 
501
                        break;
492
502
                }
 
503
                default:
 
504
                        BLI_assert(0);
493
505
        }
494
506
 
495
507
        BMESH_ASSERT(err == 0);
781
793
                        for (x = 0; x < sides; x++) {
782
794
                                for (y = 0; y < x; y++) {
783
795
                                        swap_v3_v3(co[y * sides + x], co[sides * x + y]);
 
796
                                        SWAP(float, co[y * sides + x][0], co[y * sides + x][1]);
 
797
                                        SWAP(float, co[x * sides + y][0], co[x * sides + y][1]);
784
798
                                }
 
799
                                SWAP(float, co[x * sides + x][0], co[x * sides + x][1]);
785
800
                        }
786
801
                }
787
802
        }
942
957
 */
943
958
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
944
959
{
945
 
        BMFace *f, *newf;
 
960
        BMFace *f, *f_new;
946
961
#ifdef USE_BMESH_HOLES
947
962
        BMLoopList *lst;
948
963
        ListBase holes = {NULL, NULL};
1036
1051
        }
1037
1052
 
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");
1043
1058
                goto error;
1044
1059
        }
1045
1060
 
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);
1048
1063
        do {
1049
1064
                BMLoop *l2 = l_iter->radial_next;
1050
1065
 
1064
1079
                }
1065
1080
        } while ((l_iter = l_iter->next) != l_first);
1066
1081
        
1067
 
        BM_elem_attrs_copy(bm, bm, faces[0], newf);
 
1082
        BM_elem_attrs_copy(bm, bm, faces[0], f_new);
1068
1083
 
1069
1084
#ifdef USE_BMESH_HOLES
1070
1085
        /* add holes */
1071
 
        BLI_movelisttolist(&newf->loops, &holes);
 
1086
        BLI_movelisttolist(&f_new->loops, &holes);
1072
1087
#endif
1073
1088
 
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)
1077
1092
#endif
1078
1093
        {
1079
1094
#ifdef USE_BMESH_HOLES
1080
1095
                l_iter = l_first = lst->first;
1081
1096
#else
1082
 
                l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
 
1097
                l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
1083
1098
#endif
1084
1099
                do {
1085
 
                        l_iter->f = newf;
 
1100
                        l_iter->f = f_new;
1086
1101
                } while ((l_iter = l_iter->next) != l_first);
1087
1102
        }
1088
1103
 
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);
1091
1106
 
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);
1095
1110
                do {
1096
1111
                        for (i = 0; i < totface; i++) {
1097
1112
                                BM_loop_interp_multires(bm, l_iter, faces[i]);
1120
1135
        BLI_array_free(deledges);
1121
1136
        BLI_array_free(delverts);
1122
1137
 
1123
 
        BM_CHECK_ELEMENT(newf);
1124
 
        return newf;
 
1138
        BM_CHECK_ELEMENT(f_new);
 
1139
        return f_new;
1125
1140
 
1126
1141
error:
1127
1142
        bm_elements_systag_disable(faces, totface, _FLAG_JF);
1210
1225
 
1211
1226
        BMFace *f2;
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;
1214
1229
        BMEdge *e;
1215
1230
        int i, len, f1len, f2len;
1216
1231
 
1217
1232
        /* verify that v1 and v2 are in face */
1218
1233
        len = f->len;
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;
1222
1237
        }
1223
1238
 
1224
 
        if (!v1loop || !v2loop) {
 
1239
        if (!l_v1 || !l_v2) {
1225
1240
                return NULL;
1226
1241
        }
1227
1242
 
1229
1244
        e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0);
1230
1245
 
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);
1234
 
 
1235
 
        f1loop->prev = v2loop->prev;
1236
 
        f2loop->prev = v1loop->prev;
1237
 
        v2loop->prev->next = f1loop;
1238
 
        v1loop->prev->next = f2loop;
1239
 
 
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);
 
1249
 
 
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;
 
1254
 
 
1255
        l_f1->next = l_v1;
 
1256
        l_f2->next = l_v2;
 
1257
        l_v1->prev = l_f1;
 
1258
        l_v2->prev = l_f2;
1244
1259
 
1245
1260
#ifdef USE_BMESH_HOLES
1246
1261
        lst = f->loops.first;
1247
1262
        lst2 = f2->loops.first;
1248
1263
 
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;
1251
1266
#else
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;
1255
1270
        do {
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;
1268
1283
                else
1269
 
                        f2->l_first = f2loop;
 
1284
                        f2->l_first = l_f2;
1270
1285
        }
1271
1286
        else {
1272
1287
                /* original first loop was in f2, further do same as above */
1273
1288
                f2->l_first = f->l_first;
1274
1289
 
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;
1279
1294
                else
1280
 
                        f->l_first = f1loop;
 
1295
                        f->l_first = l_f1;
1281
1296
        }
1282
1297
#endif
1283
1298
 
1293
1308
        } while ((l_iter = l_iter->next) != l_first);
1294
1309
 
1295
1310
        /* link up the new loops into the new edges radial */
1296
 
        bmesh_radial_append(e, f1loop);
1297
 
        bmesh_radial_append(e, f2loop);
 
1311
        bmesh_radial_append(e, l_f1);
 
1312
        bmesh_radial_append(e, l_f2);
1298
1313
 
1299
1314
        f2->len = f2len;
1300
1315
 
1306
1321
 
1307
1322
        f->len = f1len;
1308
1323
 
1309
 
        if (r_l) *r_l = f2loop;
 
1324
        if (r_l) *r_l = l_f2;
1310
1325
 
1311
1326
#ifdef USE_BMESH_HOLES
1312
1327
        if (holes) {
1349
1364
 */
1350
1365
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
1351
1366
{
1352
 
        BMLoop *nextl;
1353
 
        BMEdge *ne;
1354
 
        BMVert *nv, *ov;
 
1367
        BMLoop *l_next;
 
1368
        BMEdge *e_new;
 
1369
        BMVert *v_new, *v_old;
1355
1370
        int i, valence1 = 0, valence2 = 0;
1356
1371
        bool edok;
1357
1372
 
1358
1373
        BLI_assert(bmesh_vert_in_edge(e, tv) != false);
1359
1374
 
1360
 
        ov = bmesh_edge_other_vert_get(e, tv);
 
1375
        v_old = bmesh_edge_other_vert_get(e, tv);
1361
1376
 
1362
 
        valence1 = bmesh_disk_count(ov);
 
1377
        valence1 = bmesh_disk_count(v_old);
1363
1378
 
1364
1379
        valence2 = bmesh_disk_count(tv);
1365
1380
 
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);
1368
1383
 
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);
1371
1386
 
1372
1387
        /* remove e from tv's disk cycle */
1373
1388
        bmesh_disk_edge_remove(e, tv);
1374
1389
 
1375
 
        /* swap out tv for nv in e */
1376
 
        bmesh_edge_swapverts(e, tv, nv);
1377
 
 
1378
 
        /* add e to nv's disk cycle */
1379
 
        bmesh_disk_edge_append(e, nv);
1380
 
 
1381
 
        /* add ne to nv's disk cycle */
1382
 
        bmesh_disk_edge_append(ne, nv);
1383
 
 
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);
 
1392
 
 
1393
        /* add e to v_new's disk cycle */
 
1394
        bmesh_disk_edge_append(e, v_new);
 
1395
 
 
1396
        /* add e_new to v_new's disk cycle */
 
1397
        bmesh_disk_edge_append(e_new, v_new);
 
1398
 
 
1399
        /* add e_new to tv's disk cycle */
 
1400
        bmesh_disk_edge_append(e_new, tv);
1386
1401
 
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);
1394
1409
 
1395
1410
        /* Split the radial cycle if present */
1396
 
        nextl = e->l;
 
1411
        l_next = e->l;
1397
1412
        e->l = NULL;
1398
 
        if (nextl) {
1399
 
                BMLoop *nl, *l;
1400
 
                int radlen = bmesh_radial_length(nextl);
 
1413
        if (l_next) {
 
1414
                BMLoop *l_new, *l;
 
1415
                int radlen = bmesh_radial_length(l_next);
1401
1416
                int first1 = 0, first2 = 0;
1402
1417
 
1403
1418
                /* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
1404
 
                while (nextl) {
1405
 
                        l = nextl;
 
1419
                while (l_next) {
 
1420
                        l = l_next;
1406
1421
                        l->f->len++;
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);
1409
1424
 
1410
 
                        nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
1411
 
                        nl->prev = l;
1412
 
                        nl->next = (l->next);
1413
 
                        nl->prev->next = nl;
1414
 
                        nl->next->prev = nl;
1415
 
                        nl->v = nv;
 
1425
                        l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
 
1426
                        l_new->prev = l;
 
1427
                        l_new->next = (l->next);
 
1428
                        l_new->prev->next = l_new;
 
1429
                        l_new->next->prev = l_new;
 
1430
                        l_new->v = v_new;
1416
1431
 
1417
1432
                        /* assign the correct edge to the correct loop */
1418
 
                        if (bmesh_verts_in_edge(nl->v, nl->next->v, e)) {
1419
 
                                nl->e = e;
1420
 
                                l->e = ne;
 
1433
                        if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e)) {
 
1434
                                l_new->e = e;
 
1435
                                l->e = e_new;
1421
1436
 
1422
 
                                /* append l into ne's rad cycle */
 
1437
                                /* append l into e_new's rad cycle */
1423
1438
                                if (!first1) {
1424
1439
                                        first1 = 1;
1425
1440
                                        l->radial_next = l->radial_prev = NULL;
1430
1445
                                        l->radial_next = l->radial_prev = NULL;
1431
1446
                                }
1432
1447
                                
1433
 
                                bmesh_radial_append(nl->e, nl);
 
1448
                                bmesh_radial_append(l_new->e, l_new);
1434
1449
                                bmesh_radial_append(l->e, l);
1435
1450
                        }
1436
 
                        else if (bmesh_verts_in_edge(nl->v, nl->next->v, ne)) {
1437
 
                                nl->e = ne;
 
1451
                        else if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
 
1452
                                l_new->e = e_new;
1438
1453
                                l->e = e;
1439
1454
 
1440
 
                                /* append l into ne's rad cycle */
 
1455
                                /* append l into e_new's rad cycle */
1441
1456
                                if (!first1) {
1442
1457
                                        first1 = 1;
1443
1458
                                        l->radial_next = l->radial_prev = NULL;
1448
1463
                                        l->radial_next = l->radial_prev = NULL;
1449
1464
                                }
1450
1465
 
1451
 
                                bmesh_radial_append(nl->e, nl);
 
1466
                                bmesh_radial_append(l_new->e, l_new);
1452
1467
                                bmesh_radial_append(l->e, l);
1453
1468
                        }
1454
1469
 
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);
1462
1477
 
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));
1468
1483
 
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);
1479
1494
                }
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);
1494
1509
                }
1495
1510
        }
1496
1511
 
1497
 
        BM_CHECK_ELEMENT(ne);
1498
 
        BM_CHECK_ELEMENT(nv);
1499
 
        BM_CHECK_ELEMENT(ov);
 
1512
        BM_CHECK_ELEMENT(e_new);
 
1513
        BM_CHECK_ELEMENT(v_new);
 
1514
        BM_CHECK_ELEMENT(v_old);
1500
1515
        BM_CHECK_ELEMENT(e);
1501
1516
        BM_CHECK_ELEMENT(tv);
1502
1517
 
1503
 
        if (r_e) *r_e = ne;
1504
 
        return nv;
 
1518
        if (r_e) *r_e = e_new;
 
1519
        return v_new;
1505
1520
}
1506
1521
 
1507
1522
/**
1508
1523
 * \brief Join Edge Kill Vert (JEKV)
1509
1524
 *
1510
 
 * Takes an edge \a ke and pointer to one of its vertices \a kv
 
1525
 * Takes an edge \a e_kill and pointer to one of its vertices \a v_kill
1511
1526
 * and collapses the edge on that vertex.
1512
1527
 *
1513
1528
 * \par Examples:
1535
1550
 * faces with just 2 edges. It is up to the caller to decide what to do with
1536
1551
 * these faces.
1537
1552
 */
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)
1539
1554
{
1540
 
        BMEdge *oe;
1541
 
        BMVert *ov, *tv;
1542
 
        BMLoop *killoop, *l;
 
1555
        BMEdge *e_old;
 
1556
        BMVert *v_old, *tv;
 
1557
        BMLoop *l_kill, *l;
1543
1558
        int len, radlen = 0, i, valence1, valence2;
1544
1559
        bool edok, halt = false;
1545
1560
 
1546
 
        if (bmesh_vert_in_edge(ke, kv) == 0) {
 
1561
        if (bmesh_vert_in_edge(e_kill, v_kill) == 0) {
1547
1562
                return NULL;
1548
1563
        }
1549
1564
 
1550
 
        len = bmesh_disk_count(kv);
 
1565
        len = bmesh_disk_count(v_kill);
1551
1566
        
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 */
1557
1572
                
1558
1573
                if (halt) {
1559
1574
                        return NULL;
1561
1576
                else {
1562
1577
                        BMEdge *e_splice;
1563
1578
 
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);
1567
1582
 
1568
1583
                        if (check_edge_double) {
1569
 
                                e_splice = BM_edge_exists(tv, ov);
 
1584
                                e_splice = BM_edge_exists(tv, v_old);
1570
1585
                        }
1571
1586
 
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);
1580
1595
 
1581
 
                        /* deal with radial cycle of ke */
1582
 
                        radlen = bmesh_radial_length(ke->l);
1583
 
                        if (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);
 
1598
                        if (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;
1589
1604
                                        }
1590
1605
 
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;
1595
1610
                                        }
1596
 
                                        killoop->next = NULL;
1597
 
                                        killoop->prev = NULL;
 
1611
                                        l_kill->next = NULL;
 
1612
                                        l_kill->prev = NULL;
1598
1613
 
1599
1614
                                        /* fix len attribute of face */
1600
 
                                        killoop->f->len--;
 
1615
                                        l_kill->f->len--;
1601
1616
                                }
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);
1604
1619
 
1605
1620
                                if (LIKELY(radlen)) {
1606
1621
                                        BMLoop **loops = BLI_array_alloca(loops, radlen);
1607
1622
 
1608
 
                                        killoop = ke->l;
 
1623
                                        l_kill = e_kill->l;
1609
1624
 
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++) {
1612
 
                                                loops[i] = killoop;
1613
 
                                                killoop = killoop->radial_next;
 
1627
                                                loops[i] = l_kill;
 
1628
                                                l_kill = l_kill->radial_next;
1614
1629
                                        }
1615
1630
                                        for (i = 0; i < radlen; i++) {
1616
1631
                                                bm->totloop--;
1618
1633
                                        }
1619
1634
                                }
1620
1635
 
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);
1624
1639
                        }
1625
1640
 
1626
1641
                        /* deallocate edge */
1627
 
                        bm_kill_only_edge(bm, ke);
 
1642
                        bm_kill_only_edge(bm, e_kill);
1628
1643
 
1629
1644
                        /* deallocate vertex */
1630
 
                        bm_kill_only_vert(bm, kv);
 
1645
                        bm_kill_only_vert(bm, v_kill);
1631
1646
 
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);
1637
1652
 
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);
1652
1667
                        if (check_edge_double) {
1653
1668
                                if (e_splice) {
1654
1669
                                        /* removes e_splice */
1655
 
                                        BM_edge_splice(bm, e_splice, oe);
 
1670
                                        BM_edge_splice(bm, e_splice, e_old);
1656
1671
                                }
1657
1672
                        }
1658
1673
 
1659
 
                        BM_CHECK_ELEMENT(ov);
 
1674
                        BM_CHECK_ELEMENT(v_old);
1660
1675
                        BM_CHECK_ELEMENT(tv);
1661
 
                        BM_CHECK_ELEMENT(oe);
 
1676
                        BM_CHECK_ELEMENT(e_old);
1662
1677
 
1663
 
                        return oe;
 
1678
                        return e_old;
1664
1679
                }
1665
1680
        }
1666
1681
        return NULL;
1699
1714
 */
1700
1715
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
1701
1716
{
1702
 
        BMLoop *l_iter, *f1loop = NULL, *f2loop = NULL;
1703
 
        int newlen = 0, i, f1len = 0, f2len = 0, edok;
1704
 
 
 
1717
        BMLoop *l_iter, *l_f1 = NULL, *l_f2 = NULL;
 
1718
        int newlen = 0, i, f1len = 0, f2len = 0;
 
1719
        bool edok;
1705
1720
        /* can't join a face to itself */
1706
1721
        if (f1 == f2) {
1707
1722
                return NULL;
1716
1731
        f1len = f1->len;
1717
1732
        f2len = f2->len;
1718
1733
 
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))))
1721
1736
        {
1722
1737
                return NULL;
1723
1738
        }
1724
1739
 
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) {
1727
1742
                return NULL;
1728
1743
        }
1729
1744
 
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) )
1736
1751
        {
1737
1752
                return NULL;
1738
1753
        }
1751
1766
        }
1752
1767
 
1753
1768
        for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
1754
 
                if (l_iter != f1loop) {
 
1769
                if (l_iter != l_f1) {
1755
1770
                        BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
1756
1771
                }
1757
1772
        }
1758
1773
        for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
1759
 
                if (l_iter != f2loop) {
 
1774
                if (l_iter != l_f2) {
1760
1775
                        /* as soon as a duplicate is found, bail out */
1761
1776
                        if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
1762
1777
                                return NULL;
1765
1780
        }
1766
1781
 
1767
1782
        /* join the two loop */
1768
 
        f1loop->prev->next = f2loop->next;
1769
 
        f2loop->next->prev = f1loop->prev;
1770
 
        
1771
 
        f1loop->next->prev = f2loop->prev;
1772
 
        f2loop->prev->next = f1loop->next;
1773
 
        
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;
 
1785
        
 
1786
        l_f1->next->prev = l_f2->prev;
 
1787
        l_f2->prev->next = l_f1->next;
 
1788
        
 
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;
1777
1792
 
1778
1793
        /* increase length of f1 */
1779
1794
        f1->len += (f2->len - 2);
1784
1799
                l_iter->f = f1;
1785
1800
        
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);
1789
1804
        
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);
1793
1808
        }
1794
 
        BLI_mempool_free(bm->epool, f1loop->e);
 
1809
        BLI_mempool_free(bm->epool, l_f1->e);
1795
1810
        bm->totedge--;
1796
 
        BLI_mempool_free(bm->lpool, f1loop);
 
1811
        BLI_mempool_free(bm->lpool, l_f1);
1797
1812
        bm->totloop--;
1798
 
        BLI_mempool_free(bm->lpool, f2loop);
 
1813
        BLI_mempool_free(bm->lpool, l_f2);
1799
1814
        bm->totloop--;
1800
1815
        if (bm->ftoolflagpool) {
1801
1816
                BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
1881
1896
 */
1882
1897
bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
1883
1898
{
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);
 
1902
 
 
1903
        SmallHash visithash;
1886
1904
        BMVert **verts = NULL;
1887
 
        GHash *visithash;
1888
1905
        BMIter eiter, liter;
1889
1906
        BMLoop *l;
1890
1907
        BMEdge *e;
1891
1908
        int i, maxindex;
1892
 
        BMLoop *nl;
1893
 
 
1894
 
        visithash = BLI_ghash_ptr_new(__func__);
 
1909
        BMLoop *l_new;
 
1910
 
 
1911
        BLI_smallhash_init(&visithash);
 
1912
 
 
1913
        STACK_INIT(stack);
1895
1914
 
1896
1915
        maxindex = 0;
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)) {
1899
1918
                        continue;
1900
1919
                }
1901
1920
 
1902
 
                /* Prime the stack with this unvisited edge */
1903
 
                BLI_array_append(stack, e);
1904
 
 
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));
 
1923
                do {
 
1924
                        BLI_smallhash_insert(&visithash, (uintptr_t)e, SET_INT_IN_POINTER(maxindex));
1909
1925
 
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);
1914
 
                                }
 
1926
                        if (e->l) {
 
1927
                                BMLoop *l_iter, *l_first;
 
1928
                                l_iter = l_first = e->l;
 
1929
                                do {
 
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);
 
1933
                                        }
 
1934
                                } while ((l_iter = l_iter->radial_next) != l_first);
1915
1935
                        }
1916
 
                }
 
1936
                } while ((e = STACK_POP(stack)));
1917
1937
 
1918
1938
                maxindex++;
1919
1939
        }
1920
1940
 
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__);
 
1944
        }
 
1945
        else {
 
1946
                verts = BLI_array_alloca(verts, maxindex);
 
1947
        }
 
1948
 
1923
1949
        verts[0] = v;
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);
 
1981
        STACK_INIT(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);
1959
1985
                }
1960
1986
        }
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];
1964
1990
                }
1965
1991
        }
1966
1992
#endif
1967
1993
 
1968
 
        BLI_array_free(stack);
 
1994
        STACK_FREE(stack);
1969
1995
 
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));
1972
1998
                if (i == 0) {
1973
1999
                        continue;
1974
2000
                }
1979
2005
                bmesh_disk_edge_append(e, verts[i]);
1980
2006
        }
1981
2007
 
1982
 
        BLI_ghash_free(visithash, NULL, NULL);
 
2008
        BLI_smallhash_release(&visithash);
1983
2009
 
1984
2010
        for (i = 0; i < maxindex; i++) {
1985
2011
                BM_CHECK_ELEMENT(verts[i]);
1992
2018
        if (r_vout != NULL) {
1993
2019
                *r_vout = verts;
1994
2020
        }
1995
 
        else {
1996
 
                MEM_freeN(verts);
1997
 
        }
1998
2021
 
1999
2022
        return true;
2000
2023
}
2072
2095
 */
2073
2096
bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
2074
2097
{
2075
 
        BMEdge *ne;
 
2098
        BMEdge *e_new;
2076
2099
        int radlen;
2077
2100
 
2078
2101
        BLI_assert(l_sep->e == e);
2088
2111
                e->l = l_sep->radial_next;
2089
2112
        }
2090
2113
 
2091
 
        ne = BM_edge_create(bm, e->v1, e->v2, e, 0);
 
2114
        e_new = BM_edge_create(bm, e->v1, e->v2, e, 0);
2092
2115
        bmesh_radial_loop_remove(l_sep, e);
2093
 
        bmesh_radial_append(ne, l_sep);
2094
 
        l_sep->e = ne;
 
2116
        bmesh_radial_append(e_new, l_sep);
 
2117
        l_sep->e = e_new;
2095
2118
 
2096
2119
        BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
2097
 
        BLI_assert(bmesh_radial_length(ne->l) == 1);
 
2120
        BLI_assert(bmesh_radial_length(e_new->l) == 1);
2098
2121
 
2099
 
        BM_CHECK_ELEMENT(ne);
 
2122
        BM_CHECK_ELEMENT(e_new);
2100
2123
        BM_CHECK_ELEMENT(e);
2101
2124
 
2102
2125
        return true;
2105
2128
/**
2106
2129
 * \brief Un-glue Region Make Vert (URMV)
2107
2130
 *
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
2109
2132
 *
2110
2133
 * \return The newly created BMVert
2111
2134
 */
2112
 
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
 
2135
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
2113
2136
{
2114
2137
        BMVert **vtar;
2115
2138
        int len, i;
2116
 
        BMVert *nv = NULL;
2117
 
        BMVert *sv = sl->v;
 
2139
        BMVert *v_new = NULL;
 
2140
        BMVert *v_sep = l_sep->v;
2118
2141
 
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);
2123
2146
 
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. */
2127
 
                return sv;
 
2150
                return v_sep;
2128
2151
        }
2129
2152
 
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);
2136
2159
        }
2137
2160
 
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);
2141
2164
 
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);
2145
2168
 
2146
 
        nv = sl->v;
 
2169
        v_new = l_sep->v;
2147
2170
 
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]);
2153
2176
 
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 */
2156
2179
        if (len > 2) {
2157
2180
                for (i = 0; i < len; i++) {
2158
 
                        if (vtar[i] == nv) {
 
2181
                        if (vtar[i] == v_new) {
2159
2182
                                break;
2160
2183
                        }
2161
2184
                }
2174
2197
 
2175
2198
        MEM_freeN(vtar);
2176
2199
 
2177
 
        return nv;
 
2200
        return v_new;
2178
2201
}
2179
2202
 
2180
2203
/**
2181
2204
 * \brief Unglue Region Make Vert (URMV)
2182
2205
 *
2183
 
 * Disconnects sf from the vertex fan at \a sv
 
2206
 * Disconnects f_sep from the vertex fan at \a v_sep
2184
2207
 *
2185
2208
 * \return The newly created BMVert
2186
2209
 */
2187
 
BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv)
 
2210
BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep)
2188
2211
{
2189
 
        BMLoop *l = BM_face_vert_share_loop(sf, sv);
 
2212
        BMLoop *l = BM_face_vert_share_loop(f_sep, v_sep);
2190
2213
        return bmesh_urmv_loop(bm, l);
2191
2214
}