本日はBlenderモデリング枠です。
最近Blenderでスクリプトを構築することに挑戦していますが、今回は3Dビューポートに自作のタブを追加してUIとしてスクリプトを実行できるようにしていきます。
これは配布されているアドオン等で一般的にみられるものです。
例えばTrueSkyの場合3DビューポートにTrueSky-VFXのタブが出現しており、それをクリックすることでTrueSkyという表示名のパネルが表示され、その中にアドオンの独自の機能がUIとして提供されています。
今回のUIを自作します。
〇3Dビューポートに自作のタブを追加する。
メニューを追加するためにはbpy.types.Pnaleを使用します。
このクラスはBlenderのUIにおけるパネルを作成するためのクラスで、このクラスを継承して、自作のカスタムパネルを作成することができます。
class CustomPanel(bpy.types.Panel):
bpy.types.Panelで定義されている属性を使用してUIの名前などを定義することができます。
今回は次のように定義してみます。
class CustomPanel(bpy.types.Panel): bl_idname = "OBJECT_PT_custom_panel" bl_label = "Custom Panel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Custom'
bl_idnameは一意の識別子を指定します。これはコンフリクトしないためにも他のアドオンと重複しないようにする必要があります。
bl_labelはパネルのタイトルまたはラベルを指定します。ここで指定した名前がタブの名前になります。
bl_space_typeはUIが表示されるスペースのタイプを指定します。例えばVIEW_3Dと記述した場合は3Dビューポートを示します。
bl_region_typeはパネルが表示される領域のタイプを指定します。例えば、'UI'はユーザーインターフェース領域を示します。
bl_categoryはパネルが表示されるカテゴリを指定しています。冒頭のTrueSkyの場合TrueSkyと表示されていた部分になります。
draw(self, context)はパネルの描画を行うメソッドです。このメソッド内で、パネルに表示する要素(ボタン、メニュー、テキストなど)を追加するためのBlender UIの関数を使用します。
これを使用してメニューを追加するコードは以下になります。
import bpy # メニューを定義するクラス class CustomPanel(bpy.types.Panel): bl_idname = "OBJECT_PT_custom_panel" #タブに表示される名前 bl_label = "Custom Panel" #どこに追加するか? bl_space_type = 'VIEW_3D' bl_region_type = 'UI' #ウィンドウに表示される名前 bl_category = 'Custom' def draw(self, context): layout = self.layout # アドオンを有効化したときに呼び出される処理 def register(): bpy.utils.register_class(CustomPanel) # アドオンを無効化したときに呼び出される処理 def unregister(): bpy.utils.unregister_class(CustomPanel) # スクリプトを実行するときに呼び出される処理 if __name__ == "__main__": register()]
これを実行すると次のようになります。
これによってタブが表示できました。しかし内部の処理を記載していないためウィンドウ側は表示されません。
# メニューを定義するクラス class CustomPanel(bpy.types.Panel): bl_idname = "OBJECT_PT_custom_panel" bl_label = "Custom Panel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Custom' def draw(self, context): layout = self.layout # パネル内にボタンを追加する layout.operator("mesh.primitive_cube_add", text="Add Cube")
draw(self, context):の次にlayout.operate()を記述します。
第一引数にはボタンに名称、第二引数に処理内容を記述します。今回はボタンを押すとシーンにキューブが追加されるという単純なコードを記述しています。
これによってボタンが表示されます。
この処理内容をカスタマイズすることで任意の処理を任意のタイミングに実行することができるようになりました。
〇コード全文
import bpy # メニューを定義するクラス class CustomPanel(bpy.types.Panel): bl_idname = "OBJECT_PT_custom_panel" bl_label = "Custom Panel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Custom' def draw(self, context): layout = self.layout # パネル内にボタンを追加する例 layout.operator("mesh.primitive_cube_add", text="Add Cube") # アドオンを有効化したときに呼び出される処理 def register(): bpy.utils.register_class(CustomPanel) # アドオンを無効化したときに呼び出される処理 def unregister(): bpy.utils.unregister_class(CustomPanel) # スクリプトを実行するときに呼び出される処理 if __name__ == "__main__": register()
〇参考
今回は以下の記事を参考にしています。