diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-09-15 09:40:50 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-09-26 17:06:20 +0400 |
commit | 2f4e70702c5bd42845f6f7353cf6c8c0acc0bea0 (patch) | |
tree | e0b7783e9f66f92550d75b3c84ca0473ff560809 /source/blender/editors | |
parent | a5159b5fba951197e3571fb06f62809409fb4306 (diff) |
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.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 92 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 1 |
3 files changed, 94 insertions, 0 deletions
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); |