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

Last Update: 2019.4.2

2-2. 複数のオペレータクラスを登録する

2-1節 ではアドオン開発の基本的な部分について説明しました。 本節では前回解説した内容を理解していることを前提に、2-1節 よりも複雑なサンプルを用いて、複数のメニュー項目を追加する方法を解説します。 既に解説済みの部分は説明を省略しますので、不明な点がある場合は 2-1節 に戻って確認してください。

作成するアドオンの仕様

本節で作成するアドオンの仕様は以下の通りです。

アドオンを作成する

1-5節 を参考にして以下のソースコードを入力し、ファイル名 sample_2_2.py で保存します。

import bpy


bl_info = {
    "name": "サンプル2-2: オブジェクトを拡大・縮小するアドオン",
    "author": "Nutti",
    "version": (2, 0),
    "blender": (2, 75, 0),
    "location": "3Dビュー > オブジェクト",
    "description": "オブジェクトを拡大・縮小するサンプルアドオン",
    "warning": "",
    "support": "TESTING",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"
}


# オブジェクトを拡大するオペレーション
class EnlargeObject(bpy.types.Operator):

    bl_idname = "object.enlarge_object"
    bl_label = "選択オブジェクトの拡大"
    bl_description = "選択中のオブジェクトを拡大します"
    bl_options = {'REGISTER', 'UNDO'}

    # メニューを実行した時に呼ばれるメソッド
    def execute(self, context):
        active_obj = context.active_object
        active_obj.scale = active_obj.scale * 2.0
        self.report({'INFO'}, "サンプル2-2: 「%s」を2倍に拡大しました。" % (active_obj.name))
        print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))

        return {'FINISHED'}


# オブジェクトを縮小するオペレーション
class ReduceObject(bpy.types.Operator):

    bl_idname = "object.reduce_object"
    bl_label = "選択オブジェクトの縮小"
    bl_description = "選択中のオブジェクトを縮小します"
    bl_options = {'REGISTER', 'UNDO'}

    # メニューを実行した時に呼ばれる関数
    def execute(self, context):
        active_obj = context.active_object
        active_obj.scale = active_obj.scale * 0.5
        self.report({'INFO'}, "サンプル2-2: 「%s」を1/2倍に縮小しました。" % (active_obj.name))
        print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))

        return {'FINISHED'}


# メニューを構築する関数
def menu_fn(self, context):
    self.layout.separator()
    self.layout.operator(EnlargeObject.bl_idname)
    self.layout.operator(ReduceObject.bl_idname)


# アドオン有効化時の処理
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_object.append(menu_fn)
    print("サンプル2-2: アドオン「サンプル2-2」が有効化されました。")


# アドオン無効化時の処理
def unregister():
    bpy.types.VIEW3D_MT_object.remove(menu_fn)
    bpy.utils.unregister_module(__name__)
    print("サンプル2-2: アドオン「サンプル2-2」が無効化されました。")


# メイン処理
if __name__ == "__main__":
    register()

アドオンを使用する

アドオンを有効化する

1-5節 を参考にして、作成したアドオンを有効化します。

アドオンが有効化されると、コンソールウィンドウに以下の文字列が出力されるはずです。

サンプル2-2: アドオン「サンプル2-2」が有効化されました。

アドオン有効化後、[3Dビュー] エリアのメニューに [オブジェクト] > [選択オブジェクトの拡大] と、[オブジェクト] > [選択オブジェクトの縮小] が追加されていることを確認します。

アドオンの機能を使用する

以下の手順に従い、作成したアドオンの機能を使ってみます。

1 Blender起動直後に自動的に生成されているオブジェクト [Cube] を選択し、[3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの拡大] を実行します。選択したオブジェクト [Cube] のサイズが2倍に拡大されます

この時、スクリプト実行ログには以下のメッセージが出力されます。
サンプル2-2: 「Cube」を2倍に拡大しました。
また、コンソールウィンドウにも以下のメッセージが出力されます。
サンプル2-2: オペレーション「OBJECT_OT_enlarge_object」が実行されました。
2 [情報] エリアのメニューである、[ファイル] > [新規] を実行し、[スタートアップファイルの再読み込み] を行った後、[3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの縮小] を実行します。選択中のオブジェクト [Cube] のサイズが1/2倍に縮小されます。

