はじめてのBlenderアドオン開発
Last Update: 2023.3.1
Blender 2.7
はじめてのBlenderアドオン開発
Blender 2.7
Last Update: 2023.3.1
4-2. アドオンをデバッグする
プログラムを作ったことがある方は知っていると思いますが、ソフトウェアにバグはつきものです。 そしてそれは、Blenderアドオンでも同じことが言えます。 発生したバグの原因を調べて修正するためにかかる時間は、アドオン開発の大半の時間を占めることが多いため、できることならバグを修正する時間を短くし、本来の開発に注力したいと考えるのが普通です。 そこで本節では、バグの原因を効率的に調べる(デバッグ)方法について説明します。
プログラムで発生したバグを取り除く作業は、一般的にデバッグと呼ばれます。 Blenderのアドオン開発もプログラムを作ることと同じですので、ここでもバグを取り除く作業をデバッグと呼ぶことにします。 Blenderのアドオン開発においてデバッグする手段はいくつかありますが、通常のプログラム開発と異なり、デバッグ手段が確立していません。 このため本節では、筆者が行っている次のデバッグ方法について説明します。
タイトルの通り、スクリプト実行ログに文字列を出力する self.report
メソッドを使ったデバッグ手法です。 self.report
メソッドの第2引数に出力する文字列を渡しますが、ここに確認したい変数の値を指定することで変数の値をスクリプト実行ログに表示させます。 そして、表示された変数の値を見て、期待した値が保存されていることを確認します。
self.reportデバッグの例を次に示します。 次の例では、execute
メソッド内で定義された変数 a
と b
の値をスクリプト実行ログに表示することで、それぞれの変数に正しい値が代入されていることを確認します。
def execute(self, context):
a = 50
b = 4.0
self.report({'INFO'}, "a=%d, b=%f" % (a, b))
この例で execute
メソッドが実行されると、次のように変数 a
と b
の値がスクリプト実行ログに出力されます。
a=50, b=4.0
self.reportデバッグは、変数を表示したい箇所に self.report
メソッドを記述するだけで良いため、他のデバッグ方法に比べて手軽にデバッグを行える点がメリットです。 ただし、modal
メソッド内などの self.report
メソッドを利用できない処理の中では、デバッグできないことに注意する必要があります。 このように、self.report
メソッドを利用できない処理の中で変数の値を確認したい場合は、次に紹介するprintデバッグを利用する必要があります。
こちらもタイトル通り、コンソールウィンドウに文字列を出力する print
関数を用いたデバッグ手法です。 self.reportデバッグと同じように、確認したい変数の値を表示させてデバッグを行う方法ですが、self.reportデバッグでは確認できない modal
メソッドなどの処理で使用している変数についても、確認することができます。 ただし、print
関数の出力先はコンソールウィンドウであるため、1-3節 を参考にして、コンソールウィンドウからBlenderを起動する必要があります。
次の例では、execute
メソッド内で定義された変数 a
と b
の値をコンソールウィンドウに出力することで、変数に正しい値が代入されているかを確認します。
def execute(self, context):
a = 50
b = 4.0
print("a=%d, b=%f" % (a, b))
この例で execute
メソッドが実行されると、次のように変数 a
と b
の値がコンソールウィンドウに出力されます。
a=50, b=4.0
bpy.ops.XXX
(XXX:オペレーションクラスのbl_idname)を実行してアドオンの処理を行った場合、print
関数の出力先はPythonコンソールウィンドウになります。
ここまでに紹介した2つのデバッグ手法は、確認したい変数を表示するための処理をソースコード内に毎回追加する必要があるため、あまり効率的ではありません。 また、デバッグが終わったあとに追加した処理を削除する必要があり、削除中に誤って別の処理を削除するなどのバグが発生してしまう可能性があります。 もちろん簡単なデバッグ目的であれば、これらの手法でデバッグしてもよいのですが、デバッグが難航している場合は、外部のデバッガを使ってデバッグすることも検討してみましょう。
ここでは外部デバッガとしてPyDevを利用し、統合開発環境(IDE)であるEclipseを利用することで、GUIベースでデバッグできるようにします。 デバッグの手順を次に示します。
これからそれぞれの手順について、詳細な手順を説明していきます。
最初に、IDEのEclipseとデバッガPyDevをインストールします。
Eclipseのホームページ(https://www.eclipse.org/downloads/)から、最新版のEclipseをダウンロードします。
Eclipseは、JavaやC/C++、PHPなど様々なプログラミング言語に対応しているIDEですが、ここではJava用のEclipseを利用します。 Blenderのアドオンの言語がPythonであることから、PythonのプログラムをデバッグするのにJava用のEclipseをなぜ使うのか、疑問に思うかもしれません。 その理由は、Python向けに提供されているEclipseが存在しないからです。 このため、Java用のEclipseにPython用のデバッガPyDevを追加することで、Pythonで書かれたプログラムをEclipseでデバッグできるようにします。
Eclipseを動作させるためには、Java SEがインストールされている必要があります。 もし、読者のPCにEclipseがインストールされていない場合は、Java SEのダウンロードページ(http://www.oracle.com/technetwork/java/javase/downloads/index.html)からダウンロードして、インストールしてください。
続いて、Python用のデバッガPyDevをインストールします。 ダウンロードしたEclipseを起動し、次の手順に従ってPyDevをインストールします。
1 | メニューから [Help] > [Install New Software...] を実行します。 |
2 | [Available Software] ウィンドウの [Add...] をクリックします。 |
3 | [Name] に PyDev を、[Location] に http://pydev.org/updates を入力して [OK] ボタンをクリックします。 |
4 | 手順3の処理は少し時間がかかりますが、処理が終わると [Available Software] ウィンドウに [PyDev] が追加されると思いますので、[PyDev] のチェックボックスにチェックを入れたあと、[Contact all update sites during install to find required software] のチェックボックスのチェックを外し、[Next >] ボタンをクリックします。 ※注意:Contact all update sites during install to find required softwareのチェックボックスのチェックを外さないと、本ステップが完了するまでに長い時間がかかってしまいます。 |
5 | [Install Details] ウィンドウの [Next >] ボタンをクリックします。 |
6 | [Review Licenses] ウィンドウでライセンスに同意し、[Finish] をクリックします。 |
7 | PyDevのインストールが完了します。 |
8 | Eclipseを再起動します。 |
アドオンをデバッグするためのEclipseプロジェクトを作成します。
Eclipseプロジェクトを、次の手順に従って作成します。
1 | メニューから [File] > [New] > [Project...] を実行します。 |
2 | [Select a wizard] ウィンドウから [PyDev] > [PyDev Project] を選択し、[Next >] ボタンをクリックします。 |
3 | [PyDev Project] ウィンドウで [Project name] にプロジェクト名を入力し(今回の例では Blender-Addon-Debugging )、[Grammer Version] を [3.0]、[Interpreter] を [python] に設定し、[Next >] ボタンをクリックします。 |
4 | [Reference page] ウィンドウが表示されたら、[Finish] をクリックします。 |
5 | Eclipseプロジェクトが作成されます。 |
Eclipseプロジェクトを作成した直後では、bpy
モジュールなどのBlender本体と一緒に提供されるPythonモジュールなどへのパスが通っていないため、Blenderが提供するAPIを使うことができません。 そこで、作成したEclipseプロジェクトに対してBlenderが提供するモジュールへのパスを設定します。
1 | [Package Explorer] において作成したプロジェクトを選択した状態で、メニュー [Project] > [Properties] をクリックします。 |
2 | 表示されたウィンドウの左のメニューから、[PyDev - PYTHONPATH] を選択します。 |
3 | ウィンドウ右側のタブから [External Libraries] を選択します。 |
4 | [Add source folder] ボタンをクリックし、以下のパスを追加します (BLENDER_BASE_SCRIPT_PATH)/addons (BLENDER_BASE_SCRIPT_PATH)/addons/modules (BLENDER_BASE_SCRIPT_PATH)/modules (BLENDER_BASE_SCRIPT_PATH)/startup |
ここで BLENDER_BASE_SCRIPT_PATH
は、次に示すようにOS依存です(BLENDER_VER
はBlenderのバージョンです)。 例えばバージョンが2.75aのBlenderを利用している場合は、BLENDER_VER
は 2.75
となります。
OS | Blender 実行ファイルのパス例 |
BLENDER_BASE_SCRIPT_PATH |
---|---|---|
Windows | C:\path\blender.exe |
C:\path\(BLENDER_VER)\scripts |
Mac | /path/blender.app |
/path/blender.app/Contents/Resources/ (BLENDER_VER)/scripts |
Linux | /path/blender |
/path/(BLENDER_VER)/scripts |
また、必要に応じて個人用の作業ディレクトリのパスを追加してもよいです。 パスを追加することで、作業用ディレクトリのファイルがウィンドウ左側の [PyDev Package Explorer] に表示されるようになります。 ここでは上で示したパスに加えて、debug.py
と debuggee.py
が置かれたディレクトリのパスを指定します。 これらのファイルの置き場所は、本書でこれまで紹介してきたサンプルの場所と同じディレクトリです。
デバッグを行うために必要なプロジェクトの設定は終わったため、次にデバッグ実行するための関数が定義されたPythonモジュールを作成します。 次に示すスクリプトを、ファイル名 debug.py
として作成してください。
import sys
DEBUGGING = True # デバッグ有効化
# PyDevのパス(環境に応じて書き換えが必要)
PYDEV_SRC_DIR = """(eclipseディレクトリへのパス)/plugins/
org.python.pydev_XXXXX/pysrc"""
def start_debug():
if DEBUGGING is True:
if PYDEV_SRC_DIR not in sys.path:
sys.path.append(PYDEV_SRC_DIR)
import pydevd
pydevd.settrace()
print("started blender add-on debugging...")
PyDevを使うためには、pydevd
モジュールをインポートして pydevd.settrace
を呼び出す必要があり、作成したモジュールでは start_debug
関数がその役割を担っています。 このためデバッグされる側のPythonスクリプトは、debug
をインポートして debug.start_debug
関数を呼び出すことでデバッグを開始することができます。
ここで pydevd
モジュールをインポートする前に、PyDevのパスを sys.path
に追加しています。 パスを追加しないと pydevd
が見つからずインポートできません。 PYDEV_SRC_DIR
にはPyDevが置かれたディレクトリを指定しますが、環境によってPyDevが置かれるディレクトリが異なるため、各自で確認する必要があります。 筆者のMac環境ではPyDevの場所は ~/.p2/pool/plugins/org.python.pydev_XXX/pysrc
でした(XXX
はPyDevのバージョンです)。
ちなみに debug.py
には、グローバル変数 DEBUGGING
が定義されています。 常にデバッグしたいとは限らないと思い、DEBUGGING
を True
にしたときのみデバッグするようになっています。
続いて、デバッグ対象とするアドオンを作成します。 ここでは次に示すアドオンを作成し、ファイル名 debugee.py
として作成します。 なお、debug.py
と debugee.py
は同じディレクトリに置く必要があり、ここでは、本書でこれまで紹介してきたサンプルの場所と同じディレクトリに保存します。 保存先は、1-5節 を参照してください。
import bpy
import debug # デバッグ実行するクリプトをimport
bl_info = {
"name": "デバッグテスト用のアドオン",
"author": "Nutti",
"version": (2, 0),
"blender": (2, 75, 0),
"location": "3Dビュー > 追加 > メッシュ",
"description": "アドオンのデバッグテスト用アドオン",
"warning": "",
"support": "TESTING",
"wiki_url": "",
"tracker_url": "",
"category": "Object"
}
class DebugTestOps(bpy.types.Operator):
bl_idname = "object.debug_test"
bl_label = "デバッグのテスト"
bl_description = "デバッグのテストを実行する"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
debug_var = 10.0
debug_var = debug_var + 30.0
debug_var = debug_var + 9.5
print("debug_var=%f" % (debug_var))
return {'FINISHED'}
def menu_fn(self, context):
self.layout.separator()
self.layout.operator(DebugTestOps.bl_idname)
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_mesh_add.append(menu_fn)
# デバッグ開始
debug.start_debug()
def unregister():
bpy.types.INFO_MT_mesh_add.remove(menu_fn)
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
最初に、先ほど作成した debug
モジュールをインポートします。 そして、アドオン有効化時にデバッグを開始するために、register
関数で debug.start_debug
関数を実行します。 これでアドオンを有効化したときに、デバッグが開始されるようになりました。 なお、ここで紹介したアドオンは特に新しいことは行っていないため、ソースコードの解説はしません。
3で作成したデバッグ実行のためのPythonスクリプトを実行するだけでは、デバッグすることはできません。 PyDevにはデバッグサーバと呼ばれる機能があり、デバッグサーバにシグナルを送ることでデバッグを行います。 このため、スクリプト実行前にPyDevデバッグサーバを事前に起動しておく必要があります。
BlenderをEclipseから実行できるように設定し、Blenderのアドオン処理中にPyDevデバッグサーバに対してシグナルを送れるようにします。
1 | メニューから [Run] > [External Tools] > [External Tools Configurations...] を実行します。 |
2 | 表示されたウィンドウの左側にある、[Program]をダブルクリックします。 |
3 | ウィンドウ左側の [Main] タブを選択し、[Location] にBlenderの実行ファイルのパス、[Working Directory] にBlenderの実行ファイルが置かれたディレクトリを入力します。 [Name] には任意の名前を入力します。ここでは、 New_Configuration を入力します。 |
4 | 最後に、[Apply] ボタンをクリックします。 |
Blenderの実行ファイルのパスは、OSごとに異なります。 Blenderのトップディレクトリ(Blenderを非インストーラ版、すなわちzip版でダウンロードした時に、ダウンロードしたファイルを解凍したディレクトリ)を /path
としたときの、Blenderの実行ファイルのパスを次に示します。
OS | パス |
---|---|
Windows | /path/blender.exe |
Mac | /path/blender.app/Contents/MacOS/blender |
Linux | /path/blender |
続いて、PyDevデバッグサーバを起動します。
1 | メニューから、[Window] > [Perspective] > [Open Perspective] > [Other...] を実行します。 |
2 | 表示されたウィンドウで [Debug] を選択し、[OK] ボタンをクリックして [Debugパースペクティブ] を開きます。 |
3 | メニューから [Pydev] > [Start Debug Server] を実行します。 |
4 | デバッグサーバが起動します。 |
ここまで順調に手順を踏めていれば、次のような画面が表示されているはずです。
3で作成したソースコード debug.py
と debuggee.py
は、[PyDev Package Explorer] の [scripts/addons] から参照することができます。
なお、[PyDev Package Explorer] には2つの [scripts/addons] が表示されていますが、片方はサポートレベルがOfficialであるアドオンが配置されています。 ここでは、作成したアドオンのデバッグを行うため、debug.py
と debuggee.py
が配置されているほうの [scripts/addons] を参照するようにしてください。
さて、いよいよEclipseからBlenderを起動してアドオンをデバッグします。 ここでは、debugee.py
に定義された DebugTestOps
クラスの execute
メソッドの処理 debug_var = debug_var + 30.0
が実行された時にプログラムを一時的に止めて、デバッグモードに移行するようにします。
1 | ソースコードの行番号の隣の灰色部分をクリックし、debugee.py に定義された処理 debug_var = debug_var + 30.0 にブレークポイントを設定します。 |
2 | メニューから [Run] > [External Tools] > [External Tools Configurations...] を実行します。 |
3 | 表示されたウィンドウの左側から [New_Configuration] を選択し、[Run] ボタンをクリックします。 なお次回以降は、[Run] > [External Tools] > [New_Configuration] からBlenderを起動することができるようになります。 |
4 | Blenderが起動します。 |
5 | 作成したアドオンを有効化します。 |
6 | デバッガが起動します。 |
7 | [Debugパースペクティブ] で、[Resume] ボタンを押します。 |
8 | 起動中のBlenderに戻り、[3Dビュー] エリアのメニューから、[追加] > [メッシュ] > [デバッグのテスト] を実行します。 |
9 | 設定したブレークポイントで処理が止まります。 |
10 | [Debugパースペクティブ] で変数値などを参照することができます。 この他にもEclipseには様々な機能が備わっていますが、ここでは割愛します。 |
11 | デバッグを終了するためには、[Debug] タブの [New_Configuration] を選択した状態で [赤い四角] のボタンを押します。 |
12 | デバッグが終了します。この時、Debug Serverは起動したままになります。もしDebug Serverを終了したい場合は、[Debug] タブの [Debug Server] を選択した状態で [赤い四角] のボタンを押します。 |
EclipseとPyDevを用いたデバッグは、準備に時間がかかります。 少しだけデバッガを試してみたいという方にとっては、あまり魅力的ではありません。 そこで、手間をかけずにデバッガを利用したい方のために、アドオン『BreakPoint』を利用してデバッグを行う方法を紹介します。 前準備はアドオンの導入だけでよいので、EclipseとPyDevによるデバッグと違って、比較的すぐにデバッグ環境を整えることができます。
アドオン『BreakPoint』を利用してデバッグを行う手順を、次に示します。
Webサイト((http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Development/BreakPoint)[http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Development/BreakPoint])からアドオン『BreakPoint』をダウンロードし、インストールします。 アドオンのインストールの仕方がわからない場合は、1-4節 を参考にしてください。
インストールしたアドオン『BreakPoint』を有効化します。
デバッグ対象とするアドオンを作成し、debuggee_2.py
として保存します。
import bpy
bl_info = {
"name": "デバッグテスト用のアドオン2",
"author": "Nutti",
"version": (2, 0),
"blender": (2, 75, 0),
"location": "3Dビュー > 追加 > メッシュ",
"description": "アドオン『BreakPoint』を用いたデバッグテスト用アドオン",
"warning": "",
"support": "TESTING",
"wiki_url": "",
"tracker_url": "",
"category": "Object"
}
# ブレークポイント関数
breakpoint = bpy.types.bp.bp
class DebugTestOps2(bpy.types.Operator):
bl_idname = "object.debug_test_2"
bl_label = "デバッグのテスト2"
bl_description = "デバッグのテストを実行する"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
debug_var = 10.0
debug_var = debug_var + 30.0
debug_var = debug_var + 9.5
# ブレークポイント
breakpoint(locals(), debug_var)
return {'FINISHED'}
def menu_fn(self, context):
self.layout.separator()
self.layout.operator(DebugTestOps2.bl_idname)
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_mesh_add.append(menu_fn)
def unregister():
bpy.types.INFO_MT_mesh_add.remove(menu_fn)
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
ブレークポイントを設定するためには、bpy.types.bp.bp
関数を呼び出す必要がありますが、毎回これを書くのは面倒ですので、次のようにして breakpoint
と書くだけで呼び出せるようにすると、ブレークポイントの設定が少し楽になるかと思います。
# ブレークポイント関数
breakpoint = bpy.types.bp.bp
以降、ブレークポイントを設定する時は、次のようにしてブレークポイントを設定したい場所で breakpoint
関数を実行します。
# ブレークポイント
breakpoint(locals(), debug_var)
breakpoint
関数の第1引数には、変数のスコープの辞書(ローカル変数であれば locals
、グローバル変数であれば globals
)、第2引数には確認したい変数を指定します。 サンプルでは、ローカル変数である debug_var
の値を出力するため、第1引数に locals
、第2引数に globals
を指定します。
これで、デバッグを行う準備が整いました。 それでは、アドオン『BreakPoint』を使って実際にデバッグを行ってみましょう。
1 | [テキストエディター] エリアのメニューから [ビュー] > [プロパティ] を実行し、[テキストエディター] エリアのプロパティを表示します。 |
2 | [プロパティ] を表示すると、項目 [BreakPoint] が追加されていることが確認できます。 そして、[有効化] ボタンが選択されていることを確認します。 |
3 | [3Dビュー] エリアのメニューから、[追加] > [メッシュ] > [デバッグのテスト2] を実行します。 |
4 | [テキストエディター] エリアのプロパティにブレークポイントの関数に指定した変数の値が表示されます。 |
本節では、アドオンをデバッグする方法を紹介しました。 ここでは、本節で紹介したデバッグについて簡単にまとめます。
デバッグ方法 | できること | 前準備 |
---|---|---|
self.report | スクリプト実行ログに出力可能な処理中での変数値確認 | ソースコードの調べたい箇所に self.report メソッドを追加 |
すべての変数値確認 | ソースコードの調べたい箇所に print 関数を追加し、コンソールウィンドウからBlenderを起動 |
|
外部デバッガ | ブレークポイント設定やコールトレース調査、変数値確認など、Eclipseが持つデバッガ機能の利用 | EclipseやPyDevのインストール、EclipseとBlenderの連携、デバッグ実行用スクリプトの作成 |
アドオン『BreakPoint』 | ブレークポイント設定、変数値確認 | アドオン『BreakPoint』のインストール、ブレークポイント設定のためのソースコード編集 |
ここで示したように、より多くの情報をデバッグで得る場合は必要な前準備が多くなる傾向があります。 解決しようとしている問題の難しさと前準備の時間を合わせて判断し、デバッグする方法を決めましょう。