I'm trying to write a script that will automate applying shapeKeys and subSerfs into LOD's ready for export into a game engine. It's going well so far but I'm stuck on setting the value of the shape key for a copied mesh ready to be applied.
Here is what I have so far.
import bpy
obj = bpy.context.object
objName = obj.name
i = 0
shapekeysList = [] #building an array of all available sahpeKeys
for sp in obj.data.shape_keys.key_blocks: #loop through available shape keys
shapekeysList.append(sp) #add shapeKey name to array
currentShapeKey = shapekeysList[i].name #grab current shapeKey
obj_dup = obj.copy() #duplicate selected mesh
newName = objName+"_"+shapekeysList[i].name #generate a name for the copy
obj_dup.data.shape_keys.key_blocks[shapekeysList[i].name].value = 1 #<--PROBLEM HERE
obj_dup.name = newName #rename copy to match the shapeKey it'll be set to
bpy.data.scenes[0].objects.link(obj_dup) #add copy to scene (I think)
i += 1 #tick up for next round
So the problem is instead of just updating the currentShapeKey for just the current object it seems to loop through all objects both the copies and the original (but not wholly separate meshes).
I've also tried changing the value after it's been renamed, added to the scene and is outside the copy loop but it keeps telling me that the object doesn't have that kind of data.
This feels like such a simple problem so sorry if this is just wasting time and thanks in advance for any help you can offer.
Also tried adding this as a work around but no cigar
for sk in shapekeysList:
obj_dup.data.shape_keys.key_blocks[shapekeysList[skCount].name].value = 0
print (" Current: " + shapekeysList[skCount].name)
print (" Target: " + shapekeysList[i].name)
if (shapekeysList[skCount].na
me != shapekeysList[i].name):
print(" DELETE "+shapekeysList[i].name)
#obj_dup.data.shape_keys.key_blocks[shapekeysList[i].name].shape_key_remove()
iIndex = obj_dup.data.shape_keys.key_blocks.keys().index(shapekeysList[i].name)
obj_dup.active_shape_key_index = iIndex
#bpy.ops.object.shape_key_remove()
else:
print(" KEEP "+shapekeysList[skCount].name)
skCount += 1
EDIT: Okay I think I've almost got it. The script copys the mesh with shape keys that don't seem to effect each other when testing but when I try to clean out the unused shapeKeys it still seems to want to target the original mesh killing the loop after the first round leaving me with an empty original and a full copy (opposite of what I need).
import bpy
obj = bpy.context.object
objName = obj.name
spIndex = obj.active_shape_key_index
i = 0
print ("-----------------------------") #Just breaking up the consol logs
shapekeysList = [] #building an array of all available sahpeKeys
fullShapekeysList = []
x=0
for fsp in obj.data.shape_keys.key_blocks: #loop through available shape keys
fullShapekeysList.append(fsp) #add shapeKey name to array
print('fullShapekeysList gets: '+fsp.name)
x += 1
for sp in obj.data.shape_keys.key_blocks: #loop through available shape keys
shapekeysList.append(sp) #add shapeKey name to array
currentShapeKey = shapekeysList[i].name #grab current shapeKey
print ("Shapekey: "+currentShapeKey) #Checking to make sure key and name below match
obj_dup = obj.copy() #duplicate selected mesh
obj_dup.data = obj.data.copy() #duplicate selected mesh
newName = objName+"_"+shapekeysList[i].name #generate a name for the copy
print ("newName: " + newName) #Just check the name will come out right
obj_dup.data.shape_keys.key_blocks[shapekeysList[i].name].value = 1 #Set target to one
#Convert copy to mesh
skCount = 0
for sk in fullShapekeysList:
print (" Current: " + fullShapekeysList[skCount].name)
print (" Target: " + fullShapekeysList[i].name)
if (fullShapekeysList[skCount].name == fullShapekeysList[i].name):
print(" KEEP "+fullShapekeysList[skCount].name)
else:
print(" DELETE "+fullShapekeysList[skCount].name)
iIndex = obj_dup.data.shape_keys.key_blocks.keys().index(fullShapekeysList[skCount].name)
obj_dup.active_shape_key_index = iIndex
bpy.ops.object.shape_key_remove()
skCount += 1
obj_dup.name = newName #rename copy to match the shapeKey it'll be set to
bpy.data.scenes[0].objects.link(obj_dup) #add copy to scene (I think)
i += 1 #tick up for next round
```