3
$\begingroup$

I have a python script that sets vertex colors per vertex (reading the data from lists) which worked in blender3.3. I'd like to use that script in blender 3.5 (simulations branch) but it throws an error message, ( that it cannot find the color attributes name in the vertex' loops names )

I cant find any sample code of how to write the list of rgba values into a specified mesh's color attribute.

Any link or hint to sample code ? set color attributes via foreach_set() sample or smth like that? thanks for your time.

Previously used code, that wont work in blender 3.5, since it doesn't use layers to store color_attributes, i guess:

    bpy.ops.object.mode_set(mode='OBJECT')
    names=[l.name for l in obj.data.attributes]
    if colname not in names:
        bpy.ops.geometry.color_attribute_add(name=colname) 
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='DESELECT')
    bm = bmesh.from_edit_mesh(obj.data)
    for v in bm.verts:
        for l in v.link_loops:
            vcol=bm.loops.layers.color[colname]
            l[vcol] = [coldict[v.index],coldict[v.index],coldict[v.index], 1.0 ]

$\endgroup$

1 Answer 1

8
$\begingroup$

Color attributes have a domain and type. The reason your code doesn't work is the color_attribute_add creates a [Domain: Vertex, Type: Float Color] attribute, but your BMesh code is correct for a [Domain: Face Corner, Type: Byte Color] attribute.

Here's how you access the different kinds through a BMesh.

Domain Type How to access with BMesh
Vertex Byte Color bm.verts.layers.color
Vertex Float Color bm.verts.layers.float_color
Face Corner Byte Color bm.loops.layers.color
Face Corner Float Color bm.loops.layers.float_color

That said, you don't need to switch between modes, you can do it all in one mode.

In Object mode

colattr = obj.data.color_attributes.new(
    name=colname,
    type='FLOAT_COLOR',
    domain='POINT',
)

for v_index in range(len(obj.data.vertices)):
    colattr.data[v_index].color = [r, g, b, 1]

# alternatively, using foreach_set...
cols = []
for v_index in range(len(obj.data.vertices)):
    cols += [r, g, b, 1]
colattr.data.foreach_set("color", cols)

In Edit mode

bm = bmesh.from_edit_mesh(obj.data)
collayer = bm.verts.layers.float_color.new(colname)
for v in bm.verts:
    v[collayer] = [r, g, b, 1]
$\endgroup$
1
  • $\begingroup$ Thanks a million! And what a sound explanation, It will help me to get better used to attributes in bpy. $\endgroup$
    – richard
    Commented Dec 4, 2022 at 16:14

You must log in to answer this question.

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