Commit: a081a4817cf43ec20fc7ba26b2b92fad2d976c8e
Author: Campbell Barton
Date:   Thu Nov 6 15:17:16 2014 +0100
Branches: master
https://developer.blender.org/rBa081a4817cf43ec20fc7ba26b2b92fad2d976c8e

Editmesh: select more/less can now step over adjacent faces

This keeps a square shaped selection when using grid topology.

===================================================================

M       source/blender/bmesh/intern/bmesh_opdefines.c
M       source/blender/bmesh/operators/bmo_utils.c
M       source/blender/editors/include/ED_mesh.h
M       source/blender/editors/mesh/editmesh_select.c
M       source/blender/editors/mesh/editmesh_utils.c
M       source/blender/editors/uvedit/uvedit_ops.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c 
b/source/blender/bmesh/intern/bmesh_opdefines.c
index aba805c..1143588 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -173,8 +173,9 @@ static BMOpDefine bmo_region_extend_def = {
        "region_extend",
        /* slots_in */
        {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     
/* input geometry */
-        {"use_constrict", BMO_OP_SLOT_BOOL},   /* find boundary inside the 
regions, not outside. */
+        {"use_contract", BMO_OP_SLOT_BOOL},    /* find boundary inside the 
regions, not outside. */
         {"use_faces", BMO_OP_SLOT_BOOL},       /* extend from faces instead of 
edges */
+        {"use_face_step", BMO_OP_SLOT_BOOL},   /* step over connected faces */
         {{'\0'}},
        },
        /* slots_out */
diff --git a/source/blender/bmesh/operators/bmo_utils.c 
b/source/blender/bmesh/operators/bmo_utils.c
index a06d40c..e7b65a1 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -177,42 +177,94 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
 #define SEL_FLAG       1
 #define SEL_ORIG       2
 
-static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool 
use_faces)
+static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, 
const bool value)
+{
+       BMLoop *l_iter;
+       BMLoop *l_first;
+
+       BMO_elem_flag_set(bm, f, oflag, value);
+       l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+       do {
+               BMO_elem_flag_set(bm, l_iter->e, oflag, value);
+               BMO_elem_flag_set(bm, l_iter->v, oflag, value);
+       } while ((l_iter = l_iter->next) != l_first);
+}
+
+
+static void bmo_region_extend_expand(
+        BMesh *bm, BMOperator *op,
+        const bool use_faces, const bool use_faces_step)
 {
-       BMVert *v;
-       BMEdge *e;
-       BMIter eiter;
        BMOIter siter;
 
        if (!use_faces) {
+               BMVert *v;
+
                BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
-                       BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-                               if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
-                                       if (!BMO_elem_flag_test(bm, e, 
SEL_ORIG))
+                       bool found = false;
+
+                       {
+                               BMIter eiter;
+                               BMEdge *e;
+
+                               BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+                                       if (!BMO_elem_flag_test(bm, e, 
SEL_ORIG)) {
+                                               found = true;
                                                break;
+                                       }
+                               }
                        }
 
-                       if (e) {
-                               BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-                                       if (!BM_elem_flag_test(e, 
BM_ELEM_HIDDEN)) {
-                                               BMO_elem_flag_enable(bm, e, 
SEL_FLAG);
-                                               BMO_elem_flag_enable(bm, 
BM_edge_other_vert(e, v), SEL_FLAG);
+                       if (found) {
+                               if (!use_faces_step) {
+                                       BMIter eiter;
+                                       BMEdge *e;
+
+                                       BM_ITER_ELEM (e, &eiter, v, 
BM_EDGES_OF_VERT) {
+                                               if (!BMO_elem_flag_test(bm, e, 
SEL_FLAG)) {
+                                                       
BMO_elem_flag_enable(bm, e, SEL_FLAG);
+                                                       
BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG);
+                                               }
+                                       }
+                               }
+                               else {
+                                       BMIter fiter;
+                                       BMFace *f;
+
+                                       BM_ITER_ELEM (f, &fiter, v, 
BM_FACES_OF_VERT) {
+                                               if (!BMO_elem_flag_test(bm, f, 
SEL_FLAG)) {
+                                                       
bmo_face_flag_set_flush(bm, f, SEL_FLAG, true);
+                                               }
                                        }
                                }
                        }
                }
        }
        else {
-               BMIter liter, fiter;
-               BMFace *f, *f2;
-               BMLoop *l;
+               BMFace *f;
 
                BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
+                       BMIter liter;
+                       BMLoop *l;
+
                        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
-                               BM_ITER_ELEM (f2, &fiter, l->e, 
BM_FACES_OF_EDGE) {
-                                       if (!BM_elem_flag_test(f2, 
BM_ELEM_HIDDEN)) {
-                                               if (!BMO_elem_flag_test(bm, f2, 
SEL_ORIG)) {
-                                                       
BMO_elem_flag_enable(bm, f2, SEL_FLAG);
+                               if (!use_faces_step) {
+                                       BMIter fiter;
+                                       BMFace *f_other;
+
+                                       BM_ITER_ELEM (f_other, &fiter, l->e, 
BM_FACES_OF_EDGE) {
+                                               if (!BMO_elem_flag_test(bm, 
f_other, SEL_ORIG | SEL_FLAG)) {
+                                                       
BMO_elem_flag_enable(bm, f_other, SEL_FLAG);
+                                               }
+                                       }
+                               }
+                               else {
+                                       BMIter fiter;
+                                       BMFace *f_other;
+
+                                       BM_ITER_ELEM (f_other, &fiter, l->v, 
BM_FACES_OF_VERT) {
+                                               if (!BMO_elem_flag_test(bm, 
f_other, SEL_ORIG | SEL_FLAG)) {
+                                                       
BMO_elem_flag_enable(bm, f_other, SEL_FLAG);
                                                }
                                        }
                                }
@@ -221,43 +273,79 @@ static void bmo_region_extend_extend(BMesh *bm, 
BMOperator *op, const bool use_f
        }
 }
 
-static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool 
use_faces)
+static void bmo_region_extend_contract(
+        BMesh *bm, BMOperator *op,
+        const bool use_faces, const bool use_faces_step)
 {
-       BMVert *v;
-       BMEdge *e;
-       BMIter eiter;
        BMOIter siter;
 
        if (!use_faces) {
+               BMVert *v;
+
                BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
-                       BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-                               if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
-                                       if (!BMO_elem_flag_test(bm, e, 
SEL_ORIG))
+                       bool found = false;
+
+                       if (!use_faces_step) {
+                               BMIter eiter;
+                               BMEdge *e;
+
+                               BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+                                       if (!BMO_elem_flag_test(bm, e, 
SEL_ORIG)) {
+                                               found = true;
                                                break;
+                                       }
+                               }
                        }
+                       else {
+                               BMIter fiter;
+                               BMFace *f;
+
+                               BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
+                                       if (!BMO_elem_flag_test(bm, f, 
SEL_ORIG)) {
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if (found) {
+                               BMIter eiter;
+                               BMEdge *e;
 
-                       if (e) {
                                BMO_elem_flag_enable(bm, v, SEL_FLAG);
 
                                BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-                                       if (!BM_elem_flag_test(e, 
BM_ELEM_HIDDEN)) {
-                                               BMO_elem_flag_enable(bm, e, 
SEL_FLAG);
-                                       }
+                                       BMO_elem_flag_enable(bm, e, SEL_FLAG);
                                }
-
                        }
                }
        }
        else {
-               BMIter liter, fiter;
-               BMFace *f, *f2;
-               BMLoop *l;
+               BMFace *f;
 
                BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
+                       BMIter liter;
+                       BMLoop *l;
+
                        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
-                               BM_ITER_ELEM (f2, &fiter, l->e, 
BM_FACES_OF_EDGE) {
-                                       if (!BM_elem_flag_test(f2, 
BM_ELEM_HIDDEN)) {
-                                               if (!BMO_elem_flag_test(bm, f2, 
SEL_ORIG)) {
+
+                               if (!use_faces_step) {
+                                       BMIter fiter;
+                                       BMFace *f_other;
+
+                                       BM_ITER_ELEM (f_other, &fiter, l->e, 
BM_FACES_OF_EDGE) {
+                                               if (!BMO_elem_flag_test(bm, 
f_other, SEL_ORIG)) {
+                                                       
BMO_elem_flag_enable(bm, f, SEL_FLAG);
+                                                       break;
+                                               }
+                                       }
+                               }
+                               else {
+                                       BMIter fiter;
+                                       BMFace *f_other;
+
+                                       BM_ITER_ELEM (f_other, &fiter, l->v, 
BM_FACES_OF_VERT) {
+                                               if (!BMO_elem_flag_test(bm, 
f_other, SEL_ORIG)) {
                                                        
BMO_elem_flag_enable(bm, f, SEL_FLAG);
                                                        break;
                                                }
@@ -271,14 +359,17 @@ static void bmo_region_extend_constrict(BMesh *bm, 
BMOperator *op, const bool us
 void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
 {
        const bool use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
-       const bool constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
+       const bool use_face_step = BMO_slot_bool_get(op->slots_in, 
"use_face_step");
+       const bool constrict = BMO_slot_bool_get(op->slots_in, "use_contract");
 
        BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, 
SEL_ORIG);
 
-       if (constrict)
-               bmo_region_extend_constrict(bm, op, use_faces);
-       else
-               bmo_region_extend_extend(bm, op, use_faces);
+       if (constrict) {
+               bmo_region_extend_contract(bm, op, use_faces, use_face_step);
+       }
+       else {
+               bmo_region_extend_expand(bm, op, use_faces, use_face_step);
+       }
 
        BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", 
BM_ALL_NOLOOP, SEL_FLAG);
 }
diff --git a/source/blender/editors/include/ED_mesh.h 
b/source/blender/editors/include/ED_mesh.h
index c9faad6..2b4fa1b 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -101,8 +101,8 @@ struct DerivedMesh *EDBM_mesh_deform_dm_get(struct 
BMEditMesh *em);
  * verts select/deselect edges and faces, if in edge select mode,
  * edges select/deselect faces and vertices, and in face select mode faces 
select/deselect
  * edges and vertices.*/
-void EDBM_select_more(struct BMEditMesh *em);
-void EDBM_select_less(struct BMEditMesh *em);
+void EDBM_select_more(struct BMEditMesh *em, const bool use_face_step);
+void EDBM_select_less(struct BMEditMesh *em, const bool use_face_step);
 
 void EDBM_selectmode_flush_ex(struct BMEditMesh *em, const short selectmode);
 void EDBM_selectmode_flush(struct BMEditMesh *em);
diff --git a/source/blender/editors/mesh/editmesh_select.c 
b/source/blender/editors/mesh/editmesh_select.c
index 473da4c..5f3f7cb 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2473,12 +2473,13 @@ void MESH_OT_select_mirror(wmOperatorType *ot)
 
 /* ******************** **************** */
 
-static int edbm_select_more_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_more_exec(bContext *C, wmOperator *op)
 {
        Object *obedit = CTX_data_edit_object(C);
        BMEditMesh *em = BKE_editmesh_from_object(obedit);
+       const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
 
-       EDBM_select_more(em);
+       EDBM_select_more(em, use_face_step);
 
        WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
        return OPERATOR_FINISHED;
@@ -2497,14 +2498,17 @@ void MESH_OT_select_more(wmOperatorType *ot)
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", 
"Connected faces (instead of edges)");
 }
 
-static int edbm_select_less_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_less_exec(bContext *C, wmOperator *op)
 {
        Object *obedit = CTX_data_edit_object(C);
        BMEditMesh *em = BKE_editmesh_from_object(obedit);
+       const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
 
-       EDBM_select_less(em);
+       EDBM_select_less(em, use_face_step);
 
        WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
        return OPERATOR_FINISHED;
@@ -2523,6 +2527,8 @@ void MESH_OT_select_less(wmOperatorType *ot)
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", 
"Connected faces (instead of edges)");
 }
 
 /**
diff --git a/source/blender/editors/mesh/editmesh_utils.c 
b/source/blender/editors/mesh/editmesh_utils.c
index c7d1d88..3075039 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to