diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 4 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 77 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 33 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_data.c | 24 |
4 files changed, 118 insertions, 20 deletions
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 3929969c5c4..f318e17ba32 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -82,6 +82,8 @@ void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const int ax const bool use_self, const bool use_select, const bool use_toplogy); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); +struct BMEdge *EDBM_verts_mirror_get_edge(struct BMEditMesh *em, struct BMEdge *e); +struct BMFace *EDBM_verts_mirror_get_face(struct BMEditMesh *em, struct BMFace *f); void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v); void EDBM_verts_mirror_cache_end(struct BMEditMesh *em); @@ -281,6 +283,8 @@ bool ED_mesh_color_remove_active(struct Mesh *me); bool ED_mesh_color_remove_named(struct Mesh *me, const char *name); void ED_mesh_report_mirror(struct wmOperator *op, int totmirr, int totfail); +void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, + char selectmode); /* mesh backup */ typedef struct BMBackup { diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 0e71408edcc..e9694b8a8f3 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -78,7 +78,7 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend, int *r_totmirr, int *r_totfail) { Mesh *me = (Mesh *)em->ob->data; - BMVert *v1, *v2; + BMesh *bm = em->bm; BMIter iter; int totmirr = 0; int totfail = 0; @@ -86,12 +86,23 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend, *r_totmirr = *r_totfail = 0; - BM_ITER_MESH (v1, &iter, em->bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(v1, BM_ELEM_SELECT) || BM_elem_flag_test(v1, BM_ELEM_HIDDEN)) { - BM_elem_flag_disable(v1, BM_ELEM_TAG); + /* select -> tag */ + if (bm->selectmode & SCE_SELECT_VERTEX) { + BMVert *v; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT)); } - else { - BM_elem_flag_enable(v1, BM_ELEM_TAG); + } + else if (em->selectmode & SCE_SELECT_EDGE) { + BMEdge *e; + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT)); + } + } + else { + BMFace *f; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BM_elem_flag_set(f, BM_ELEM_TAG, BM_elem_flag_test(f, BM_ELEM_SELECT)); } } @@ -100,19 +111,50 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend, if (!extend) EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BM_ITER_MESH (v1, &iter, em->bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(v1, BM_ELEM_TAG) || BM_elem_flag_test(v1, BM_ELEM_HIDDEN)) - continue; - v2 = EDBM_verts_mirror_get(em, v1); - if (v2) { - if (!BM_elem_flag_test(v2, BM_ELEM_HIDDEN)) { - BM_vert_select_set(em->bm, v2, true); - totmirr++; + if (bm->selectmode & SCE_SELECT_VERTEX) { + BMVert *v; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_TAG)) { + BMVert *v_mirr = EDBM_verts_mirror_get(em, v); + if (v_mirr && !BM_elem_flag_test(v_mirr, BM_ELEM_HIDDEN)) { + BM_vert_select_set(bm, v_mirr, true); + totmirr++; + } + else { + totfail++; + } } } - else { - totfail++; + } + else if (em->selectmode & SCE_SELECT_EDGE) { + BMEdge *e; + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN) && BM_elem_flag_test(e, BM_ELEM_TAG)) { + BMEdge *e_mirr = EDBM_verts_mirror_get_edge(em, e); + if (e_mirr && !BM_elem_flag_test(e_mirr, BM_ELEM_HIDDEN)) { + BM_edge_select_set(bm, e_mirr, true); + totmirr++; + } + else { + totfail++; + } + } + } + } + else { + BMFace *f; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN) && BM_elem_flag_test(f, BM_ELEM_TAG)) { + BMFace *f_mirr = EDBM_verts_mirror_get_face(em, f); + if (f_mirr && !BM_elem_flag_test(f_mirr, BM_ELEM_HIDDEN)) { + BM_face_select_set(bm, f_mirr, true); + totmirr++; + } + else { + totfail++; + } + } } } @@ -2215,13 +2257,14 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op) if (em->bm->totvert && em->bm->totvertsel) { int totmirr, totfail; + EDBM_select_mirrored(em, extend, &totmirr, &totfail); if (totmirr) { EDBM_selectmode_flush(em); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); } - ED_mesh_report_mirror(op, totmirr, totfail); + ED_mesh_report_mirror_ex(op, totmirr, totfail, em->bm->selectmode); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 834db3f9ad1..effbe3a619d 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -35,6 +35,7 @@ #include "DNA_object_types.h" #include "BLI_math.h" +#include "BLI_array.h" #include "BKE_DerivedMesh.h" #include "BKE_context.h" @@ -1270,6 +1271,38 @@ BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) return NULL; } +BMEdge *EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e) +{ + BMVert *v1_mirr = EDBM_verts_mirror_get(em, e->v1); + if (v1_mirr) { + BMVert *v2_mirr = EDBM_verts_mirror_get(em, e->v2); + if (v2_mirr) { + return BM_edge_exists(v1_mirr, v2_mirr); + } + } + + return NULL; +} + +BMFace *EDBM_verts_mirror_get_face(BMEditMesh *em, BMFace *f) +{ + BMFace *f_mirr = NULL; + BMVert **v_mirr_arr = BLI_array_alloca(v_mirr_arr, f->len); + + BMLoop *l_iter, *l_first; + unsigned int i = 0; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if ((v_mirr_arr[i++] = EDBM_verts_mirror_get(em, l_iter->v)) == NULL) { + return NULL; + } + } while ((l_iter = l_iter->next) != l_first); + + BM_face_exists(v_mirr_arr, f->len, &f_mirr); + return f_mirr; +} + void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v) { int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index d0869a30cbf..21fe51c03ef 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -1244,12 +1244,30 @@ void ED_mesh_calc_tessface(Mesh *mesh) } } -void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail) +void ED_mesh_report_mirror_ex(wmOperator *op, int totmirr, int totfail, + char selectmode) { + const char *elem_type; + + if (selectmode & SCE_SELECT_VERTEX) { + elem_type = "vertices"; + } + else if (selectmode & SCE_SELECT_EDGE) { + elem_type = "edges"; + } + else { + elem_type = "faces"; + } + if (totfail) { - BKE_reportf(op->reports, RPT_WARNING, "%d vertices mirrored, %d failed", totmirr, totfail); + BKE_reportf(op->reports, RPT_WARNING, "%d %s mirrored, %d failed", totmirr, elem_type, totfail); } else { - BKE_reportf(op->reports, RPT_INFO, "%d vertices mirrored", totmirr); + BKE_reportf(op->reports, RPT_INFO, "%d %s mirrored", totmirr, elem_type); } } + +void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail) +{ + ED_mesh_report_mirror_ex(op, totmirr, totfail, SCE_SELECT_VERTEX); +} |