1
$\begingroup$

I'm trying to highlight different poses in my Pose Library(Asset Browser) with Python. The same way like when you just click it once—but this time with code. Asset Browser screenshot showing a highlighted asset

I need it to execute bpy.ops.poselib.apply_pose_asset(override, blend_factor=1, flipped=False)

How can I do that?

Blender 3.0.1

$\endgroup$
3
  • $\begingroup$ Have you tried {id = bpy.data.armatures["Armature.00x"]} as an override ? $\endgroup$
    – Gorgious
    Commented May 2, 2022 at 12:59
  • $\begingroup$ @Gorgious I like your thinking, but I can't get it to work. And after fiddling with it I believe it's actually bpy.data.actions but even with that it doesn't work. $\endgroup$
    – AlexM
    Commented May 2, 2022 at 13:41
  • $\begingroup$ I would not try using the bpy interface to the asset browser just now. There are discussions of issues on devtalk and it seems like there's a rewrite coming. $\endgroup$ Commented May 3, 2022 at 0:23

2 Answers 2

1
$\begingroup$

The Pose Library doesn't really have a Python API (this makes me miss the pose lib a lot, tbh)

You can work around it by getting a hold of the SpaceFileBrowser space_data. I see people looping through the screens/areas etc, trying to find it (with heuristics like "what is the largest area on screen" and stuff like that). I just run the operator from the asset browser itself to just go context.space_data.

This type of space_data has a couple of methods that will allow you to prepare for the apply_pose_asset operator. The most important one is activate_asset_by_id. Note that it doesn't take a string, but if you know the name of your action, you can pluck it from bpy.data.actions and pass the id_data prop.

Then you can call the operator and the pose will be applied. Just be careful with which selected bones you might have, etc. as it might make it seem that it's not working when it is.

See here a minimalist example:

    def execute(self, context):
        data = context.space_data
        data.deselect_all()
        data.activate_asset_by_id(bpy.data.actions['zz_jawDrop'].id_data)
        bpy.ops.poselib.apply_pose_asset(blend_factor=1)
        return {'FINISHED'}
$\endgroup$
1
  • $\begingroup$ How do you run the operator from the asset browser itself? $\endgroup$ Commented May 9 at 21:11
0
$\begingroup$

Thank you gabriel. I used part of your example to write this script trying to help someone else do the same thing but also keyframe the poses on every frame in a new action.

import bpy

def get_poses():
    
    poses = []
    
    for action in bpy.data.actions:
        if action.asset_data != None:
            poses.append(action.name)
    
    return(poses)        


def apply_pose(action):
    area = [area for window in bpy.context.window_manager.windows for area in window.screen.areas if area.ui_type == 'ASSETS']
    
    bpy.ops.pose.transforms_clear()
    
    w = bpy.context.window
    
    for a in area:
        for s in a.spaces:
            if s.type == 'FILE_BROWSER':
                space = s
        
    
    with bpy.context.temp_override(window=w, area=area[0]):
        space.deselect_all()
        space.activate_asset_by_id(bpy.data.actions[action].id_data)

        bpy.ops.poselib.apply_pose_asset(blend_factor=1)
        
def key_frame_poses():
    
    bpy.ops.anim.keying_set_active_set(type='LocRotScale')
    
    if bpy.context.active_object.type == 'ARMATURE' and bpy.context.mode == 'POSE':
        
        scene = bpy.context.scene
        rig = bpy.context.active_object
        
        action_exists = False
        
        for act in bpy.data.actions:
            if act.name == "Pose Library All Poses":
                action = act
                action_exists = True
            else:
                action_exists = False
        
        if action_exists:
            bpy.data.actions.new(name = "Pose Library All Poses")
        
        rig.animation_data.action = action
    
        pose_asset_names = get_poses()
    
        for i, pose_name in enumerate(pose_asset_names):
    
            scene.frame_set(i + 1)  # Set the current frame
            apply_pose(pose_name)
        
            bpy.ops.anim.keyframe_insert_menu(type='LocRotScale')

key_frame_poses()

Hopefully someone will find this useful. Sharing is caring after all

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .