UV Editor Improvements - Final Report

For this Google Summer of Code project, I worked on improvements for Blender's UV editor and also worked on adding some new UV editing tools.


Almost all the deliverables outlined in my project proposal have been implemented and I also managed to work on some additional tasks that were not originally included in my proposal. A few deliverables from the proposal were modified based on initial feedback and discussions with my mentor and Daniel Bystedt. The work I've done is divided between 2 separate git branches and functionality wise, all the implemented features/tools work as intended.


Work done

Pack islands to closest/desired UDIM

This feature extends the functionality of the original pack islands operator to work with tiled/UDIM textures. Previously UVs were always packed to the 0-1 UV space (UDIM 1001).

  • 2 new options have been added to the properties panel that allow the user to specify the target UDIM for packing the selected UVs
New options for packing UVs
  • Closest UDIM : Packs UVs to the UDIM they were originally placed on. In case selected UVs are not present on a valid UDIM tile then, they will be packed to the closest UDIM tile in the UV space.
  • Specified UDIM : This option exposes a target UDIM field in the properties panel, where the user can specify the UDIM tile number where the UVs will be packed to.
Packing to specified UDIM
  • This implementation works with the UDIM grid as well

In the future, this can also be implemented for the UV unwrap operator as well.

Pack islands to box area

Pack islands to area is a new modal operator that allows packing selected UVs to a user specified area in the UV space.

  • Defining the packing area is done similar to how selections are made using the box select operator
  • Depending on the use case, packing is done by using one of 2 algorithms, but the basic idea for both algorithms is to use the same bounding box approach. The choice of algorithm is done on the basis of whether the scale option in the properties panel is enabled or disabled :
    • Scaling enabled uses the same algorithm that is used by the original pack islands operator.
    • Scaling disabled uses a new algorithm that is a modified version of the algorithm used in BLI_box_pack_2d_fixedarea()
      • The basic idea of this algorithm is to keep a list of empty spaces currently available for packing and for each island find an empty space that can contain its bounding box.
      • In case no empty space can fit a particular island then it is concluded that the packing area isn't big enough to fit all selected UVs and the operator is cancelled.
  • To provide more precise control over the packing area, the box coordinates are displayed as user editable fields in the properties panel
  • Similar to the original pack islands operator, options for setting island margin and rotating islands for best fit have also been included

New grid types for the UV Editor :

The default UV editor grid has been replaced with 2 new grid types

Subdividing grid

This replaces the original UV editor grid with a grid similar to the one used in the 3D viewport.

  • Zooming in will subdivide the grid into smaller grid units and vice-versa when zooming out
  • The default dimensions of the grid is 8x8 which will further subdivide when zooming in
Subdividing grid in the UV editor

Dynamic grid

  • This is an implementation of dynamic grid as described in T78389
  • Allows the users to create an NxN grid in the UV editor
  • This is exposed as a separate property under the View tab in the side properties panel
Dynamic grid for the UV editor

Snapping improvements

Increment snapping

Previously increment snapping was limited to fixed values of 0.0625 UV units (default) and 0.03125 UV units (precision snapping). Now, the snapping value is calculated based on the grid type that is being used in the UV editor.

  • For subdividing grid, the snapping value is decided based on the visible grid lines in the UV editor
  • For dynamic grid the increment snapping value is equal to the inverse of dynamic grid size. In other words the snapping value is equal to the size of one dynamic grid unit.
  • Precision snapping is calculated as 0.5 times the snapping value that is being used currently

Absolute Grid snap

Originally this was planned to be implemented as a separate snapping option, but since it only affects UVs during translation/movement, I decided to add it as a toggle for increment snapping. Similar to the 3D viewport, absolute grid snap is now present in the UV editor as a toggle for increment snapping.

  • For subdividing grid : snapping is done based on visible grid lines in the UV editor
  • For dynamic grid  : snapping is done based on dynamic grid size
  • Precision snapping is calculated as 0.5 times the snapping value that is being used currently
