1
$\begingroup$

I try to transfert a facial animation using shapekeys from one model to my target model using Rigify rig and drivers facial animation.

enter image description here

enter image description here

It works to do it by hand with this technique :

enter image description here

I copy as new driver the shapekey and go to paste this on the matching driver. Just add "+ value" on the expression. This allows me to keep the driver that connects the facial bones rig. I absolutely have to keep them.

But i have 52 shapekeys to link with a another model, and I risk having to make these exchanges on a lot of characters, that's why I started making a script.

I started by matching the names of the shape keys :

import bpy
import re

# get the selected object

depsgraph = bpy.context.evaluated_depsgraph_get()

obj_a = bpy.context.object
selected_object = depsgraph.objects[ obj_a.name ]

obj_b = [obj for obj in bpy.context.selected_objects if obj != obj_a][0]

# get its shapekeys
shape_keys_a = obj_a.data.shape_keys.key_blocks
shape_keys_b = obj_b.data.shape_keys.key_blocks

Lsuffix = 'Left'
# loop through shapekeys and replace the names
for index, key in enumerate(shape_keys_b):
    if ('_L' in key.name) and not ('cor_' in key.name):
        key.name = key.name.replace("_L",Lsuffix)
        print (key.name)
        
Rsuffix = 'Right'
# loop through shapekeys and replace the names
for index, key in enumerate(shape_keys_b):
    if ('_R' in key.name) and not ('cor_' in key.name):
        key.name = key.name.replace("_R",Rsuffix)
        print (key.name)
        
print (obj_a.name)
print (obj_b.name)

I chose the method where I select the 2 objects with an active, then I match the names of the shape keys.

For this part it's ok, but I get stuck when it comes to adding a variable to the already existing driver.

I saw on several topics on the website that we could not use python interface commands like :

bpy.ops.ui.copy_as_driver_button()
bpy.ops.graph.driver_variable_paste()

The 2 commands which correspond to Copy as a New Driver, and Paste Driver Variable.

I read that to edit a driver it was better to delete it and create a new one with the new information, but i can't do it because i will lose the first variable connected with rig.

So far I've tried something like this, but several things aren't working.

for index, key_a in enumerate(shape_keys_a):
    for index, key_b in enumerate(shape_keys_b):
        if (key_a.name == key_b.name) and (key_a.name != 'Basis'):
            
            #print (key_a.name)
            
            idx = obj_a.data.shape_keys.key_blocks.find(key_a.name)
            
            #print (idx)      
            drvs = bpy.data.shape_keys['Key.004'].animation_data.drivers[idx]
            var1 = drvs.driver.variables.new()
            var1.name = "value" # add a name to this variable
            var1.targets[0].id_type = 'KEY' # set ID type to a target object with the custom attribute
            var1.targets[0].id = bpy.data.shape_keys['Key.008'] # set the object as ID
            var1.targets[0].data_path = ' key_blocks["' + key_a.name + '"].value' # link the custom property
            drvs.driver.expression = drvs.driver.expression + '+value' # set the variable with the custom attribute value as an expression

Edit : Now I manage to add the variables to the drivers but I have a discrepancy in the ID levels i think. The key_a.name on data_path dont't match with the good shapekey name. I don't understand why...

enter image description here

A good challenge ahead, thanks for any help!

$\endgroup$

0

You must log in to answer this question.

Browse other questions tagged .