A noob needs help with weights

Hi everyone,
I’m a noob to both Blender and 3d in general. I’m a pro 2D artist, and understand the concepts of 3d art and animating, but the interfaces and specific details cause me trouble. :wink:

Anyway:

I’ve created a humanoid robot model made of lots of seperate parts. I managed to use armitures to rig it, and the auto weights got me most of the way there. But heres my problem.

Becuase this is a robot made of parts, each part should in its entirety, be eother 100 percent weighted or not at all to the specific bones! Is there any better and more fool proof way besides weight painting to make sure I get ALL verts completely set to either zero or 100 percent weighted depending on the case. With painting, its too easy to miss some hidden verts for a given part.

thanks much.

When rigging a mechanical object, I just parent the mesh object to the bone. Select the mesh object, shift-select the armature, enter pose mode, select the bone, ctrl-p -> set parent to bone.

No need for armature modifier or weight painting/vertex groups. If you want to mess with the armature modifier & weight painting/vertex groups, it’s best to work from the object data panel, the vertex groups section, where you can manually assign/remove weights from vertex groups.

Randy

Thanks much revolt_randy.

If you are on 2.5 or higher, then another option is to use my ‘distribute weights’ operator.

Normally, I uses this script to ensure that only 3 bones affect a given vertex for exporting models to game engines. However, I’ve modified this version so that it limits each vertex to having 1 bone affecting it.

If you run this script then "normalize all’ you should end up with a mesh that has each bone influence at “1.0” or “0.0”.

To use it, make your target mesh the ‘active object’ then run the script.


import bpy


# Distributes the weighting on the vertices so that at most 'maxInfluence' bones
# affect the vertex.
def distributeWeight(obj, maxInfluence):

    print("--- %s ----" % (obj.name))

    # Access the mesh data.
    mesh = obj.data

    # Run though the vertices
    for v in mesh.vertices:
        
        # Get a list of the non-zero group weightings for the vertex
        nonZero = []
        for g in v.groups:
            
            g.weight = round(g.weight, 4)
            
            if g.weight < .0001:
                continue
            
            nonZero.append(g)

        # Sort them by weight decending
        byWeight = sorted(nonZero, key=lambda group: group.weight)
        byWeight.reverse()

        # As long as there are more than 'maxInfluence' bones, take the lowest influence bone
        # and distribute the weight to the other bones.
        while len(byWeight) > maxInfluence:

            print("Distributing weight for vertex %d" % (v.index))

            # Pop the lowest influence off and compute how much should go to the other bones.
            minInfluence = byWeight.pop()
            distributeWeight = minInfluence.weight / len(byWeight)
            minInfluence.weight = 0

            # Add this amount to the other bones        
            for influence in byWeight:
                influence.weight = influence.weight + distributeWeight

            # Round off the remaining values.
            for influence in byWeight:
                influence.weight = round(influence.weight, 4)

class DistributeWeightOperator(bpy.types.Operator):
    '''Distributes the weights at each vertex so that at most 1 group affect it.'''
    bl_idname = "object.distribute_weight_operator"
    bl_label = "Distribute Weight Operator"

    @classmethod
    def poll(cls, context):
        return len(context.selected_objects) > 0

    def execute(self, context):
        for obj in context.selected_objects:
            distributeWeight(obj, 1)
        return {'FINISHED'}


def register():
    bpy.utils.register_class(DistributeWeightOperator)


def unregister():
    bpy.utils.unregister_class(DistributeWeightOperator)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.distribute_weight_operator()