I have 3 vertexgroups VG1 VG2 VG3 and 3 materials with exactly the same name VG1 VG2 VG2 as the vertexgroups, how I can assign each material to the corresponding vertexgroup in python? Also how I can get a list of faces in a vertexgroup?
EDITED:
A slightly more sophisticated version of the previous script, that now finds all the vertex groups of all the vertices of each polygon, isolates the most frequent vertex group and uses it to choose the correct material from the list. Also uses the method to find the material name that matches the vertex group name, as suggested by @batFINGER.
Try this (with the selected object):
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
# Now find the material slot with the same VG's name
ms_index = o.material_slots.find( groupName )
# Set material to polygon
if ms_index != -1: # material found
p.material_index = ms_index
-
2$\begingroup$ A couple of things, firstly surely only the faces with vertices all in a group would satisfy setting the material_index... and
material_index = o.material_slots.find(groupName)
$\endgroup$ – batFINGER Dec 5 '16 at 12:07 -
$\begingroup$ Good points @batFINGER. Will edit later when I have access to a computer. $\endgroup$ – TLousky Dec 5 '16 at 12:45
A more operator-centric approach
import bpy
context = bpy.context
obj = context.object
bpy.ops.object.mode_set(mode='EDIT')
for vg in obj.vertex_groups:
bpy.ops.mesh.select_all(action='DESELECT')
#obj.vertex_groups.active = vg # don't work
obj.vertex_groups.active_index = vg.index
bpy.ops.object.vertex_group_select()
i = obj.material_slots.find(vg.name)
if i >= 0:
obj.active_material_index = i
bpy.ops.object.material_slot_assign()
bpy.ops.object.mode_set(mode='OBJECT')
- can ofcourse have multiple vert groups per vertex, above code will set material to last vg in list with all verts in face in group. I suppose that's why vg's and materials aren't often linked together, as a face can be in multiple vg's and have only one material.
It's also easy to select the faces from the material with
bpy.ops.object.material_slot_select()
As for faces in a vertex group, run the bpy.ops.object.vertex_group_select()
operator after selecting active vertex group, (and clearing selection) then all selected faces will be in that group.