3
$\begingroup$

I'm trying to make a script so that I can apply all blended shape keys (starting from a specific one and then iterating through the list, keeping them in order) so that they work well when exporting as fbx but it's making a bit of a mess for some reason and I can't figure out why. Anyone has an idea? Or is there any other way to apply lots of shape keys with blends in an efficient way?

import bpy

obj = bpy.context.object
shapekeysList = len(obj.data.shape_keys.key_blocks)
spIndex = obj.active_shape_key_index

for sp in obj.data.shape_keys.key_blocks:
    print (obj.active_shape_key.name)
    obj.active_shape_key.value = 1   # enable shapekey before copying

    #apply shapekey
    obj.shape_key_add(name=str(obj.active_shape_key.name) + "_applied", from_mix=True)

    obj.active_shape_key.value = 0              # reset shapekey
    obj.active_shape_key_index = spIndex        # select shapekey
    bpy.ops.object.shape_key_remove()           # delete blended shape key

    # select next shape key
    spIndex = spIndex + 1
    obj.active_shape_key_index = spIndex

These are the original shape keys:

original

These are the original shape keys left after running the script:

original_created

These are the ones that get created:

created

This is my first Python script for Blender so I might be missing something pretty obvious or something... Thanks!

UPDATE: Ok if I go one by one manually with this code it works... but if I try to loop it it messes everything up, so the looping part is the one that's not working o.O

print (obj.active_shape_key.name)
obj.active_shape_key.value = 1              # enable shapekey before copying
index = obj.active_shape_key_index          # save index
obj.shape_key_add(name=str(obj.active_shape_key.name) + "_applied", from_mix=True)   #apply shapekey
obj.active_shape_key_index = index          # select original selection
bpy.ops.object.shape_key_remove()           # delete blended shape key
obj.active_shape_key_index += 1             # selec next in list

Also tried looping with this:

import bpy

obj = bpy.context.object
shapekeysList = len(obj.data.shape_keys.key_blocks)
spIndex = obj.active_shape_key_index

shapekeysList = []
for sp in obj.data.shape_keys.key_blocks:
    shapekeysList.append(sp)

for sp in shapekeysList:
    #the thing that's in the snipet above
$\endgroup$
1
$\begingroup$

Got this working:

import bpy

obj = bpy.context.object
spIndex = obj.active_shape_key_index
i = 0

### EDITABLE VARIABLES ###
last = "fullbody"       # Last shapekey to save
add =  "_applied"       # Add this to new blendshape's name

shapekeysList = []
shapekeyValues = []

for sp in obj.data.shape_keys.key_blocks:
    if last in sp.name:
        break
    shapekeysList.append(sp)
    shapekeyValues.append(sp.value)
    sp.value = 0
    print (shapekeysList[i].name + " | Value saved: " +  str(shapekeyValues[i]))
    i += 1

print ('\nFinished saving shape keys\n')
i = spIndex

while i < len(shapekeysList):
    shapekeysList[i].value = 1                                  # enable shapekey before copying
    print (shapekeysList[i].name + " | " + str(shapekeysList[i].value))

    obj.active_shape_key_index = i                    # select shape key to mix

    obj.shape_key_add(name=str(obj.active_shape_key.name) + add, from_mix=True)   #apply shapekey
    obj.active_shape_key_index = i                    # select original selection
    #bpy.ops.object.shape_key_remove()                           # delete blended shape key
    shapekeysList[i].value = 0
    #obj.active_shape_key_index += 1                             # select next in list
    i += 1
$\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.