循环仅保存上一次迭代

时间:2019-08-18 22:39:37

标签: python for-loop blender

我在blenderapi上下文中使用python,因此可能是该问题特定于该api(也在该论坛中问),但我想我正在更通用的python错误,因此我认为在这种情况下可能值得提出。请注意,我是python的完整入门。

我正在编写一个相当简单的脚本,该脚本循环遍历场景的每一帧,并将某些动画数据从类型转换为另一种(电枢装置-> shapekey)。然后,我遍历每一帧,尝试将新的动画数据设置为关键帧值1,并将所有其他关键点设置为0。

将问题从该特定问题中抽象出来,例如一个场景中有13个帧,每个帧有13种可能的动画状态,对于每个场景,这些动画状态中的1个应设置为值1,而所有其他状态应设置为0。我遇到的问题是,而不是每个帧的对应动画状态均设置为1,无论帧如何,最后一个动画状态均设置为1。

请在下面查看我的代码。我提供了所有内容供参考,但是第一部分工作正常,这是存在问题的第二部分。

#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)

我希望发生的是,对于每一帧,相应的shapekey的关键帧值将为1,其他所有关键帧的值将为0。

所以:

  • 对于第0帧,“ Armature” shapekey的值为1,其他所有值为0

  • 对于第1帧,“ Armature.001” shapekey的值为1,其他所有值为0

  • 对于第2帧,“ Armature.002” shapekey的值为1,其他所有值为0

但是,对于所有帧,只有'Armature.013'shapekey的值为1,其他所有帧的值都设置为0。

出于这个原因,我认为我正在犯一个通用错误,其中每个循环都以某种方式覆盖了最后一个循环,因此为什么只显示最后一个迭代。

我希望我已经足够清楚地解释了这个问题。 Here是我在Blender论坛中的问题,如果有帮助的话,其中包括示例文件。

1 个答案:

答案 0 :(得分:0)

根据我的想法回答自己的问题。万一其他人有需要,下面的脚本将按预期工作。

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)