# How to get the UV corresponding to a vertex via the Python API?

How do I get a selected vertex and it's corresponding uv vertex?

A vertex I can get with

bpy.context.active_object.data.vertices[0]


A uv vertex I can get with

bpy.context.active_object.data.uv_layers['UVMap'].data[0]


But the index is not the same for uv and mesh vertex.

• In your first line you retrieve a vertex from the active object's mesh, in the second line you retrieve the uv layer from the active object's mesh, and you don't need to add '.data[0]'. What you are refering to as the "index" of the uv map is its name itself, there is not way you will have a correlation between a mesh's vertices index and a mesh's UV_layer Mar 23, 2016 at 12:11

As madlaina says, A vertex doesn't have a 1:1 corraspondance with UV coordinates.

However using BMesh you can loop over a vertices connected face corners (loops), and find the UV's used by a vertex.

Heres a script that prints all vertices UV's in editmode.

Both the first-uv found (which is OK if you assume all UV's attached to a vertex will be the same).
And the mean average.

import bpy
import bmesh
from mathutils import Vector

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

def uv_from_vert_first(uv_layer, v):
uv_data = l[uv_layer]
return uv_data.uv
return None

def uv_from_vert_average(uv_layer, v):
uv_average = Vector((0.0, 0.0))
total = 0.0
uv_average += loop[uv_layer].uv
total += 1.0

if total != 0.0:
return uv_average * (1.0 / total)
else:
return None

# Example using the functions above
uv_layer = bm.loops.layers.uv.active

for v in bm.verts:
uv_first = uv_from_vert_first(uv_layer, v)
uv_average = uv_from_vert_average(uv_layer, v)
print("Vertex: %r, uv_first=%r, uv_average=%r" % (v, uv_first, uv_average))

• exactly what I was looking for. Thank you!
– ndee
Mar 23, 2016 at 13:33

The thing you need to consider is that a vertex can have multiple uv-coordinates (for example if you unwrap two faces then there are two uv coordinates for one vertex where the seams are)

The UV Coordinates are actually stored per face-loop and not per vertex. It is a good idea to read up on this here to understand the concept better:

https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design

Maybe you can give us more information, what you would like to do with the uv coordinates.

As already said, a vertex can be associated to multiple UVs. That's because, from 3D authors' point of view, UV editing is done distributing polygons (not vertices) over the texture surface.

I propose here a snippet to scan the association between polygons, vertices and UV coordinates running in Object mode (no BMesh).

import bpy
import mathutils

src_obj: bpy.types.Object = bpy.context.active_object
assert src_obj.type == 'MESH'

# get reference to mesh
src_mesh: bpy.types.Mesh = src_obj.data

# Get basic UV info
active_uv_idx: int = src_mesh.uv_layers.active_index
active_uv: bpy.types.MeshUVLoopLayer = src_mesh.uv_layers[active_uv_idx]

print(f"Info for uvlayer {active_uv_idx} '{active_uv.name}' on object {src_obj.name}")

#
# Iterate over the polygons of the mesh
for poly in src_mesh.polygons:
assert type(poly) == bpy.types.MeshPolygon
assert len(poly.vertices) == len(poly.loop_indices)

# For each vertex of the polygon, and uv loop indices
for v_idx, loop_idx in zip(poly.vertices, poly.loop_indices):
assert type(v_idx) == int
assert type(loop_idx) == int

# Get the UV coords
# U increases on width (left to right), and V increases on height (bottom to top!)
uv_coords: mathutils.Vector = active_uv.uv[loop_idx].vector
assert 0.0 <= uv_coords.x <= 1.0
assert 0.0 <= uv_coords.y <= 1.0

print(f"UV in poly {poly.index} for vertex ID {v_idx} and loop ID {loop_idx}:", uv_coords)

print("All done.")


Discretely commented and heavily typed :-)

Output will be something like:

Info for uvlayer 0 'UVMapUVshpere' on object UVSphere
UV in poly 0 for vertex ID 4 and loop ID 0: <Vector (0.7500, 0.4375)>
UV in poly 0 for vertex ID 3 and loop ID 1: <Vector (0.7500, 0.5000)>
UV in poly 0 for vertex ID 13 and loop ID 2: <Vector (0.7188, 0.5000)>
UV in poly 0 for vertex ID 14 and loop ID 3: <Vector (0.7188, 0.4375)>
UV in poly 1 for vertex ID 474 and loop ID 4: <Vector (0.7500, 0.8750)>
UV in poly 1 for vertex ID 473 and loop ID 5: <Vector (0.7500, 0.9375)>
UV in poly 1 for vertex ID 6 and loop ID 6: <Vector (0.7188, 0.9375)>
UV in poly 1 for vertex ID 7 and loop ID 7: <Vector (0.7188, 0.8750)>
UV in poly 2 for vertex ID 477 and loop ID 8: <Vector (0.7500, 0.3750)>
UV in poly 2 for vertex ID 4 and loop ID 9: <Vector (0.7500, 0.4375)>
[...]