script to convert all actions to NLA strips

I am trying to make a script that freezes all the actions into nla strips automatically—

but when I try to make an action into a NLA strip for the console via–>
bpy.ops.nla.actionclip_add(action=‘myactions’) it fails - what am I missing?

such operators need to run in the context of the target space, so the NLA editor in this case. If you run it from the pyconsole, the context is the pyconsole. You could use an override, but I suggest to use RNA methods instead:

import bpy

ob = bpy.context.object
assert(ob is not None), "no active object"

if ob.animation_data is None:
    ob.animation_data_create()
    
anim_data = ob.animation_data
anim_data.use_nla = True

track = anim_data.nla_tracks.new()
offset = 0
for action in reversed(bpy.data.actions):
    track.strips.new(action.name, offset, action)
    start, end = action.frame_range
    offset += end - start

OK wow firstly I am in awe of your intimate knowledge of blender python. you must have been at this for at least 15 years.

The problem I am having-- I am trying to directly freeze the actions that are currently assigned to the objects to NLA strips. I just don’t know the python to call to make the active actions in the NLA editor convert automatically.

Example Here are my animations- what I have been doing is constantly clicking the snowflake button until my mind explodes from boredom. It doesn’t look like much here in my example, but when I have over 200 objects in a scene it just becomes stupid.

I am trying to go from this


to this in one click


To be honest, I toyed around with the PyConsole and checked the API docs, but there’s nothing like “freezing”.

It took me a while to figure out what actually happens: An NLA track is created and a single strip added with the name of the action, at the position of the first frame in the action. The action of the object is then set to None (cleared) and the freeze-icon goes away (and “<No Action>” is shown).

import bpy

for ob in bpy.context.scene.objects:
    if ob.animation_data is not None:
        action = ob.animation_data.action
        if action is not None:
            track = ob.animation_data.nla_tracks.new()
            track.strips.new(action.name, action.frame_range[0], action)
            ob.animation_data.action = None

Wow you’re right—
how did you go about finding that?! Are you putting the console into verbose mode? I have no way of finding out what is happening under the hood like in this instance.

Well I created two objects with actions, then compared several possibly related properties of the objects and actions before and after unfreezing. That revealed that an NLA track is added and the action set to None. PyConsole was my greatest help.

I could have looked at the C code, but it’s not always easy to locate the right lines and not always easy to follow.