5
$\begingroup$

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?

$\endgroup$
5
$\begingroup$

enter image description here

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
|improve this answer|||||
$\endgroup$
  • 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
1
$\begingroup$

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.

|improve this answer|||||
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.