この時、スクリプト実行ログには以下のメッセージが出力されます。
サンプル2-2: 「Cube」を1/2倍に縮小しました。
また、コンソールウィンドウには以下のメッセージが出力されます。
サンプル2-2: オペレーション「OBJECT_OT_reduce_object」が実行されました。

アドオンを無効化する

1-5節 を参考に、有効化したアドオンを無効化します。

アドオンを無効化すると、コンソールウィンドウに以下の文字列が出力されます。

サンプル2-2: アドオン「サンプル2-2」が無効化されました。

ソースコードの解説

アドオンの動作を確認したところで、次にソースコードの解説をします。 ここでは、前節で説明した内容から新しく追加された部分について説明します。

複数のオペレータクラスの定義

本節で新たに加わった処理の1つとして、複数のオペレータクラスを定義する処理があります。

1つのファイルに複数のオペレータクラスを定義するためには、作りたい機能の数だけオペレーションクラスを定義する 必要があります。 本節のサンプルでは、オブジェクトの拡大とオブジェクトの縮小の2つの機能のために、2つのオペーレーションクラスを以下のように作成しました。

# オブジェクトを拡大するオペレーション
class EnlargeObject(bpy.types.Operator):

    bl_idname = "object.enlarge_object"
    bl_label = "選択オブジェクトの拡大"
    bl_description = "選択中のオブジェクトを拡大します"
    bl_options = {'REGISTER', 'UNDO'}
# オブジェクトを縮小するオペレーション
class ReduceObject(bpy.types.Operator):

    bl_idname = "object.reduce_object"
    bl_label = "選択オブジェクトの縮小"
    bl_description = "選択中のオブジェクトを縮小します"
    bl_options = {'REGISTER', 'UNDO'}

bl_idname はオペレータクラスごとに固有の文字列を指定する必要があるため、重複しないように気をつけてください。 重複しないようにするための方法は、後ほど紹介します。

スクリプト実行ログへの出力

オペレータクラスの execute メソッドの処理の中には、メニューが実行された時にスクリプト実行ログへメッセージを出力する処理が含まれています。

ここでは、EnlargeObject クラスの execute メソッド内に定義されている、スクリプト実行ログへメッセージを出力する処理について説明します。

    # メニューを実行した時に呼ばれるメソッド
    def execute(self, context):
        active_obj = context.active_object
        active_obj.scale = active_obj.scale * 2.0
        self.report({'INFO'}, "サンプル2-2: 「%s」を2倍に拡大しました。" % (active_obj.name))
        print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))

        return {'FINISHED'}

execute メソッドに渡されてくる引数については、2-1節 で説明しましたので、引数の詳細についての説明はここでは省略します。 引数 context から、現在のコンテキスト(実行状態)を取得することができます。

現在選択されているオブジェクトである context.active_objectactive_obj に一度保存し、active_obj.scale を2倍にすることで取得したオブジェクトのサイズを2倍に拡大することができます。

その後 self.report メソッドを用いて、ユーザに対してオペレーションを実行した後に、オブジェクトを拡大・縮小したことがわかるようなメッセージをスクリプト実行ログに出力します。 ここで、execute メソッドの引数である self は、オブジェクトのインスタンスです。

self.report メソッドに指定する必要のある引数を以下に示します。

引数 値の型 値の説明
第1引数 集合型 出力メッセージの種類
第2引数 文字列 メッセージ本文

表示したいメッセージの内容に応じてメッセージの種類を指定し、スクリプト実行ログへ出力することができます。 出力メッセージの種類には例えば以下のようなものがあります。

種類 コンソールウィンドウへの出力 情報ウィンドウのメニューへの出力
INFO ハイライト表示(緑色) 通知メッセージ
WARNING ハイライト表示(橙色) 警告メッセージ
ERROR ハイライト表示(赤色) エラーメッセージ
OPERATOR 表示 (なし)

本節のサンプルでは、オブジェクトが拡大・縮小されたことをユーザへ知らせるために {'INFO'} を指定し、拡大・縮小したオブジェクト名(active_obj.name)も表示しています。

