简体   繁体   中英

Loop only saves last iteration

I am using python in the context of blender 's api so it could be that this problem is particular to that api (am asking in that forum too) but I think I am making a more generic python error so I thought it might be worth asking in this context. Please note I am a complete beginner to python.

I am writing a fairly simple script that loops through every frame of a scene copying and translating some animation data from type to another (armature rig -> shapekeys). I then go through each frame and try to set the new animation data as a keyframe value of 1, and set all other keys to 0.

To abstract the problem away from this particular issue, for eg 13 frames in a scene, each frame has 13 possible animation states, and for each scene 1 of those animation states should be set to a value of 1 while all the others should be set to 0. The problem I am having is that rather than each frame having its corresponding animation state set to 1, only the last animation state is set to 1 regardless of the frame.

Please see my code below. I include all for reference but the first section works fine, it is the 2nd section where the issue exists.

#blender import
import bpy
#save the total number of frames as var
frames = bpy.context.scene.frame_end + 1

#loop through frames, jump to each frame, add the armature, set as shapekey
for frame in range(frames):
    bpy.context.scene.frame_set(frame)
    bpy.ops.object.modifier_add(type='ARMATURE')
    bpy.context.object.modifiers["Armature"].object = bpy.data.objects["rig"]
    bpy.ops.object.modifier_apply(apply_as='SHAPE', modifier="Armature")
    #loop through shapekeys and add as keyframe per frame, this is where the issue is.
    for shapekey in bpy.data.shape_keys:
        for i, keyblock in enumerate(shapekey.key_blocks):
            if keyblock.name != 'Basis':
                curr = i - 1
                if curr != frame:
                    keyblock.value = 0
                    keyblock.keyframe_insert("value",frame=curr)
                else:
                    keyblock.value = 1
                    keyblock.keyframe_insert("value",frame=curr)

What I expect to happen is that for each frame, the corresponding shapekey will have a keyframed value of 1 and all the others have 0.

So:

  • for frame 0, 'Armature' shapekey has value 1, all others have 0

  • for frame 1, 'Armature.001' shapekey has value 1, all others have 0

  • for frame 2, 'Armature.002' shapekey has value 1, all others have 0

But instead for all frames only 'Armature.013' shapekey has value 1 and all others are set to 0.

For this reason I think I am making a generic error, where somehow each loop is overwriting the last hence why only the last iteration shows.

I hope I have explained the issue clearly enough. Here is my question in the blender forum where a sample file is included if that helps at all.

Answering my own question as I figured it out. Just in case anyone else has a need for it, the below script works as expected.

import bpy

#save the total number of frames as var
frames = bpy.context.scene.frame_end + 1

#loop through frames, jump to each frame, add the armature, set as shapekey
for frame in range(frames):
    bpy.context.scene.frame_set(frame)
    bpy.ops.object.modifier_add(type='ARMATURE')
    bpy.context.object.modifiers["Armature"].object = bpy.data.objects["rig"]
    bpy.ops.object.modifier_apply(apply_as='SHAPE', modifier="Armature")

#for each frame, loop through shapekeys and add as keyframe per frame, set value to 1 if current frame = corresponding shapekey
for frame in range(frames):
    for shapekey in bpy.data.shape_keys:
        for i, keyblock in enumerate(shapekey.key_blocks):
            if keyblock.name != 'Basis':
               curr = i - 1
               if curr != frame:
                   keyblock.value = 0
                   keyblock.keyframe_insert("value", frame=frame)
               else:
                   keyblock.value = 1
                   keyblock.keyframe_insert("value", frame=frame)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM