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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "bmesh.h"
40
40
#include "intern/bmesh_private.h"
41
41
 
42
 
#define BM_OVERLAP (1 << 13)
43
 
 
44
42
/**
45
43
 * Returns whether or not a given vertex is
46
44
 * is part of a given edge.
47
45
 */
48
 
int BM_vert_in_edge(BMEdge *e, BMVert *v)
 
46
bool BM_vert_in_edge(BMEdge *e, BMVert *v)
49
47
{
50
48
        return bmesh_vert_in_edge(e, v);
51
49
}
54
52
 * \brief Other Loop in Face Sharing an Edge
55
53
 *
56
54
 * Finds the other loop that shares \a v with \a e loop in \a f.
57
 
 *
 
55
 * <pre>
58
56
 *     +----------+
59
57
 *     |          |
60
58
 *     |    f     |
64
62
 *     ^     ^ <------- These vert args define direction
65
63
 *                      in the face to check.
66
64
 *                      The faces loop direction is ignored.
67
 
 *
 
65
 * </pre>
68
66
 */
69
67
BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v)
70
68
{
92
90
 * This function returns a loop in \a f that shares an edge with \a v
93
91
 * The direction is defined by \a v_prev, where the return value is
94
92
 * the loop of what would be 'v_next'
95
 
 *
96
 
 *
 
93
 * <pre>
97
94
 *     +----------+ <-- return the face loop of this vertex.
98
95
 *     |          |
99
96
 *     |    f     |
103
100
 *     ^^^^^^     ^ <-- These vert args define direction
104
101
 *                      in the face to check.
105
102
 *                      The faces loop direction is ignored.
 
103
 * </pre>
106
104
 *
107
105
 * \note \a v_prev and \a v _implicitly_ define an edge.
108
106
 */
143
141
 * \brief Other Loop in Face Sharing a Vert
144
142
 *
145
143
 * Finds the other loop that shares \a v with \a e loop in \a f.
146
 
 *
 
144
 * <pre>
147
145
 *     +----------+ <-- return the face loop of this vertex.
148
146
 *     |          |
149
147
 *     |          |
153
151
 *           ^ <------- This loop defines both the face to search
154
152
 *                      and the edge, in combination with 'v'
155
153
 *                      The faces loop direction is ignored.
 
154
 * </pre>
156
155
 */
157
156
 
158
157
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v)
190
189
}
191
190
 
192
191
/**
193
 
 * Returns TRUE if the vertex is used in a given face.
194
 
 */
195
 
 
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
 
193
 * iterator API
 
194
 */
 
195
BMLoop *BM_vert_find_first_loop(BMVert *v)
 
196
{
 
197
        BMEdge *e;
 
198
 
 
199
        if (!v || !v->e)
 
200
                return NULL;
 
201
 
 
202
        e = bmesh_disk_faceedge_find_first(v->e, v);
 
203
 
 
204
        if (!e)
 
205
                return NULL;
 
206
 
 
207
        return bmesh_radial_faceloop_find_first(e->l, v);
 
208
}
 
209
 
 
210
/**
 
211
 * Returns true if the vertex is used in a given face.
 
212
 */
 
213
bool BM_vert_in_face(BMFace *f, BMVert *v)
197
214
{
198
215
        BMLoop *l_iter, *l_first;
199
216
 
209
226
#endif
210
227
                do {
211
228
                        if (l_iter->v == v) {
212
 
                                return TRUE;
 
229
                                return true;
213
230
                        }
214
231
                } while ((l_iter = l_iter->next) != l_first);
215
232
        }
216
233
 
217
 
        return FALSE;
 
234
        return false;
218
235
}
219
236
 
220
237
/**
221
238
 * Compares the number of vertices in an array
222
239
 * that appear in a given face
223
240
 */
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)
225
242
{
226
243
        BMLoop *l_iter, *l_first;
227
244
 
232
249
        int i, count = 0;
233
250
        
234
251
        for (i = 0; i < len; i++) {
235
 
                BMO_elem_flag_enable(bm, varr[i], BM_OVERLAP);
 
252
                BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
236
253
        }
237
254
 
238
255
#ifdef USE_BMESH_HOLES
247
264
#endif
248
265
 
249
266
                do {
250
 
                        if (BMO_elem_flag_test(bm, l_iter->v, BM_OVERLAP)) {
 
267
                        if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
251
268
                                count++;
252
269
                        }
253
270
 
254
271
                } while ((l_iter = l_iter->next) != l_first);
255
272
        }
256
273
 
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);
 
276
        }
258
277
 
259
278
        return count;
260
279
}
261
280
 
 
281
 
 
282
/**
 
283
 * Return true if all verts are in the face.
 
284
 */
 
