From 2f4e70702c5bd42845f6f7353cf6c8c0acc0bea0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Sep 2014 15:40:50 +1000 Subject: BMesh: select similar regions Select operator that takes multiple selected face regions and selects any number of matching regions (when they have distinguishing features to isolate them). UI access next. --- source/blender/editors/mesh/editmesh_select.c | 92 +++++++++++++++++++++++++++ source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 1 + 3 files changed, 94 insertions(+) (limited to 'source/blender/editors/mesh') diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 9cdfb43ae15..473da4c9756 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -66,6 +66,8 @@ #include "UI_resources.h" +#include "bmesh_tools.h" + #include "mesh_intern.h" /* own include */ /* use bmesh operator flags for a few operators */ @@ -929,6 +931,96 @@ void MESH_OT_select_similar(wmOperatorType *ot) } +/* -------------------------------------------------------------------- */ +/* Select Similar Regions */ + +static int edbm_select_similar_region_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + bool changed = false; + + /* group vars */ + int *groups_array; + int (*group_index)[2]; + int group_tot; + int i; + + if (bm->totfacesel < 2) { + BKE_report(op->reports, RPT_ERROR, "No face regions selected"); + return OPERATOR_CANCELLED; + } + + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__); + group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index, + NULL, NULL, + BM_ELEM_SELECT, BM_VERT); + + BM_mesh_elem_table_ensure(bm, BM_FACE); + + for (i = 0; i < group_tot; i++) { + ListBase faces_regions; + int tot; + + const int fg_sta = group_index[i][0]; + const int fg_len = group_index[i][1]; + int j; + BMFace **fg = MEM_mallocN(sizeof(*fg) * fg_len, __func__); + + + for (j = 0; j < fg_len; j++) { + fg[j] = BM_face_at_index(bm, groups_array[fg_sta + j]); + } + + tot = BM_mesh_region_match(bm, fg, fg_len, &faces_regions); + + MEM_freeN(fg); + + if (tot) { + LinkData *link; + while ((link = BLI_pophead(&faces_regions))) { + BMFace *f, **faces = link->data; + unsigned int i = 0; + while ((f = faces[i++])) { + BM_face_select_set(bm, f, true); + } + MEM_freeN(faces); + MEM_freeN(link); + + changed = true; + } + } + } + + MEM_freeN(groups_array); + + if (changed) { + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); + } + else { + BKE_report(op->reports, RPT_WARNING, "No matching face regions found"); + } + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_similar_region(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Similar Regions"; + ot->idname = "MESH_OT_select_similar_region"; + ot->description = "Select similar face regions to the current selection"; + + /* api callbacks */ + ot->exec = edbm_select_similar_region_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + /* **************** Mode Select *************** */ static int edbm_select_mode_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 76f6cb5ebb8..6ba91097ec4 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -137,6 +137,7 @@ void MESH_OT_rip_edge(struct wmOperatorType *ot); /* *** editmesh_select.c *** */ void MESH_OT_select_similar(struct wmOperatorType *ot); +void MESH_OT_select_similar_region(struct wmOperatorType *ot); void MESH_OT_select_mode(struct wmOperatorType *ot); void MESH_OT_loop_multi_select(struct wmOperatorType *ot); void MESH_OT_loop_select(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 31653efa735..5f3af733ebd 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -130,6 +130,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_edge_face_add); WM_operatortype_append(MESH_OT_shortest_path_pick); WM_operatortype_append(MESH_OT_select_similar); + WM_operatortype_append(MESH_OT_select_similar_region); WM_operatortype_append(MESH_OT_select_mode); WM_operatortype_append(MESH_OT_loop_multi_select); WM_operatortype_append(MESH_OT_mark_seam); -- cgit v1.2.3