diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-11-06 17:17:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-11-06 17:35:46 +0300 |
commit | a081a4817cf43ec20fc7ba26b2b92fad2d976c8e (patch) | |
tree | 440dc7241ba7eebff4eb11b8119575dd340044d8 | |
parent | d1eb762b579b531a78f117a1c123465b8647296d (diff) |
Editmesh: select more/less can now step over adjacent faces
This keeps a square shaped selection when using grid topology.
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_utils.c | 175 | ||||
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 4 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 14 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 16 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 4 |
6 files changed, 157 insertions, 59 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index aba805cccd7..114358884b7 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 a06d40c8c0f..e7b65a10790 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 c9faad62d6e..2b4fa1b9196 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 473da4c9756..5f3f7cb242c 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 c7d1d883537..30750393f39 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -432,14 +432,14 @@ void EDBM_select_flush(BMEditMesh *em) BM_mesh_select_flush(em->bm); } -void EDBM_select_more(BMEditMesh *em) +void EDBM_select_more(BMEditMesh *em, const bool use_face_step) { BMOperator bmop; - int use_faces = em->selectmode == SCE_SELECT_FACE; + const bool use_faces = (em->selectmode == SCE_SELECT_FACE); BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS, - "region_extend geom=%hvef use_constrict=%b use_faces=%b", - BM_ELEM_SELECT, false, use_faces); + "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b", + BM_ELEM_SELECT, false, use_faces, use_face_step); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false); @@ -448,14 +448,14 @@ void EDBM_select_more(BMEditMesh *em) EDBM_selectmode_flush(em); } -void EDBM_select_less(BMEditMesh *em) +void EDBM_select_less(BMEditMesh *em, const bool use_face_step) { BMOperator bmop; - int use_faces = em->selectmode == SCE_SELECT_FACE; + const bool use_faces = (em->selectmode == SCE_SELECT_FACE); BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS, - "region_extend geom=%hvef use_constrict=%b use_faces=%b", - BM_ELEM_SELECT, true, use_faces); + "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b", + BM_ELEM_SELECT, true, use_faces, use_face_step); BMO_op_exec(em->bm, &bmop); /* don't flush selection in edge/vertex mode */ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index bcddd6b4156..b58944e4003 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1309,10 +1309,10 @@ static int uv_select_more_less(bContext *C, const bool select) if (ts->uv_flag & UV_SYNC_SELECTION) { if (select) { - EDBM_select_more(em); + EDBM_select_more(em, true); } else { - EDBM_select_less(em); + EDBM_select_less(em, true); } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); |