[Blender] ユーザがツールシェルフのオプションからプラグインを制御できるようにするための方法

Blenderのツールシェルフをご存知ですか？

**ツールシェルフ**というのは、Tキーで表示/非表示を切り替えることのできるメニューで、**画面左端に表示されるツールバー**のことです。
ツールシェルフにはツールが多数ありますが、下には**オプション**と呼ばれる、**直前に行った操作に対してユーザが細かい制御を行うための設定項目**が存在します。
例えば「Subdivision Set」のLevelはその1つの例です。

今回はツールシェルフのオプションから直前の操作に対して、ユーザからの制御を有効化するための機能をプラグインに追加する方法を紹介します。


# サンプル

細かく説明するよりもサンプルを出した方がわかりやすいと思うので、オプションで設定された値の角度だけオブジェクトをX軸周りに回転する操作を行うサンプルプラグインを紹介します。

```py3:rotate_around_x_axis.py
import bpy
import mathutils
from math import radians
from bpy.props import *

bl_info = {
    "name" : "Property sample",
    "author" : "Nutti",
    "version" : (1, 0),
    "blender" : (2, 7, 0),
    "location" : "UV Mapping > Property sample",
    "description" : "Property sample",
    "warning" : "",
    "wiki_url" : "",
    "tracker_url" : "",
    "category" : "UV"
}

class PropertySample(bpy.types.Operator):
    """"""
    
    bl_idname = "uv.property_samle"
    bl_label = "Property Sample"
    bl_description = "Property Sample"
    bl_options = {'REGISTER', 'UNDO'}

    # ツールシェルフへ表示させる値
    # X軸を中心として回転させる角度（0度から360度の整数値を選択可能）
    rot = IntProperty(
        name = "Rotate X",                # ツールシェルフに表示されるラベル名
        description = "Rotate X ...",     # ツールシェルフに表示される説明文
        default = 0,                      # デフォルト値
        min = 0,                          # 選択可能な最小値
        max = 360)                        # 選択可能な最大値
    
    base_euler = None                     # 初期の角度
    
    # 初期化処理
    # __init__はメニューから選択されたときのみ実行される
    # 初期状態をここで保存しておかないと回転量に不具合が生じる
    def __init__(self):
        active_obj = bpy.context.active_object
        mode = active_obj.rotation_mode
        active_obj.rotation_mode = 'QUATERNION'
 
        # オブジェクトの初期状態を保存
        self.base_euler = active_obj.rotation_quaternion.to_euler()
        active_obj.rotation_mode = mode
        
        # 2度目以降にメニューから選択された時、
        # 手動でデフォルト値に設定する必要がある
        self.rot = 0   
    
    # メニューから選択した時に加え、
    # "ツールシェルフで値を変更した時"にも呼ばれる
    def execute(self, context):
        active_obj = bpy.context.active_object
        mode = active_obj.rotation_mode
        active_obj.rotation_mode = 'QUATERNION'
        
        # 新しいオブジェクトの状態を設定
        new_euler = self.base_euler.copy()
        new_euler.x = self.base_euler.x + radians(self.rot)
        active_obj.rotation_quaternion = new_euler.to_quaternion()
        
        active_obj.rotation_mode = mode
        
        return {'FINISHED'}


# registration
def menu_func(self, context):
    self.layout.operator(PropertySample.bl_idname)

def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.append(menu_func)

def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.remove(menu_func)


if __name__ == "__main__":
    register()
```


# サンプルの使い方

サンプルのインストールの方法などは[BlenderのWikiページ](http://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Extensions/Python/Add-Ons)をご覧ください。

サンプルの使い方を以下に示します。

1. 「EDIT」モードに変更 
2. 「U」ボタンを押して、「Property Sample」を選択
3. ツールシェルフに、「Rotate X」というオプションが表示されるので適当な値に設定し、オブジェクトが回転することを確かめる

サンプルの実行結果の例を以下に示します。

![sample_1.png](https://qiita-image-store.s3.amazonaws.com/0/38888/d1f39815-6964-774e-5c05-8961cec8ceee.png)


# サンプルの解説

基本的なソースコードは[\[Blender\] Blenderプラグインの作り方](http://qiita.com/nutti/items/a836391723bd28cd3e4c)で説明していますので省略します。


オプションの値を指定しているのは以下の部分です。

```py3:set_option.py
# ツールシェルフへ表示させる値
# X軸を中心として回転させる角度（0度から360度の整数値を選択可能）
rot = IntProperty(
    name = "Rotate X",                # ツールシェルフに表示されるラベル名
    description = "Rotate X ...",     # ツールシェルフに表示される説明文
    default = 0,                          # デフォルト値
    min = 0,                               # 選択可能な最小値
    max = 360)                          # 選択可能な最大値
```

**IntProperty**という関数を用いることで、ユーザがオプションとして値を設定することができるようになります。
このサンプルでは、X軸を中心として回転させる角度を0度から360度で指定できるようにしています。
その他細かい部分については、ソースコードに適宜コメントを入れているので参考にしてください。

# オプションに指定できる値一覧

サンプルでは整数値をオプションとして設定できるようにしていましたが、他の型のオプションの値も設定できます。
設定可能な値とそれに対応する関数をまとめておきますので、参考にしてみてください。

|型|関数|
|---|---|
|ブーリアン|BoolProperty|
|整数|IntProperty|
|浮動小数点|FloatProperty|
|文字列|StringProperty|

# オプションに指定できる値の範囲を指定

オプションに指定可能な値を制限することも出来ます。
整数型のオプションについて範囲を-100から400の間に制限する方法を示します。

```py3:max_min.py
i = IntProperty(
    name = "Integer",
    description = "Integer ...",
    default = 0,
    min = -100,
    max = 400)
```

# 〜Propertyに指定可能な引数

〜Propertyに指定可能な引数をまとめておきます。
他にも指定可能な引数がありますが、詳しくは[Blender公式ページ](http://www.blender.org/api/blender_python_api_2_66_release/bpy.props.html)をご覧ください。

|引数|説明|
|---|---|
|name|ツールシェルフに表示されるオプション名|
|description|オプションにマウスポインタを当てた時に表示される説明文|
|default|初期状態のオプション値|
|max|オプションに指定できる値の最大値|
|min|オプションに指定できる値の最小値|

# 最後に

ユーザがオプションに指定された値を取得する方法を紹介しました。
オプションを利用することでユーザが機能に対して設定できるようになり、プラグイン作成の幅が広がるはずです。

# 参考情報

* http://www.blender.org/api/blender_python_api_2_66_release/bpy.props.html
* [\[Blender\] Blenderプラグインの作り方](http://qiita.com/nutti/items/a836391723bd28cd3e4c)
* http://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Extensions/Python/Add-Ons
* http://www.blender.org/api/blender_python_api_2_58_1/mathutils.html