Blender のアドオンを作る準備
Kinect と Blender でモーションキャプチャするために AMBloop(https://github.com/asahiufo/AMBloop)を使ってがんばっていますが、どうにも希望通り動作させることが出来ないかつ、ソース修正の方法が分からないということで、Bloop を参考にモーションキャプチャツールを自作することにしました。C# 製 Kinect データ送信プログラムはなんとなく出来たので、次は Blender でデータ受信、メッシュへ適用、アニメーションとして録画する Blender アドオンを作らなければなりません。 Python は触ったことがないかつ、Blender のアドオンを作るのも初めてなので、まず開発の進め方を調べてみました。(自分の作りたいものに特化しています。Python の文法周りは、都度都度調べるということで無視です。)
対象環境
- Blender 2.64
1. どんなのを作りたいのか ↓のように、Bloop と同じような形で作る予定です。
2. 調べ方 やっぱり公式が良さそうです。(英語) Blender Documentation Contents — Blender 2.64.1 - API documentation
以下のようなコアとなる処理は Bloop を参考にするとします。
- OSC(Open Sound Control)データの受信
- メッシュの座標へ適用
- 録画
まずは Bloop での処理の頭を見てみます。
多分このあたりで Blender 上での GUI を記述しているのではないかと。
AMBloop/nui/init.py at master · asahiufo/AMBloop · GitHub
import bpy
from .nui_sensor import NUISensor #@UnresolvedImport
from .nui_sensor import NUIUser #@UnresolvedImport
from .nui_draw import NUI_draw_end #@UnresolvedImport
from .nui_panel import NUIPanel #@UnresolvedImport
from .nui_panel import NUIToggleDraw #@UnresolvedImport
from .nui_panel import NUIProps #@UnresolvedImport
bl_info = { “name”: “NUI Interface”, “description”: “Provides access to Kinect NUI data via OSCeleton”, “author”: “Florian Biermann”, “version”: (1,0), “blender”: (2, 5, 9), “api”: 31236, “location”: “bpy.nui”, “warning”: “A user property, like ‘head’, returns a tuple of (Vector, Quaternion).”, “wiki_url”: “”, “tracker_url”: “”, “category”: “Development”}
def register(): bpy.utils.register_class(NUIToggleDraw) bpy.utils.register_class(NUIPanel) bpy.utils.register_class(NUIProps) bpy.types.WindowManager.nui_props = bpy.props.PointerProperty(type=NUIProps) bpy.nui = NUISensor(mode=“oscpuppet”, debug=False) #bpy.nui = NUISensor(mode=“mssdk”)
def unregister():
bpy.utils.unregister_class(NUIToggleDraw)
bpy.utils.unregister_class(NUIPanel)
bpy.utils.unregister_class(NUIProps)
del bpy.nui
AMBloop/nui/nui_panel.py at master · asahiufo/AMBloop · GitHub
import bpy
from .nui_draw import NUI_draw_begin
from .nui_draw import NUI_draw_end
class NUIPanel(bpy.types.Panel):
bl_label = "NUI"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
@classmethod
def poll(cls, context):
return hasattr(bpy, "nui")
def draw(self, context):
col = self.layout.column(align=False)
if bpy.nui.draw:
col.operator("nui.toggle_draw", text="Stop user display")
else:
col.operator("nui.toggle_draw", text="Start user display")
col = self.layout.column(align=True)
col.prop(context.window_manager.nui_props, "offset_x")
col.prop(context.window_manager.nui_props, "offset_y")
if not bpy.nui.mode == "mssdk":
col = self.layout.column(align=True)
col.prop(context.window_manager.nui_props, "sensor_angle")
class NUIToggleDraw(bpy.types.Operator):
bl_idname = "nui.toggle_draw"
bl_label = "Toggle NUI user display"
@classmethod
def poll(cls, context):
return NUIPanel.poll(context)
def execute(self, context):
if bpy.nui.draw:
NUI_draw_end(context)
else:
NUI_draw_begin(context)
return {"FINISHED"}
class NUIProps(bpy.types.PropertyGroup): do_draw = bpy.props.BoolProperty(name=“Draw user”, default = True) offset_x = bpy.props.IntProperty(name=“Screen offset X”, default=200) offset_y = bpy.props.IntProperty(name=“Screen offset Y”, default=200) sensor_angle = bpy.props.IntProperty(name=“Sensor angle”, default=0, soft_min=-31, soft_max=31)
特に↓のあたりは怪しそうです。
class NUIPanel(bpy.types.Panel):
bl_label = "NUI"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
公式ドキュメントを漁ってみると、bpy.types.Panel のサンプルがありました。 Quickstart Introduction — Blender 2.64.1 - API documentation まずはこれを動かしてみようと思います。
3. スクリプトの実行確認
3.1. Blender 起動
3.3. TextEditor 表示 TextEditor の下の「-」印を押しておき、右に 3 つ並んでいる□のアイコンを 3 つともクリックしておくと、エディタが見やすくなりそうです。
3.4. スクリプト貼り付け
「+ New」ボタンを押してソースを新規作成します。(名前は適当に “panel.py” としておきます。)
ここに公式ドキュメントの bpy.types.Panel のサンプルを貼り付けるのですが、今回作りたいものに合わせて以下のとおり修正します。
import bpy
class AMK2BPanel(bpy.types.Panel): “”“Creates a Panel in the Object properties window”“” bl_label = “AMK2B” bl_space_type = ‘VIEW_3D’ bl_region_type = ‘TOOLS’
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.label(text="Hello world!", icon='WORLD_DATA')
row = layout.row()
row.label(text="Active object is: " + obj.name)
row = layout.row()
row.prop(obj, "name")
row = layout.row()
row.operator("mesh.primitive_cube_add")
def register(): bpy.utils.register_class(AMK2BPanel)
def unregister(): bpy.utils.unregister_class(AMK2BPanel)
if name == “main”: register() 結果こんな感じです。
3.5. 実行結果確認 TextEditor 下の 「Run Script」ボタンを押して実行します。 実行すると、「3D View」パネルの左("Object Tools" があるあたり)に “AMK2B” というパネルが追加されるはずです。 実行前 実行後 変化無し・・・。 どうやら、パネルの表示を変えた場合、Blender の GUI の表示を更新してやらなければならないようです。 表示の更新は、エディタの表示幅等を弄ればよいようです。 以下では、「3D View」エディタの幅を右へ少し広げた結果です。 新しい Panel が追加されました! これを繰り返せば、編集、実行結果確認を進めていけそうです。
終わりに Blender のアドオンを作る場合、一旦 Blender 上でファイル編集をして、出来上がったらソースを別ファイルやフォルダに格納すれば良いのでしょうか?この辺りは作りながら様子を見ようと思います。