285
bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
 
286
{
 
287
        BMLoop *l_iter, *l_first;
 
288
 
 
289
#ifdef USE_BMESH_HOLES
 
290
        BMLoopList *lst;
 
291
#endif
 
292
 
 
293
        int i;
 
294
        bool ok = true;
 
295
 
 
296
        /* simple check, we know can't succeed */
 
297
        if (f->len < len) {
 
298
                return false;
 
299
        }
 
300
 
 
301
        for (i = 0; i < len; i++) {
 
302
                BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
 
303
        }
 
304
 
 
305
#ifdef USE_BMESH_HOLES
 
306
        for (lst = f->loops.first; lst; lst = lst->next)
 
307
#endif
 
308
        {
 
309
 
 
310
#ifdef USE_BMESH_HOLES
 
311
                l_iter = l_first = lst->first;
 
312
#else
 
313
                l_iter = l_first = f->l_first;
 
314
#endif
 
315
 
 
316
                do {
 
317
                        if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
 
318
                                /* pass */
 
319
                        }
 
320
                        else {
 
321
                                ok = false;
 
322
                                break;
 
323
                        }
 
324
 
 
325
                } while ((l_iter = l_iter->next) != l_first);
 
326
        }
 
327
 
 
328
        for (i = 0; i < len; i++) {
 
329
                BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
 
330
        }
 
331
 
 
332
        return ok;
 
333
}
 
334
 
262
335
/**
263
336
 * Returns whether or not a given edge is is part of a given face.
264
337
 */
265
 
int BM_edge_in_face(BMFace *f, BMEdge *e)
 
338
bool BM_edge_in_face(BMFace *f, BMEdge *e)
266
339
{
267
340
        BMLoop *l_iter;
268
341
        BMLoop *l_first;
271
344
 
272
345
        do {
273
346
                if (l_iter->e == e) {
274
 
                        return TRUE;
 
347
                        return true;
275
348
                }
276
349
        } while ((l_iter = l_iter->next) != l_first);
277
350
 
278
 
        return FALSE;
 
351
        return false;
 
352
}
 
353
 
 
354
/**
 
355
 * Returns whether or not a given edge is is part of a given loop.
 
356
 */
 
357
bool BM_edge_in_loop(BMEdge *e, BMLoop *l)
 
358
{
 
359
        return (l->e == e || l->prev->e == e);
279
360
}
280
361
 
281
362
/**
282
363
 * Returns whether or not two vertices are in
283
364
 * a given edge
284
365
 */
285
 
int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
 
366
bool BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
286
367
{
287
368
        return bmesh_verts_in_edge(v1, v2, e);
288
369
}
297
378
}
298
379
 
299
380
/**
 
381
 * Given a edge and a loop (assumes the edge is manifold). returns
 
382
 * the other faces loop, sharing the same vertex.
 
383
 *
 
384
 * <pre>
 
385
 * +-------------------+
 
386
 * |                   |
 
387
 * |                   |
 
388
 * |l_other <-- return |
 
389
 * +-------------------+ <-- A manifold edge between 2 faces
 
390
 * |l    e  <-- edge   |
 
391
 * |^ <-------- loop   |
 
392
 * |                   |
 
393
 * +-------------------+
 
394
 * </pre>
 
395
 */
 
396
BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l)
 
397
{
 
398
        BMLoop *l_other;
 
399
 
 
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));
 
403
 
 
404
        l_other = (l->e == e) ? l : l->prev;
 
405
        l_other = l_other->radial_next;
 
406
        BLI_assert(l_other->e == e);
 
407
 
 
408
        if (l_other->v == l->v) {
 
409
                /* pass */
 
410
        }
 
411
        else if (l_other->next->v == l->v) {
 
412
                l_other = l_other->next;
 
413
        }
 
414
        else {
 
415
                BLI_assert(0);
 
416
        }
 
417
 
 
418
        return l_other;
 
419
}
 
420
 
 
421
/**
 
422
 * Utility function to step around a fan of loops,
 
423
 * using an edge to mark the previous side.
 
424
 *
 
425
 * \note all edges must be manifold,
 
426
 * once a non manifold edge is hit, return NULL.
 
427
 *
 
428
 * <pre>
 
429
 *                ,.,-->|
 
430
 *            _,-'      |
 
431
 *          ,'          | (notice how 'e_step'
 
432
 *         /            |  and 'l' define the
 
433
 *        /             |  direction the arrow
 
434
 *       |     return   |  points).
 
435
 *       |     loop --> |
 
436
 * ---------------------+---------------------
 
437
 *         ^      l --> |
 
438
 *         |            |
 
439
 *  assign e_step       |
 
440
 *                      |
 
441
 *   begin e_step ----> |
 
442
 *                      |
 
443
 * </pre>
 
444
 */
 
