From 5b0ee040a3f35584da9c553d8f25cb715314d087 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Nov 2012 02:33:26 +0000 Subject: further cleanup for selecting the shortest path, remove the need for EDBM_index_arrays_* functions. --- source/blender/editors/mesh/editmesh_select.c | 95 ++++++++++----------------- 1 file changed, 36 insertions(+), 59 deletions(-) (limited to 'source') diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 88f8113f1c6..55a2abb1c45 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1177,7 +1177,7 @@ void MESH_OT_edgering_select(wmOperatorType *ot) /* ******************* edgetag_shortest_path and helpers ****************** */ -static float edgetag_cut_cost(BMEditMesh *UNUSED(em), BMEdge *e1, BMEdge *e2, BMVert *v) +static float edgetag_cut_cost(BMEdge *e1, BMEdge *e2, BMVert *v) { BMVert *v1 = (e1->v1 == v) ? e1->v2 : e1->v1; BMVert *v2 = (e2->v1 == v) ? e2->v2 : e2->v1; @@ -1196,9 +1196,7 @@ static float edgetag_cut_cost(BMEditMesh *UNUSED(em), BMEdge *e1, BMEdge *e2, BM return cost; } -static void edgetag_add_adjacent(BMEditMesh *em, Heap *heap, - BMEdge *e1, BMVert *v, - int *prevedge, float *cost) +static void edgetag_add_adjacent(Heap *heap, BMEdge *e1, BMVert *v, BMEdge **edges_prev, float *cost) { BMIter eiter; BMEdge *e2; @@ -1208,24 +1206,24 @@ static void edgetag_add_adjacent(BMEditMesh *em, Heap *heap, BM_ITER_ELEM (e2, &eiter, v, BM_EDGES_OF_VERT) { if (!BM_elem_flag_test(e2, BM_ELEM_TAG)) { const int e2_index = BM_elem_index_get(e2); - const float cost_cut = edgetag_cut_cost(em, e1, e2, v); + const float cost_cut = edgetag_cut_cost(e1, e2, v); const float cost_new = cost[e1_index] + cost_cut; if (cost[e2_index] > cost_new) { cost[e2_index] = cost_new; - prevedge[e2_index] = e1_index; + edges_prev[e2_index] = e1; BLI_heap_insert(heap, cost_new, e2); } } } } -static void edgetag_context_set(BMEditMesh *em, Scene *scene, BMEdge *e, int val) +static void edgetag_context_set(BMesh *bm, Scene *scene, BMEdge *e, int val) { switch (scene->toolsettings->edge_mode) { case EDGE_MODE_SELECT: - BM_edge_select_set(em->bm, e, val); + BM_edge_select_set(bm, e, val); break; case EDGE_MODE_TAG_SEAM: BM_elem_flag_set(e, BM_ELEM_SEAM, val); @@ -1234,51 +1232,45 @@ static void edgetag_context_set(BMEditMesh *em, Scene *scene, BMEdge *e, int val BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val); break; case EDGE_MODE_TAG_CREASE: - { - float *crease = CustomData_bmesh_get(&em->bm->edata, e->head.data, CD_CREASE); - *crease = (val) ? 1.0f : 0.0f; + BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f); break; - } case EDGE_MODE_TAG_BEVEL: - { - float *bweight = CustomData_bmesh_get(&em->bm->edata, e->head.data, CD_BWEIGHT); - *bweight = (val) ? 1.0f : 0.0f; + BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f); break; - } } } -static int edgetag_context_check(Scene *scene, BMEditMesh *em, BMEdge *e) +static int edgetag_context_check(Scene *scene, BMesh *bm, BMEdge *e) { switch (scene->toolsettings->edge_mode) { case EDGE_MODE_SELECT: - return BM_elem_flag_test(e, BM_ELEM_SELECT) ? 1 : 0; + return BM_elem_flag_test(e, BM_ELEM_SELECT) ? TRUE : FALSE; case EDGE_MODE_TAG_SEAM: return BM_elem_flag_test(e, BM_ELEM_SEAM); case EDGE_MODE_TAG_SHARP: return !BM_elem_flag_test(e, BM_ELEM_SMOOTH); case EDGE_MODE_TAG_CREASE: - return BM_elem_float_data_get(&em->bm->edata, e, CD_CREASE) ? 1 : 0; + return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? TRUE : FALSE; case EDGE_MODE_TAG_BEVEL: - return BM_elem_float_data_get(&em->bm->edata, e, CD_BWEIGHT) ? 1 : 0; + return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? TRUE : FALSE; } return 0; } -static int edgetag_shortest_path(Scene *scene, BMEditMesh *em, BMEdge *e_src, BMEdge *e_dst) +static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge *e_dst) { /* BM_ELEM_TAG flag is used to store visited edges */ BMEdge *e; BMIter eiter; Heap *heap; float *cost; - int *prevedge; + BMEdge **edges_prev; int i, totedge; /* note, would pass BM_EDGE except we are looping over all edges anyway */ - BM_mesh_elem_index_ensure(em->bm, BM_VERT /* | BM_EDGE */); + BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */); - BM_ITER_MESH_INDEX (e, &eiter, em->bm, BM_EDGES_OF_MESH, i) { + BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) { BM_elem_flag_disable(e, BM_ELEM_TAG); } @@ -1288,17 +1280,14 @@ static int edgetag_shortest_path(Scene *scene, BMEditMesh *em, BMEdge *e_src, BM BM_elem_index_set(e, i); /* set_inline */ } - em->bm->elem_index_dirty &= ~BM_EDGE; + bm->elem_index_dirty &= ~BM_EDGE; /* alloc */ - totedge = em->bm->totedge; - prevedge = MEM_mallocN(sizeof(*prevedge) * totedge, "SeamPathPrevious"); + totedge = bm->totedge; + edges_prev = MEM_callocN(sizeof(*edges_prev) * totedge, "SeamPathPrevious"); cost = MEM_mallocN(sizeof(*cost) * totedge, "SeamPathCost"); - for (i = 0; i < totedge; i++) { - cost[i] = 1e20f; - prevedge[i] = -1; - } + fill_vn_fl(cost, totedge, 1e20f); /* * Arrays are now filled as follows: @@ -1315,55 +1304,43 @@ static int edgetag_shortest_path(Scene *scene, BMEditMesh *em, BMEdge *e_src, BM heap = BLI_heap_new(); BLI_heap_insert(heap, 0.0f, e_src); cost[BM_elem_index_get(e_src)] = 0.0f; - EDBM_index_arrays_init(em, 1, 1, 0); e = NULL; + while (!BLI_heap_is_empty(heap)) { e = BLI_heap_popmin(heap); if (e == e_dst) break; - if (BM_elem_flag_test(e, BM_ELEM_TAG)) { - continue; + if (!BM_elem_flag_test(e, BM_ELEM_TAG)) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + edgetag_add_adjacent(heap, e, e->v1, edges_prev, cost); + edgetag_add_adjacent(heap, e, e->v2, edges_prev, cost); } - - BM_elem_flag_enable(e, BM_ELEM_TAG); - - edgetag_add_adjacent(em, heap, e, e->v1, prevedge, cost); - edgetag_add_adjacent(em, heap, e, e->v2, prevedge, cost); } if (e == e_dst) { short allseams = 1; - int e_index; /* Check whether the path is already completely tagged. * if it is, the tags will be cleared instead of set. */ - e_index = BM_elem_index_get(e_dst); + e = e_dst; do { - e = EDBM_edge_at_index(em, e_index); - if (!edgetag_context_check(scene, em, e)) { + if (!edgetag_context_check(scene, bm, e)) { allseams = 0; break; } - e_index = prevedge[e_index]; - } while (e != e_src); + } while ((e = edges_prev[BM_elem_index_get(e)])); /* Follow path back and source and add or remove tags */ - e_index = BM_elem_index_get(e_dst); + e = e_dst; do { - e = EDBM_edge_at_index(em, e_index); - if (allseams) - edgetag_context_set(em, scene, e, 0); - else - edgetag_context_set(em, scene, e, 1); - e_index = prevedge[e_index]; - } while (e_index != -1); + edgetag_context_set(bm, scene, e, !allseams); + } while ((e = edges_prev[BM_elem_index_get(e)])); } - EDBM_index_arrays_free(em); - MEM_freeN(prevedge); + MEM_freeN(edges_prev); MEM_freeN(cost); BLI_heap_free(heap, NULL); @@ -1397,7 +1374,7 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2]) BMEdge *e_act; e_act = (BMEdge *)ese->ele; if (e_act != e) { - if (edgetag_shortest_path(vc.scene, em, e_act, e)) { + if (edgetag_shortest_path(vc.scene, em->bm, e_act, e)) { BM_select_history_remove(em->bm, e_act); path = 1; } @@ -1405,14 +1382,14 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2]) } } if (path == 0) { - int act = (edgetag_context_check(vc.scene, em, e) == 0); - edgetag_context_set(em, vc.scene, e, act); /* switch the edge option */ + int act = (edgetag_context_check(vc.scene, em->bm, e) == 0); + edgetag_context_set(em->bm, vc.scene, e, act); /* switch the edge option */ } EDBM_selectmode_flush(em); /* even if this is selected it may not be in the selection list */ - if (edgetag_context_check(vc.scene, em, e) == 0) + if (edgetag_context_check(vc.scene, em->bm, e) == 0) BM_select_history_remove(em->bm, e); else BM_select_history_store(em->bm, e); -- cgit v1.2.3