40
40
#include "intern/bmesh_private.h"
42
#define BM_OVERLAP (1 << 13)
45
43
* Returns whether or not a given vertex is
46
44
* is part of a given edge.
48
int BM_vert_in_edge(BMEdge *e, BMVert *v)
46
bool BM_vert_in_edge(BMEdge *e, BMVert *v)
50
48
return bmesh_vert_in_edge(e, v);
193
* Returns TRUE if the vertex is used in a given face.
196
int BM_vert_in_face(BMFace *f, BMVert *v)
192
* Get the first loop of a vert. Uses the same initialization code for the first loop of the
195
BMLoop *BM_vert_find_first_loop(BMVert *v)
202
e = bmesh_disk_faceedge_find_first(v->e, v);
207
return bmesh_radial_faceloop_find_first(e->l, v);
211
* Returns true if the vertex is used in a given face.
213
bool BM_vert_in_face(BMFace *f, BMVert *v)
198
215
BMLoop *l_iter, *l_first;
211
228
if (l_iter->v == v) {
214
231
} while ((l_iter = l_iter->next) != l_first);
221
238
* Compares the number of vertices in an array
222
239
* that appear in a given face
224
int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len)
241
int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len)
226
243
BMLoop *l_iter, *l_first;
250
if (BMO_elem_flag_test(bm, l_iter->v, BM_OVERLAP)) {
267
if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
254
271
} while ((l_iter = l_iter->next) != l_first);
257
for (i = 0; i < len; i++) BMO_elem_flag_disable(bm, varr[i], BM_OVERLAP);
274
for (i = 0; i < len; i++) {
275
BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
283
* Return true if all verts are in the face.
285
bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
287
BMLoop *l_iter, *l_first;
289
#ifdef USE_BMESH_HOLES
296
/* simple check, we know can't succeed */
301
for (i = 0; i < len; i++) {
302
BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
305
#ifdef USE_BMESH_HOLES
306
for (lst = f->loops.first; lst; lst = lst->next)
310
#ifdef USE_BMESH_HOLES
311
l_iter = l_first = lst->first;
313
l_iter = l_first = f->l_first;
317
if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
325
} while ((l_iter = l_iter->next) != l_first);
328
for (i = 0; i < len; i++) {
329
BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
263
336
* Returns whether or not a given edge is is part of a given face.
265
int BM_edge_in_face(BMFace *f, BMEdge *e)
338
bool BM_edge_in_face(BMFace *f, BMEdge *e)
273
346
if (l_iter->e == e) {
276
349
} while ((l_iter = l_iter->next) != l_first);
355
* Returns whether or not a given edge is is part of a given loop.
357
bool BM_edge_in_loop(BMEdge *e, BMLoop *l)
359
return (l->e == e || l->prev->e == e);
282
363
* Returns whether or not two vertices are in
285
int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
366
bool BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
287
368
return bmesh_verts_in_edge(v1, v2, e);
381
* Given a edge and a loop (assumes the edge is manifold). returns
382
* the other faces loop, sharing the same vertex.
385
* +-------------------+
388
* |l_other <-- return |
389
* +-------------------+ <-- A manifold edge between 2 faces
391
* |^ <-------- loop |
393
* +-------------------+
396
BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l)
400
// BLI_assert(BM_edge_is_manifold(e)); // TOO strict, just check if we have another radial face
401
BLI_assert(e->l && e->l->radial_next != e->l);
402
BLI_assert(BM_vert_in_edge(e, l->v));
404
l_other = (l->e == e) ? l : l->prev;
405
l_other = l_other->radial_next;
406
BLI_assert(l_other->e == e);
408
if (l_other->v == l->v) {
411
else if (l_other->next->v == l->v) {
412
l_other = l_other->next;
422
* Utility function to step around a fan of loops,
423
* using an edge to mark the previous side.
425
* \note all edges must be manifold,
426
* once a non manifold edge is hit, return NULL.
431
* ,' | (notice how 'e_step'
432
* / | and 'l' define the
433
* / | direction the arrow
434
* | return | points).
436
* ---------------------+---------------------
441
* begin e_step ----> |
446
BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
448
BMEdge *e_prev = *e_step;
450
if (l->e == e_prev) {
453
else if (l->prev->e == e_prev) {
461
if (BM_edge_is_manifold(e_next)) {
462
return BM_edge_other_loop((*e_step = e_next), l);
300
472
* The function takes a vertex at the center of a fan and returns the opposite edge in the fan.
301
473
* All edges in the fan must be manifold, otherwise return NULL.
303
* \note This could (probably) be done more effieiently.
475
* \note This could (probably) be done more efficiently.
305
477
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
533
* Returns edge length squared (for comparisons)
535
float BM_edge_calc_length_squared(BMEdge *e)
537
return len_squared_v3v3(e->v1->co, e->v2->co);
361
541
* Utility function, since enough times we have an edge
362
542
* and want to access 2 connected faces.
364
* \return TRUE when only 2 faces are found.
544
* \return true when only 2 faces are found.
366
int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
546
bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
370
550
if ((la = e->l) &&
371
551
(lb = la->radial_next) &&
372
553
(lb->radial_next == la))
386
567
* Utility function, since enough times we have an edge
387
568
* and want to access 2 connected loops.
389
* \return TRUE when only 2 faces are found.
570
* \return true when only 2 faces are found.
391
int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
572
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
395
576
if ((la = e->l) &&
396
577
(lb = la->radial_next) &&
397
579
(lb->radial_next == la))
452
* Returns the number of faces around this vert
634
* Returns the number of faces around this vert
635
* length matches #BM_LOOPS_OF_VERT iterator
454
637
int BM_vert_face_count(BMVert *v)
460
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
465
#if 0 //this code isn't working
466
BMEdge *curedge = NULL;
639
return bmesh_disk_facevert_count(v);
643
* Tests whether or not the vertex is part of a wire edge.
644
* (ie: has no faces attached to it)
646
bool BM_vert_is_wire(BMVert *v)
649
BMEdge *e_first, *e_iter;
651
e_first = e_iter = v->e;
471
if (curedge->l) count += BM_edge_face_count(curedge);
472
curedge = bmesh_disk_edge_next(curedge, v);
473
} while (curedge != v->e);
480
* Tests whether or not the vertex is part of a wire edge.
481
* (ie: has no faces attached to it)
483
int BM_vert_is_wire(BMVert *v)
497
curedge = bmesh_disk_edge_next(curedge, v);
498
} while (curedge != v->e);
656
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
504
666
* Tests whether or not the edge is part of a wire.
505
667
* (ie: has no faces attached to it)
507
int BM_edge_is_wire(BMEdge *e)
669
bool BM_edge_is_wire(BMEdge *e)
509
return (e->l) ? FALSE : TRUE;
671
return (e->l == NULL);
593
755
int count = BM_edge_face_count(e);
594
756
if (count == 2) {
766
* Tests that the edge is manifold and
767
* that both its faces point the same way.
769
bool BM_edge_is_contiguous(BMEdge *e)
771
const BMLoop *l = e->l;
772
const BMLoop *l_other = l->radial_next;
773
return (l && (l_other != l) && /* not 0 or 1 face users */
774
(l_other->radial_next == l) && /* 2 face users */
775
(l_other->v != l->v));
604
779
* Tests whether or not an edge is on the boundary
605
780
* of a shell (has one face associated with it)
608
783
#if 1 /* fast path for checking boundary */
609
int BM_edge_is_boundary(BMEdge *e)
784
bool BM_edge_is_boundary(BMEdge *e)
611
786
const BMLoop *l = e->l;
612
787
return (l && (l->radial_next == l));
617
792
int count = BM_edge_face_count(e);
618
793
if (count == 1) {
803
* Returns the number of faces that are adjacent to both f1 and f2,
804
* \note Could be sped up a bit by not using iterators and by tagging
805
* faces on either side, then count the tags rather then searching.
807
int BM_face_share_face_count(BMFace *f1, BMFace *f2)
814
BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
815
BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
816
if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2))
825
* same as #BM_face_share_face_count but returns a bool
827
bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
833
BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
834
BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
835
if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2))
628
844
* Counts the number of edges two faces share (if any)
630
846
int BM_face_share_edge_count(BMFace *f1, BMFace *f2)
647
* Test if e1 shares any faces with e2
649
int BM_edge_share_face_count(BMEdge *e1, BMEdge *e2)
863
* Returns true if the faces share an edge
865
bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
870
l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
872
if (bmesh_radial_face_find(l_iter->e, f2)) {
875
} while ((l_iter = l_iter->next) != l_first);
881
* Test if e1 shares any faces with e2
883
bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
658
892
if (bmesh_radial_face_find(e2, f)) {
662
} while (l != e1->l);
896
} while (l != e1->l);
902
* Test if e1 shares any quad faces with e2
904
bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
909
if (e1->l && e2->l) {
914
if (bmesh_radial_face_find(e2, f)) {
919
} while (l != e1->l);
668
925
* Tests to see if e1 shares a vertex with e2
670
int BM_edge_share_vert_count(BMEdge *e1, BMEdge *e2)
927
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
672
929
return (e1->v1 == e2->v1 ||
673
930
e1->v1 == e2->v2 ||
745
1002
* BM_face_create_ngon() on an arbitrary array of verts,
746
1003
* though be sure to pick an edge which has a face.
748
* \note This is infact quite a simple check, mainly include this function so the intent is more obvious.
1005
* \note This is in fact quite a simple check, mainly include this function so the intent is more obvious.
749
1006
* We know these 2 verts will _always_ make up the loops edge
751
1008
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
752
1009
BMLoop *edge_loop)
754
1011
BLI_assert(edge_loop->e == edge);
1012
(void)edge; /* quiet warning in release build */
755
1013
*r_v1 = edge_loop->v;
756
1014
*r_v2 = edge_loop->next->v;
1023
* Check if the loop is convex or concave
1024
* (depends on face normal)
1026
bool BM_loop_is_convex(BMLoop *l)
1028
float e_dir_prev[3];
1029
float e_dir_next[3];
1032
sub_v3_v3v3(e_dir_prev, l->prev->v->co, l->v->co);
1033
sub_v3_v3v3(e_dir_next, l->next->v->co, l->v->co);
1034
cross_v3_v3v3(l_no, e_dir_next, e_dir_prev);
1035
return dot_v3v3(l_no, l->f->no) > 0.0f;
765
1039
* Calculates the angle between the previous and next loops
766
1040
* (angle at this loops face corner).
1074
* \brief BM_loop_calc_face_direction
1076
* Calculate the direction a loop is pointing.
1078
* \param l The loop to calculate the direction at
1079
* \param r_dir Resulting direction
1081
void BM_loop_calc_face_direction(BMLoop *l, float r_dir[3])
1086
sub_v3_v3v3(v_prev, l->v->co, l->prev->v->co);
1087
sub_v3_v3v3(v_next, l->next->v->co, l->v->co);
1089
normalize_v3(v_prev);
1090
normalize_v3(v_next);
1092
add_v3_v3v3(r_dir, v_prev, v_next);
1093
normalize_v3(r_dir);
801
1097
* \brief BM_loop_calc_face_tangent
803
* Calculate the tangent at this loop corner or fallback to the face normal on straignt lines.
1099
* Calculate the tangent at this loop corner or fallback to the face normal on straight lines.
804
1100
* This vector always points inward into the face.
806
* \param bm The BMesh
807
1102
* \param l The loop to calculate the tangent at
808
1103
* \param r_tangent Resulting tangent
812
1107
float v_prev[3];
813
1108
float v_next[3];
815
1111
sub_v3_v3v3(v_prev, l->prev->v->co, l->v->co);
816
1112
sub_v3_v3v3(v_next, l->v->co, l->next->v->co);
818
1114
normalize_v3(v_prev);
819
1115
normalize_v3(v_next);
1116
add_v3_v3v3(dir, v_prev, v_next);
821
if (compare_v3v3(v_prev, v_next, FLT_EPSILON) == FALSE) {
1118
if (compare_v3v3(v_prev, v_next, FLT_EPSILON * 10.0f) == false) {
823
1119
float nor[3]; /* for this purpose doesn't need to be normalized */
824
add_v3_v3v3(dir, v_prev, v_next);
825
1120
cross_v3_v3v3(nor, v_prev, v_next);
1121
/* concave face check */
1122
if (UNLIKELY(dot_v3v3(nor, l->f->no) < 0.0f)) {
826
1125
cross_v3_v3v3(r_tangent, dir, nor);
829
1128
/* prev/next are the same - compare with face normal since we don't have one */
830
cross_v3_v3v3(r_tangent, v_next, l->f->no);
1129
cross_v3_v3v3(r_tangent, dir, l->f->no);
833
1132
normalize_v3(r_tangent);
857
1156
* \brief BMESH EDGE/FACE TANGENT
859
* Calculate the tangent at this loop corner or fallback to the face normal on straignt lines.
1158
* Calculate the tangent at this loop corner or fallback to the face normal on straight lines.
860
1159
* This vector always points inward into the face.
862
1161
* \brief BM_edge_calc_face_tangent
864
1163
* \param e_loop The loop to calculate the tangent at,
865
1164
* used to get the face and winding direction.
1165
* \param r_tangent The loop corner tangent to set
868
1168
void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3])
924
1224
accum_angle += face_angle;
927
return accum_shell / accum_angle;
1227
if (accum_angle != 0.0f) {
1228
return accum_shell / accum_angle;
1234
/* alternate version of #BM_vert_calc_shell_factor which only
1235
* uses 'hflag' faces, but falls back to all if none found. */
1236
float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
1240
float accum_shell = 0.0f;
1241
float accum_angle = 0.0f;
1242
int tot_sel = 0, tot = 0;
1244
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
1245
if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
1246
const float face_angle = BM_loop_calc_face_angle(l);
1247
accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
1248
accum_angle += face_angle;
1254
if (accum_angle != 0.0f) {
1255
return accum_shell / accum_angle;
1258
/* other main difference from BM_vert_calc_shell_factor! */
1259
if (tot != 0 && tot_sel == 0) {
1260
/* none selected, so use all */
1261
return BM_vert_calc_shell_factor(v);
1270
* \note quite an obscure function.
1271
* used in bmesh operators that have a relative scale options,
1273
float BM_vert_calc_mean_tagged_edge_length(BMVert *v)
1278
float length = 0.0f;
1280
BM_ITER_ELEM_INDEX (e, &iter, v, BM_EDGES_OF_VERT, tot) {
1281
BMVert *v_other = BM_edge_other_vert(e, v);
1282
if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
1283
length += BM_edge_calc_length(e);
1288
return length / (float)tot;
1297
* Returns the loop of the shortest edge in f.
1299
BMLoop *BM_face_find_shortest_loop(BMFace *f)
1301
BMLoop *shortest_loop = NULL;
1302
float shortest_len = FLT_MAX;
1307
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1310
const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
1311
if (len <= shortest_len) {
1312
shortest_loop = l_iter;
1315
} while ((l_iter = l_iter->next) != l_first);
1317
return shortest_loop;
1321
* Returns the loop of the longest edge in f.
1323
BMLoop *BM_face_find_longest_loop(BMFace *f)
1325
BMLoop *longest_loop = NULL;
1326
float longest_len = 0.0f;
1331
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1334
const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
1335
if (len >= longest_len) {
1336
longest_loop = l_iter;
1339
} while ((l_iter = l_iter->next) != l_first);
1341
return longest_loop;
950
* Given a set of vertices \a varr, find out if
951
* all those vertices overlap an existing face.
953
* \note Making a face here is valid but in some cases you wont want to
954
* make a face thats part of another.
956
* \returns TRUE for overlap
1364
* Returns an edge sharing the same vertices as this one.
1365
* This isn't an invalid state but tools should clean up these cases before
1366
* returning the mesh to the user.
959
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlapface)
1368
BMEdge *BM_edge_find_double(BMEdge *e)
965
for (i = 0; i < len; i++) {
966
BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
967
amount = BM_verts_in_face(bm, f, varr, len);
1371
BMVert *v_other = e->v2;
1376
while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) {
1377
if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) {
978
*r_overlapface = NULL;
985
1386
* Given a set of vertices (varr), find out if
986
1387
* there is a face with exactly those vertices
987
1388
* (and only those vertices).
1390
* \note there used to be a BM_face_exists_overlap function that checked for partial overlap,
1391
* however this is no longer used, simple to add back.
989
int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface)
1393
bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
1395
BMVert *v_search = varr[0]; /* we can search any of the verts in the array */
995
for (i = 0; i < len; i++) {
996
BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
997
amount = BM_verts_in_face(bm, f, varr, len);
998
if (amount == len && amount == f->len) {
1401
BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
1402
if (f->len == len) {
1403
if (BM_verts_in_face(f, varr, len)) {
999
1404
if (r_existface) {
1000
1405
*r_existface = f;
1007
1412
if (r_existface) {
1008
1413
*r_existface = NULL;
1419
/* faster to do the flagging once, and inline */
1420
bool is_init = false;
1421
bool is_found = false;
1425
BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
1426
if (f->len == len) {
1427
if (is_init == false) {
1429
for (i = 0; i < len; i++) {
1430
BLI_assert(!BM_ELEM_API_FLAG_TEST(varr[i], _FLAG_OVERLAP));
1431
BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
1441
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1444
if (!BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
1448
} while ((l_iter = l_iter->next) != l_first);
1460
if (is_found == false) {
1462
*r_existface = NULL;
1466
if (is_init == true) {
1467
for (i = 0; i < len; i++) {
1468
BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
1068
1531
for (i = 0; i < len; i++) {
1069
1532
BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
1070
1533
if (!BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
1072
1535
BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
1073
1536
if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
1091
1554
if (tot_tag == 0) {
1092
1555
/* no faces use only boundary verts, quit early */
1096
1559
/* 2) loop over non-boundary edges that use boundary verts,
1097
1560
* check each have 2 tagges faces connected (faces that only use 'varr' verts) */
1099
1562
for (i = 0; i < len; i++) {
1100
1563
BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
1102
1565
if (/* non-boundary edge */
1103
BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == FALSE &&
1566
BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == false &&
1104
1567
/* ...using boundary verts */
1105
BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == TRUE &&
1106
BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == TRUE)
1568
BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == true &&
1569
BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == true)
1108
1571
int tot_face_tag = 0;
1109
1572
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
1131
1594
/* same as 'BM_face_exists_multi' but built vert array from edges */
1132
int BM_face_exists_multi_edge(BMEdge **earr, int len)
1595
bool BM_face_exists_multi_edge(BMEdge **earr, int len)
1135
BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
1597
BMVert **varr = BLI_array_alloca(varr, len);
1140
1602
/* first check if verts have edges, if not we can bail out early */
1142
1604
for (i = len - 1, i_next = 0; i_next < len; (i = i_next++)) {
1143
1605
if (!(varr[i] = BM_edge_share_vert(earr[i], earr[i_next]))) {
1150
1612
BMESH_ASSERT(0);
1151
BLI_array_fixedstack_free(varr);
1155
1616
ok = BM_face_exists_multi(varr, earr, len);
1157
BLI_array_fixedstack_free(varr);
1621
/* convenience functions for checking flags */
1622
bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
1624
return (BM_elem_flag_test(e->v1, hflag) ||
1625
BM_elem_flag_test(e->v2, hflag));
1628
bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
1633
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1635
if (BM_elem_flag_test(l_iter->v, hflag)) {
1638
} while ((l_iter = l_iter->next) != l_first);
1642
bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
1647
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1649
if (BM_elem_flag_test(l_iter->e, hflag)) {
1652
} while ((l_iter = l_iter->next) != l_first);