forked from bartvdbraak/blender
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.
This commit is contained in:
parent
590dbb87e7
commit
add5dd3797
@ -1736,18 +1736,9 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
|
||||
props.value = "(True, False, False)"
|
||||
props.data_path = "tool_settings.mesh_select_mode"
|
||||
|
||||
props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
|
||||
props.value = "(False, True, False)"
|
||||
props.data_path = "tool_settings.mesh_select_mode"
|
||||
|
||||
props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
|
||||
props.value = "(False, False, True)"
|
||||
props.data_path = "tool_settings.mesh_select_mode"
|
||||
layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
|
||||
layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
|
||||
layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_extrude(Menu):
|
||||
|
@ -153,6 +153,11 @@ int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
|
||||
void EDBM_selectmode_set(struct BMEditMesh *em);
|
||||
void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new);
|
||||
|
||||
/* user access this */
|
||||
int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
|
||||
const int action, const int use_extend, const int use_expand);
|
||||
|
||||
|
||||
void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
|
||||
|
||||
void EDBM_select_toggle_all(struct BMEditMesh *em);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
|
||||
return (string);
|
||||
}
|
||||
|
||||
|
||||
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = NULL;
|
||||
const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
|
||||
PointerRNA props_ptr;
|
||||
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
em = BMEdit_FromObject(obedit);
|
||||
}
|
||||
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
|
||||
|
||||
switch (event) {
|
||||
@ -336,47 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
|
||||
break;
|
||||
|
||||
case B_SEL_VERT:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0)
|
||||
em->selectmode = SCE_SELECT_VERTEX;
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Vertex");
|
||||
}
|
||||
break;
|
||||
case B_SEL_EDGE:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0) {
|
||||
if (ctrl) {
|
||||
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);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Edge");
|
||||
}
|
||||
break;
|
||||
case B_SEL_FACE:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0) {
|
||||
if (ctrl) {
|
||||
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);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Face");
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user