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 <campbell@blender.org>2022-03-17 16:28:15 +0300
committerCampbell Barton <campbell@blender.org>2022-03-23 08:09:22 +0300
commitd356edf420ba13b3a544dcc598a0e31a36e1d86c (patch)
tree9f2d8383e500d221bf4dd4aa8ac23a2ccba478a6 /source/blender/editors/uvedit
parentcf1a0ca612f0f96c7513d5c31f3bd4d665057c28 (diff)
UV: support "Tweak Tool: Left Mouse Select & Move"
- Follow the same conventions as the 3D viewport for UV selection (using SelectPick_Params internally). - Use WM_operator_properties_mouse_select for selection properties.
Diffstat (limited to 'source/blender/editors/uvedit')
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c235
1 files changed, 131 insertions, 104 deletions
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 938b798f4b6..ed4aa6985c4 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -2388,12 +2388,11 @@ void UV_OT_select_all(wmOperatorType *ot)
/** \name Mouse Select Operator
* \{ */
-static int uv_mouse_select_multi(bContext *C,
- Object **objects,
- uint objects_len,
- const float co[2],
- const bool extend,
- const bool deselect_all)
+static bool uv_mouse_select_multi(bContext *C,
+ Object **objects,
+ uint objects_len,
+ const float co[2],
+ const struct SelectPick_Params *params)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
const ARegion *region = CTX_wm_region(C);
@@ -2477,117 +2476,145 @@ static int uv_mouse_select_multi(bContext *C,
}
}
- if (!found_item) {
- if (deselect_all) {
- uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
+ bool found = found_item;
+ bool changed = false;
+
+ bool is_selected = false;
+ if (found) {
+ Object *obedit = hit.ob;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ if (selectmode == UV_SELECT_FACE) {
+ is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset);
+ }
+ else if (selectmode == UV_SELECT_EDGE) {
+ is_selected = uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset);
+ }
+ else { /* Vertex or island. */
+ is_selected = uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset);
+ }
+ }
+ if (params->sel_op == SEL_OP_SET) {
+ if ((found && params->select_passthrough) && is_selected) {
+ found = false;
+ }
+ else if (found || params->deselect_all) {
+ /* Deselect everything. */
+ uv_select_all_perform_multi(scene, 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;
+ changed = true;
}
- return OPERATOR_CANCELLED;
}
- Object *obedit = hit.ob;
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ if (found) {
+ Object *obedit = hit.ob;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- /* do selection */
- if (selectmode == UV_SELECT_ISLAND) {
- if (!extend) {
- uv_select_all_perform_multi_ex(scene, objects, objects_len, SEL_DESELECT, obedit);
- }
- /* Current behavior of 'extend'
- * is actually toggling, so pass extend flag as 'toggle' here */
- uv_select_linked_multi(scene, objects, objects_len, &hit, false, false, extend, false);
- }
- else if (extend) {
- bool select = true;
- if (selectmode == UV_SELECT_VERTEX) {
- /* (de)select uv vertex */
- select = !uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
- flush = 1;
- }
- else if (selectmode == UV_SELECT_EDGE) {
- /* (de)select edge */
- select = !(uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset));
- uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
- flush = 1;
- }
- else if (selectmode == UV_SELECT_FACE) {
- /* (de)select face */
- select = !(uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset));
- uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset);
- flush = -1;
+ if (selectmode == UV_SELECT_ISLAND) {
+ const bool extend = params->sel_op == SEL_OP_ADD;
+ const bool deselect = params->sel_op == SEL_OP_SUB;
+ const bool toggle = params->sel_op == SEL_OP_XOR;
+ /* Current behavior of 'extend'
+ * is actually toggling, so pass extend flag as 'toggle' here */
+ uv_select_linked_multi(scene, objects, objects_len, &hit, extend, deselect, toggle, false);
+ /* TODO: check if this actually changed. */
+ changed = true;
}
+ else {
+ BLI_assert(ELEM(selectmode, UV_SELECT_VERTEX, UV_SELECT_EDGE, UV_SELECT_FACE));
+ bool select_value = false;
+ switch (params->sel_op) {
+ case SEL_OP_ADD: {
+ select_value = true;
+ break;
+ }
+ case SEL_OP_SUB: {
+ select_value = false;
+ break;
+ }
+ case SEL_OP_XOR: {
+ select_value = !is_selected;
+ break;
+ }
+ case SEL_OP_SET: {
+ /* Deselect has already been performed. */
+ select_value = true;
+ break;
+ }
+ case SEL_OP_AND: {
+ BLI_assert_unreachable(); /* Doesn't make sense for picking. */
+ break;
+ }
+ }
- /* de-selecting an edge may deselect a face too - validate */
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (select == false) {
- BM_select_history_validate(em->bm);
+ if (selectmode == UV_SELECT_FACE) {
+ uvedit_face_select_set_with_sticky(
+ scene, em, hit.efa, select_value, true, cd_loop_uv_offset);
+ flush = 1;
+ }
+ else if (selectmode == UV_SELECT_EDGE) {
+ uvedit_edge_select_set_with_sticky(
+ scene, em, hit.l, select_value, true, cd_loop_uv_offset);
+ flush = 1;
+ }
+ else if (selectmode == UV_SELECT_VERTEX) {
+ uvedit_uv_select_set_with_sticky(scene, em, hit.l, select_value, true, cd_loop_uv_offset);
+ flush = 1;
+ }
+ else {
+ BLI_assert_unreachable();
}
- }
- /* (de)select sticky uv nodes */
- if (sticky != SI_STICKY_DISABLE) {
- flush = select ? 1 : -1;
- }
- }
- else {
- const bool select = true;
- /* deselect all */
- uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
+ /* De-selecting an edge may deselect a face too - validate. */
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (select_value == false) {
+ BM_select_history_validate(em->bm);
+ }
+ }
- if (selectmode == UV_SELECT_VERTEX) {
- /* select vertex */
- uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
- flush = 1;
- }
- else if (selectmode == UV_SELECT_EDGE) {
- /* select edge */
- uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset);
- flush = 1;
- }
- else if (selectmode == UV_SELECT_FACE) {
- /* select face */
- uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset);
- flush = 1;
+ /* (de)select sticky UV nodes. */
+ if (sticky != SI_STICKY_DISABLE) {
+ flush = select_value ? 1 : -1;
+ }
+
+ changed = true;
}
- }
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (flush != 0) {
- EDBM_selectmode_flush(em);
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (flush != 0) {
+ EDBM_selectmode_flush(em);
+ }
+ }
+ else {
+ /* Setting the selection implies a single element, which doesn't need to be flushed. */
+ if (params->sel_op != SEL_OP_SET) {
+ ED_uvedit_selectmode_flush(scene, em);
+ }
}
- }
- /* #extend=false implies single vertex selection, which doesn't need to be flushed. */
- else if (extend) {
- ED_uvedit_selectmode_flush(scene, em);
}
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obiter = objects[ob_index];
- uv_select_tag_update_for_object(depsgraph, ts, obiter);
+ if (changed && found) {
+ /* Only update the `hit` object as de-selecting all will have refreshed the others. */
+ Object *obedit = hit.ob;
+ uv_select_tag_update_for_object(depsgraph, ts, obedit);
}
- return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
+ return changed || found;
}
-static int uv_mouse_select(bContext *C,
- const float co[2],
- const bool extend,
- const bool deselect_all)
+static bool uv_mouse_select(bContext *C, const float co[2], const struct SelectPick_Params *params)
{
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, deselect_all);
+ bool changed = uv_mouse_select_multi(C, objects, objects_len, co, params);
MEM_freeN(objects);
- return ret;
+ return changed;
}
static int uv_select_exec(bContext *C, wmOperator *op)
@@ -2595,10 +2622,20 @@ static int uv_select_exec(bContext *C, wmOperator *op)
float co[2];
RNA_float_get_array(op->ptr, "location", co);
- const bool extend = RNA_boolean_get(op->ptr, "extend");
- const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
+ const struct SelectPick_Params params = {
+ .sel_op = ED_select_op_from_booleans(RNA_boolean_get(op->ptr, "extend"),
+ RNA_boolean_get(op->ptr, "deselect"),
+ RNA_boolean_get(op->ptr, "toggle")),
+ .deselect_all = RNA_boolean_get(op->ptr, "deselect_all"),
+ .select_passthrough = RNA_boolean_get(op->ptr, "select_passthrough"),
+ };
- return uv_mouse_select(C, co, extend, deselect_all);
+ const bool changed = uv_mouse_select(C, co, &params);
+
+ if (changed) {
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ }
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
static int uv_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2629,18 +2666,8 @@ void UV_OT_select(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna,
- "extend",
- 0,
- "Extend",
- "Extend selection rather than clearing the existing selection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- 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);
+
+ WM_operator_properties_mouse_select(ot);
prop = RNA_def_float_vector(
ot->srna,