MRが楽しい

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

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

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

Blender 2.8 Python API Documentation

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

今日は「ヒントとコツ」の「高度なヒント」までです。
f:id:bluebirdofoz:20191023080419j:plain

Blenderを利用しないケース

独自のスクリプトを開発している間、Blenderインターフェイスが邪魔になることがあります。
リロード、スクリプトを実行、ファイルのインポートなどを開くとオーバーヘッドが追加されます。

対話型ではないスクリプトの場合、Blenderインターフェースを使用せずにコマンドラインスクリプトを実行する方が効率的です。
コマンドライン上からスクリプトを実行するには以下のコマンドを利用します。

blender --background --python myscript.py

スクリプトに操作するデータが含まれるように、ブレンドファイルを指定して実行することもできます。

blender myscene.blend --background --python myscript.py

スクリプトをバックグラウンドモードで実行した場合、何らかの手段でスクリプトの出力を確認する必要があります。
これは実行タスクに完全に依存しますが、いくつかの方法があります。

・出力を画像にレンダリングし、画像ビューアを使用して、毎回同じ画像を上書きし続けます。
・新しいブレンドファイルを保存するか、Blenderエクスポーターのいずれかを使用してファイルをエクスポートします。
・結果をテキストとして表示できる場合は結果を print するか、ファイルに書き込みます。

これはセットアップに少し時間がかかりますが、変更をテストするのにかかる時間を削減します。
Blenderで数秒ごとにスクリプトを実行し、ビューアーで結果を更新することもできます。

外部ツールを使用する

Pythonがデータに対して外部コマンドを実行し、結果を読み込むことができる場合があることに留意してください。

外部プログラムを使用すると追加の依存関係が追加され、スクリプトを使用できるユーザーが制限される場合があります。
独自のカスタムパイプラインをすばやくセットアップしたり、1回限りのスクリプトを作成したりすると便利です。

例えば、以下のようなケースが考えられます。

・The Gimp をバッチモードで実行して、高度な画像処理用のカスタムスクリプトを実行します。
・外部のメッシュ操作ツールを使用する3Dモデルを作成し、結果を読み戻します。
・読む前にファイルを認識可能な形式に変換します。

バンドルされたPython拡張機能

blender.orgから配布されるBlenderリリースには、すべてのプラットフォームに完全なPythonインストールが含まれています。
これにはシステムにインストールした拡張機能Blenderからは検出されないという欠点があります。

対策として2つの方法があります。

Blender Pythonサブディレクトリを削除すると、BlenderはシステムPythonでフォールバックし、代わりにそれを使用します。
 プラットフォームによっては、PYTHONPATH 環境変数を使用してPythonインストールの場所を明示的に参照する必要があります。
 参照するPythonバージョンは、Blenderに付属しているものと一致する必要があります。

PYTHONPATH=/usr/lib/python3.5 ./blender

拡張機能BlenderPythonサブディレクトリにコピーまたはリンクして、Blenderがアクセスできるようにする。
 またはPython全体をBlendersサブディレクトリにコピーして、Blenderに付属しているものを置き換えることもできます。
 これは、Pythonのバージョンが一致し、パスが同じ相対的な場所に作成される限り機能します。
 これにはBlenderを使用して、依存する拡張機能を含め、このバンドルを他のユーザーに再配布できるという利点があります。

参考

以下の本ブログの記事でもblenderpythonで外部ライブラリを利用する方法を紹介しています。
bluebirdofoz.hatenablog.com

スクリプトPythonインタープリターにドロップする

いくつかの変数を検査し、いくつかの関数を実行したスクリプトの途中で何が起こっているのかを確認したい場合があります。

import code
code.interact(local=locals())

グローバル変数とローカル変数の両方にアクセスする場合は、以下を行います。

import code
namespace = globals().copy()
namespace.update(locals())
code.interact(local=namespace)

次の例は、上記のスクリプトと同等の機能を持った単一行であり、コードに簡単に貼り付けることができます。

__import__('code').interact(local=dict(globals(), **locals()))

code.interact はスクリプトの任意の行に追加することができます。
スクリプトを一時停止し、ターミナルで対話型インタープリターを起動します。
対話が完了したら、インタープリターを終了してスクリプトを実行し続けます。
f:id:bluebirdofoz:20191023080449j:plain

IPythonをインストール済みの場合、embed() 関数を使用することができます。
IPythonプロンプトには、標準のPython eval-loopにはないオートコンプリートといくつかの便利な機能があります。

import IPython
IPython.embed()

高度なヒント

モジュールとしてのBlender

Pythonの観点から見ると、Blender拡張機能として用意する方が便利です。

利点は次のとおりです。

・外部エディタ/IDEでBlenders Python APIを使用し、IDE内でスクリプトを実行できます。
 (コードをステップオーバーし、スクリプトの実行中に変数を検査することができます)
・外部エディタ/IDEBlenderモジュールと変数を自動補完できます。
・既存のスクリプトBlender内で実行することなくBlender APIをインポートできます。

BlenderPythonモジュールとして実行するには特別なビルドオプションが必要なため、これは高度とマークされています。

参考

以下の本ブログの記事でもPythonモジュール向けのBlender2.8のビルド方法を紹介しています。
bluebirdofoz.hatenablog.com

Pythonの安全性(ビルドオプション)

削除されたデータにもアクセスできるため、クラッシュの原因を突き止めるのは困難です。

(クラッシュではなく)解放されたデータへのアクセスで例外を発生させるには、以下のCMakeビルドオプションを有効にします。
・WITH_PYTHON_SAFETY

これにより、データトラッキングが有効になる代わりに、データアクセスが約2倍遅くなります。
このため、リリースビルドではこのオプションが有効になっていません。