I have a game model format which stores the UV coordinates for each vertex. To implement seams in the UV mapping, a vertex just appears twice, each having a different UV coordinate (it solves the lighting issues introduced with that by using custom normals stored for each vertex, but sadly I can't teach Blender custom normals correctly yet as I learned... another story).
Basically, my vertex data looks like this (made-up data):
Index X Y Z U V
0 1.4235 0.2434 -0.322 0.0 0.5
1 2.3242 0.231 0.323 0.5 0.0
2 1.2242 0.531 -0.323 0.5 0.5
...
So I started writing an importer for this format, and thought it's easy enough to just set an uv
property of a BMVert
instance - just to find out that BMVert
does not have a property for UV mapping at all.
From looking at the samples, it (logically) looks like I have to set the UV coordinates by iterating through loops rather than the vertices. But I'm a little stumped for an answer on how to find out the index of the vertex having the required UV coordinate when iterating through the loops.
The answer here UV Vertex using Python? was suggested, but it does not show how to retrieve the corresponding index of a vertex.
My current code to import the XYZ vertex positions (and normals) is as follows:
# Get the vertices and indices of the most detailled LoD model.
vertices = get_vertices(...)
indices = get_indices(...)
# Create a mesh and a bmesh to represent the polygon.
mesh = bpy.data.meshes.new(fshp.header.name_offset.name)
bm = bmesh.new()
bm.from_mesh(mesh)
# Go through the vertices and add them to the bmesh.
for vertex in vertices:
bm_vert = bm.verts.new(vertex.p0)
#bm_vert.normal = vertex.n0 # TODO: Blender does not really support custom normals yet, and they look weird.
bm.verts.ensure_lookup_table() # Required after adding / removing vertices and before accessing them by index.
# Connect the faces, they are organized as a triangle list.
for i in range(0, len(indices), 3):
bm.faces.new(bm.verts[j] for j in indices[i:i + 3])
# TODO: Set the UV coordinates??
uv_layer = bm.loops.layers.uv.active
for face in bm.faces:
for loop in face.loops:
loop[uv_layer].uv = #..?
# Write the bmesh data back to the mesh.
bm.to_mesh(mesh)
bm.free()
mesh_obj = bpy.data.objects.new(mesh.name, mesh)
bpy.context.scene.objects.link(mesh_obj)