1
$\begingroup$

This started with this question.

I have a list of shape keys where some have and some don't have a driver. How do I get an index of a selected shape key driver? I thought of inputing just the index of the shape key but that of course doesn't work because they don't matchup.

a table representing indexes

My end game is to input the index of the selected shape key and get the name of the target bone which drives the selected shape key

Here is the code that I have currently (I currently get the name of the bone on the driver index 0 because I set it to that but of course I want that to be dynamic):

import bpy

#Defines the Basis name.
selected = bpy.context.object.active_shape_key_index
bpy.context.object.active_shape_key_index = 0
basis_name = bpy.context.object.active_shape_key.name
bpy.context.object.active_shape_key_index = selected

#Defines the selected shape key index.
selected_shape_key_index = bpy.context.object.active_shape_key_index

#Defines the selected shape key name.
selected_shape_key_name = bpy.context.object.active_shape_key.name

#Defines the selected shape key collection.
selected_shape_key_collection = bpy.context.object.active_shape_key.id_data.name

#x is the index of shape key with a driver. In my scene since I have 2 shape keys with drivers the index goes from 0 to 1.
x = 0

print(bpy.data.shape_keys["ShapeKeyCollection"].id_data.animation_data.drivers[x].driver.variables[0].targets[0].bone_target)

This is the little test/example file (Blender 2.9 alpha):

$\endgroup$
3
  • 1
    $\begingroup$ Is limitation that search target is variables[0].targets[0].bone_target and driven property is 'value' only? $\endgroup$ – tetii Jul 12 '20 at 1:02
  • 1
    $\begingroup$ It doesn't seem like a good idea using an index to match a shape_key and driver. Because multiple drivers can be contained in one shape_key. Also a variables and targets collection can have multiple elements.Can you clarify the condition? $\endgroup$ – tetii Jul 12 '20 at 5:08
  • $\begingroup$ Well I posted an answer. So now it might me more clear what I want. The only problem with the answer is that to me it looks a bit hacky, especially the .replace parts. $\endgroup$ – koko ze Jul 12 '20 at 19:36
1
$\begingroup$

I figured out a way of how to get a name of the bone that is driving a shape key. Although it is a bit hacky and it does work for only the first target in the driver. Also I abandoned the idea of trying to match the shape key index and the driver index. Now I use the shape key name to get the index of the driver if that makes sense.

import bpy

selected_shape_key_collection = bpy.context.object.active_shape_key.id_data.name
selected_shape_key_index = bpy.context.object.active_shape_key_index
selected_shape_key_name = bpy.context.object.active_shape_key.name


name_list = []
for x in bpy.context.object.active_shape_key.id_data.animation_data.drivers:
    #Hacky because I don't know how to get just the raw names so I used .replace
    name = x.data_path.replace('key_blocks["',"").replace('"].value',"")
    name_list.append(name)

if selected_shape_key_name not in name_list:
    print("No")
else:
    driver_index = name_list.index(selected_shape_key_name)
    print(bpy.data.shape_keys[selected_shape_key_collection].id_data.animation_data.drivers[driver_index].driver.variables[0].targets[0].bone_target)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.