Increment and grid snapping demonstrated for subdividing and dynamic grid

UV offset operator

As described in T78405, new keymaps have been added for offsetting selected UVs by a fixed amount in a specified direction.

  • CTRL+ARROW KEYS offsets the selected UVs by one UDIM unit
  • ALT+ARROW KEYS offsets the selected UVs by one dynamic grid unit. This only works if dynamic grid is enabled.

Proper UV edge selection support

This is an additional task that I worked on this summer that wasn't originally included in my proposal.

This task aims to fix the known limitation of UV selection that has been present in Blender for a long time. Previously, UV edge selection was just selecting and deselecting the vertices of the edge, which caused many problems such as T78757, T76343 and T26676.

The first step for this task was adding back the edge selection flag (MLOOPUV_EDGESEL) that was removed previously and then working on rewriting parts of code where this flag was required. Each MloopUV struct is now associated with a particular UV vertex and UV edge. For a selected edge to be a valid selection state, it requires both vertices to be selected and the corresponding edge selection flag for that edge to be set.

The following operators now support proper edge selection :

  • Mouse select
  • Box select
  • Circle select
  • Lasso select
  • (De)Select All
  • Invert selection
  • Select more/less
  • Select split
  • Select pinned
  • Loop select
  • Edge ring select

While much of the work for this task has been completed, there's still some things left to do such as drawing of selected edges and edge selection support for UV rip tool and select shortest path operator. I did spend sometime working on a solution for drawing of selected UV edges, but I wasn't able to finish it due to time constraints. All of the work for this task is done on the soc-2021-uv-edge-select-support branch and the current progress for this task can also be tracked using the patch - D12028

Deviations from original proposal

Based on the use cases and feedback, some of the deliverables from the original proposal were either modified or discarded completely.

  • Pack islands to correct/desired UDIM - Initially it was planned to work only with UDIM textures/images. After discussion with Daniel Bystedt it was decided that this should also work with UDIM grids as well. This is because users should never need to load an UDIM texture/sequence in the editor simple for specifying a packing target.
  • User editable increment snapping value was abandoned since it didn't serve many use cases and would actually disrupt UV editing workflows. This was substituted with a different solution that involves subdividing grid, dynamic grid and improved UV increment snapping
  • Grid snapping was initially planned to be implemented as a separate snapping option, but since it only affects UV during translation, it was decided to add this as a toggle instead. Similar to the 3D viewport, this was implemented as Absolute grid snap in the UV editor

Tasks that I worked on during GSoC, but were not included in the original proposal :

  • Edge selection support for UV editing
  • Pack islands to box area
  • Subdividing grid

What's left to do?

Functionality wise, all the implemented features, tools and improvements work as intended. A few things that are yet to be completed :

  • Edge selection support for UV rip tool and select shortest path operator
  • Proper drawing of selected UV edges
  • Pack islands to area operator - Option for rotating islands when using the new algorithm has some issues that need to be resolved
  • Testing for changes in performance, caused by the addition of proper edge selection to the UV editor. Based on the results I'll be making further optimizations to the selection code.

Future Work

Some further improvements that I had discussed with my mentor:

  • Active element pivot option for UV editor
  • An improved algorithm for packing UVs that is space efficient, but not necessarily fast (computationally).
  • Extend functionality of unwrap operator to allow unwrapping to a specified UDIM (currently unwraps to UDIM 1001)

Apart from these, there are many design tasks that can be found in the Under Discussion section of the UV Editing Workboard and I have also collected some potential improvements that were suggested by users during GSoC.


Huge thanks to my mentor Campbell Barton for clearing all of my doubts and providing valuable guidance throughout the course of this project. Also, special thanks to Daniel Bystedt for testing the implemented features and providing valuable feedback. I also want to thank the awesome Blender community for providing me the opportunity to work on this project!