I have a UV unwrapped mesh with multiple UV faces. They are all part of the same UV island. I want to scale all of them down on their individual origins, so each UV face will shrink, but remain in the same location.

Right now, the only way I can do this is by disabling sticky selection mode and scaling down individual faces one at a time. This is incredibly tedious and I wish to automate it. How can I achieve that?

  • $\begingroup$ You can set the pivot point to individual origins, but you need to separate the faces for them to scale individually. $\endgroup$
    – sambler
    Nov 6, 2017 at 13:46
  • $\begingroup$ How would I separate the faces without having to re unwrap the mesh? $\endgroup$
    – Erik
    Nov 6, 2017 at 17:57
  • 1
    $\begingroup$ The slow way is select a uv face and Alt-V - the quick way is to pin the verts and then add a seam to all edges and unwrap. Pinning the verts will keep them in place. $\endgroup$
    – sambler
    Nov 7, 2017 at 0:21

3 Answers 3


I finally figured out a way to do this that works in my case:

Assuming the connectivity of your UV map topology is similar to your object:

  1. On the object side: Select your target object faces as usual.
  2. (UV unwrap if you haven't already done it)
  3. On the object side: Select -> Checker Deselect
  4. On the UV side: Select all, set individual origins, scale. As long as none of the visible vertices are touching, each face will scale along its own origin.

This problem bugged me so hard I decided just to waste 2 days by learning some basic phython and writing an addon against it. So if anyone wants it here you can find it. With the addon you can scale the UVs of the associated selected faces in the 3d View by a self determinated factor.


I couldn't find a way to do it in the UI, so I wrote a script.
This is what I came up with:

import bpy
import mathutils
import bmesh

# Get the selected object and its mesh
obj = bpy.context.object
mesh = obj.data

# Create a bmesh from the mesh
bm = bmesh.from_edit_mesh(mesh)

# Get the active UV layer
uv_lay = bm.loops.layers.uv[0]

# Scale factor for the UVs
x = 0.9

# Iterate over the selected faces and their loops
for face in bm.faces:
    if face.select:
        # Calculate the UV face center
        loop_sum = mathutils.Vector((0, 0, 0))
        loop_count = len(face.loops)
        for loop in face.loops:
            uv = loop[uv_lay].uv
            loop_sum.xy += uv
        center = loop_sum / loop_count
        for loop in face.loops:
            # Move the UV coordinates to the middle
            loop[uv_lay].uv -= center.xy
            # Scale the UV coordinates by x
            loop[uv_lay].uv *= x
            # Move the UV coordinates back to where they were
            loop[uv_lay].uv += center.xy

# Update the mesh with the changes

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .