2
$\begingroup$

I recently decided to make a binary exporter to load into a game engine I am also writing, but I'm very much stuck on blender UVs. I understand that the UVs have to for loop indices because of hard edges, but I have no idea how to pair the UV up with their respective vertices.

What is the relationship between a UV coordinate and a vertex in blender? I would like to be able to remove the duplicate vertice/UV pairs to cut down on buffer data in my program (which I would imagine would save a LOT of data for a handful of complex models), but I can't seem to pair the two together.

I can see how loop indices pair with vertices in the polygons class and via the vertex_index property of loop indices, but I have no idea how to relate these to the appropriate uv_layers data. Any help would be greatly appreciated; thanks for your time!

$\endgroup$
6
$\begingroup$

The UVs and Vcols (vertex Colors) have the same logic of "per vertex in a face" order, flated in a simple sequence.

enter image description here

  1. You have the polygon vertex indices and vertices list, so it can be deduces from here. Simple and very useful. More so, if u actually generate the mesh data and not read from an object.
  2. You can access the mesh loops (the very rule of vert per face etc) to read what contains the vert index / uv. This should be done probably with foreach_get/set function that is more efficient.

Let's see var 1, as you actually seam to know these but just miss the relation poly/vert index

(note that I create list of indices of the uv/vcol and verts, for precise coords etc you can further use them to read or write to actual data):

creating perPolygon and perVertex lists of lists like [[1, 3],[2, 5], [6, 8, 9]..] that correspond to the polygon / vertex list

    perPoly = []
    perVert = []    # best variable name yet :D

    if Object is not None and getattr(Object, 'type', '') == "MESH":
        # these are the poly vertex indices (as in the vert list)
        polyIndices = [p.vertices for p in Object.data.polygons]

        # create an list with empty lists for all verts
        perVert = [ [] for i in range(len(Object.data.vertices))]

        increment = 0
        for poly in polyIndices:
            lenP = len(poly)

            perPoly.append(i + increment for i in range(lenP))
            for i, vi in enumerate(poly): perVert[vi].append(i + increment) 

            increment += lenP

Note that I have not even read the uv (or vcol) data, if any. So you can use this in the very process of creating your own mesh or where there is no uv/vcol yet.

perVert / perPoly contain indication to positions in the ...uv_layers[0].data


the opposite, creating a list that parallels the uv list but contains the vertex index goes by flattening the polygon indices (polygon.vertices) list Basically, that is the way the uv list is done..

# explicit
flatVertsLikeUVs = []
for poly in Object.data.polygons:
    for i in poly.vertices:
        flatVertsLikeUVs.append(i)

or using chain, same stuff..

from itertools import chain

flatVertsLikeUVs = list( chain.from_iterable([p.vertices for p in Object.data.polygons]) )

an example:

uvs = Object.data.uv_layers[0].data
matchingVertIndex = list(chain.from_iterable(polyIndices))

# example, matching list of uv coord and 3dVert coord:
uvs_XY = [i.uv for i in Object.data.uv_layers[0].data]
vertXYZ= [v.co for v in Object.data.vertices]

matchingVertIndex = list(chain.from_iterable([p.vertices for p in Object.data.polygons]))
# and now, the coord to pair with uv coord:
matchingVertsCoord = [vertsXYZ[i] for i in matchingVertIndex]

-

ps:

getting the mesh loop data/ uv layers with another option, but logic is the same: you may wanna look here for populating the list with fromeach get / set http://blenderartists.org/forum/showthread.php?391847-Efficient-copying-of-vertex-coords-to-and-from-numpy-arrays&highlight=numpy

you can skip the numpy part and just populate a previously created list, (like the perVert above).

$\endgroup$
  • 1
    $\begingroup$ I appreciate the time you took to help with this, and your sense of humor. I think I worded my question poorly. I have no issues obtaining the data for each of these items, but I'm not sure what uv_layers.active.data[x] would translate to in loops or loop indices. Once I understand that relationship, I can sort the rest of everything else out. I'm not really worried about exporter efficiency, as I have 0 python skills; I just want the file to be efficient for the engine. $\endgroup$ – user2446445 Feb 20 '16 at 13:11
  • $\begingroup$ the perVert/perPoly are a list of indices (in the same order as vert/poly lists, so you can zip them) that reference the uv_layers[0].data list. I'll try to add an extra visual explanation. $\endgroup$ – o.g. Feb 20 '16 at 20:54
  • $\begingroup$ This is exactly what I was confused about. Thank you so much! Also learned some new Python tricks looking through your code as well! $\endgroup$ – user2446445 Feb 21 '16 at 3:10
  • $\begingroup$ Can't you just use the mesh's .loops attribute? $\endgroup$ – Gustavo6046 Oct 5 '18 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.