Easy Way to Access Vertex Colors in Python(BMesh)

I lost a bit the overview on all that vertex indexing stuff, that even becomes more complicated with “loops” in bmesh… Can somebody point me to an easy method to read/write the vertex color of a vertex in a mesh? I just check out the possibilities of Blender, Python, and VertexColors in order to mark points/vertices of interest for instance and later use the vertex for further computation (that part I have to come up with yet).

Problem:
obj.data.vertex_colors[0].data[0].color accesses a different vertex (by data[0]) than obj.data.vertices[0]

I’ve been looking at the BMesh module, but from_mesh() and to_mesh() don’t make it much easier actually…

Suggestions?

vertices don’t have color. Colors are actually stored in loops (per-face vertices).

>>> bpy.context.object.data.vertex_colors.active.data[0].color
Color((1.0, 0.2235294133424759, 0.0470588244497776))

data[0] <-- zero means loop zero

&gt;&gt;&gt; me = bpy.context.object.data
&gt;&gt;&gt; for li in me.polygons[0].loop_indices:
...     me.vertex_colors.active.data[li].color
... 
Color((1.0, 0.2235294133424759, 0.0470588244497776))
Color((0.4941176474094391, 0.03529411926865578, 1.0))
Color((0.003921568859368563, 0.23137255012989044, 1.0))
Color((0.0941176488995552, 0.9921568632125854, 0.003921568859368563))

Does anyone have an idea as to how to access the elements via BMesh API itself? I can reference a layer by name or index number, such as:

DCLayer = BMesh.loops.layers.color[“Diffuse Color”]

Where BMesh is a bmesh object generated by bmesh.from_mesh(). But I haven’t figured out how to access the color valuesl. The above line returns a BMLayerItem, which cannot be indexed, and has “name” and “copy_from” accessible. For instance, if I print(DCLayer.name), it will return “Diffuse Color”. Any help is appreciated.

This is for reading data that is supposed to exist, as it is for an exporter. The normal Blender object contains the vertex colors. Presumably bmesh.to_mesh() brings those values over as well. I know it brings the layer name over.

Hi Traveller13,

You’re on the right track. Once you have the layer stored in DCLayer, you then use it as key to access data from the BMesh. So for example;

DCLayer = BMesh.loops.layers.color["Diffuse Color"]
loopcolour = BMesh.faces[0].loops[0][DCLayer]

Then the loop colour will be stored in the loopcolour variable. Hope that helps.

Cheers,
Truman

Thank you. Are UV’s handled the same way?

yep:

UVLayer = BMesh.loops.layers.uv.active
loop_uv = BMesh.faces[0].loops[0][UVLayer]
uv = loop_uv.uv

And vertex groups? I would like to convert vertex weights to vertex colors. I Have no idea of how to start. I found some old examples, but they don’t seem to work.

Cheers.