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")