1
$\begingroup$

Imagine you have the following situation: you want to color the vertices relative to a certain vertex group x in red. I used the following function the problem is that it is not very efficient in fact blender stops working immediately, I'm working on a mesh with about 230,000 vertices and 500,000 faces (I just started developing addons blender and I still have a long way to go). PS. This operation will not be repeated once but many more depending on how many vertex groups I need to color

            name_vertex_group = "myVG"
            name_mesh = "myMesh"
            
            mesh = bpy.data.objects[name_mesh].data
            vertex_group = bpy.data.objects[name_mesh].vertex_groups[name_vertex_group].index
            bpy.ops.object.mode_set(mode = "VERTEX_PAINT")

            index_vertex = []   
            vs = [vertex for vertex in mesh.vertices if(vertex.groups)]
            for vertex in vs:
                for vgroup in vertex.groups:
                    if(vgroup.group==vertex_group):
                        index_vertex.append(vertex.index)
                        break

            for face in mesh.polygons:
                for vert in index_vertex:
                    for loop_index in face.loop_indices:
                        loop_vert_index = mesh.loops[loop_index].vertex_index
                        if vert == loop_vert_index:
                            mesh.vertex_colors.active.data[loop_index].color = [255, 0, 0, 1]
                            break
            
            bpy.ops.object.mode_set(mode = "EDIT")
$\endgroup$

1 Answer 1

2
$\begingroup$

Am I right to guess you're running this script from Edit Mode? If that's the case, you can use Bmesh to loop through the mesh and set the colors.

The execution time will vary wildly depending on your computer build, but this method has been taking 1-2s to process a mesh with 1.5 million faces, as opposed to 15 seconds when using an approach altering data directly like yours.

import bpy
import bmesh
from time import time


obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

# Vertex group index => vertex color
vgroup_colors = {
    obj.vertex_groups['Test_VGroup'].index: (0, 0, 1, 0),  # BLUE
    obj.vertex_groups['Test_VGroup2'].index: (1, 0, 0, 1),  # RED
}

# Extract group indexes for later usage
target_vertex_groups = vgroup_colors.keys()

# Destination vertex color layers
vcolor_layers = {
    obj.vertex_groups['Test_VGroup'].index: bm.loops.layers.color['Col'],
    obj.vertex_groups['Test_VGroup2'].index: bm.loops.layers.color['Col2'],
}

# Get vertex group weight layers
dl = bm.verts.layers.deform.verify()

start = time()
for vertex in bm.verts:
    
    # Only loop through vertex groups when vertex belongs to any
    if len(vertex[dl]):

        # Return keys (vertex group indexes) of groups in which this vertex has weight over 0
        in_vgroups = [vgroup_index for vgroup_index, weight in vertex[dl].items() if (weight)]
        
        # Extract indexes of groups of interest from this list
        in_target_vgroups = set(target_vertex_groups).intersection(in_vgroups)
        
        
        # For each face corner this vertex is part of
        for face_corner in vertex.link_loops:
        
            # Set colors for found vertex groups
            for vgroup_idx in in_target_vgroups:
                face_corner[vcolor_layers[vgroup_idx]] = vgroup_colors[vgroup_idx]

end = time()
print("%ss elapsed" % (end-start))

# Update viewport
obj.data.update()
$\endgroup$
1
  • $\begingroup$ hi your solution is very good but I still have a problem. If for example I have to color 1 or 2 vertex groups then your solution is perfect, but if I am in the bad case where I have to color a hundred vertex groups then blender takes longer to run your script. To give you an idea, the largest vertex group has 42000 vertices inside it, is there a more efficient solution in this case? $\endgroup$
    – luke_mcp
    Commented Aug 10, 2022 at 16:31

You must log in to answer this question.

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