3
$\begingroup$

Taking a cue from this question, I'm testing to make a one-color fill to a vertex_colors. Works fine, but is very slow on meshes with many polygons.

ob = context.object
color = (0,0,0,0)
vertex_color = ob.data.vertex_colors['My Vertex color']
            
i = 0
for p in ob.data.polygons:
    for idx in p.loop_indices:
        vertex_color.data[i].color = (color)
        i += 1

I also found an operator,bpy.ops.paint.vertex_color_set() (It seems to be twice as fast) but I don't really like the idea, plus it's an operator with no input apparently

Is there any blender Api that do this directly?

After a good answer:

The code above is code that doesn't make sense in this case. My tests moved to this method (Not very fast):

for d in vertex_color.data[:]: #Slow method
    d.color = (1,0,0,1)

In any case, given @batFINGER answer, and @lemon help, the code is now 4 times and more, faster than before.

$\endgroup$
3
  • 1
    $\begingroup$ You can use "o.data.vertex_colors['Col'].data.foreach_set( "color", colors )" where "colors" is a flatten array of all the rgba colors. $\endgroup$
    – lemon
    Aug 23, 2020 at 15:11
  • $\begingroup$ Sorry @lemon RuntimeError: internal error setting the array $\endgroup$
    – Noob Cat
    Aug 23, 2020 at 15:18
  • 2
    $\begingroup$ the array needs to be flatten: [1, 0, 0, 1, 0, 1, 0, 1, ...] not [(1, 0, 0, 1), (0, 1, 0, 1), ...] and its length is so each vertex is considered for each face it belongs to. So for the cube, there are 24 vcols. $\endgroup$
    – lemon
    Aug 23, 2020 at 15:20

1 Answer 1

6
$\begingroup$

Set all loop vertex colors to one

Use foreach set method. Example of use here creating bezier curves https://blender.stackexchange.com/a/180184/15543

import bpy
import numpy as np

context = bpy.context

name = "Xxxx"
r, g, b, a = (1, 0, 0, 1) # red


ob = context.object
me = ob.data

color_layer = (me.vertex_colors.get(name)
               or me.vertex_colors.new(name=name)
               )
ones = np.ones(len(color_layer.data))

color_layer.data.foreach_set(
        "color",
        np.array((r * ones, g * ones, b * ones, a * ones)).T.ravel(),
        )
        
me.update()

Could also simply

np.array((r, g, b, a) * len(color_layer.data)).T.ravel()
$\endgroup$
0

You must log in to answer this question.

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