UV: initial implementation of UV sync select

Support sync selection in the UV editor, with face-corner selection,
so it's possible to select individual UV vertices/edges in the UV editor
without UV's attached to the same underlying edge also becoming selected.

There is limited support for maintaining the UV selection when selecting
from the 3D viewport, common operations such as picking &
box/circle/lasso select support this, however other selection operations
such as "Select Random" or "Select Similar" will clear this data,
causing all UV's connected to selected mesh elements to become selected.
We may add support for additional operators as needed.

Details:

- UV Sync Selection is now enabled by default.
- In edit-mode the UV selection is stored in BMLoop/BMFace which are
  written to custom-data layers when converted to a Mesh.
- To avoid unnecessary overhead - this data is created on demand.
  Operators may clear this data - selecting all or none do so,
  as there is no reason to store this data for a uniform selection.
- The Python API includes functions to synchronize the selection to/from
  UV's as well as flushing based on the mode.
- Python scripts that manipulate the selection will either need to clear
  this synchronized state or maintain it.

See:
- Design task: #78393.
- Implementation task: #131642.

Ref !138197
This commit is contained in:
Campbell Barton
2025-10-07 01:41:16 +00:00
parent 88b5319596
commit 62d72bd0b5
50 changed files with 6592 additions and 391 deletions

View File

@@ -870,15 +870,6 @@ class IMAGE_HT_header(Header):
if tool_settings.use_uv_select_sync:
layout.template_edit_mode_selection()
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)
else:
row = layout.row(align=True)
uv_select_mode = tool_settings.uv_select_mode[:]
@@ -889,8 +880,8 @@ class IMAGE_HT_header(Header):
row.operator("uv.select_mode", text="", icon='UV_FACESEL',
depress=(uv_select_mode == 'FACE')).type = 'FACE'
layout.prop(tool_settings, "use_uv_select_island", icon_only=True)
layout.prop(tool_settings, "uv_sticky_select_mode", icon_only=True)
layout.prop(tool_settings, "use_uv_select_island", icon_only=True)
layout.prop(tool_settings, "uv_sticky_select_mode", icon_only=True)
IMAGE_MT_editor_menus.draw_collapsible(context, layout)