diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-03-20 20:03:34 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-03-20 20:03:34 +0400 |
commit | f8611bac8f805974d71501b323ec4a8adf9405d0 (patch) | |
tree | 6356141f42e0aef1a58495c8a65c70455ceceeb3 /source/blender/editors/mesh | |
parent | 447de0a6c4b9be8d5ca37d4827f2e3b703657d08 (diff) |
- add knife project to toolbar.
- when running knife project, disable vertex selection since it may select areas between the newly cut regions.
add EDBM_selectmode_disable() function since loopcut does this too.
- (optimization) avoid looping over all geometry when flushing and no selection exists.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife_project.c | 8 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_loopcut.c | 12 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 96 |
3 files changed, 86 insertions, 30 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index c581ce5a2e8..0903dd54208 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -51,6 +51,7 @@ #include "WM_types.h" +#include "ED_mesh.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -137,6 +138,12 @@ static int knifeproject_exec(bContext *C, wmOperator *op) /* select only tagged faces */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + + /* note essential, but switch out of vertex mode since the + * selected regions wont be nicely isolated after flushing. + * note: call after de-select to avoid selection flushing */ + EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE); + BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG); BM_mesh_select_mode_flush(em->bm); @@ -165,4 +172,3 @@ void MESH_OT_knife_project(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; } - diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 89bfc315094..ee1c274b154 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -300,17 +300,11 @@ static void ringsel_finish(bContext *C, wmOperator *op) EDBM_update_generic(em, false, true); /* force edge slide to edge select mode in in face select mode */ - if (em->selectmode & SCE_SELECT_FACE) { - if (em->selectmode == SCE_SELECT_FACE) - em->selectmode = SCE_SELECT_EDGE; - else - em->selectmode &= ~SCE_SELECT_FACE; - CTX_data_tool_settings(C)->selectmode = em->selectmode; - EDBM_selectmode_set(em); - - WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C)); + if (EDBM_selectmode_disable(lcd->vc.scene, em, SCE_SELECT_FACE, SCE_SELECT_EDGE)) { + /* pass, the change will flush selection */ } else { + /* else flush explicitly */ EDBM_selectmode_flush(lcd->em); } } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 449ab45da69..947ee240e0d 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1946,38 +1946,57 @@ void EDBM_selectmode_set(BMEditMesh *em) edbm_strip_selections(em); /* strip BMEditSelections from em->selected that are not relevant to new mode */ + if (em->bm->totvertsel == 0 && + em->bm->totedgesel == 0 && + em->bm->totfacesel == 0) + { + return; + } + if (em->selectmode & SCE_SELECT_VERTEX) { - EDBM_select_flush(em); + if (em->bm->totvertsel) { + EDBM_select_flush(em); + } } else if (em->selectmode & SCE_SELECT_EDGE) { /* deselect vertices, and select again based on edge select */ - eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for (; eve; eve = BM_iter_step(&iter)) BM_vert_select_set(em->bm, eve, false); - - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter)) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - BM_edge_select_set(em->bm, eed, true); + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_vert_select_set(em->bm, eve, false); + } + + if (em->bm->totedgesel) { + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + BM_edge_select_set(em->bm, eed, true); + } } + + /* selects faces based on edge status */ + EDBM_selectmode_flush(em); } - - /* selects faces based on edge status */ - EDBM_selectmode_flush(em); } else if (em->selectmode & SCE_SELECT_FACE) { /* deselect eges, and select again based on face select */ - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter)) BM_edge_select_set(em->bm, eed, false); - - efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter)) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - BM_face_select_set(em->bm, efa, true); + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_edge_select_set(em->bm, eed, false); + } + + if (em->bm->totfacesel) { + efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); + for (; efa; efa = BM_iter_step(&iter)) { + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_face_select_set(em->bm, efa, true); + } } } } } +/** + * Flush the selection up: + * - vert -> edge + * - edge -> face + */ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const short selectmode_new) { BMEdge *eed; @@ -1988,7 +2007,10 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s /* have to find out what the selectionmode was previously */ if (selectmode_old == SCE_SELECT_VERTEX) { - if (selectmode_new == SCE_SELECT_EDGE) { + if (em->bm->totvertsel == 0) { + /* pass */ + } + else if (selectmode_new == SCE_SELECT_EDGE) { /* select all edges associated with every selected vert */ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT)); @@ -2014,7 +2036,10 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s } } else if (selectmode_old == SCE_SELECT_EDGE) { - if (selectmode_new == SCE_SELECT_FACE) { + if (em->bm->totedgesel == 0) { + /* pass */ + } + else if (selectmode_new == SCE_SELECT_FACE) { /* select all faces associated with every selected edge */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT)); @@ -2125,6 +2150,37 @@ bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new, return ret; } +/** + * Use to disable a selectmode if its enabled, Using another mode as a fallback + * if the disabled mode is the only mode set. + * + * \return true if the mode is changed. + */ +bool EDBM_selectmode_disable(Scene *scene, BMEditMesh *em, + const short selectmode_disable, + const short selectmode_fallback) +{ + /* note essential, but switch out of vertex mode since the + * selected regions wont be nicely isolated after flushing */ + if (em->selectmode & selectmode_disable) { + if (em->selectmode == selectmode_disable) { + em->selectmode = selectmode_fallback; + } + else { + em->selectmode &= ~selectmode_disable; + } + scene->toolsettings->selectmode = em->selectmode; + EDBM_selectmode_set(em); + + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, scene); + + return true; + } + else { + return false; + } +} + void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select) { BMIter iter; |