Tools to work with vertex groups on Lattices?

Are there any scripts/addons that help with doing weights on lattices? There’s no weight paint mode for them, but you can assign weights in edit mode. So they could have complex weight groups, its just a pain to make. It’d be really useful if you could transfer weights from a mesh or something.

if there are scripts or addons I can’t tell you.
Standard it should not be possible, but that is my guess.
Since you can’t assign a datatransfer modifier for example, it doesn’t seem to be possible to get into a weightpainmode(that’s what it should really be called :crazy_face:) like it is usually the case with envelopes (geo).
What works is a hook modifier here you can change the Vertexweight afterwards but transfer “no!”.
Maybe a mesh-deformer is the better choice.

1 Like

Yeah. Lattices are difficult to work with, and usually, for no reason that I can tell.

Most of the time that you’re using a lattice, you can use a dynamic mesh deform instead, which allows you to use all the mesh tools you want on the mesh deformer. Unless I’m just trying to do something quick and permanent to deform something high poly (ie, high bind time), I usually just use mesh deformers.

Mesh deformers only ever interpolate linearly (or something like it), and can’t extend out to infinity, but otherwise, they can replace lattices.

1 Like

The situation i’m in requires a lot of precision. If I use mesh deformers, i have to turn the precision up to 8 and Dynamic on. And since I’m using several, I end up with my file size going up by like 800mb from the binding caches, which is annoying. The shapes i’m using are such that lattices will work, and don’t have the precision problem. There’s no technical limitation on using them, just the hassle of setting up all their weight groups by hand.

One thing you can do is use a mesh deformer on a lattice. That should simplify precision and bind times quite a bit. Don’t forget that you can use multiple manifold meshes for your mesh deform to have different behavior inside the lattice from outside. Then, you can deform the mesh deformer with its vertex groups and let the mesh deform propagate those changes to the lattice (which propagates them to your mesh.)

1 Like

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)
1 Like

Wow, thank you a lot for this

1 Like