445
 
 
446
BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
 
447
{
 
448
        BMEdge *e_prev = *e_step;
 
449
        BMEdge *e_next;
 
450
        if (l->e == e_prev) {
 
451
                e_next = l->prev->e;
 
452
        }
 
453
        else if (l->prev->e == e_prev) {
 
454
                e_next = l->e;
 
455
        }
 
456
        else {
 
457
                BLI_assert(0);
 
458
                return NULL;
 
459
        }
 
460
 
 
461
        if (BM_edge_is_manifold(e_next)) {
 
462
                return BM_edge_other_loop((*e_step = e_next), l);
 
463
        }
 
464
        else {
 
465
                return NULL;
 
466
        }
 
467
}
 
468
 
 
469
 
 
470
 
 
471
/**
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.
302
474
 *
303
 
 * \note This could (probably) be done more effieiently.
 
475
 * \note This could (probably) be done more efficiently.
304
476
 */
305
477
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
306
478
{
350
522
}
351
523
 
352
524
/**
353
 
 * Returms edge length
 
525
 * Returns edge length
354
526
 */
355
527
float BM_edge_calc_length(BMEdge *e)
356
528
{
358
530
}
359
531
 
360
532
/**
 
533
 * Returns edge length squared (for comparisons)
 
534
 */
 
535
float BM_edge_calc_length_squared(BMEdge *e)
 
536
{
 
537
        return len_squared_v3v3(e->v1->co, e->v2->co);
 
538
}
 
539
 
 
540
/**
361
541
 * Utility function, since enough times we have an edge
362
542
 * and want to access 2 connected faces.
363
543
 *
364
 
 * \return TRUE when only 2 faces are found.
 
544
 * \return true when only 2 faces are found.
365
545
 */
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)
367
547
{
368
548
        BMLoop *la, *lb;
369
549
 
370
550
        if ((la = e->l) &&
371
551
            (lb = la->radial_next) &&
 
552
            (la != lb) &&
372
553
            (lb->radial_next == la))
373
554
        {
374
555
                *r_fa = la->f;
375
556
                *r_fb = lb->f;
376
 
                return TRUE;
 
557
                return true;
377
558
        }
378
559
        else {
379
560
                *r_fa = NULL;
380
561
                *r_fb = NULL;
381
 
                return FALSE;
 
562
                return false;
382
563
        }
383
564
}
384
565
 
386
567
 * Utility function, since enough times we have an edge
387
568
 * and want to access 2 connected loops.
388
569
 *
389
 
 * \return TRUE when only 2 faces are found.
 
570
 * \return true when only 2 faces are found.
390
571
 */
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)
392
573
{
393
574
        BMLoop *la, *lb;
394
575
 
395
576
        if ((la = e->l) &&
396
577
            (lb = la->radial_next) &&
 
578
            (la != lb) &&
397
579
            (lb->radial_next == la))
398
580
        {
399
581
                *r_la = la;
400
582
                *r_lb = lb;
401
 
                return TRUE;
 
583
                return true;
402
584
        }
403
585
        else {
404
586
                *r_la = NULL;
405
587
                *r_lb = NULL;
406
 
                return FALSE;
 
588
                return false;
407
589
        }
408
590
}
409
591
 
449
631
}
450
632
 
451
633
/**
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
453
636
 */
454
637
int BM_vert_face_count(BMVert *v)
455
638
{
456
 
        int count = 0;
457
 
        BMLoop *l;
458
 
        BMIter iter;
459
 
 
460
 
        BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
461
 
                count++;
462
 
        }
463
 
 
464
 
        return count;
465
 
#if 0 //this code isn't working
466
 
        BMEdge *curedge = NULL;
467
 
 
 
639
        return bmesh_disk_facevert_count(v);
 
640
}
 
641
 
 
642
/**
 
643
 * Tests whether or not the vertex is part of a wire edge.
 
644
 * (ie: has no faces attached to it)
 
645
 */
 
646
bool BM_vert_is_wire(BMVert *v)
 
647
{
468
648
        if (v->e) {
469
 
                curedge = v->e;
 
649
                BMEdge *e_first, *e_iter;
 
650
 
 
651
                e_first = e_iter = v->e;
470
652
                do {
471
 
                        if (curedge->l) count += BM_edge_face_count(curedge);
472
 
                        curedge = bmesh_disk_edge_next(curedge, v);
473
 
                } while (curedge != v->e);
474
 
        }
475
 
        return count;
476
 
#endif
477
 
}
478
 
 
479
 
/**
480
 
 * Tests whether or not the vertex is part of a wire edge.
481
 
 * (ie: has no faces attached to it)
482
 
 */
