NLA script not working properly

I have my .blend file here If you follow the below steps you will find it not working in the first time I run the script:

  • toogle to pose mode rotate the rightArm bone
  • switch to object mode
  • run the script you will find that an action strip is created in the NLA editor but it’s not working, I don’t know why?
  • Do steps 1->3 again and you will find it working. Not sure why it doesn’t work in the first time then works after that for the next runs?

like in the NLA editor, you will find the strip properties created from the first run is exactly the same as the strip properties created from the second one, but it just don’t do the action for some reason.

Not sure if this is a bug in blender or what?

Try to save the pose in poselib at the beginning of the script and restore it before this line:

bpy.ops.anim.keyframe_insert_menu(type='Rotation')

Thank you. Could you please show me how this can be done?

This code works for me:


import bpy
SMOOTH_TIME = 25
bpy.ops.object.select_all(action='DESELECT')
C = bpy.context
cf = C.scene.frame_current
bpy.context.scene.objects.active = bpy.data.objects['sit']

# to save the pose you have to be in pose mode and you need to select all bones
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.pose.select_all(action='SELECT')
bpy.ops.poselib.pose_add(frame=999, name="TempPose")

ob = bpy.data.objects['sit']
action = ob.animation_data.action
if action is not None:
    print('Entered 1 if')
    track1 = ob.animation_data.nla_tracks.new()
    #track.name = "FullNLATrack"
    track1.strips.new(action.name, action.frame_range[0], action)
    ob.animation_data.action = None
#bpy.ops.nla.action_pushdown(channel_index=1)
#bpy.ops.object.posemode_toggle()

# restore the pose and remove temp pose
idx = C.object.pose_library.pose_markers.find("TempPose")
bpy.ops.poselib.apply_pose(idx)
bpy.ops.poselib.pose_remove(pose="TempPose")

bpy.ops.pose.select_all(action='DESELECT')
bpy.data.objects['sit'].data.bones['RightArm'].select = True
bpy.data.objects['sit'].data.bones.active = bpy.data.objects['sit'].data.bones['RightArm']
bpy.ops.anim.keyframe_insert_menu(type='Rotation')
#bpy.ops.nla.action_pushdown(channel_index=1)
action = ob.animation_data.action
if action is not None:
    print('Entered 2 if')
    track2 = ob.animation_data.nla_tracks.new()
    #track.name = "NewNLATrack"
    strip2 = track2.strips.new(action.name, action.frame_range[0], action)
    #ob.animation_data.action = None
    #strip.name = "NewStrip"
    #bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].action_frame_start = (bpy.context.scene.frame_current - 15)
    bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].frame_start = (bpy.context.scene.frame_current - SMOOTH_TIME)
    #print(bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].action_frame_start)
    #bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].action_frame_end = (bpy.context.scene.frame_current + 15)
    bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].frame_end = (bpy.context.scene.frame_current + SMOOTH_TIME)
    #print(bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].action_frame_end)
    bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].blend_in = SMOOTH_TIME
    bpy.context.object.animation_data.nla_tracks[track2.name].strips[strip2.name].blend_out = SMOOTH_TIME
    ob.animation_data.action = None

bpy.ops.object.posemode_toggle()
bpy.ops.object.select_all(action='DESELECT')

Thank you very much. But I wonder why it wasn’t working in only the first time in my original script?

The code in the first if block will be executed only once (when action is not None). That block resets all changes in pose mode. That’s why you need to save the changed pose somewhere and restore it after that block.

Thank you very much