Remove unused actions that were created through script

Hello,

Removing unused actions while developing animation scripts is necessary to avoid clattering of .blend
file. I have written a script to dispose of mesh objects and any associated data that is not shared
with another object and it works as expected with one exception. Animation data Action which was
created with new F-CURVE. If the action is created through ‘keyframe_insert’, it is removed with no
problems. But if I create a new f-curve, that action will not go away, no matter what. I need to
re-load the .blend file for it to go to the ‘orphaned data’ folder.

Rather than posting code here, I attach a sample file with all the script functions. If anyone has
seen the light with this and would be willing to help out I will be grateful.

ani_action.blend (670.9 KB)

ps. I am using version 2.83.5

I think this simple script can remove unused action.

for action in bpy.data.actions:
    # remove only unused action and does not have use_fake_user
    if action.users == 0 and not action.use_fake_user:
        bpy.data.actions.remove(action)

Well, I’m sorry but you do not answer the question. That script was already included in the attached file.
Besides, I never mentioned anything about fake users… :upside_down_face:
Thanks for trying anyway.

You can use File > Clean up > Purge all to get rid of orphaned data without having to reload the blend file.

You can call it from script like so: bpy.ops.outliner.orphans_purge()

Perhaps you could use this to get rid of the stubborn actions.

Hi there, yes, I am aware of that operator but it does not help in this case. You see, the specific ‘obsolete’ action is not moved into the ‘orphans’ until the .blend file is re-loaded. It is strange because even though it has zero users, and no fake user, it still appears in the list of actions, in Action Editor, without the ‘0’ in front of it.

Hello again, a week has gone by without any feedback!

I am sorry I had to bump this up, I will not do it again, but I need to know whether the problem is due to my doing something wrong. If I get no feedback, I will have to assume that this is one of those bug/feature things and I will just have to live with it.

Thanks

Here I am again, answering my own question… :smile: a few days ago, I revisited this problem and I realized that the solution was to remove the ‘fcurve’ myself. It appears that if you create a ‘fcurve’, you must explicitly remove it before attempting to remove the action it was associated with. So, here is a function to remove animation data, action and fcurves:

def anim_data_remove(ob):
    """ delete animation data/action/fcurves """
    if ob.animation_data:
        if ob.animation_data.action:
            action = ob.animation_data.action
            fcs = [fc for fc in action.fcurves]
            for fc in fcs:
                action.fcurves.remove(fc)
            bpy.data.actions.remove(action)
        ob.animation_data_clear()

EDIT - 07/11/2023
Hi, I was just looking at this and thought I should update it for future reference. Here is a more complete version that will also remove unwanted nla tracks/strips.

def action_remove(action):
    if action:
        action.fcurves.clear()
        bpy.data.actions.remove(action)

def nla_tracks_clear(ob):
 """ note: expects ob with animation data """
    nt = [t for t in ob.animation_data.nla_tracks]
    for t in nt:
        ns = [s for s in t.strips]
        for s in ns:
            action_remove(s.action)
            t.strips.remove(s)
        ob.animation_data.nla_tracks.remove(t)

def anim_data_remove(ob):
    if ob.animation_data:
        nla_tracks_clear(ob)
        action_remove(ob.animation_data.action)
        ob.animation_data_clear()

Hope it helps

2 Likes