483
 
int BM_vert_is_wire(BMVert *v)
484
 
{
485
 
        BMEdge *curedge;
486
 
 
487
 
        if (v->e == NULL) {
488
 
                return FALSE;
489
 
        }
490
 
        
491
 
        curedge = v->e;
492
 
        do {
493
 
                if (curedge->l) {
494
 
                        return FALSE;
495
 
                }
496
 
 
497
 
                curedge = bmesh_disk_edge_next(curedge, v);
498
 
        } while (curedge != v->e);
499
 
 
500
 
        return TRUE;
 
653
                        if (e_iter->l) {
 
654
                                return false;
 
655
                        }
 
656
                } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
 
657
 
 
658
                return true;
 
659
        }
 
660
        else {
 
661
                return false;
 
662
        }
501
663
}
502
664
 
503
665
/**
504
666
 * Tests whether or not the edge is part of a wire.
505
667
 * (ie: has no faces attached to it)
506
668
 */
507
 
int BM_edge_is_wire(BMEdge *e)
 
669
bool BM_edge_is_wire(BMEdge *e)
508
670
{
509
 
        return (e->l) ? FALSE : TRUE;
 
671
        return (e->l == NULL);
510
672
}
511
673
 
512
674
/**
516
678
 * 3: Is part of a an edge with more than 2 faces.
517
679
 * 4: Is part of a wire edge.
518
680
 */
519
 
int BM_vert_is_manifold(BMVert *v)
 
681
bool BM_vert_is_manifold(BMVert *v)
520
682
{
521
683
        BMEdge *e, *oe;
522
684
        BMLoop *l;
524
686
 
525
687
        if (v->e == NULL) {
526
688
                /* loose vert */
527
 
                return FALSE;
 
689
                return false;
528
690
        }
529
691
 
530
692
        /* count edges while looking for non-manifold edges */
535
697
                 * edges with 1 face user are OK, otherwise we could
536
698
                 * use BM_edge_is_manifold() here */
537
699
                if (e->l == NULL || bmesh_radial_length(e->l) > 2) {
538
 
                        return FALSE;
 
700
                        return false;
539
701
                }
540
702
                len++;
541
703
        } while ((e = bmesh_disk_edge_next(e, v)) != oe);
569
731
 
570
732
        if (count < len) {
571
733
                /* vert shared by multiple regions */
572
 
                return FALSE;
 
734
                return false;
573
735
        }
574
736
 
575
 
        return TRUE;
 
737
        return true;
576
738
}
577
739
 
578
740
/**
581
743
 */
582
744
 
583
745
#if 1 /* fast path for checking manifold */
584
 
int BM_edge_is_manifold(BMEdge *e)
 
746
bool BM_edge_is_manifold(BMEdge *e)
585
747
{
586
748
        const BMLoop *l = e->l;
587
749
        return (l && (l->radial_next != l) &&             /* not 0 or 1 face users */
592
754
{
593
755
        int count = BM_edge_face_count(e);
594
756
        if (count == 2) {
595
 
                return TRUE;
 
757
                return true;
596
758
        }
597
759
        else {
598
 
                return FALSE;
 
760
                return false;
599
761
        }
600
762
}
601
763
#endif
602
764
 
603
765
/**
 
766
 * Tests that the edge is manifold and
 
767
 * that both its faces point the same way.
 
768
 */
 
769
bool BM_edge_is_contiguous(BMEdge *e)
 
770
{
 
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));
 
776
}
 
777
 
 
778
/**
604
779
 * Tests whether or not an edge is on the boundary
605
780
 * of a shell (has one face associated with it)
606
781
 */
607
782
 
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)
610
785
{
611
786
        const BMLoop *l = e->l;
612
787
        return (l && (l->radial_next == l));
616
791
{
617
792
        int count = BM_edge_face_count(e);
618
793
        if (count == 1) {
619
 
                return TRUE;
 
794
                return true;
620
795
        }
621
796
        else {
622
 
                return FALSE;
 
797
                return false;
623
798
        }
624
799
}
625
800
#endif
626
801
 
627
802
/**
 
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.
 
806
 */
 
807
int BM_face_share_face_count(BMFace *f1, BMFace *f2)
 
808
{
 
809
        BMIter iter1, iter2;
 
810
        BMEdge *e;
 
811
        BMFace *f;
 
812
        int count = 0;
 
813
 
 
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))
 
817
                                count++;
 
818
                }
 
819
        }
 
820
 
 
821
        return count;
 
822
}
 
823
 
 
824
/**
 
825
 * same as #BM_face_share_face_count but returns a bool
 
826
 */
 
827
bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
 
