本日はBlender枠です。
現在MixedRealityModelingToolsなるBlenderとUnityで相互に情報をやり取りできるパッケージを作成しています。
今回はBlender側の実装する上での基礎的なコードとしてテキストフィールドを表示して、任意の文字をログに出力するようなことを行います。
目的としてはBlender内で入力した任意の文字列をコード内で使用できることを実装するというところで、今回はprint()でログ出力しますが、変数として格納したstring型のデータとしてあらゆる場面で使用できます。
〇シンプルなアドオン
まずBlenderでのシンプルなアドオンのコードを紹介します。
import bpy # Define a new operator (action or function) class HelloWorldOperator(bpy.types.Operator): bl_idname = "object.hello_world" bl_label = "Hello, World!" def execute(self, context): self.report({'INFO'}, "Hello, World!") return {'FINISHED'} # Define a new UI panel class HelloWorldPanel(bpy.types.Panel): bl_label = "My Panel" bl_idname = "OBJECT_PT_hello_world" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Tool' def draw(self, context): layout = self.layout # Add the operator to the panel layout.operator("object.hello_world") # Registration def register(): bpy.utils.register_class(HelloWorldOperator) bpy.utils.register_class(HelloWorldPanel) def unregister(): bpy.utils.unregister_class(HelloWorldOperator) bpy.utils.unregister_class(HelloWorldPanel) if __name__ == "__main__": register()
こちらのコードは過去の記事で詳しく紹介しています。
今回はこのコードをベースにテキストフィールドを作成していきます。
〇Blenderでテキストフィールドを作成する。
Blenderでテキストフィールドを追加するためにはStringProperty()を使用します。
テキストフィールドとその機能を定義するためのオペレータとして次のクラスを作成しました。
# Define a new operator to print text class PrintTextOperator(bpy.types.Operator): bl_idname = "object.print_text" # アドオン内で一意のIDを設定 bl_label = "Print Text" #UI上で表示されるラベルを設定します text_input: bpy.props.StringProperty(name="Input Text") # StringPropertyを使用してテキストフィールド用のプロパティを定義 def execute(self, context): print("Input Text:", self.text_input) # 入力されたテキストをコンソールに出力 return {'FINISHED'} # オペレーションの実行が終了したことを示すステータスを返す
このクラスをBlenderでUIとして表示する処理が次です。
def draw(self, context): layout = self.layout # Add a text field to the panel layout.prop(context.scene, "my_text_input") # Add the print operator to the panel layout.operator("object.print_text")
ここではlayout.prop()とlayout.operator()の二つを定義しています。
prop()はテキストフィールドを定義します。第一引数のcontext.sceneはプロパティオブジェクト、第二引数がstring型の変数になります。 つまり入力したテキストはmy_text_inputに格納されることになります。
operator()はBlender内でUIとしてのボタンを定義します。 引数内はBlender内のIDでPrintTextOperatorと一致させることで紐づけています。
BlenderのUI側では次のように表示されます。
〇ボタンを押した際の処理
# Add the print operator to the panel layout.operator("object.print_text")
定義されているボタンを押した場合はobject.print_textによって紐づけられているPrintTextOperatorクラスの def execute(self, context):が実行されます。
def execute(self, context): print("Input Text:", self.text_input) # 入力されたテキストをコンソールに出力 return {'FINISHED'} # オペレーションの実行が終了したことを示すステータスを返す
ここでは終了処理のほかに入力された文字をコンソールに出力しています。
〇アドオンとしての登録
最後に定義した各UIやクラスをアドオンとしてBlenderに登録する処理が以下です。
# Registration def register(): bpy.utils.register_class(HelloWorldOperator) bpy.utils.register_class(PrintTextOperator) bpy.utils.register_class(HelloWorldPanel) bpy.types.Scene.my_text_input = bpy.props.StringProperty(name="Text Input") def unregister(): bpy.utils.unregister_class(HelloWorldOperator) bpy.utils.unregister_class(PrintTextOperator) bpy.utils.unregister_class(HelloWorldPanel) del bpy.types.Scene.my_text_input
registerはBlenderのアドオン登録時、unregisterは登録解除時に実行される関数でそれぞれ、アドオンの定義、解除を行っています。
〇コード全文
import bpy # Define a new operator (action or function) class HelloWorldOperator(bpy.types.Operator): bl_idname = "object.hello_world" bl_label = "Hello, World!" def execute(self, context): self.report({'INFO'}, "Hello, World!") return {'FINISHED'} # Define a new operator to print text class PrintTextOperator(bpy.types.Operator): bl_idname = "object.print_text" bl_label = "Print Text" text_input: bpy.props.StringProperty(name="Input Text") def execute(self, context): print("Input Text:", self.text_input) return {'FINISHED'} # Define a new UI panel class HelloWorldPanel(bpy.types.Panel): bl_label = "My Panel" bl_idname = "OBJECT_PT_hello_world" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Tool' def draw(self, context): layout = self.layout # Add a text field to the panel layout.prop(context.scene, "my_text_input") # Add the print operator to the panel layout.operator("object.print_text") # Registration def register(): bpy.utils.register_class(HelloWorldOperator) bpy.utils.register_class(PrintTextOperator) bpy.utils.register_class(HelloWorldPanel) bpy.types.Scene.my_text_input = bpy.props.StringProperty(name="Text Input") def unregister(): bpy.utils.unregister_class(HelloWorldOperator) bpy.utils.unregister_class(PrintTextOperator) bpy.utils.unregister_class(HelloWorldPanel) del bpy.types.Scene.my_text_input if __name__ == "__main__": register()
以上でテキストフィールドの実装とコンソールの出力が行えました。