Mesh Visual UV¶
Interactive UV island editing performed directly on the mesh surface in the 3D viewport. The operator detects UV islands on selected faces, draws their bounding box and scale/rotate handles projected through the mesh, and lets you grab/rotate/scale/flip/align/randomize/unwrap them without leaving the viewport. It is meant for quick UV cleanup and alignment work while you are still focused on the model.
Overview¶
Working on UVs usually means context-switching to the UV/Image editor. Visual UV keeps you in the 3D view: islands are color-coded, the active island shows a UV-aligned bbox with corner/midpoint handles, and a pivot dot plus a rotation knob lifted along the face normal. Transforms operate on screen vectors decomposed into the projected UV axes, so dragging behaves consistent with the texture orientation even when the surface is angled.
It is intended for "in-place" adjustments — aligning shells to an edge, matching texel density between islands, flipping, randomizing offsets, or straightening an edge chain — without losing sight of the model.
Usage¶
- Edit Mode on a mesh, at least one face selected. The operator collects UV islands from those faces.
- Default keymap: Ctrl+Alt+U in the 3D Viewport.
- The active island shows the bbox + 8 handles + center pivot + rotation knob. Hover over a handle to make it the implicit pivot for the next R/S press; click a handle to start a handle-driven scale; click the rotation knob to start a handle-driven rotate; click on island geometry to make that island active; Tab cycles active island.
- Confirm with Enter/Space, cancel with Esc (cancel restores the original UVs cached at invoke time).
Modal Controls¶
| Key | Action |
|---|---|
| LMB on handle | Start handle scale (opposite handle = pivot) |
| LMB on rotation knob | Start handle rotate |
| LMB on island | Make that island active |
| LMB (in edge-pick mode) | Pick edge to align active island to |
| LMB (in density modes) | Pick reference, then target island |
| G | Grab / Move selected islands |
| R | Rotate around pivot (uses hovered handle if any) |
| S | Scale around pivot (uses hovered handle if any) |
| X / Y | Toggle axis lock (during G / S / handle-S) |
| Shift (during G) | Constrain dominant axis |
| Shift (during S corner) | Uniform scale |
| Ctrl (during G) | Snap offset to 1/16 UV |
| Ctrl (during R) | Snap to current rotation step |
| Ctrl (during S) | Snap factor to 0.05 |
| Ctrl+Wheel (during R) | Cycle rotation step (1, 5, 10, 15, 30, 45, 90 deg) |
| Alt+Wheel | Adjust grab/transform sensitivity (5%..300%) |
| C | Place UV cursor at mouse (and set pivot to CURSOR) |
| P | Toggle pivot mode CENTER / CURSOR |
| A | Align: with hovered handle, snap selected islands to active's handle on that axis; without a handle, enter edge-pick mode |
| F | Flip horizontal (around pivot) |
| Shift+F | Flip vertical |
| D | Match dimensions of selected islands to active |
| N | Randomize UV (both axes) per island |
| Shift+N | Randomize U only |
| Ctrl+N | Randomize V only |
| U | Unwrap selection (Angle Based, margin 0.001) |
| T | Straighten edge chain through hovered edge (>= 3 verts) |
| Q | Toggle clean view (hide viewport overlays + operator HUD) |
| Tab | Cycle active island |
| Ctrl+Z / Ctrl+Shift+Z | Undo / Redo within the modal session |
| LMB press (in transform) | Confirm key-driven transform |
| LMB release (in handle transform) | Confirm handle-driven transform |
| RMB (in transform) | Cancel current transform |
| Enter / NumpadEnter / Space | Confirm transform / Confirm operator |
| Esc | Cancel operator (restores UVs) |
| H | Toggle Help overlay / HUD (handled by shared HUD layer) |
| MMB / Wheel (no modifier) | Pass-through to viewport navigation |
HUD¶
The shortcuts/help overlay is the shared IOPS HUD. Header shows current state, pivot mode, sensitivity percent, island count and current rotation step. The help panel lists every shortcut and is toggled with the standard HUD H binding.
In-view drawing:
- Per-island translucent fill, color from theme.island_palette (8 slots, cycled). Active island brighter, selected slightly brighter, idle dimmer.
- Island outline edges drawn via line roles: Role.ACTIVE_LINE for active, Role.CLOSEST_LINE for selected, Role.LINE otherwise.
- UV-aligned bounding box (Role.BBOX), corner handles (circles) and midpoint handles (diamonds) in Role.HANDLE, hovered handle in Role.HANDLE_HOVER.
- Center pivot ring + dot and rotation knob in Role.PIVOT; hovered rotation knob in Role.HANDLE_HOVER.
- UV cursor crosshair + dot in Role.CURSOR.
- Hovered edge for align/straighten in Role.PREVIEW_LINE (pick-edge state) or Role.LOCKED_LINE otherwise.
- Per-island TD: (texel density) label near each center in island color.
- Transform feedback near the mouse uses Role.HUD_ACTIVE_VALUE; axis-locked text uses axis_color('X') / axis_color('Y').
Q hides the overlay (and Blender's viewport overlays).
Properties¶
| Name | Type | Default | Description |
|---|---|---|---|
tile_limit_prop |
Int (1..10) | 2 | Max tiles away from the 0-1 area before an island gets re-centered to (0.5, 0.5) during live transforms. |
rotation_step_prop |
Int (1..90) | 90 | Ctrl-snap rotation step in degrees. Stored as one of (1, 5, 10, 15, 30, 45, 90). |
grab_sensitivity_prop |
Float (0.05..3.0) | 1.0 | Multiplier on grab and pixel-derived motion. Adjusted live with Alt+Wheel. |
These three props are also written back from the live session state when the operator finishes (so the redo panel reflects the last in-modal values).
Notes¶
- Cancel (
Esc) restores the snapshot taken at invoke viacache_all_uvs/restore_uvs. Confirm finalizes the bmesh. - Undo/Redo stacks are local to the modal session; they do not feed Blender's global undo.
- Tile bounds are enforced every live update — if any selected island drifts more than
tile_limitUV units past 0-1 on either axis it snaps back to center (0.5, 0.5). Uinvokesbpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0.001)on the current selection.Tstraightens a chain of UV edges traversed from the hovered edge through shared UV endpoints; needs at least 3 chain vertices.- Grab uses the projected UV axes (
_u_dir,_v_dir) when both have non-trivial screen length; otherwise it falls back to a view-distance pixel-to-UV scale. - Density match (
match_texel_density) is exposed in code but reached only through the pick states; key binding for entering those states is not in the current modal table — they are driven bystatetransitions in code paths (left as an internal feature). - Only one operator class is registered in this module (
IOPS_OT_MeshVisualUV); no panel or property group accompanies it.