828
{
 
829
        BMIter iter1, iter2;
 
830
        BMEdge *e;
 
831
        BMFace *f;
 
832
 
 
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))
 
836
                                return true;
 
837
                }
 
838
        }
 
839
 
 
840
        return false;
 
841
}
 
842
 
 
843
/**
628
844
 *  Counts the number of edges two faces share (if any)
629
845
 */
630
846
int BM_face_share_edge_count(BMFace *f1, BMFace *f2)
644
860
}
645
861
 
646
862
/**
647
 
 *      Test if e1 shares any faces with e2
648
 
 */
649
 
int BM_edge_share_face_count(BMEdge *e1, BMEdge *e2)
 
863
 *  Returns true if the faces share an edge
 
864
 */
 
865
bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
 
866
{
 
867
        BMLoop *l_iter;
 
868
        BMLoop *l_first;
 
869
 
 
870
        l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
 
871
        do {
 
872
                if (bmesh_radial_face_find(l_iter->e, f2)) {
 
873
                        return true;
 
874
                }
 
875
        } while ((l_iter = l_iter->next) != l_first);
 
876
 
 
877
        return false;
 
878
}
 
879
 
 
880
/**
 
881
 * Test if e1 shares any faces with e2
 
882
 */
 
883
bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
650
884
{
651
885
        BMLoop *l;
652
886
        BMFace *f;
656
890
                do {
657
891
                        f = l->f;
658
892
                        if (bmesh_radial_face_find(e2, f)) {
659
 
                                return TRUE;
660
 
                        }
661
 
                        l = l->radial_next;
662
 
                } while (l != e1->l);
663
 
        }
664
 
        return FALSE;
 
893
                                return true;
 
894
                        }
 
895
                        l = l->radial_next;
 
896
                } while (l != e1->l);
 
897
        }
 
898
        return false;
 
899
}
 
900
 
 
901
/**
 
902
 *      Test if e1 shares any quad faces with e2
 
903
 */
 
904
bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
 
905
{
 
906
        BMLoop *l;
 
907
        BMFace *f;
 
908
 
 
909
        if (e1->l && e2->l) {
 
910
                l = e1->l;
 
911
                do {
 
912
                        f = l->f;
 
913
                        if (f->len == 4) {
 
914
                                if (bmesh_radial_face_find(e2, f)) {
 
915
                                        return true;
 
916
                                }
 
917
                        }
 
918
                        l = l->radial_next;
 
919
                } while (l != e1->l);
 
920
        }
 
921
        return false;
665
922
}
666
923
 
667
924
/**
668
925
 *      Tests to see if e1 shares a vertex with e2
669
926
 */
670
 
int BM_edge_share_vert_count(BMEdge *e1, BMEdge *e2)
 
927
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
671
928
{
672
929
        return (e1->v1 == e2->v1 ||
673
930
                e1->v1 == e2->v2 ||
696
953
 *
697
954
 * Finds the loop used which uses \a v in face loop \a l
698
955
 *
699
 
 * \note currenly this just uses simple loop in future may be speeded up
 
956
 * \note currently this just uses simple loop in future may be sped up
700
957
 * using radial vars
701
958
 */
702
959
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v)
719
976
 *
720
977
 * Finds the loop used which uses \a e in face loop \a l
721
978
 *
722
 
 * \note currenly this just uses simple loop in future may be speeded up
 
979
 * \note currently this just uses simple loop in future may be sped up
723
980
 * using radial vars
724
981
 */
725
982
BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e)
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.
747
1004
 *
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
750
1007
 */
751
1008
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
752
1009
                              BMLoop *edge_loop)
753
1010
{
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;
757
1015
}
762
1020
}
763
1021
 
764
1022
/**
 
1023
 * Check if the loop is convex or concave
 
1024
 * (depends on face normal)
 
1025
 */
 
1026
bool BM_loop_is_convex(BMLoop *l)
 
1027
{
 
1028
        float e_dir_prev[3];
 
1029
        float e_dir_next[3];
 
1030
        float l_no[3];
 
1031
 
 
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;
 
1036
}
 
1037
 
 
1038
/**
765
1039
 * Calculates the angle between the previous and next loops
766
1040
 * (angle at this loops face corner).
767
1041
 *
777
1051
/**
778
1052
 * \brief BM_loop_calc_face_normal
779
1053
 *
780
 
 * Calculate the normal at this loop corner or fallback to the face normal on straignt lines.
 
1054
 * Calculate the normal at this loop corner or fallback to the face normal on straight lines.
781
1055
 *
782
 
 * \param bm The BMesh
783
1056
 * \param l The loop to calculate the normal at
784
1057
 * \param r_normal Resulting normal
785
1058
 */
790
1063
                          l->v->co,
