Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-03-07 03:10:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-03-07 03:39:31 +0400
commit276ef3b3b5192aad5c3e5e02c69246818f89033b (patch)
treee996807504d949a58b0f4d464b8017f294d124f3 /source/blender
parenta7a7a032a6b6eb63a5d3798b1bd893b9cc32cb38 (diff)
Editmesh: Toggle between all edge-loop boundaries when selecting
Now Alt+RMB,RMB will select all connected boundaries. There are times when you just want to select an entire boundary loop ignoring face topology, previously there was no way to do this.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/mesh/editmesh_select.c110
1 files changed, 95 insertions, 15 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 0c7810ab52a..41546e7bf07 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1007,6 +1007,34 @@ void MESH_OT_select_mode(wmOperatorType *ot)
/* **************** LOOP SELECTS *************** */
+static void walker_select_count(BMEditMesh *em, int walkercode, void *start, const bool select, const bool select_mix,
+ int *r_totsel, int *r_totunsel)
+{
+ BMesh *bm = em->bm;
+ BMElem *ele;
+ BMWalker walker;
+ int tot[2] = {0, 0};
+
+ BMW_init(&walker, bm, walkercode,
+ BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
+ BMW_FLAG_TEST_HIDDEN,
+ BMW_NIL_LAY);
+
+ for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) {
+ tot[(BM_elem_flag_test_bool(ele, BM_ELEM_SELECT) != select)] += 1;
+
+ if (!select_mix && tot[0] && tot[1]) {
+ tot[0] = tot[1] = -1;
+ break;
+ }
+ }
+
+ *r_totsel = tot[0];
+ *r_totunsel = tot[1];
+
+ BMW_end(&walker);
+}
+
static void walker_select(BMEditMesh *em, int walkercode, void *start, const bool select)
{
BMesh *bm = em->bm;
@@ -1101,12 +1129,68 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
/* ***************** loop select (non modal) ************** */
+static void mouse_mesh_loop_face(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
+{
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ walker_select(em, BMW_FACELOOP, eed, select);
+}
+
+static void mouse_mesh_loop_edge_ring(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
+{
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ walker_select(em, BMW_EDGERING, eed, select);
+}
+
+static void mouse_mesh_loop_edge(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear, bool select_cycle)
+{
+ bool edge_boundary = false;
+
+ /* cycle between BMW_LOOP / BMW_EDGEBOUNDARY */
+ if (select_cycle && BM_edge_is_boundary(eed)) {
+ int tot[2];
+
+ /* if the loops selected toggle the boundaries */
+ walker_select_count(em, BMW_LOOP, eed, select, false,
+ &tot[0], &tot[1]);
+ if (tot[select] == 0) {
+ edge_boundary = true;
+
+ /* if the boundaries selected, toggle back to the loop */
+ walker_select_count(em, BMW_EDGEBOUNDARY, eed, select, false,
+ &tot[0], &tot[1]);
+ if (tot[select] == 0) {
+ edge_boundary = false;
+ }
+ }
+ }
+
+ if (select_clear) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ if (edge_boundary) {
+ walker_select(em, BMW_EDGEBOUNDARY, eed, select);
+ }
+ else {
+ walker_select(em, BMW_LOOP, eed, select);
+ }
+}
+
+
static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
{
ViewContext vc;
BMEditMesh *em;
BMEdge *eed;
bool select = true;
+ bool select_clear = false;
+ bool select_cycle = true;
float dist = 50.0f;
float mvalf[2];
@@ -1124,7 +1208,7 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
}
if (extend == false && deselect == false && toggle == false) {
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ select_clear = true;
}
if (extend) {
@@ -1133,28 +1217,24 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
else if (deselect) {
select = false;
}
- else if (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0) {
+ else if (select_clear || (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0)) {
select = true;
}
else if (toggle) {
select = false;
+ select_cycle = false;
}
if (em->selectmode & SCE_SELECT_FACE) {
- walker_select(em, BMW_FACELOOP, eed, select);
- }
- else if (em->selectmode & SCE_SELECT_EDGE) {
- if (ring)
- walker_select(em, BMW_EDGERING, eed, select);
- else
- walker_select(em, BMW_LOOP, eed, select);
+ mouse_mesh_loop_face(em, eed, select, select_clear);
}
- else if (em->selectmode & SCE_SELECT_VERTEX) {
- if (ring)
- walker_select(em, BMW_EDGERING, eed, select);
-
- else
- walker_select(em, BMW_LOOP, eed, select);
+ else {
+ if (ring) {
+ mouse_mesh_loop_edge_ring(em, eed, select, select_clear);
+ }
+ else {
+ mouse_mesh_loop_edge(em, eed, select, select_clear, select_cycle);
+ }
}
EDBM_selectmode_flush(em);