MRが楽しい

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

Blender 2.8のPython APIドキュメントを少しずつ読み解く ヒントとコツ その1

本日は Blender2.8 の調査枠です。
Blender 2.8 の Python API ドキュメントを少しずつ読みつつ試していきます。

Blender 2.8 Python API Documentation

以下のページを日本語訳しつつ実際に試して記事を進めていきます。
docs.blender.org
docs.blender.org

今日は「ヒントとコツ」の「外部エディターを使用する」までです。
f:id:bluebirdofoz:20191022205915j:plain

ヒントとコツ

スクリプトを記述するときに役立つさまざまな方法を以下に示します
これらの一部は、スクリプト作成者がBlenderで使用することを考えていなかったPython機能にすぎません。

ターミナルを使用する

Pythonスクリプトを記述するとき、ターミナルを開いておくと便利です。
これは組み込みのPythonコンソールではなく、Blenderを起動するために使用されるターミナルアプリケーションです。
f:id:bluebirdofoz:20191022210003j:plain

端末には次の3つの主な用途があります。

・print()スクリプトの実行時にの出力を確認できます。これは、デバッグ情報を表示するのに役立ちます。
・エラートレースバックは端末に完全に出力されます。
 Blenderユーザーインターフェイスで常にエラーポップアップが生成されるわけではありません
 (スクリプトの実行方法によって異なります)。
・ターミナル(Ctrl-BreakWindows)で Ctrl-C キーを使ってスクリプトを途中で終了できます。
 スクリプトの実行時間が長すぎる場合、または誤って無限ループに入った場合に利用します。

インターフェースのトリック

アクセスオペレータコマンド

メニュー項目とボタンのツールチップには、そのボタンを実行するコマンドが含まれています。(bpy.ops.[...]など)
メニュー項目/ボタンにマウスオーバーした状態で Ctrl-C キーを押してこのコマンドをクリップボードにコピーできます。
f:id:bluebirdofoz:20191022210015j:plain

アクセスデータパス

IDデータブロックからその設定までのパスを見つけることは、ネストされている可能性があるため、必ずしも簡単ではありません。
これをすばやく取得するには、設定を右クリックして[ データパスのコピー ]を選択します。
生成できない場合は、プロパティ名のみがコピーされます。
f:id:bluebirdofoz:20191022210025j:plain

すべての演算子を表示する

Blenderはオペレーターを Info スペースに記録します。これは REGISTER オプションが有効なオペレーターのみを報告します。
Info ビューに bpy.ops.view3d.smoothview と bpy.ops.view3d.zoom の呼び出しであふれないようにするためです。

ただし、テストでは端末で呼び出される全ての演算子を確認できると便利です。
これを行うには以下のいずれかの手順を実行してデバッグオプションを有効にします。
Blender 起動時に --debug-wm 引数を渡す。
Blender 実行中に bpy.app.debug_wm を True にする。
f:id:bluebirdofoz:20191022210035j:plain

外部エディターを使用する

Blendersテキストエディターは、小さな変更やテストの作成には適していますが、十分な機能ではありません。
大規模なプロジェクトではスタンドアロンエディターまたは Python IDE を使用する必要があります。

テキストファイルを外部で編集し、同じテキストをBlenderで開いても機能しますが、最適ではありません。
Blenderから外部ファイルを簡単に使用できる2つの方法があります。

以下の例では Blender でテキストブロックを実行する必要がありますが、外部ファイルを直接含めずに参照できます。

外部スクリプトの実行

これはスクリプトのファイルパスを参照して、スクリプトを直接実行するのと同じです。

filename = "/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))

ブレンドファイルに関連するスクリプトを参照したい場合は以下の通りです。
bpy のインポートと、実行中の blend ファイルのパス(bpy.data.filepath)を取得しています。

import bpy
import os

filename = os.path.join(os.path.dirname(bpy.data.filepath), "myscript.py")
exec(compile(open(filename).read(), filename, 'exec'))
モジュールの実行

この例では、スクリプトをモジュールとしてロードし、モジュール関数を実行しています。

import myscript
import importlib

importlib.reload(myscript)
myscript.main()

スクリプトは実行するたび、毎回リロードされることに注意してください。
これにより、変更されたバージョンが強制的に使用されます。
リロードしない場合、Blender が再起動されるまでキャッシュされたバージョンが使用されます。

これとスクリプトを直接実行することの重要な違いは、モジュール内の関数を呼び出す必要があることです。
この場合、任意の関数を使用できます。
この利点は、この小さなスクリプトから関数に引数を渡すことができることです。
さまざまな設定をすばやくテストするのに役立ちます。

これに関する他の問題は、スクリプトPython モジュールの検索パスにある必要があることです。
以下の例はベストプラクティスではありませんが、テストのために検索パスを拡張できます。
この例では、現在のブレンドファイルディレクトリを検索パスに追加し、スクリプトをモジュールとしてロードします。

import sys
import os
import bpy

blend_dir = os.path.dirname(bpy.data.filepath)
if blend_dir not in sys.path:
   sys.path.append(blend_dir)

import myscript
import importlib
importlib.reload(myscript)
myscript.main()
参考

以下の本ブログの記事でも利用中の python ファイルのパスをシステムパスに追加する方法を紹介しています。
bluebirdofoz.hatenablog.com

bluebirdofoz.hatenablog.com