791
1064
                          l->next->v->co) != 0.0f)
792
1065
        {
793
 
                return;
 
1066
                /* pass */
794
1067
        }
795
1068
        else {
796
1069
                copy_v3_v3(r_normal, l->f->no);
798
1071
}
799
1072
 
800
1073
/**
 
1074
 * \brief BM_loop_calc_face_direction
 
1075
 *
 
1076
 * Calculate the direction a loop is pointing.
 
1077
 *
 
1078
 * \param l The loop to calculate the direction at
 
1079
 * \param r_dir Resulting direction
 
1080
 */
 
1081
void BM_loop_calc_face_direction(BMLoop *l, float r_dir[3])
 
1082
{
 
1083
        float v_prev[3];
 
1084
        float v_next[3];
 
1085
 
 
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);
 
1088
 
 
1089
        normalize_v3(v_prev);
 
1090
        normalize_v3(v_next);
 
1091
 
 
1092
        add_v3_v3v3(r_dir, v_prev, v_next);
 
1093
        normalize_v3(r_dir);
 
1094
}
 
1095
 
 
1096
/**
801
1097
 * \brief BM_loop_calc_face_tangent
802
1098
 *
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.
805
1101
 *
806
 
 * \param bm The BMesh
807
1102
 * \param l The loop to calculate the tangent at
808
1103
 * \param r_tangent Resulting tangent
809
1104
 */
811
1106
{
812
1107
        float v_prev[3];
813
1108
        float v_next[3];
 
1109
        float dir[3];
814
1110
 
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);
817
1113
 
818
1114
        normalize_v3(v_prev);
819
1115
        normalize_v3(v_next);
 
1116
        add_v3_v3v3(dir, v_prev, v_next);
820
1117
 
821
 
        if (compare_v3v3(v_prev, v_next, FLT_EPSILON) == FALSE) {
822
 
                float dir[3];
 
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)) {
 
1123
                        negate_v3(nor);
 
1124
                }
826
1125
                cross_v3_v3v3(r_tangent, dir, nor);
827
1126
        }
828
1127
        else {
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);
831
1130
        }
832
1131
 
833
1132
        normalize_v3(r_tangent);
856
1155
/**
857
1156
 * \brief BMESH EDGE/FACE TANGENT
858
1157
 *
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.
861
1160
 *
862
1161
 * \brief BM_edge_calc_face_tangent
863
1162
 * \param e
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
866
1166
 */
867
1167
 
868
1168
void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3])
900
1200
                BMVert *v1 = BM_edge_other_vert(e1, v);
901
1201
                BMVert *v2 = BM_edge_other_vert(e2, v);
902
1202
 
903
 
                return M_PI - angle_v3v3v3(v1->co, v->co, v2->co);
 
1203
                return (float)M_PI - angle_v3v3v3(v1->co, v->co, v2->co);
904
1204
        }
905
1205
        else {
906
1206
                return DEG2RADF(90.0f);
924
1224
                accum_angle += face_angle;
925
1225
        }
926
1226
 
927
 
        return accum_shell / accum_angle;
 
1227
        if (accum_angle != 0.0f) {
 
1228
                return accum_shell / accum_angle;
 
1229
        }
 
1230
        else {
 
1231
                return 1.0f;
 
1232
        }
 
1233
}
 
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)
 
1237
{
 
1238
        BMIter iter;
 
1239
        BMLoop *l;
 
1240
        float accum_shell = 0.0f;
 
1241
        float accum_angle = 0.0f;
 
1242
        int tot_sel = 0, tot = 0;
 
1243
 
 
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;
 
1249
                        tot_sel++;
 
1250
                }
 
1251
                tot++;
 
1252
        }
 
1253
 
 
1254
        if (accum_angle != 0.0f) {
 
1255
                return accum_shell / accum_angle;
 
1256
        }
 
1257
        else {
 
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);
 
1262
                }
 
1263
                else {
 
1264
                        return 1.0f;
 
1265
                }
 
1266
        }
 
1267
}
 
1268
 
 
1269
/**
 
1270
 * \note quite an obscure function.
 
1271
 * used in bmesh operators that have a relative scale options,
 
1272
 */
 
1273
float BM_vert_calc_mean_tagged_edge_length(BMVert *v)
 
1274
{
 
1275
        BMIter iter;
 
1276
        BMEdge *e;
 
1277
        int tot;
 
1278
        float length = 0.0f;
 
1279
 
 
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);
 
1284
                }
 
1285
        }
 
1286
 
 
1287
        if (tot) {
 
1288
                return length / (float)tot;
 
1289
        }
 
1290
        else {
 
1291
                return 0.0f;
 
1292
        }
 
1293
}
 
