MRが楽しい

MRやVRについて学習したことを書き残す

Blender3.0で利用可能なpythonスクリプトを作る その135(指定種別のエリアコンテキストの参照を取得する)

本日は Blender の技術調査枠です。
Blender3.0で利用可能なpythonスクリプトを作ります。

poll() failed, context is incorrect エラー

Blenderpython スクリプトから特定のオペレータを呼び出そうとしたとき、以下のエラーが発生することがあります。

RuntimeError: Operator bpy.ops.XXX.YYY.poll() failed, context is incorrect

これは指定のオペレータを実行する際、適切なコンテキストの参照が設定されていないことが原因である可能性があります。

指定種別のエリアコンテキストの参照を取得する

Blender のオペレータには特定のウィンドウエリアでのみ利用可能なオペレータが存在します。
例えば、bpy.ops.action.select_all はドープシートのエリアで利用可能です。

通常 GUI 操作の場合はこれらのオペレータは各エリア内のメニューから実行するため意識する必要はありません。
しかし python スクリプトから実行する場合はどのエリアでオペレータ操作を行うかコンテキストを渡して指定する必要があります。

各エリアの参照と種別は bpy.context.screen.areas から取得可能です。
docs.blender.org

以下の例のように各エリアのコンテキストの参照(context)を走査して指定の種別の参照を取得することができます。

# bpy.ops.action のオペレータはドープシートエリアで実行可能
# 全エリアを確認してドープシートの参照を取得する
override_context = None
for area in bpy.context.screen.areas:
    # エリアの種別マニュアル
    # https://docs.blender.org/api/current/bpy.types.Area.html#bpy.types.Area.type
    if area.type == 'DOPESHEET_EDITOR':
        # context の参照を作成する
        override_context = bpy.context.copy()
        override_context["space_data"] = area.spaces[0]
        override_context["area"] = area
if override_context == None:
    return False
    
# ドープシートエリア内のアクションのキーフレームをすべて選択する
bpy.ops.action.select_all(override_context, action='SELECT')

エリア種別の定義については以下を参照ください。
docs.blender.org

EMPTY Empty
VIEW_3D 3D Viewport Manipulate objects in a 3D environment.
IMAGE_EDITOR UV/Image Editor View and edit images and UV Maps.
NODE_EDITOR Node Editor Editor for node-based shading and compositing tools.
SEQUENCE_EDITOR Video Sequencer Video editing tools.
CLIP_EDITOR Movie Clip Editor Motion tracking tools.
DOPESHEET_EDITOR Dope Sheet Adjust timing of keyframes.
GRAPH_EDITOR Graph Editor Edit drivers and keyframe interpolation.
NLA_EDITOR Nonlinear Animation Combine and layer Actions.
TEXT_EDITOR Text Editor Edit scripts and in-file documentation.
CONSOLE Python Console Interactive programmatic console for advanced editing and script development.
INFO Info Log of operations, warnings and error messages.
TOPBAR Top Bar Global bar at the top of the screen for global per-window settings.
STATUSBAR Status Bar Global bar at the bottom of the screen for general status information.
OUTLINER Outliner Overview of scene graph and all available data-blocks.
PROPERTIES Properties Edit properties of active object and related data-blocks.
FILE_BROWSER File Browser Browse for files and assets.
SPREADSHEET Spreadsheet Explore geometry data in a table.
PREFERENCES Preferences Edit persistent configuration settings.

サンプルスクリプト

スクリプトを実行すると画面内のドープシートのコンテキスト参照を取得してアクションのキーフレームの全選択オペレータを実行します。
・Script_override_context_example.py

# bpyインポート
import bpy

# ドープシートエリア内のアクションのキーフレームをすべて選択する
def select_all_key() -> bool:
    """ドープシートエリア内のアクションのキーフレームをすべて選択する

    Keyword Arguments:

    Returns:
        bool -- 実行成否
    """

    # bpy.ops.action のオペレータはドープシートエリアで実行可能
    # 全エリアを確認してドープシートの参照を取得する
    override_context = None
    for area in bpy.context.screen.areas:
        # エリアの種別マニュアル
        # https://docs.blender.org/api/current/bpy.types.Area.html#bpy.types.Area.type
        if area.type == 'DOPESHEET_EDITOR':
            # context の参照を作成する
            override_context = bpy.context.copy()
            override_context["space_data"] = area.spaces[0]
            override_context["area"] = area
    if override_context == None:
        return False
    
    # ドープシートエリア内のアクションのキーフレームをすべて選択する
    bpy.ops.action.select_all(override_context, action='SELECT')

    return True

# 関数の実行例
select_all_key()