BMesh: simple edge boundary walker
authorCampbell Barton <ideasman42@gmail.com>
Thu, 6 Mar 2014 20:58:22 +0000 (07:58 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 6 Mar 2014 23:39:30 +0000 (10:39 +1100)
source/blender/bmesh/intern/bmesh_walkers.h
source/blender/bmesh/intern/bmesh_walkers_impl.c
source/blender/bmesh/intern/bmesh_walkers_private.h

index ea1dbc6..9b0c200 100644 (file)
@@ -118,6 +118,7 @@ enum {
        BMW_LOOP,
        BMW_FACELOOP,
        BMW_EDGERING,
+       BMW_EDGEBOUNDARY,
        /* #define BMW_RING     2 */
        /* walk over uv islands; takes a loop as input.  restrict flag
         * restricts the walking to loops whose vert has restrict flag set as a
index dee5015..357fe05 100644 (file)
@@ -993,6 +993,77 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
 /** \} */
 
 
+/** \name Boundary Edge Walker
+ * \{ */
+
+static void bmw_EdgeboundaryWalker_begin(BMWalker *walker, void *data)
+{
+       BMwEdgeboundaryWalker *lwalk;
+       BMEdge *e = data;
+
+       BLI_assert(BM_edge_is_boundary(e));
+
+       if (BLI_gset_haskey(walker->visit_set, e))
+               return;
+
+       lwalk = BMW_state_add(walker);
+       lwalk->e = e;
+       BLI_gset_insert(walker->visit_set, e);
+}
+
+static void *bmw_EdgeboundaryWalker_yield(BMWalker *walker)
+{
+       BMwEdgeboundaryWalker *lwalk = BMW_current_state(walker);
+
+       if (!lwalk) {
+               return NULL;
+       }
+
+       return lwalk->e;
+}
+
+static void *bmw_EdgeboundaryWalker_step(BMWalker *walker)
+{
+       BMwEdgeboundaryWalker *lwalk, owalk;
+       BMEdge *e, *e_other;
+       BMVert *v;
+       BMIter eiter;
+       BMIter viter;
+
+       BMW_state_remove_r(walker, &owalk);
+       lwalk = &owalk;
+
+       e = lwalk->e;
+
+       if (!bmw_mask_check_edge(walker, e)) {
+               return e;
+       }
+
+       BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
+               BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
+                       if (e != e_other && BM_edge_is_boundary(e_other)) {
+                               if (BLI_gset_haskey(walker->visit_set, e_other)) {
+                                       continue;
+                               }
+
+                               if (!bmw_mask_check_edge(walker, e_other)) {
+                                       continue;
+                               }
+
+                               lwalk = BMW_state_add(walker);
+                               BLI_gset_insert(walker->visit_set, e_other);
+
+                               lwalk->e = e_other;
+                       }
+               }
+       }
+
+       return e;
+}
+
+/** \} */
+
+
 /** \name UV Edge Walker
  * \{ */
 
@@ -1133,7 +1204,16 @@ static BMWalker bmw_EdgeringWalker_Type = {
        bmw_EdgeringWalker_yield,
        sizeof(BMwEdgeringWalker),
        BMW_DEPTH_FIRST,
-       0, /* valid restrict masks */ /* could add flags here but so far none are used */
+       BM_EDGE, /* valid restrict masks */
+};
+
+static BMWalker bmw_EdgeboundaryWalker_Type = {
+       bmw_EdgeboundaryWalker_begin,
+       bmw_EdgeboundaryWalker_step,
+       bmw_EdgeboundaryWalker_yield,
+       sizeof(BMwEdgeboundaryWalker),
+       BMW_DEPTH_FIRST,
+       0,
 };
 
 static BMWalker bmw_UVEdgeWalker_Type = {
@@ -1159,6 +1239,7 @@ BMWalker *bm_walker_types[] = {
        &bmw_LoopWalker_Type,               /* BMW_LOOP */
        &bmw_FaceLoopWalker_Type,           /* BMW_FACELOOP */
        &bmw_EdgeringWalker_Type,           /* BMW_EDGERING */
+       &bmw_EdgeboundaryWalker_Type,       /* BMW_EDGEBOUNDARY */
        &bmw_UVEdgeWalker_Type,             /* BMW_LOOPDATA_ISLAND */
        &bmw_IslandboundWalker_Type,        /* BMW_ISLANDBOUND */
        &bmw_IslandWalker_Type,             /* BMW_ISLAND */
index 09dd4f1..82d1e76 100644 (file)
@@ -78,6 +78,11 @@ typedef struct BMwEdgeringWalker {
        BMEdge *wireedge;
 } BMwEdgeringWalker;
 
+typedef struct BMwEdgeboundaryWalker {
+       BMwGenericWalker header;
+       BMEdge *e;
+} BMwEdgeboundaryWalker;
+
 typedef struct BMwUVEdgeWalker {
        BMwGenericWalker header;
        BMLoop *l;