# How to export UVs per-vertex in script (as OBJ format does)?

OpenGL (the model's final destination) only accepts per-vertex UVs, so it is a must to use per-vertex and not "per face-vertex" UVs. The question isn't about OGL, that's just my reasoning. The OBJ format stores UVs per-vertex, proving that it is possible. I also have checked the code of the default OBJ exporter. However, it's UV exporting code is completely reliant on the rest of it's code making it very difficult to read and understand the default OBJ exporter script.

Current code for exporting UVs:

for face in mesh.polygons:
for vert, loop in zip(face.vertices, face.loop_indices):
if (vert in usedverts):
print("duplicate")
else:
for z in (mesh.uv_layers.active.data[loop].uv if mesh.uv_layers.active is not None else (0.0, 0.0)):
f.write(struct.pack('f', z))


It doesn't export them correctly, whether or not I use the if (vert in usedverts):. I think because when removing duplicates, they end up in the wrong order or something like that. Maybe someone has a better example of per vertex UV exporting [than the confusing default obj exporter]?

• I think the "per vertex" you mention here is incorrect (and logically impossible). I'm not experimented so much in openGL, but to me, UV coord has to be defined accordingly to the 3D faces definitions. – lemon Apr 21 '17 at 6:38
• I'm voting to close this question as off-topic because this is a openGL programming problem which is not directly related to Blender's usage, function or scripting. – lemon Apr 21 '17 at 7:20
• Yes it is, it's related to writing exporting scripts. – Accumulator Apr 21 '17 at 18:38
• Please see my first comment. In this script you'll have to export per face data. In order to recompose faces 3D coordinates and its corresponding us coordinates. – lemon Apr 21 '17 at 20:30
• Edited my question a lot. @lemon OBJ format exports per-vertex UVs. – Accumulator Apr 23 '17 at 20:01

If you are aiming to use UV coordinates with OpenGL, at some step, you'll have to use instructions like this one:

   glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);

glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();


Which means that:

• UV coordinates are given per vertex...
• ... but given per vertex only in the scope of a drawn face

So we have, in fact a per face information.

In your export program, you may:

• Loop over the vertices to store their coordinates
• Loop over the faces to store the vertices they use (e.g. making fan polygons)
• Loop over the UV maps, and for each:
• Loop over the polygons (at obj.data level)
• Loop over each polygon's loop_indices and take the corresponding data (uv coordinates) in the current UV map.

This can be something like this (code template):

import bpy

obj = bpy.context.object #An object (selected one)

#Write 3D coordinates
for v in obj.data.vertices:
pass

#Write polygons (faces)
for p in obj.data.polygons:
#Write a line per polygon indicating the vertices it uses
for i in p.vertices:
#See explanation 1 below
pass

#Write each uv map
for uvMap in obj.data.uv_layers:
#Process this uvMap
for p in obj.data.polygons:
#Use the polygon loop indices
for li in p.loop_indices:
#Write the uv coordinates for each vertex in the uv map
uvMap.data[li].uv
#See explanation 2 below


Explanation 1 (see comments in code):

The indices stored here refer to the previously written 3D coordinates in the same order they've been written

Explanation 2 (see comments in code):

The uv coordinates stored here correspond to the polygons vertices indices in the same order they are written previously in the polygons part

• My problem is, each vertex is only processed once, so only one UV coord can be used for any given vertex, so any repeating UVs will break everything. A vertex is not processed again when drawing another face, so using indice-based UVs isn't possible, if that's what you're suggesting (is it)? So if blender will only give indice based UVs which which includes repeats, I need a way to sort them into a list that is in the same order of the vertex they correspond to – Accumulator Apr 24 '17 at 17:05
• There is a discussion link in the comments below your question above, please use it so that we can talk about it – lemon Apr 24 '17 at 17:07