# How can I add UV coords to a mesh from script?

I am adapting an old script to Blender 2.6, the script reads mesh data from a custom file type and then creates a mesh array with that data.

I managed to make almost all of it, but U can't set the UV values of each vertex to the mesh.

I create the mesh array like this:

for i in range(0,numeroparts):
malla.append(bpy.data.meshes.new(name="2k_Part"+str(i)))
uv = []
xyz= []
for j in range(0,numerovertxpart[i]):
x,y,z,u,v=float(line.split()[0].replace(',','.')),float(line.split()[1].replace(',','.')),float(line.split()[2].replace(',','.')),float(line.split()[3].replace(',','.')),float(line.split()[4].replace(',','.'))
uv.append((u,v))
xyz.append((x,y,z))
print(x,y,z)

aa = []
bb = []
cc = []
faces= []

for j in range(0,numerofacexpart[i]):
a,b,c=int(line.split()[0]),int(line.split()[1]),int(line.split()[2])
faces.append((a,b,c))
aa.append(a)
bb.append(b)
cc.append(c)
print(a,b,c)

malla[i].from_pydata(xyz, [], faces)

for q in range(len(malla[i].polygons)):
#malla[i].faces[q].mode |= Blender.Mesh.FaceModes['TWOSIDE']
#malla[i].faces[q].transp = Blender.NMesh.FaceTranspModes['ALPHA']
#malla[i].faces[q].uv=Mathutils.Vector(uv[aa[q]]), Mathutils.Vector(uv[bb[q]]), Mathutils.Vector(uv[cc[q]])


My problem is here, the lines commented out are how it worked in Blender 2.49:

for q in range(len(malla[i].polygons)):
#malla[i].faces[q].mode |= Blender.Mesh.FaceModes['TWOSIDE']
#malla[i].faces[q].transp = Blender.NMesh.FaceTranspModes['ALPHA']
#malla[i].faces[q].uv=Mathutils.Vector(uv[aa[q]]), Mathutils.Vector(uv[bb[q]]), Mathutils.Vector(uv[cc[q]])

• There are a few posts around how to import UV coordinates. Note that UVs are per-loop since 2.63: blender.org/documentation/blender_python_api_2_70_release/… – CoDEmanX Apr 1 '14 at 15:14
• I am trying to understand some examples but i can´t. Supossing that i have the uv per vertex values in uv=[], i still don´t know how to assing them to each loop. – Jorge Apr 1 '14 at 15:41
• With the next code i get the indices of the vertex that shapes each face: for face in malla[i].polygons: for indice in face.loop_indices: – Jorge Apr 2 '14 at 9:11
• With the next code i get the indices of the vertex that shapes each face: for face in malla[i].polygons: for indice in face.loop_indices: now in tha variable indices i am getting each of the indices of each face, but after reading many examples i still don´t know how uv per loop works. In my code uv[] has the UV coords of each vertex with the same order that the vertex has on the mesh, so uv[0] has the UV values of vertex[0].I need to know how can i set to vertex[0] of the mesh the uv[0] value using uvs per loop because I still don´t know how it works – Jorge Apr 2 '14 at 9:27

Below you find a very well-performaning solution to set mesh UVs from a source in a per-vertex format to Blender's per-loop (face corner).

This assumes you have a sequence of float pairs (UV coord),
e.g. ((0.2, 0.1), (0.8, 0.9), (0.2,0.1), ...).

import bpy
from random import random

me = bpy.context.object.data

# Sample data
vert_uvs = [(random(), random()) for i in range(len(me.vertices))]

me.uv_textures.new("test")
me.uv_layers[-1].data.foreach_set("uv", [uv for pair in [vert_uvs[l.vertex_index] for l in me.loops] for uv in pair])


I made it work adapting this http://blenderartists.org/forum/showthread.php?321210-Importing-UV-coordinates. My problem is that it works but I don´t understand it, if someone wants to explain the code i would very grateful, anyway here is my solution:

for i in range(0,numeroparts):
malla.append(bpy.data.meshes.new(name="2k_Part"+str(i)))
uv = []
xyz= []
for j in range(0,numerovertxpart[i]):
x,y,z,u,v=float(line.split()[0].replace(',','.')),float(line.split()[1].replace(',','.')),float(line.split()[2].replace(',','.')),float(line.split()[3].replace(',','.')),float(line.split()[4].replace(',','.'))
uv.append((u,v))
xyz.append((x,y,z))
print(x,y,z)

aa = []
bb = []
cc = []
faces= []

for j in range(0,numerofacexpart[i]):
a,b,c=int(line.split()[0]),int(line.split()[1]),int(line.split()[2])
faces.append((a,b,c))
aa.append(a)
bb.append(b)
cc.append(c)
print(a,b,c)

malla[i].from_pydata(xyz, [], faces)

malla[i].uv_textures.new(name="UVMap")
uv_layer = malla[i].uv_layers[-1].data

vert_loops = {}
for l in malla[i].loops:
vert_loops.setdefault(l.vertex_index, []).append(l.index)

# Assume as uv = [(0.3, 0.6), (0.1, 0.4), ...]
# with uv coords in order of vertices

for q, coord in enumerate(uv):
# For every loop of a vertex
for li in vert_loops[q]:
uv_layer[li].uv = coord