1
$\begingroup$

I have a mesh and I want to know how I can color the whole vertex group of a certain face. I currently can color a face from a list as shown below, but I want to set the material of the whole vertex group of each of these faces in the list instead of just the faces.

for poly in bpy.data.objects['Mymesh'].data.polygons:
    #set material 1 for the whole mesh
    poly.material_index = 0 

for a in list:
#set material 2 for some faces - I want it instead to set the material of vertex groups 
#of these faces in the list instead of just the faces 
bpy.data.objects['Mymesh'].data.polygons[a].material_index = 1 
$\endgroup$

1 Answer 1

1
$\begingroup$

You can modify a previous answer to do this:

import bpy

o = bpy.context.object

for p in o.data.polygons:
    # Get all the vertex groups of all the vertices of this polygon
    verts_vertexGroups = [ g.group for v in p.vertices for g in o.data.vertices[ v ].groups ]

    # Find the most frequent (mode) of all vertex groups
    counts    = [ verts_vertexGroups.count( idx ) for idx in verts_vertexGroups ]
    modeIndex = counts.index( max( counts ) )
    mode      = verts_vertexGroups[ modeIndex ]

    groupName = o.vertex_groups[ mode ].name

    # If this polygon belongs to a specific VG, change its material
    if groupName == "VGwereInterestedIn":
        p.material_index = material_index # The material slot we want to use to shade polygons in this VG

EDITED:

I revised the code to answer the actual question, while leaving the above answer in case it interests other users. The code below takes a list of face indices and a material index, and assigns the material index to all the polygons that belong to these faces' vertex group/s.

import bpy

o = bpy.context.object

# List of face indices that represent vertex groups we want to shade with a specific material
myFaceList = [ 0, 100, 52, 32 ] 

# Index of the material for shading the vertex group/s of the faces above
materialIndex = 1

def find_polygons_vertexgroup( p ):
    # Get all the vertex groups of all the vertices of this polygon
    verts_vertexGroups = [ g.group for v in p.vertices for g in o.data.vertices[ v ].groups ]

    # Find the most frequent (mode) of all vertex groups
    counts    = [ verts_vertexGroups.count( idx ) for idx in verts_vertexGroups ]
    modeIndex = counts.index( max( counts ) )
    mode      = verts_vertexGroups[ modeIndex ]

    return mode

for pi in myFaceList:
    # Find the current polygon's vertex group index
    vgIndex = find_polygons_vertexgroup( o.data.polygons[ pi ] )

    # Iterate over all polygons and change their material VG is the same
    for p in o.data.polygons:
        p_vgIndex = find_polygons_vertexgroup( p )

        if p_vgIndex == vgIndex:
            p.material_index = materialIndex
$\endgroup$
6
  • $\begingroup$ Thanks for your answer. I think you misunderstood my question. I don't want to color a specific VG by name. Each vertex in my mesh is assigned to one and only one vertex group, where a vertex group will have it's unique vertices, so no vertex sharing among vertex groups. I then have a list of faces which I want to color the whole vertex groups connected to this faces with a certain material. Can you leave the answer above as I may use it in the future and it may be helpful to others and just edit it with another approach to fit my case? Many thanks $\endgroup$
    – Tak
    Commented Dec 13, 2016 at 23:04
  • $\begingroup$ I've tried doing it but I did it with couple of next for loops which made it very slow, so I look forward for your efficient solution, and as I mentioned previously, please don't remove or update the script in your answer as it may be helpful to others, I'd just appreciate it if you could edit the answer and include another script for my problem. I've already upvoted your answer. $\endgroup$
    – Tak
    Commented Dec 13, 2016 at 23:25
  • 1
    $\begingroup$ @Tak, revised answer included in edited answer. Let me know if this works for you. $\endgroup$
    – TLousky
    Commented Dec 14, 2016 at 9:39
  • $\begingroup$ Hello, sorry to bother you again. I'm currently using this method to color the whole vertex groups of faces in a list. The problem that my mesh is very high poly and blender hangs for ages during the animation every frame (about 20 sec per frame) so too slow. There is no better way to set the material of a vertex group at once? so if vertex a has weights in both vg1 and vg2 straight away set the color or material of these groups to red without having to loop on all vertices? $\endgroup$
    – Tak
    Commented Feb 27, 2017 at 9:03
  • $\begingroup$ @Tak, sorry, unfortunately not really available to try solve this at the moment (workload). I'd try using operators to mass select the entire vertex group (bpy.ops.object.vertex_group_select()) and mass assign materials (blender.stackexchange.com/questions/27190/…) $\endgroup$
    – TLousky
    Commented Feb 28, 2017 at 8:37

You must log in to answer this question.

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