Tools to work with vertex groups on Lattices?

Well it didn’t exist, so I have created it. I doubt this script is optimal, but this will transfer weights between a selected lattice and an active mesh object based on vertex proximity. Hopefully we get full weight tools for lattices one day.

###  MADE BY aVersionOfReality.com, @AversionReality
# How it works:
# - Select a lattice and then a mesh you want to transfer groups from.
# - All vertex groups on the mesh object will be created on the lattice. with 0 weight at first.
# - For each point in the lattice, it checks for any verts within the distance margin.
# - For each vert in range (should only be 1), it assigns weights to vertex groups.
# - Works in Global space, so origin point location doesn't matter, only vert and point location.
# - I don't know what will happen if multiple points are in range. Not extensively tested.
# - I am not experienced at Python so don't use this as a reference.

import bpy
from mathutils import Vector

####
margin = .0001

####
selected = bpy.context.selected_editable_objects
active = bpy.context.active_object
selected.remove(active)

mesh = active
lattice = selected[0]

#####################
def make_groups(mesh, latt):   
    #get vertex groups on objects
    mesh_groups = [g.name for g in mesh.vertex_groups]
    latt_groups = [g.name for g in lattice.vertex_groups]
    
    #create groups that don't already exist
    for g in mesh_groups:
        if g not in latt_groups:
            lattice.vertex_groups.new(name=g)

def compare_loc(loc1, loc2):
    distance = (loc2 - loc1).length
    return distance

def copy_weights(mesh, lattice, vert, point, index):    
    #get group names and weight
    group_weight = {}
    for vg in vert.groups:
        for vgroup in mesh.vertex_groups:
            if vgroup.index == vg.group:
                gname = vgroup.name
                
        group_weight.update({gname:vg.weight})
        group_keys = [key for key in group_weight]
        #print(group_keys)

    #get index of group of the same name on lattice, replace group name with index
    for vgroup in lattice.vertex_groups:
        for key in group_keys:
            if vgroup.name == key:
                group_weight[vgroup.index] = group_weight.pop(key)
    
    #print(group_weight)
    #assign weights to points
    for ind, weight in group_weight.items():
        #print('index =', ind, 'weight =', weight)
        lattice.vertex_groups[ind].add([index], weight, 'REPLACE')
    
#-------Program-------#

make_groups(mesh, lattice)

#list verts and points
verts = [v for v in mesh.data.vertices]
points = [p for p in lattice.data.points]

#if same loc, copy weights
for ind, p in enumerate(points):
    p_loc = lattice.matrix_world @ p.co
    for v in verts:
        v_loc = mesh.matrix_world @ v.co
        #compare locations
        distance = compare_loc(p_loc, v_loc)
        #print(distance)
        
        if distance <= margin:
            match = True
            #print(match, distance)
        else:
            match = False
        
        if match:
            copy_weights(mesh, lattice, v, p, ind)
5 Likes