diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-04-30 16:18:00 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-04-30 17:09:58 +0300 |
commit | 86ff61f853cac74b7901397246881ca02056dd5d (patch) | |
tree | 0cc5015303c962d3f856d1ac4c6cd6ed75792da6 /source/blender/editors/uvedit/uvedit_ops.c | |
parent | 40b66ac2a654809f518b3df91c5af2111013cb4d (diff) |
Select: Add 'deselect on nothing' to UV editor.
As with mask, when this is enabled there is now a maximum click distance
from an item to actually select it.
Part of T63995.
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_ops.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 146 |
1 files changed, 84 insertions, 62 deletions
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index d2d85437b94..e6990430f0e 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2457,8 +2457,13 @@ static bool uv_sticky_select( return false; } -static int uv_mouse_select_multi( - bContext *C, Object **objects, uint objects_len, const float co[2], bool extend, bool loop) +static int uv_mouse_select_multi(bContext *C, + Object **objects, + uint objects_len, + const float co[2], + const bool extend, + const bool deselect_all, + const bool loop) { Depsgraph *depsgraph = CTX_data_depsgraph(C); SpaceImage *sima = CTX_wm_space_image(C); @@ -2472,6 +2477,7 @@ static int uv_mouse_select_multi( UvNearestHit hit = UV_NEAREST_HIT_INIT; int i, selectmode, sticky, sync, *hitv = NULL; bool select = true; + bool found_item = false; /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ int flush = 0; int hitlen = 0; @@ -2516,79 +2522,86 @@ static int uv_mouse_select_multi( /* find nearest element */ if (loop) { /* find edge */ - if (!uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit)) { - return OPERATOR_CANCELLED; - } - - hitlen = 0; + found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit); } else if (selectmode == UV_SELECT_VERTEX) { /* find vertex */ - if (!uv_find_nearest_vert_multi(scene, ima, objects, objects_len, co, penalty_dist, &hit)) { - return OPERATOR_CANCELLED; - } + found_item = uv_find_nearest_vert_multi( + scene, ima, objects, objects_len, co, penalty_dist, &hit); + found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - /* mark 1 vertex as being hit */ - hitv = BLI_array_alloca(hitv, hit.efa->len); - hituv = BLI_array_alloca(hituv, hit.efa->len); - copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); + if (found_item) { + /* mark 1 vertex as being hit */ + hitv = BLI_array_alloca(hitv, hit.efa->len); + hituv = BLI_array_alloca(hituv, hit.efa->len); + copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); - hitv[hit.lindex] = BM_elem_index_get(hit.l->v); - hituv[hit.lindex] = hit.luv->uv; + hitv[hit.lindex] = BM_elem_index_get(hit.l->v); + hituv[hit.lindex] = hit.luv->uv; - hitlen = hit.efa->len; + hitlen = hit.efa->len; + } } else if (selectmode == UV_SELECT_EDGE) { /* find edge */ - if (!uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit)) { - return OPERATOR_CANCELLED; - } + found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit); + found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - /* mark 2 edge vertices as being hit */ - hitv = BLI_array_alloca(hitv, hit.efa->len); - hituv = BLI_array_alloca(hituv, hit.efa->len); - copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); + if (found_item) { + /* mark 2 edge vertices as being hit */ + hitv = BLI_array_alloca(hitv, hit.efa->len); + hituv = BLI_array_alloca(hituv, hit.efa->len); + copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); - hitv[hit.lindex] = BM_elem_index_get(hit.l->v); - hitv[(hit.lindex + 1) % hit.efa->len] = BM_elem_index_get(hit.l->next->v); - hituv[hit.lindex] = hit.luv->uv; - hituv[(hit.lindex + 1) % hit.efa->len] = hit.luv_next->uv; + hitv[hit.lindex] = BM_elem_index_get(hit.l->v); + hitv[(hit.lindex + 1) % hit.efa->len] = BM_elem_index_get(hit.l->next->v); + hituv[hit.lindex] = hit.luv->uv; + hituv[(hit.lindex + 1) % hit.efa->len] = hit.luv_next->uv; - hitlen = hit.efa->len; + hitlen = hit.efa->len; + } } else if (selectmode == UV_SELECT_FACE) { /* find face */ - if (!uv_find_nearest_face_multi(scene, ima, objects, objects_len, co, &hit)) { - return OPERATOR_CANCELLED; - } + found_item = uv_find_nearest_face_multi(scene, ima, objects, objects_len, co, &hit); + found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - BMEditMesh *em = BKE_editmesh_from_object(hit.ob); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + if (found_item) { + BMEditMesh *em = BKE_editmesh_from_object(hit.ob); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - /* make active */ - BM_mesh_active_face_set(em->bm, hit.efa); + /* make active */ + BM_mesh_active_face_set(em->bm, hit.efa); - /* mark all face vertices as being hit */ + /* mark all face vertices as being hit */ - hitv = BLI_array_alloca(hitv, hit.efa->len); - hituv = BLI_array_alloca(hituv, hit.efa->len); - BM_ITER_ELEM_INDEX (l, &liter, hit.efa, BM_LOOPS_OF_FACE, i) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - hituv[i] = luv->uv; - hitv[i] = BM_elem_index_get(l->v); - } + hitv = BLI_array_alloca(hitv, hit.efa->len); + hituv = BLI_array_alloca(hituv, hit.efa->len); + BM_ITER_ELEM_INDEX (l, &liter, hit.efa, BM_LOOPS_OF_FACE, i) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + hituv[i] = luv->uv; + hitv[i] = BM_elem_index_get(l->v); + } - hitlen = hit.efa->len; + hitlen = hit.efa->len; + } } else if (selectmode == UV_SELECT_ISLAND) { - if (!uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit)) { - return OPERATOR_CANCELLED; - } - - hitlen = 0; + found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit); + found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); } - else { - hitlen = 0; + + if (!found_item) { + if (deselect_all) { + uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + uv_select_tag_update_for_object(depsgraph, ts, obedit); + } + + return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; + } return OPERATOR_CANCELLED; } @@ -2742,13 +2755,14 @@ static int uv_mouse_select_multi( return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; } -static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loop) +static int uv_mouse_select( + bContext *C, const float co[2], const bool extend, const bool deselect_all, const bool loop) { ViewLayer *view_layer = CTX_data_view_layer(C); uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( view_layer, ((View3D *)NULL), &objects_len); - int ret = uv_mouse_select_multi(C, objects, objects_len, co, extend, loop); + int ret = uv_mouse_select_multi(C, objects, objects_len, co, extend, deselect_all, loop); MEM_freeN(objects); return ret; } @@ -2756,13 +2770,13 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo static int uv_select_exec(bContext *C, wmOperator *op) { float co[2]; - bool extend, loop; RNA_float_get_array(op->ptr, "location", co); - extend = RNA_boolean_get(op->ptr, "extend"); - loop = false; + const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all"); + const bool loop = false; - return uv_mouse_select(C, co, extend, loop); + return uv_mouse_select(C, co, extend, deselect_all, loop); } static int uv_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2790,11 +2804,19 @@ static void UV_OT_select(wmOperatorType *ot) ot->poll = ED_operator_uvedit; /* requires space image */ /* properties */ + PropertyRNA *prop; RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection rather than clearing the existing selection"); + prop = RNA_def_boolean(ot->srna, + "deselect_all", + false, + "Deselect On Nothing", + "Deselect all when nothing under the cursor"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + RNA_def_float_vector( ot->srna, "location", @@ -2817,13 +2839,13 @@ static void UV_OT_select(wmOperatorType *ot) static int uv_select_loop_exec(bContext *C, wmOperator *op) { float co[2]; - bool extend, loop; RNA_float_get_array(op->ptr, "location", co); - extend = RNA_boolean_get(op->ptr, "extend"); - loop = true; + const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool deselect_all = false; + const bool loop = true; - return uv_mouse_select(C, co, extend, loop); + return uv_mouse_select(C, co, extend, deselect_all, loop); } static int uv_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event) |