UV: support island selection with sync-select in vertex/edge mode

This was disabled because island selection used to be exposed as a
UV selection mode (along with vertex/edge/face) where selecting
parts of other islands would seem like a bug.

Now island selection has been moved to a separate toggle it makes
sense to allow connected geometry to be included in the selection when
other selection options enforce this.
This commit is contained in:
Campbell Barton
2025-08-08 05:58:04 +00:00
parent 1b618461f3
commit 73afa1c94f
2 changed files with 57 additions and 28 deletions

View File

@@ -535,15 +535,7 @@ class IMAGE_MT_uvs_select_mode(Menu):
layout.separator()
is_select_island_supported = True
if tool_settings.use_uv_select_sync:
mesh_select_mode = tool_settings.mesh_select_mode
if mesh_select_mode[0] or mesh_select_mode[1]:
is_select_island_supported = False
row = layout.row()
row.active = is_select_island_supported
row.prop(tool_settings, "use_uv_select_island", text="Island")
layout.prop(tool_settings, "use_uv_select_island", text="Island")
class IMAGE_MT_uvs_context_menu(Menu):
@@ -873,15 +865,11 @@ class IMAGE_HT_header(Header):
if tool_settings.use_uv_select_sync:
layout.template_edit_mode_selection()
# Currently this only works for face-select mode.
mesh_select_mode = tool_settings.mesh_select_mode
row = layout.row()
if mesh_select_mode[0] or mesh_select_mode[1]:
row.active = False
row.prop(tool_settings, "use_uv_select_island", icon_only=True)
layout.prop(tool_settings, "use_uv_select_island", icon_only=True)
# Currently this only works for edge-select & face-select modes.
row = layout.row()
mesh_select_mode = tool_settings.mesh_select_mode
if mesh_select_mode[0]:
row.active = False
row.prop(tool_settings, "uv_sticky_select_mode", icon_only=True)

View File

@@ -188,12 +188,21 @@ bool ED_uvedit_select_island_check(const ToolSettings *ts)
if ((ts->uv_flag & UV_FLAG_ISLAND_SELECT) == 0) {
return false;
}
if (ts->uv_flag & UV_FLAG_SYNC_SELECT) {
if (ts->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
/* Not currently supported. */
return false;
/* NOTE: when "strict" only return true when it's possible to select an island in isolation.
* At the moment none of the callers require this however it may be necessary to ignore the
* "island" selection option for some operations in the future.
* This could be exposed as an argument. */
const bool strict = false;
if (strict) {
if (ts->uv_flag & UV_FLAG_SYNC_SELECT) {
if (ts->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
return false;
}
}
}
return true;
}
@@ -2084,20 +2093,52 @@ static void uv_select_linked_multi(Scene *scene,
} \
(void)0
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if (!flag[a]) {
if (!extend && !deselect && !toggle) {
/* When sync-select is enabled in vertex or edge selection modes,
* selecting an islands faces may select vertices or edges on other UV islands.
* In this case it's important perform selection in two passes,
* otherwise the final vertex/edge selection around UV island boundaries
* will contain a mixed selection depending on the order of faces. */
const bool needs_multi_pass = uv_sync_select &&
(scene->toolsettings->selectmode &
(SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) &&
(deselect == false);
const bool deselect_elem = !extend && !deselect && !toggle;
if (needs_multi_pass == false) {
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if (!flag[a]) {
if (deselect_elem) {
SET_SELECTION(false);
}
continue;
}
if (deselect) {
SET_SELECTION(false);
}
continue;
else {
SET_SELECTION(true);
}
}
if (!deselect) {
}
else {
/* The same as the previous block, just use multiple passes.
* It just so happens that multi-pass is only needed when selecting (deselect==false). */
BLI_assert(deselect == false);
/* Pass 1 (de-select). */
if (deselect_elem) {
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if (!flag[a]) {
SET_SELECTION(false);
}
}
}
/* Pass 2 (select). */
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) {
if (!flag[a]) {
continue;
}
SET_SELECTION(true);
}
else {
SET_SELECTION(false);
}
}
#undef SET_SELECTION