BMesh: avoid extra calls per faces-of-vert iterator
authorCampbell Barton <ideasman42@gmail.com>
Mon, 14 Nov 2016 20:30:36 +0000 (07:30 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 14 Nov 2016 20:39:39 +0000 (07:39 +1100)
- `bmesh_radial_faceloop_find_first` & `bmesh_disk_faceedge_find_first`
  can be replaced with a single call to a new function:
  `bmesh_disk_faceloop_find_first`

- `bmesh_disk_faceedge_find_first` called `bmesh_radial_facevert_check`
  which isn't needed, since either the current or next loop in the
  cycle is attached to the edge we're looking for.

source/blender/bmesh/intern/bmesh_iterators.c
source/blender/bmesh/intern/bmesh_structure.c
source/blender/bmesh/intern/bmesh_structure.h

index 961b10d848aca96947466cfd15ba1b4ab8b8bd5a..96154f051f93a7c430d747e2d0d8150c095c4903 100644 (file)
@@ -485,9 +485,9 @@ void  bmiter__face_of_vert_begin(struct BMIter__face_of_vert *iter)
 {
        ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
        if (((BMIter *)iter)->count) {
-               iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata);
+               iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
+               iter->e_first = iter->l_first->e;
                iter->e_next = iter->e_first;
-               iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata);
                iter->l_next = iter->l_first;
        }
        else {
@@ -526,9 +526,9 @@ void  bmiter__loop_of_vert_begin(struct BMIter__loop_of_vert *iter)
 {
        ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
        if (((BMIter *)iter)->count) {
-               iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata);
+               iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
+               iter->e_first = iter->l_first->e;
                iter->e_next = iter->e_first;
-               iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata);
                iter->l_next = iter->l_first;
        }
        else {
index 6052de421dda4de66615ed8164847716d6a04605..8e484841568d4a223f1779deec82d01815faa4cb 100644 (file)
@@ -338,13 +338,28 @@ int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max)
  */
 BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
 {
-       const BMEdge *e_find = e;
+       const BMEdge *e_iter = e;
        do {
-               if (e_find->l && bmesh_radial_facevert_check(e_find->l, v)) {
-                       return (BMEdge *)e_find;
+               if (e_iter->l != NULL) {
+                       return (BMEdge *)((e_iter->l->v == v) ? e_iter : e_iter->l->next->e);
                }
-       } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
+       } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
+       return NULL;
+}
 
+/**
+ * Special case for BM_LOOPS_OF_VERT & BM_FACES_OF_VERT, avoids 2x calls.
+ *
+ * The returned BMLoop.e matches the result of #bmesh_disk_faceedge_find_first
+ */
+BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v)
+{
+       const BMEdge *e_iter = e;
+       do {
+               if (e_iter->l != NULL) {
+                       return (e_iter->l->v == v) ? e_iter->l : e_iter->l->next;
+               }
+       } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
        return NULL;
 }
 
index 679e7a269b3814af787b02c123310704bb1e8b95..0efb25da37c6126d3dd5cf2c9ceceb5519ff7b08 100644 (file)
@@ -52,6 +52,7 @@ BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_W
 int     bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 int     bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
 /* RADIAL CYCLE MANAGMENT */