0
$\begingroup$

There's several answers on how to get vertex colors here on StackExchange, but something seems to have changed in 4.0 because none of them work.

bmesh.loops.layers.color[0] returns index out of range

$\endgroup$
1

1 Answer 1

1
$\begingroup$

I've done this only a few times, so maybe regulars can explain this in more technical terms, but here it goes.

  • First make sure your mesh does have vertex colors data
  • Vertex colors are stored in attribute group, as face corner / byte color data

In my case I have a Vertex Color attribute group called 'Color' in my mesh:

enter image description here

Then my mesh looks like this (it has two red vertices, one blue and one green vertex):

enter image description here

Here is code, which prints vertex colors of each face's loops:

def print_vertex_colors(obj):

    bm = bmesh.new()
    bm.from_mesh(obj.data)    
    
    # Update bmesh
    bm.faces.ensure_lookup_table()
    
    # Get color layer
    color = bm.loops.layers.color['Color']
    
    print("--- Bmesh Face Corner / Byte Color ---")
    
    # Print all face vertex colors
    for f in bm.faces:
        for loop in f.loops:        
            print(loop[color])

print_vertex_colors(bpy.context.active_object)

# Output:
#--- Bmesh Face Corner / Byte Color ---
#<Vector (0.0000, 1.0000, 0.0000, 1.0000)>
#<Vector (1.0000, 0.0000, 0.0000, 1.0000)>
#<Vector (1.0000, 0.0000, 0.0000, 1.0000)>
#<Vector (0.0000, 0.0000, 1.0000, 1.0000)>
$\endgroup$
7
  • 1
    $\begingroup$ Thank you, I will test this answer in the evening, but just to note, when you bake something to a vertex color using Cycles, it seems to produce both an attribute and a color attribute and both have vertex -> color as their... "type"? $\endgroup$
    – eobet
    Mar 19 at 7:57
  • $\begingroup$ OK, that is interesting. There colors were created using Vertex Paint mode. I haven't touched Cycles / rendering in long time, as I mostly work with realtime models, so I have no idea how it behaves in regards to vertex colors. Probably will test it though to see how this works with Cycles. $\endgroup$
    – ezez
    Mar 19 at 12:22
  • $\begingroup$ Color Attributes are a subset of Attributes so it is normal that the color attributes are also found in the more general Attributes panel. In recent versions vertex colors have been generalized to use the same system as all other attributes, I guess for legacy reasons and for interoperability with other softs they are still shown as a separate group of entities when they in fact are the same thing $\endgroup$
    – Gorgious
    Mar 19 at 14:58
  • $\begingroup$ Sorry, testing your code, I tried to replace 'color' with 0, because I don't want to hardcode a name, but rather get the first color attribute there is (it's in the original question), but that gives me error "Nonetype object has no attribute faces", so what's the proper syntax for getting whatever is the first in loops.layers.color? $\endgroup$
    – eobet
    Mar 19 at 17:07
  • 1
    $\begingroup$ Note - if your data is of type Face Corner / Byte color, you can access it with bm.loops.layers.color['Color'] or .color[0] (if its the first element in your attributes list). But if your data is of type Vertex / Color, you have to use verts data, instead of loops in faces. So do bm.verts.ensure_lookup_table() then get the vertex data with color = bm.verts.layers.float_color['Color2'] or .float_color[0] (if its the first element) and the in the loop for verts, you can get the color value with vert[color] $\endgroup$
    – ezez
    Mar 19 at 18:09

You must log in to answer this question.

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