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):
            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]?

  • $\begingroup$ 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. $\endgroup$
    – lemon
    Apr 21, 2017 at 6:38
  • 2
    $\begingroup$ 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. $\endgroup$
    – lemon
    Apr 21, 2017 at 7:20
  • $\begingroup$ Yes it is, it's related to writing exporting scripts. $\endgroup$ Apr 21, 2017 at 18:38
  • $\begingroup$ 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. $\endgroup$
    – lemon
    Apr 21, 2017 at 20:30
  • $\begingroup$ Edited my question a lot. @lemon OBJ format exports per-vertex UVs. $\endgroup$ Apr 23, 2017 at 20:01

1 Answer 1


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

   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);

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: 
    #Write v.co in your file

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

#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
            #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

  • $\begingroup$ 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 $\endgroup$ Apr 24, 2017 at 17:05
  • $\begingroup$ There is a discussion link in the comments below your question above, please use it so that we can talk about it $\endgroup$
    – lemon
    Apr 24, 2017 at 17:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .