はじめてのBlenderアドオン開発 (Blender 2.7版)

Last Update: 2019.4.2

4-2. アドオンをデバッグする

プログラムを作ったことがある方は知っていると思いますが、ソフトウェアにバグはつきものです。 そしてそれは、Blenderアドオンでも同じことが言えます。 発生したバグの原因を調べて修正するためにかかる時間は、アドオン開発の大半の時間を占めることが多いため、できることならバグを修正する時間を短くし、本来の開発に注力したいと考えるのが普通です。 そこで本節では、バグの原因を効率的に調べる(デバッグ)方法について説明します。

アドオンのデバッグ手段

プログラムで発生したバグを取り除く作業は、一般的にデバッグと呼ばれます。 Blenderのアドオン開発もプログラムを作ることと同じですので、ここでもバグを取り除く作業をデバッグと呼ぶことにします。 Blenderのアドオン開発においてデバッグする手段はいくつかありますが、通常のプログラム開発と異なり、デバッグ手段が確立していません。 このため本節では、筆者が行っている次のデバッグ方法について説明します。

self.reportデバッグ

タイトルの通り、スクリプト実行ログに文字列を出力する self.report メソッドを使ったデバッグ手法です。 self.report メソッドの第2引数に出力する文字列を渡しますが、ここに確認したい変数の値を指定することで変数の値をスクリプト実行ログに表示させます。 そして、表示された変数の値を見て、期待した値が保存されていることを確認します。

self.reportデバッグの例を次に示します。 次の例では、execute メソッド内で定義された変数 ab の値をスクリプト実行ログに表示することで、それぞれの変数に正しい値が代入されていることを確認します。

def execute(self, context):
    a = 50
    b = 4.0
    self.report({'INFO'}, "a=%d, b=%f" % (a, b))

この例で execute メソッドが実行されると、次のように変数 ab の値がスクリプト実行ログに出力されます。

a=50, b=4.0

self.reportデバッグは、変数を表示したい箇所に self.report メソッドを記述するだけで良いため、他のデバッグ方法に比べて手軽にデバッグを行える点がメリットです。 ただし、modal メソッド内などの self.report メソッドを利用できない処理の中では、デバッグできないことに注意する必要があります。 このように、self.report メソッドを利用できない処理の中で変数の値を確認したい場合は、次に紹介するprintデバッグを利用する必要があります。

printデバッグ

こちらもタイトル通り、コンソールウィンドウに文字列を出力する print 関数を用いたデバッグ手法です。 self.reportデバッグと同じように、確認したい変数の値を表示させてデバッグを行う方法ですが、self.reportデバッグでは確認できない modal メソッドなどの処理で使用している変数についても、確認することができます。 ただし、print 関数の出力先はコンソールウィンドウであるため、1-3節 を参考にして、コンソールウィンドウからBlenderを起動する必要があります。

次の例では、execute メソッド内で定義された変数 ab の値をコンソールウィンドウに出力することで、変数に正しい値が代入されているかを確認します。

def execute(self, context):
    a = 50
    b = 4.0
    print("a=%d, b=%f" % (a, b))

この例で execute メソッドが実行されると、次のように変数 ab の値がコンソールウィンドウに出力されます。

a=50, b=4.0
Pythonコンソールウィンドウから、bpy.ops.XXX (XXX:オペレーションクラスのbl_idname)を実行してアドオンの処理を行った場合、print 関数の出力先はPythonコンソールウィンドウになります。

外部デバッガを利用したデバッグ

ここまでに紹介した2つのデバッグ手法は、確認したい変数を表示するための処理をソースコード内に毎回追加する必要があるため、あまり効率的ではありません。 また、デバッグが終わったあとに追加した処理を削除する必要があり、削除中に誤って別の処理を削除するなどのバグが発生してしまう可能性があります。 もちろん簡単なデバッグ目的であれば、これらの手法でデバッグしてもよいのですが、デバッグが難航している場合は、外部のデバッガを使ってデバッグすることも検討してみましょう。

ここでは外部デバッガとしてPyDevを利用し、統合開発環境(IDE)であるEclipseを利用することで、GUIベースでデバッグできるようにします。 デバッグの手順を次に示します。

  1. PyDevとEclipseのインストール
  2. デバッグ用Eclipseプロジョクトの作成
  3. デバッグ実行のためのPythonスクリプトの作成
  4. PyDevデバッグサーバの起動
  5. デバッグ開始

これからそれぞれの手順について、詳細な手順を説明していきます。

1. EclipseとPyDevのインストール

最初に、IDEのEclipseとデバッガPyDevをインストールします。

Eclipseのインストール

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)からダウンロードして、インストールしてください。

PyDevのインストール

続いて、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を再起動します。

2. デバッグ用Eclipseプロジョクトの作成

アドオンをデバッグするための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_VER2.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.pydebuggee.py が置かれたディレクトリのパスを指定します。 これらのファイルの置き場所は、本書でこれまで紹介してきたサンプルの場所と同じディレクトリです。

3. デバッグ実行のためのPythonスクリプト作成

デバッグを行うために必要なプロジェクトの設定は終わったため、次にデバッグ実行するための関数が定義された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 が定義されています。 常にデバッグしたいとは限らないと思い、DEBUGGINGTrue にしたときのみデバッグするようになっています。

続いて、デバッグ対象とするアドオンを作成します。 ここでは次に示すアドオンを作成し、ファイル名 debugee.py として作成します。 なお、debug.pydebugee.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 関数を実行します。 これでアドオンを有効化したときに、デバッグが開始されるようになりました。 なお、ここで紹介したアドオンは特に新しいことは行っていないため、ソースコードの解説はしません。

4. PyDevデバッグサーバの起動

3で作成したデバッグ実行のためのPythonスクリプトを実行するだけでは、デバッグすることはできません。 PyDevにはデバッグサーバと呼ばれる機能があり、デバッグサーバにシグナルを送ることでデバッグを行います。 このため、スクリプト実行前にPyDevデバッグサーバを事前に起動しておく必要があります。

EclipseからBlenderを実行できるようにする

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 デバッグサーバが起動します。

5. デバッグ開始

ここまで順調に手順を踏めていれば、次のような画面が表示されているはずです。

3で作成したソースコード debug.pydebuggee.py は、[PyDev Package Explorer] の [scripts/addons] から参照することができます。

なお、[PyDev Package Explorer] には2つの [scripts/addons] が表示されていますが、片方はサポートレベルがOfficialであるアドオンが配置されています。 ここでは、作成したアドオンのデバッグを行うため、debug.pydebuggee.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] を選択した状態で [赤い四角] のボタンを押します。

アドオン『BreakPoint』を利用したデバッグ

EclipseとPyDevを用いたデバッグは、準備に時間がかかります。 少しだけデバッガを試してみたいという方にとっては、あまり魅力的ではありません。 そこで、手間をかけずにデバッガを利用したい方のために、アドオン『BreakPoint』を利用してデバッグを行う方法を紹介します。 前準備はアドオンの導入だけでよいので、EclipseとPyDevによるデバッグと違って、比較的すぐにデバッグ環境を整えることができます。

アドオン『BreakPoint』を利用してデバッグを行う手順を、次に示します。

  1. アドオン『BreakPoint』のインストール
  2. アドオン『BreakPoint』の有効化
  3. ブレークポイントをデバッグ対象のスクリプトに設定
  4. デバッグ開始

1. アドオン『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節 を参考にしてください。

2. アドオン『BreakPoint』の有効化

インストールしたアドオン『BreakPoint』を有効化します。

3. ブレークポイントをデバッグ対象のスクリプトに設定

デバッグ対象とするアドオンを作成し、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 を指定します。

4. デバッグ開始

これで、デバッグを行う準備が整いました。 それでは、アドオン『BreakPoint』を使って実際にデバッグを行ってみましょう。

1 [テキストエディター] エリアのメニューから [ビュー] > [プロパティ] を実行し、[テキストエディター] エリアのプロパティを表示します。
2 [プロパティ] を表示すると、項目 [BreakPoint] が追加されていることが確認できます。
そして、[有効化] ボタンが選択されていることを確認します。
3 [3Dビュー] エリアのメニューから、[追加] > [メッシュ] > [デバッグのテスト2] を実行します。
4 [テキストエディター] エリアのプロパティにブレークポイントの関数に指定した変数の値が表示されます。
1-3節 で説明した方法で、Blenderをコンソールウィンドウから開いた場合は、コンソールウィンドウにもデバッグ情報が表示されているはずです。
また、コンソールウィンドウから起動した場合に限り、Blender本体からコンソールウィンドウに制御が移ります。 制御が移っている間は、コンソールウィンドウでPythonインタープリタを使うことができますが、Blender側ではいかなる操作も受け付けなくなります。
Blender本体に制御を戻す(アドオンの実行を再開する)場合は、Windowsでは [Ctrl] + [Z] キーを、Mac/Linuxでは [Ctrl] + [D] キーを押してください。

まとめ

本節では、アドオンをデバッグする方法を紹介しました。 ここでは、本節で紹介したデバッグについて簡単にまとめます。

デバッグ方法 できること 前準備
self.report スクリプト実行ログに出力可能な処理中での変数値確認 ソースコードの調べたい箇所に self.report メソッドを追加
print すべての変数値確認 ソースコードの調べたい箇所に print 関数を追加し、コンソールウィンドウからBlenderを起動
外部デバッガ ブレークポイント設定やコールトレース調査、変数値確認など、Eclipseが持つデバッガ機能の利用 EclipseやPyDevのインストール、EclipseとBlenderの連携、デバッグ実行用スクリプトの作成
アドオン『BreakPoint』 ブレークポイント設定、変数値確認 アドオン『BreakPoint』のインストール、ブレークポイント設定のためのソースコード編集

ここで示したように、より多くの情報をデバッグで得る場合は必要な前準備が多くなる傾向があります。 解決しようとしている問題の難しさと前準備の時間を合わせて判断し、デバッグする方法を決めましょう。

ポイント