1294
 
 
1295
 
 
1296
/**
 
1297
 * Returns the loop of the shortest edge in f.
 
1298
 */
 
1299
BMLoop *BM_face_find_shortest_loop(BMFace *f)
 
1300
{
 
1301
        BMLoop *shortest_loop = NULL;
 
1302
        float shortest_len = FLT_MAX;
 
1303
 
 
1304
        BMLoop *l_iter;
 
1305
        BMLoop *l_first;
 
1306
 
 
1307
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 
1308
 
 
1309
        do {
 
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;
 
1313
                        shortest_len = len;
 
1314
                }
 
1315
        } while ((l_iter = l_iter->next) != l_first);
 
1316
 
 
1317
        return shortest_loop;
 
1318
}
 
1319
 
 
1320
/**
 
1321
 * Returns the loop of the longest edge in f.
 
1322
 */
 
1323
BMLoop *BM_face_find_longest_loop(BMFace *f)
 
1324
{
 
1325
        BMLoop *longest_loop = NULL;
 
1326
        float longest_len = 0.0f;
 
1327
 
 
1328
        BMLoop *l_iter;
 
1329
        BMLoop *l_first;
 
1330
 
 
1331
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 
1332
 
 
1333
        do {
 
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;
 
1337
                        longest_len = len;
 
1338
                }
 
1339
        } while ((l_iter = l_iter->next) != l_first);
 
1340
 
 
1341
        return longest_loop;
928
1342
}
929
1343
 
930
1344
/**
947
1361
}
948
1362
 
949
1363
/**
950
 
 * Given a set of vertices \a varr, find out if
951
 
 * all those vertices overlap an existing face.
952
 
 *
953
 
 * \note Making a face here is valid but in some cases you wont want to
954
 
 * make a face thats part of another.
955
 
 *
956
 
 * \returns TRUE for overlap
957
 
 *
 
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.
958
1367
 */
959
 
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlapface)
 
1368
BMEdge *BM_edge_find_double(BMEdge *e)
960
1369
{
961
 
        BMIter viter;
962
 
        BMFace *f;
963
 
        int i, amount;
964
 
 
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);
968
 
                        if (amount >= len) {
969
 
                                if (r_overlapface) {
970
 
                                        *r_overlapface = f;
971
 
                                }
972
 
                                return TRUE;
973
 
                        }
 
1370
        BMVert *v       = e->v1;
 
1371
        BMVert *v_other = e->v2;
 
1372
 
 
1373
        BMEdge *e_iter;
 
1374
 
 
1375
        e_iter = e;
 
1376
        while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) {
 
1377
                if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) {
 
1378
                        return e_iter;
974
1379
                }
975
1380
        }
976
1381
 
977
 
        if (r_overlapface) {
978
 
                *r_overlapface = NULL;
979
 
        }
980
 
 
981
 
        return FALSE;
 
1382
        return NULL;
982
1383
}
983
1384
 
984
1385
/**
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).
 
1389
 *
 
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.
988
1392
 */
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)
990
1394
{
 
1395
        BMVert *v_search = varr[0];  /* we can search any of the verts in the array */
991
1396
        BMIter viter;
992
1397
        BMFace *f;
993
 
        int i, amount;
994
 
 
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) {
 
1398
 
 
1399
 
 
1400
#if 0
 
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;
1001
1406
                                }
1002
 
                                return TRUE;
 
1407
                                return true;
1003
1408
                        }
1004
1409
                }
1005
1410
        }
1007
1412
        if (r_existface) {
1008
1413
                *r_existface = NULL;
1009
1414
        }
1010
 
        return FALSE;
 
1415
        return false;
 
1416
 
 
1417
#else
 
1418
 
 
1419
        /* faster to do the flagging once, and inline */
 
1420
        bool is_init = false;
 
1421
        bool is_found = false;
 
1422
        int i;
 
1423
 
 
1424
 
 
1425
        BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
 
1426
                if (f->len == len) {
 
1427
                        if (is_init == false) {
 
1428
                                is_init = true;
 
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);
 
1432
                                }
 
1433
                        }
 
1434
 
 
1435
                        is_found = true;
 
1436
 
 
1437
                        {
 
1438
                                BMLoop *l_iter;
 
1439
                                BMLoop *l_first;
 
1440
 
 
1441
                                l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 
1442
 
 
1443
                                do {
 
1444
                                        if (!BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
 
1445
                                                is_found = false;
 
1446
                                                break;
 
1447
                                        }
 
1448
                                } while ((l_iter = l_iter->next) != l_first);
 
1449
                        }
 
1450
 
 
1451
                        if (is_found) {
 
1452
                                if (r_existface) {
 
1453
                                        *r_existface = f;
 
1454
                                }
 
1455
                                break;
 
1456
                        }
 
