When creating new geometry in Blender using the Python API, we often need to not only create new polygons but also immediately assign them the correct UV coordinates. When working with a BMesh object, this could be done using MeshLoop links between geometry verices and UV points.
Let’s take any object in a Blender scene, the default cube, for example. Create a new polygon inside it and assign the required UV coordinates to the points of this polygon.
If the cube was in edit mode, switch to object mode.
|
1 |
bpy.ops.object.mode_set(mode = 'OBJECT') |
Create a BMesh object and dump the geometry data of the currently active object into it.
|
1 2 |
bm = bmesh.new() bm.from_mesh(bpy.context.object.data) |
Create four new vertices to use for creating a new polygon. Let’s arrange them in a 1×1 square in the XY plane, at the scene’s origin.
Select them. Selecting is not necessary, it’s just for we can see them on the UV immediately.
|
1 2 3 4 5 6 7 |
v0 = bm.verts.new((0.0, 0.0, 0.0)) v1 = bm.verts.new((1.0, 0.0, 0.0)) v2 = bm.verts.new((1.0, 1.0, 0.0)) v3 = bm.verts.new((0.0, 1.0, 0.0)) for v in [v0, v1, v2, v3]: v.select = True |
Create a new polygon using these vertices.
|
1 |
face = bm.faces.new((v0, v1, v2, v3)) |
Get a pointer to the currently active UV map layer. If there’s no UV map, it will be created by this command.
|
1 |
uv_layer = bm.loops.layers.uv.verify() |
Create a list of coordinates for the points of our polygon on the UV map. Let them form a trapezoid from the origin.
|
1 2 3 4 5 6 |
uv_coords = [ (0.0, 0.0), (0.5, 0.0), (0.4, 0.5), (0.1, 0.5) ] |
Now iterate over the meshloop points of the polygon we created. Using them, we can link the polygon points to the UV points. The order of the meshloop points corresponds to the order of both the polygon vertices and the UV points.
|
1 2 |
for loop, co in zip(face.loops, uv_coords): loop[uv_layer].uv = co |
Now all we have to do is return the updated geometry to the original cube object and clear the no longer needed BMesh object.
|
1 2 |
bm.to_mesh(bpy.context.object.data) bm.free() |
Switch to edit mode to view the changes on the UV.
|
1 |
bpy.ops.object.mode_set(mode = 'EDIT') |
As we can see, another polygon has been created within the object in the scene, and its UV points have been assigned the coordinates we specified.

.blend file on Patreon