.fi

- Blender: Python Scripting Bones / Vertex Groups / Shape Keys

Blender: Python Scripting Bones / Vertex Groups / Shape Keys

Posted: 2022-02-05 19:11:14Edited: 2023-01-10 15:37:01
Chronological Date: 2022-02-05

Blender has a powerfull scripting engine, that is no secret. I have had to utilize it more and more as time goes on. Here are a few examples for what I have had to use it for.

One example I have is when I had to create a script to automatically copy shape key names to another object, as AFAIK there is no function to do so in the GUI.

With this, we can just select 2 objects (one of which is active), and copy all the shape key names from the active to the other object:

import bpy
import re

actobj = bpy.context.active_object
if actobj:
    print("active: " + actobj.name)
    if len(bpy.context.selected_objects) == 2:
        if not actobj.data.shape_keys:
            for obj in bpy.context.selected_objects:
                if obj != actobj:
                    print("selected: " + obj.name)
                    if obj.data.shape_keys:
                        print("shapekeys")
                        for key in obj.data.shape_keys.key_blocks:
                            actobj.shape_key_add(name=str(key.name), from_mix=False);
                            print("Added " + key.name + " to " + actobj.name)

Another case I had was to rename some bones and their matching vertex groups (so it was going to be slow by hand!) to match Source Engine skeleton bone names. This time I had to utilize RegEx to match the names:

import bpy
import re

# script renaming MakeHuman (game engine rig) fingers to valveBiped

valveBipedBaseName = "ValveBiped.Bip01_"
valveBipedFingerName = "_Finger"

for rig in bpy.context.selected_objects:
    if rig.type == 'ARMATURE':
        # assuming this armature has the meshes as it's child
        for mesh in rig.children:
            # loop through the mesh vertex groups, they should be same as bones
            for vg in mesh.vertex_groups:
                oldname = vg.name
                newName = ""
                sideName = ""
                fingerName = ""
                jointName = ""
                regexHand = re.search("(hand)_([l|r])", oldname)
                regexFingor = re.search("([a-z]*)_([0-3]{2})_([l|r])", oldname)
                # check for hands first, they are need for gmod fingerposer
                if regexHand:
                    if regexHand.group(2) == "r":
                        sideName = "R"
                    else:
                        sideName = "L"
                    newName = valveBipedBaseName + sideName + "_Hand"
                # do some logic to replace names correctly
                elif regexFingor:
                    if regexFingor.group(3) == "r":
                        sideName = "R"
                    else:
                        sideName = "L"
                    if regexFingor.group(2) == "01":
                        jointName = ""
                    elif regexFingor.group(2) == "02":
                        jointName = "1"
                    elif regexFingor.group(2) == "03":
                        jointName = "2"
                    if regex.group(1) == "thumb":
                        fingerName = "0"
                    elif regexFingor.group(1) == "index":
                        fingerName = "1"
                    elif regexFingor.group(1) == "middle":
                        fingerName = "2"
                    elif regexFingor.group(1) == "ring":
                        fingerName = "3"
                    elif regexFingor.group(1) == "pinky":
                        fingerName = "4"
                    newName = valveBipedBaseName + sideName + valveBipedFingerName + fingerName + jointName
                if newName != "":
                    # rename them
                    rig.pose.bones[vg.name].name = newName
                    vg.name = newName
                    print("Renamed bone:" + oldname + " to: " + newName)
                else:
                    print("no new name")