Pythonコンソールを活用しよう

bl_idname が重複していないかを確認する

bl_idname が重複してはならないと説明しましたが、bl_idname が重複していないかを確認するためにはどのようにしたら良いのでしょうか? すでに存在する bl_idname を確認したい時に役に立つのが、Pythonコンソールです。

Pythonコンソールを利用することにより、例えば以下のようなことができます。

ここではPythonコンソールを使って、本節のサンプルで追加したオペレータクラスの bl_idname が既存のAPIと重複していないかを実際に確認してみます。 確認対象とする bl_idnameobject.enlarge_object とします。

Blenderのエリア構成が 1-3節 で紹介したような設定となっていれば、左上のウィンドウが [Pythonコンソール] エリアとなります。

1 設定したオペレータクラスの bl_idnamebpy.ops.<オペレーションクラスのbl_idname> に登録されることを利用します。[Pythonコンソール] エリアに bpy.ops.object.enlarge_obje と入力してみます。入力が完了したら、WindowsやLinuxであれば [Ctrl] + [Space]、Macであれば [control] + [space] を押します。ここで単語が補完されなければ、bl_idname として bpy.ops.object.enlarge_object が利用されていないことになり、bl_idname への指定が可能であることがわかります。
2 本節で作成したアドオンを有効化した後に、Pythonコンソールに以下を打ち込んで [Enter] キーを押します。
bpy.ops.object.enlarge_object

[3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの拡大] を実行した時と同様の効果が得られます。このようにオペレータクラスを登録すると、オペレータクラスの bl_idnamebpy.ops.<オペレーションクラスのbl_idname> として登録されることがわかります。

Pythonコンソールのショートカットキー

[Pythonコンソール] エリアではショートカットキーが利用できますので、作業効率化のためにぜひ活用してください。

Windows Mac Linux 動作
Shift + F4 shift + fn + F4 Shift + F4 Python Consoleを開く
過去に入力した履歴を戻る
過去に入力した履歴を進める
Tab tab Tab インデント
Shift + tab shift + tab shift + tab アンインデント
Home ⌘ + ← Home 行頭にカーソルを移動
End ⌘ + → End 行末にカーソルを移動
Ctrl + ← control + ←
fn + ←
Ctrl + ← 単語単位で左にカーソルを移動
Ctrl + → control + →
fn + →
Ctrl + → 単語単位で右にカーソルを移動
Ctrl + Backspace control + delete Ctrl + Backspace カーソルの位置から行頭に向かって単語単位で削除
Ctrl + Delete control + fn +delete Ctrl + Delete カーソルの位置から行末に向かって単語単位で削除
Shift + Enter shift + return Shift + Enter 行を削除
Ctrl + Space control + space Ctrl + Space ソースコード補完
Ctrl + ↑
Ctrl + ↓
control + ↑
control + ↓
Ctrl + ↑
Ctrl + ↓
コンソールウィンドウのフルスクリーン化/解除
Ctrl + C control + C Ctrl + C 選択部分をクリップボードへコピー
Ctrl + V control + V Ctrl + V クリップボードからの貼り付け
Shift + Ctrl + C shift + control + C Shift + Ctrl + C Python Consoleで実行されたスクリプトを全てコピー。
実行結果についてもコピーされるが、行頭に「#~ 」が自動的についてコメント化される

※ ⌘はMacのcommandを指す

Macでショートカットキーを利用するためには、Macのショートカットキーに標準で割り当てられているcontrolと⌘キーについて、以下の手順に沿って割り当てを解除する必要があります。

1 [システム環境設定...] をクリック
2 [キーボード] をクリック
3 [ショートカットタブ] をクリック
4 [Pythonコンソール] で使いたいショートカットキーの割り当てを解除

まとめ

本節では、複数のオペレータクラスを作る方法やスクリプト実行ログにメッセージを出力する方法を紹介しました。 さらに、Pythonコンソールの利用方法を紹介しました。 Pythonコンソールを利用することでAPIやテストしたい処理を直接実行して動作確認できることから、アドオン開発の効率化のために積極的に活用していきましょう。

ポイント