1457
                }
 
1458
        }
 
1459
 
 
1460
        if (is_found == false) {
 
1461
                if (r_existface) {
 
1462
                        *r_existface = NULL;
 
1463
                }
 
1464
        }
 
1465
 
 
1466
        if (is_init == true) {
 
1467
                for (i = 0; i < len; i++) {
 
1468
                        BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
 
1469
                }
 
1470
        }
 
1471
 
 
1472
        return is_found;
 
1473
#endif
1011
1474
}
1012
1475
 
1013
1476
 
1023
1486
 *
1024
1487
 * \a earr and \a varr can be in any order, however they _must_ form a closed loop.
1025
1488
 */
1026
 
int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
 
1489
bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
1027
1490
{
1028
1491
        BMFace *f;
1029
1492
        BMEdge *e;
1030
1493
        BMVert *v;
1031
 
        int ok;
 
1494
        bool ok;
1032
1495
        int tot_tag;
1033
1496
 
1034
1497
        BMIter fiter;
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)) {
1071
 
                                ok = TRUE;
 
1534
                                ok = true;
1072
1535
                                BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
1073
1536
                                        if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
1074
 
                                                ok = FALSE;
 
1537
                                                ok = false;
1075
1538
                                                break;
1076
1539
                                        }
1077
1540
                                }
1090
1553
 
1091
1554
        if (tot_tag == 0) {
1092
1555
                /* no faces use only boundary verts, quit early */
1093
 
                return FALSE;
 
1556
                return false;
1094
1557
        }
1095
1558
 
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) */
1098
 
        ok = TRUE;
 
1561
        ok = true;
1099
1562
        for (i = 0; i < len; i++) {
1100
1563
                BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
1101
1564
 
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)
1107
1570
                        {
1108
1571
                                int tot_face_tag = 0;
1109
1572
                                BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
1113
1576
                                }
1114
1577
 
1115
1578
                                if (tot_face_tag != 2) {
1116
 
                                        ok = FALSE;
 
1579
                                        ok = false;
1117
1580
                                        break;
1118
1581
                                }
1119
1582
 
1120
1583
                        }
1121
1584
                }
1122
1585
 
1123
 
                if (ok == FALSE) {
 
1586
                if (ok == false) {
1124
1587
                        break;
1125
1588
                }
1126
1589
        }
1129
1592
}
1130
1593
 
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)
1133
1596
{
1134
 
        BMVert **varr;
1135
 
        BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
 
1597
        BMVert **varr = BLI_array_alloca(varr, len);
1136
1598
 
1137
 
        int ok;
 
1599
        bool ok;
1138
1600
        int i, i_next;
1139
1601
 
1140
1602
        /* first check if verts have edges, if not we can bail out early */
1141
 
        ok = TRUE;
 
1603
        ok = true;
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]))) {
1144
 
                        ok = FALSE;
 
1606
                        ok = false;
1145
1607
                        break;
1146
1608
                }
1147
1609
        }
1148
1610
 
1149
 
        if (ok == FALSE) {
 
1611
        if (ok == false) {
1150
1612
                BMESH_ASSERT(0);
1151
 
                BLI_array_fixedstack_free(varr);
1152
 
                return FALSE;
 
1613
                return false;
1153
1614
        }
1154
1615
 
1155
1616
        ok = BM_face_exists_multi(varr, earr, len);
1156
1617
 
1157
 
        BLI_array_fixedstack_free(varr);
1158
 
 
1159
1618
        return ok;
1160
1619
}
 
1620
 
 
1621
/* convenience functions for checking flags */
 
1622
bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
 
1623
{
 
1624
        return (BM_elem_flag_test(e->v1, hflag) ||
 
1625
                BM_elem_flag_test(e->v2, hflag));
 
1626
}
 
1627
 
 
1628
bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
 
1629
{
 
1630
        BMLoop *l_iter;
 
1631
        BMLoop *l_first;
 
1632
 
 
1633
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 
1634
        do {
 
1635
                if (BM_elem_flag_test(l_iter->v, hflag)) {
 
1636
                        return true;
 
1637
                }
 
1638
        } while ((l_iter = l_iter->next) != l_first);
 
1639
        return false;
 
1640
}
 
1641
 
 
1642
bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
 
1643
{
 
1644
        BMLoop *l_iter;
 
1645
        BMLoop *l_first;
 
1646
 
 
1647
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
 
1648
        do {
 
1649
                if (BM_elem_flag_test(l_iter->e, hflag)) {
 
1650
                        return true;
 
1651
                }
 
1652
        } while ((l_iter = l_iter->next) != l_first);
 
1653
        return false;
 
1654
}