diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-11-13 09:44:49 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-11-13 09:44:49 +0400 |
commit | add5dd3797bb09be76e3a1ff04a9f641d1ef23e9 (patch) | |
tree | 5afdcdef7ba7c09eddac5f7ac385cc8f7af2091d /source/blender/editors/mesh | |
parent | 590dbb87e773a69d302548e20b73fbb1ea96aed3 (diff) |
add an operator for mesh mode switching,
this lets python menu for mode setting do mixed selection and extending the selection - just like the buttons in the header.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 165 | ||||
-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, 167 insertions, 0 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 2acbbb6e006..5be03c50240 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -56,6 +56,7 @@ #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_util.h" #include "ED_uvedit.h" #include "ED_object.h" #include "ED_view3d.h" @@ -68,6 +69,7 @@ #include "mesh_intern.h" +#include "UI_resources.h" /* ****************************** MIRROR **************** */ @@ -915,6 +917,74 @@ void MESH_OT_select_similar(wmOperatorType *ot) RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0); } + +/* **************** Mode Select *************** */ + +static int edbm_select_mode_exec(bContext *C, wmOperator *op) +{ + const int type = RNA_enum_get(op->ptr, "type"); + const int action = RNA_enum_get(op->ptr, "action"); + const int use_extend = RNA_boolean_get(op->ptr, "use_extend"); + const int use_expand = RNA_boolean_get(op->ptr, "use_expand"); + + if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) { + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + // RNA_enum_set(op->ptr, "type"); /* type must be set already */ + RNA_boolean_set(op->ptr, "use_extend", event->shift); + RNA_boolean_set(op->ptr, "use_expand", event->ctrl); + return edbm_select_mode_exec(C, op); +} + +void MESH_OT_select_mode(wmOperatorType *ot) +{ + PropertyRNA *prop; + + static EnumPropertyItem elem_items[] = { + {SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""}, + {SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""}, + {SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + static EnumPropertyItem actions_items[] = { + {0, "DISABLE", 0, "Disable", "Disable selected markers"}, + {1, "ENABLE", 0, "Enable", "Enable selected markers"}, + {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Select Mode"; + ot->idname = "MESH_OT_select_mode"; + ot->description = "Change selection mode"; + + /* api callbacks */ + ot->invoke = edbm_select_mode_invoke; + ot->exec = edbm_select_mode_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute"); +} + /* ***************************************************** */ /* **************** LOOP SELECTS *************** */ @@ -1926,6 +1996,101 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s } } +/* user facing function, does notification and undo push */ +int EDBM_selectmode_toggle(bContext *C, const short selectmode_new, + const int action, const int use_extend, const int use_expand) +{ + ToolSettings *ts = CTX_data_tool_settings(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = NULL; + int ret = FALSE; + + if (obedit && obedit->type == OB_MESH) { + em = BMEdit_FromObject(obedit); + } + + if (em == NULL) { + return ret; + } + + switch (action) { + case -1: + /* already set */ + break; + case 0: /* disable */ + /* check we have something to do */ + if ((em->selectmode & selectmode_new) == 0) { + return FALSE; + } + em->selectmode &= ~selectmode_new; + break; + case 1: /* enable */ + /* check we have something to do */ + if ((em->selectmode & selectmode_new) != 0) { + return FALSE; + } + em->selectmode |= selectmode_new; + break; + case 2: /* toggle */ + /* can't disable this flag if its the only one set */ + if (em->selectmode == selectmode_new) { + return FALSE; + } + em->selectmode ^= selectmode_new; + break; + default: + BLI_assert(0); + } + + switch (selectmode_new) { + case SCE_SELECT_VERTEX: + if (use_extend == 0 || em->selectmode == 0) + em->selectmode = SCE_SELECT_VERTEX; + ts->selectmode = em->selectmode; + EDBM_selectmode_set(em); + ret = TRUE; + break; + case SCE_SELECT_EDGE: + if (use_extend == 0 || em->selectmode == 0) { + if (use_expand) { + const short selmode_max = highest_order_bit_s(ts->selectmode); + if (selmode_max == SCE_SELECT_VERTEX) { + EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE); + } + } + em->selectmode = SCE_SELECT_EDGE; + } + ts->selectmode = em->selectmode; + EDBM_selectmode_set(em); + ret = TRUE; + break; + case SCE_SELECT_FACE: + if (use_extend == 0 || em->selectmode == 0) { + if (use_expand) { + const short selmode_max = highest_order_bit_s(ts->selectmode); + if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) { + EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE); + } + } + + em->selectmode = SCE_SELECT_FACE; + } + ts->selectmode = em->selectmode; + EDBM_selectmode_set(em); + ret = TRUE; + break; + default: + BLI_assert(0); + break; + } + + if (ret == TRUE) { + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); + } + + return ret; +} void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select) { diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 82b785e5785..8e63bd74ece 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot); void MESH_OT_edges_select_sharp(struct wmOperatorType *ot); void MESH_OT_select_shortest_path(struct wmOperatorType *ot); void MESH_OT_select_similar(struct wmOperatorType *ot); +void MESH_OT_select_mode(struct wmOperatorType *ot); void MESH_OT_select_random(struct wmOperatorType *ot); void MESH_OT_loop_multi_select(struct wmOperatorType *ot); void MESH_OT_mark_seam(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index d319fdcca26..91fb6e0c487 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -129,6 +129,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_edge_face_add); WM_operatortype_append(MESH_OT_select_shortest_path); WM_operatortype_append(MESH_OT_select_similar); + WM_operatortype_append(MESH_OT_select_mode); WM_operatortype_append(MESH_OT_loop_multi_select); WM_operatortype_append(MESH_OT_mark_seam); WM_operatortype_append(MESH_OT_mark_sharp); |