From d020b4ca91e1097573a439fdab16e707922fd5a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 27 Dec 2015 18:03:20 +1100 Subject: BMesh: extract int/bmesh element access funcs. Support getting an vert/edge/face from a single index, useful for operator redo. --- source/blender/editors/mesh/editmesh_select.c | 37 +++++----------- source/blender/editors/mesh/editmesh_utils.c | 63 +++++++++++++++++++++++++++ source/blender/editors/mesh/mesh_intern.h | 6 +++ 3 files changed, 81 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index fba775518c7..8240f29d7f9 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2798,21 +2798,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE edbm_select_linked_pick_ex(em, eve, eed, efa, sel, delimit); /* to support redo */ - if ((em->selectmode & SCE_SELECT_VERTEX) && eve) { - BM_mesh_elem_index_ensure(bm, BM_VERT); - index = BM_elem_index_get(eve); - } - else if ((em->selectmode & SCE_SELECT_EDGE) && eed) { - BM_mesh_elem_index_ensure(bm, BM_EDGE); - index = BM_elem_index_get(eed) + bm->totvert; - } - else if ((em->selectmode & SCE_SELECT_FACE) && efa) { - BM_mesh_elem_index_ensure(bm, BM_FACE); - index = BM_elem_index_get(efa) + bm->totvert + bm->totedge; - } - else { - index = -1; - } + index = EDBM_elem_to_index_any_selectmode(em, eve, eed, efa); RNA_int_set(op->ptr, "index", index); @@ -2838,16 +2824,17 @@ static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (index < bm->totvert) { - eve = BM_vert_at_index_find_or_table(bm, index); - } - else if (index < (bm->totvert + bm->totedge)) { - index -= bm->totvert; - eed = BM_edge_at_index_find_or_table(bm, index); - } - else if (index < (bm->totvert + bm->totedge + bm->totface)) { - index -= (bm->totvert + bm->totedge); - efa = BM_face_at_index_find_or_table(bm, index); + BMElem *ele = EDBM_elem_from_index_any(em, index); + switch (ele->head.htype) { + case BM_VERT: + eve = (BMVert *)ele; + break; + case BM_EDGE: + eed = (BMEdge *)ele; + break; + case BM_FACE: + efa = (BMFace *)ele; + break; } #ifdef USE_LINKED_SELECT_DEFAULT_HACK diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 4a9be4978b1..656869f9dec 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1431,7 +1431,70 @@ int EDBM_view3d_poll(bContext *C) return 0; } +/** + * Used when we want to store a single index for any vert/edge/face. + * + * Intended for use with operators. + */ +int EDBM_elem_to_index_any(BMEditMesh *em, BMElem *ele) +{ + BMesh *bm = em->bm; + int index = BM_elem_index_get(ele); + + if (ele->head.htype == BM_VERT) { + BLI_assert(!(bm->elem_index_dirty & BM_VERT)); + } + else if (ele->head.htype == BM_EDGE) { + BLI_assert(!(bm->elem_index_dirty & BM_EDGE)); + index += bm->totvert; + } + else if (ele->head.htype == BM_FACE) { + BLI_assert(!(bm->elem_index_dirty & BM_FACE)); + index += bm->totvert + bm->totedge; + } + else { + BLI_assert(0); + } + + return index; +} + +int EDBM_elem_to_index_any_selectmode(BMEditMesh *em, BMVert *eve, BMEdge *eed, BMFace *efa) +{ + BMElem *ele = NULL; + if ((em->selectmode & SCE_SELECT_VERTEX) && eve) { + ele = (BMElem *)eve; + } + else if ((em->selectmode & SCE_SELECT_EDGE) && eed) { + ele = (BMElem *)eed; + } + else if ((em->selectmode & SCE_SELECT_FACE) && efa) { + ele = (BMElem *)efa; + } + + return ele ? EDBM_elem_to_index_any(em, ele) : -1; +} + + +BMElem *EDBM_elem_from_index_any(BMEditMesh *em, int index) +{ + BMesh *bm = em->bm; + + if (index < bm->totvert) { + return (BMElem *)BM_vert_at_index_find_or_table(bm, index); + } + index -= bm->totvert; + if (index < bm->totedge) { + return (BMElem *)BM_edge_at_index_find_or_table(bm, index); + } + index -= bm->totedge; + if (index < bm->totface) { + return (BMElem *)BM_face_at_index_find_or_table(bm, index); + } + + return NULL; +} /* -------------------------------------------------------------------- */ /* BMBVH functions */ diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 3b018eadb2d..05c339b8eaf 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -36,6 +36,7 @@ struct BMEditMesh; struct BMOperator; +struct BMElem; struct EnumPropertyItem; struct bContext; struct wmKeyConfig; @@ -74,6 +75,11 @@ void EDBM_stats_update(struct BMEditMesh *em); int EDBM_view3d_poll(struct bContext *C); +int EDBM_elem_to_index_any(struct BMEditMesh *em, struct BMElem *ele); +int EDBM_elem_to_index_any_selectmode( + struct BMEditMesh *em, + struct BMVert *eve, struct BMEdge *eed, struct BMFace *efa); +struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, int index); /* *** editmesh_add.c *** */ void MESH_OT_primitive_plane_add(struct wmOperatorType *ot); -- cgit v1.2.3