本日は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()
以上でテキストフィールドの実装とコンソールの出力が行えました。