Changeset View
Standalone View
source/blender/bmesh/intern/bmesh_walkers_impl.c
| Show First 20 Lines • Show All 1,590 Lines • ▼ Show 20 Lines | for (i = 0; i < 2; i++) { | ||||
| } | } | ||||
| } | } | ||||
| return l; | return l; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name Non-manifold Edge Walker | |||||
| * \{ */ | |||||
| static void bmw_NonManifoldedgeWalker_begin(BMWalker *walker, void *data) | |||||
| { | |||||
| BMwNonManifoldEdgeLoopWalker *lwalk; | |||||
| BMEdge *e = data; | |||||
| if (BLI_gset_haskey(walker->visit_set, e)) { | |||||
| return; | |||||
| } | |||||
| lwalk = BMW_state_add(walker); | |||||
| lwalk->start = e; | |||||
| lwalk->cur = e; | |||||
| lwalk->startv = e->v2; | |||||
| lwalk->lastv = e->v1; | |||||
| lwalk->face_count = BM_edge_face_count(e); | |||||
| BLI_gset_insert(walker->visit_set, e); | |||||
campbellbarton: This doesn't make sense to set, it can be removed from a new struct.
Instead, the face_count… | |||||
| } | |||||
| static void *bmw_NonManifoldedgeWalker_yield(BMWalker *walker) | |||||
| { | |||||
| BMwNonManifoldEdgeLoopWalker *lwalk = BMW_current_state(walker); | |||||
| if (!lwalk) { | |||||
| return NULL; | |||||
| } | |||||
| return lwalk->cur; | |||||
| } | |||||
| /* `bmw_NonManifoldLoop_edgeloop` is used to find edge from one of the radial edge . | |||||
| * will find the match with same number of faces as that of lwalk.cur */ | |||||
| static BMLoop *bmw_NonManifoldLoop_edgeloop(BMLoop *l, BMVert *v, int face_count) | |||||
| { | |||||
| BLI_assert(!BM_loop_is_manifold(l)); | |||||
| do { | |||||
| l = BM_loop_other_edge_loop(l, v); | |||||
| if (BM_loop_is_manifold(l)) { | |||||
| l = l->radial_next; | |||||
| } | |||||
| else if (BM_edge_face_count_is_equal(l->e, face_count)) { | |||||
| break; | |||||
| } | |||||
| } while (true); | |||||
| return l; | |||||
| } | |||||
Done Inline ActionsWalkers shouldn't depend on selection (notice none of the other walkers here do). campbellbarton: Walkers shouldn't depend on selection (notice none of the other walkers here do). | |||||
Done Inline ActionsThis isn't used. campbellbarton: This isn't used. | |||||
| static void *bmw_NonManifoldedgeWalker_step(BMWalker *walker) | |||||
| { | |||||
Done Inline ActionsThis assumes loop is part of an edge with two face users. That should be checked for with BM_loop_is_manifold, if that fails. bail out of the loopl. campbellbarton: This assumes loop is part of an edge with two face users. That should be checked for with… | |||||
| BMwNonManifoldEdgeLoopWalker *lwalk, owalk; | |||||
| BMW_state_remove_r(walker, &owalk); | |||||
Done Inline ActionsThis can be extracted into a function, since it's called again below. campbellbarton: This can be extracted into a function, since it's called again below. | |||||
| lwalk = &owalk; | |||||
| BMEdge *e = lwalk->cur; | |||||
| BMVert *v = BM_edge_other_vert(e, lwalk->lastv); | |||||
| BMLoop *l, *l_init, *l_cur = NULL; | |||||
| int face_count = lwalk->face_count; | |||||
| l = l_init = e->l; | |||||
Done Inline ActionsThis is starting out from one of the loops only, it could start out from any of 3+ loops. Shouldn't all of them be considered as candidates for stepping over? campbellbarton: This is starting out from one of the loops only, it could start out from any of 3+ loops. | |||||
| /* Loop here to avoid separate loop code for reverse traversing. | |||||
| * "Integration Explanation" below to see purpose of this loop. */ | |||||
Done Inline ActionsThis still seems to be campbellbarton: This still seems to be | |||||
| for (int i = 0; i < 2; i++) { | |||||
| do { | |||||
Done Inline ActionsFor a predictable outcome this should check all radial loops connect to the same edge (or can't find an edge that matches). This way there can never be a branch in the path which follows only one of the edges. campbellbarton: For a predictable outcome this should check all radial loops connect to the same edge (or can't… | |||||
Done Inline Actionsbmw_NonManifoldLoop_edgeloop will never return an BM_edge_is_boundary(l->e) edge, this check is redundant. campbellbarton: `bmw_NonManifoldLoop_edgeloop` will never return an `BM_edge_is_boundary(l->e)` edge, this… | |||||
| BMLoop *l_next = bmw_NonManifoldLoop_edgeloop(l, v, face_count); | |||||
| if (!BLI_gset_haskey(walker->visit_set, l_next->e)) { | |||||
| if (l_cur == NULL) { | |||||
| l_cur = l_next; | |||||
| } | |||||
| else if (l_cur->e != l_next->e) { | |||||
| l_cur = NULL; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } while ((l = l->radial_next) != l_init); | |||||
| /* Integration Explanation: | |||||
| * | |||||
| * - First iteration of for loop: `i == 0`: | |||||
| * `l_cur == NULL` indicates valid loop edge is either not found | |||||
| * or more than one solutions are possible. | |||||
| * In that case, after `do-while` loop , | |||||
| * start traversing opposite direction from first selected edge. | |||||
| * if valid edge is found `l_cur != NULL` , exit `for` loop | |||||
| * | |||||
| * - Second iteration of for loop `i == 1`: | |||||
| * for reverse traversing when `l_cur = NULL` was obtained from first iteration. | |||||
| * Second iteration occurs at most for one time on calling `walker_select`. */ | |||||
| if (l_cur == NULL) { | |||||
| e = lwalk->start; | |||||
| v = BM_edge_other_vert(e, lwalk->startv); | |||||
| l = l_init = e->l; | |||||
| } | |||||
| else { | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (l_cur != NULL) { | |||||
| if (!BLI_gset_haskey(walker->visit_set, l_cur->e)) { | |||||
| lwalk = BMW_state_add(walker); | |||||
| lwalk->lastv = v; | |||||
| lwalk->cur = l_cur->e; | |||||
| lwalk->face_count = BM_edge_face_count(l_cur->e); | |||||
| BLI_gset_insert(walker->visit_set, l_cur->e); | |||||
| } | |||||
| } | |||||
| return owalk.cur; | |||||
| } | |||||
| /** \} */ | |||||
| static BMWalker bmw_VertShellWalker_Type = { | static BMWalker bmw_VertShellWalker_Type = { | ||||
| BM_VERT | BM_EDGE, | BM_VERT | BM_EDGE, | ||||
| bmw_VertShellWalker_begin, | bmw_VertShellWalker_begin, | ||||
| bmw_VertShellWalker_step, | bmw_VertShellWalker_step, | ||||
| bmw_VertShellWalker_yield, | bmw_VertShellWalker_yield, | ||||
| sizeof(BMwShellWalker), | sizeof(BMwShellWalker), | ||||
| BMW_BREADTH_FIRST, | BMW_BREADTH_FIRST, | ||||
| BM_EDGE, /* Valid restrict masks. */ | BM_EDGE, /* Valid restrict masks. */ | ||||
| ▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | static BMWalker bmw_EdgeboundaryWalker_Type = { | ||||
| bmw_EdgeboundaryWalker_begin, | bmw_EdgeboundaryWalker_begin, | ||||
| bmw_EdgeboundaryWalker_step, | bmw_EdgeboundaryWalker_step, | ||||
| bmw_EdgeboundaryWalker_yield, | bmw_EdgeboundaryWalker_yield, | ||||
| sizeof(BMwEdgeboundaryWalker), | sizeof(BMwEdgeboundaryWalker), | ||||
| BMW_DEPTH_FIRST, | BMW_DEPTH_FIRST, | ||||
| 0, | 0, | ||||
| }; | }; | ||||
| static BMWalker bmw_NonManifoldedgeWalker_type = { | |||||
| BM_EDGE, | |||||
| bmw_NonManifoldedgeWalker_begin, | |||||
| bmw_NonManifoldedgeWalker_step, | |||||
| bmw_NonManifoldedgeWalker_yield, | |||||
| sizeof(BMwNonManifoldEdgeLoopWalker), | |||||
| BMW_DEPTH_FIRST, | |||||
| 0, | |||||
| }; | |||||
| static BMWalker bmw_UVEdgeWalker_Type = { | static BMWalker bmw_UVEdgeWalker_Type = { | ||||
| BM_LOOP, | BM_LOOP, | ||||
| bmw_UVEdgeWalker_begin, | bmw_UVEdgeWalker_begin, | ||||
| bmw_UVEdgeWalker_step, | bmw_UVEdgeWalker_step, | ||||
| bmw_UVEdgeWalker_yield, | bmw_UVEdgeWalker_yield, | ||||
| sizeof(BMwUVEdgeWalker), | sizeof(BMwUVEdgeWalker), | ||||
| BMW_DEPTH_FIRST, | BMW_DEPTH_FIRST, | ||||
| BM_EDGE, /* Valid restrict masks. */ | BM_EDGE, /* Valid restrict masks. */ | ||||
| Show All 13 Lines | BMWalker *bm_walker_types[] = { | ||||
| &bmw_VertShellWalker_Type, /* #BMW_VERT_SHELL */ | &bmw_VertShellWalker_Type, /* #BMW_VERT_SHELL */ | ||||
| &bmw_LoopShellWalker_Type, /* #BMW_LOOP_SHELL */ | &bmw_LoopShellWalker_Type, /* #BMW_LOOP_SHELL */ | ||||
| &bmw_LoopShellWireWalker_Type, /* #BMW_LOOP_SHELL_WIRE */ | &bmw_LoopShellWireWalker_Type, /* #BMW_LOOP_SHELL_WIRE */ | ||||
| &bmw_FaceShellWalker_Type, /* #BMW_FACE_SHELL */ | &bmw_FaceShellWalker_Type, /* #BMW_FACE_SHELL */ | ||||
| &bmw_EdgeLoopWalker_Type, /* #BMW_EDGELOOP */ | &bmw_EdgeLoopWalker_Type, /* #BMW_EDGELOOP */ | ||||
| &bmw_FaceLoopWalker_Type, /* #BMW_FACELOOP */ | &bmw_FaceLoopWalker_Type, /* #BMW_FACELOOP */ | ||||
| &bmw_EdgeringWalker_Type, /* #BMW_EDGERING */ | &bmw_EdgeringWalker_Type, /* #BMW_EDGERING */ | ||||
| &bmw_EdgeboundaryWalker_Type, /* #BMW_EDGEBOUNDARY */ | &bmw_EdgeboundaryWalker_Type, /* #BMW_EDGEBOUNDARY */ | ||||
| &bmw_NonManifoldedgeWalker_type, /* #BMW_EDGELOOP_NONMANIFOLD*/ | |||||
| &bmw_UVEdgeWalker_Type, /* #BMW_LOOPDATA_ISLAND */ | &bmw_UVEdgeWalker_Type, /* #BMW_LOOPDATA_ISLAND */ | ||||
| &bmw_IslandboundWalker_Type, /* #BMW_ISLANDBOUND */ | &bmw_IslandboundWalker_Type, /* #BMW_ISLANDBOUND */ | ||||
| &bmw_IslandWalker_Type, /* #BMW_ISLAND */ | &bmw_IslandWalker_Type, /* #BMW_ISLAND */ | ||||
| &bmw_IslandManifoldWalker_Type, /* #BMW_ISLAND_MANIFOLD */ | &bmw_IslandManifoldWalker_Type, /* #BMW_ISLAND_MANIFOLD */ | ||||
| &bmw_ConnectedVertexWalker_Type, /* #BMW_CONNECTED_VERTEX */ | &bmw_ConnectedVertexWalker_Type, /* #BMW_CONNECTED_VERTEX */ | ||||
| }; | }; | ||||
| const int bm_totwalkers = ARRAY_SIZE(bm_walker_types); | const int bm_totwalkers = ARRAY_SIZE(bm_walker_types); | ||||
This doesn't make sense to set, it can be removed from a new struct.
Instead, the face_count should be stored, currently this is counted on every edge step which isn't needed.