blender 2.5 スクリプト概要把握用メモ
blender 2.4用のpythonスクリプトを2.5用に書き換えようと思ったら、仕様がごっそり変わってて大変だった件。
大まかな書き方を理解するのに、英語wiki必死に読んだが、英語力なくて死にかけたw
とりあえず仕様把握のための備忘録。
ざっくり見た感じなので、かなり不正確だが、とりあえず現行の2.56だと……
bpy
bpyモジュールをimportして、その機能を使うことでスクリプトを書くよ。
bpy以外にもgame blender用のbgeモジュールとか、数学ユーティリティとかのモジュールが入ってるスタンドアローンなんちゃらとかってのもあるけど、基本的にはbpyだよ。
bpyの下には、様々なクラスが格納してある、bpy.typesがある。
これ大事。ここで定義されているクラスのインスタンスを使ってスクリプトを書くことになる。
で、bpyの下に他に何があるかだけど
実際にユーザーが操作しているblenderの現在の状態に触るための
bpy.context ※bpy.types.Contextのインスタンス
開かれているblendファイルの中にある、様々なデータに実際に触るための
bpy.data ※bpy.types.BlendDataのインスタンス
の二つがあって、この辺を操作するのが
Operator ※bpy.types.Operatorのサブクラス
であり、このOperatorを新たに作ってblenderに登録することが、基本的なスクリプトの書き方になる。
ちなみにあらかじめblenderに入っていたり、スクリプトで登録したOperatorはbpy.opsの下に置かれるので、ここから好きに呼び出して使うことが出来るよ。
あと、この登録されたOperatorを、ユーザーが利用するためのUIを提供するには
Menu ※bpy.types.Menuのサブクラス
Panel ※bpy.types.Panelのサブクラス
ってのがあって、この辺のサブクラスを作って登録することで、メニューとかボタンとかをクリックして使えるようにできるっぽいけど、まだちょっとよく分からない。
なんかOperator自体もDraw()メソッド持ってるっぽいけど、よくわかんないよ。
他にもbpyの下には、アプリ情報を取得するためのbpy.appやユーティリティを格納したbpy.utilsやbpy.pathなんかがあるよ。
Operator
こいつを作って、色々操作するよ。
それにはクラスを作って、そのクラスを bpy.utils.register_class(クラス名) で登録する必要がある。
登録するクラスに必要なことは
登録するとbpy.ops.bl_idnameで登録した名前()で呼び出すことが出来る。
例えば
大まかな書き方を理解するのに、英語wiki必死に読んだが、英語力なくて死にかけたw
とりあえず仕様把握のための備忘録。
ざっくり見た感じなので、かなり不正確だが、とりあえず現行の2.56だと……
bpy
bpyモジュールをimportして、その機能を使うことでスクリプトを書くよ。
bpy以外にもgame blender用のbgeモジュールとか、数学ユーティリティとかのモジュールが入ってるスタンドアローンなんちゃらとかってのもあるけど、基本的にはbpyだよ。
bpyの下には、様々なクラスが格納してある、bpy.typesがある。
これ大事。ここで定義されているクラスのインスタンスを使ってスクリプトを書くことになる。
で、bpyの下に他に何があるかだけど
実際にユーザーが操作しているblenderの現在の状態に触るための
bpy.context ※bpy.types.Contextのインスタンス
開かれているblendファイルの中にある、様々なデータに実際に触るための
bpy.data ※bpy.types.BlendDataのインスタンス
の二つがあって、この辺を操作するのが
Operator ※bpy.types.Operatorのサブクラス
であり、このOperatorを新たに作ってblenderに登録することが、基本的なスクリプトの書き方になる。
ちなみにあらかじめblenderに入っていたり、スクリプトで登録したOperatorはbpy.opsの下に置かれるので、ここから好きに呼び出して使うことが出来るよ。
あと、この登録されたOperatorを、ユーザーが利用するためのUIを提供するには
Menu ※bpy.types.Menuのサブクラス
Panel ※bpy.types.Panelのサブクラス
ってのがあって、この辺のサブクラスを作って登録することで、メニューとかボタンとかをクリックして使えるようにできるっぽいけど、まだちょっとよく分からない。
なんかOperator自体もDraw()メソッド持ってるっぽいけど、よくわかんないよ。
それからbpyの下には、様々なプロパティの型が登録してある、bpy.props ってのもある。
これも重要で、Operatorにプロパティを持たせる場合、ここに登録したプロパティの型を使う必要があるっぽい。Int型の変数持たせるだけでも、
x = bpy.props.IntProperty()みたいに書く必要があるっぽい。
これを使って作ったプロパティは、Operatorを呼び出すときに、呼び出し側から好きに初期値を設定できるみたい。
あとこれを使うと、既存の色んなクラスに、好き勝手にプロパティを付け足していけるらしいよ。
他にもbpyの下には、アプリ情報を取得するためのbpy.appやユーティリティを格納したbpy.utilsやbpy.pathなんかがあるよ。
Operator
こいつを作って、色々操作するよ。
それにはクラスを作って、そのクラスを bpy.utils.register_class(クラス名) で登録する必要がある。
登録するクラスに必要なことは
- bpy.types.Operatorのサブクラスとして作ること。
- Operatorを呼び出す際に使う名前 bl_idname と、説明用の文章 bl_label の文字列変数を持つこと。
- 実際の処理内容を記述するメソッド execute() を持つこと。
登録するとbpy.ops.bl_idnameで登録した名前()で呼び出すことが出来る。
例えば
class HogeOperator(bpy.types.Operator):
bl_idname = "hoge.pyoro"
って設定したオペレーターなら、bpy.props.hoge.pyoro()で呼び出せる。
また、bpy.propsに登録されている型を使ったプロパティを持たせておくと、オペレーターを呼び出す際
もしこれらのプロパティの値を呼び出し時に直接決めるのではなく、特殊な処理を通して決めたい場合はinvoke()というプロパティ初期化用のメソッドを持たせて、そこにプロパティの内容を決める処理を書く。
その後
ちなみに多分、そのままではinvoke()だけ呼び出されて、execute()を呼んでくれないので、invoke()の内部でexecute()を呼び出す処理を書く必要がある。
なお、ここにあるみたいに
context.window_manager.fileselect_add()や
context.window_manager.invoke_props_dialog()
みたいなやつを呼んでいると、そいつらがexecute()を呼んでくれるみたいだ。
もうひとつ、poll()というメソッドを定義すると、これが事前にOperatorを使えるかどうかチェックしてくれる。
poll()がFalseを返すと、そのOperatorはそこで終了になるので、エラーが起こりそうな条件をチェックして、ここで返してしまえば、エラーを起こさないで済むっぽい。
モジュール
トップレベルにregister()関数とunregister()関数を持っているモジュールを、blenderは読み込むことが出来る。
モジュールがロードされる際register()関数が呼ばれ、破棄される場合unregister()関数が呼ばれる。
先述したとおり、Operatorは bpy.utils.register_class(クラス名) で登録して、bpy.utils.unregister_class(クラス名) で登録を解除することが出来るので、普通は何らかのクラスを作りregister()関数内でbpy.utils.register_class()を呼んで登録し、unregister()関数内でbpy.utils.unregister_class() を呼ぶのが一般的。
更にbl_info という辞書の中身を設定し、モジュールデータをaddonsフォルダにつっこむと、アドオンとして使用することが出来る。
UI周辺
まだちょっと色々分かっていないんだけど、分かってる部分だけ。
これ、概ね .blender/ scripts/ ui/ フォルダに入ってるスクリプトで定義されてるっぽい。
space_ほにゃらら.pyってスクリプトには、各ウィンドウモードのヘッダー部分(メニューとかがある所)と、nキーで呼び出せるプロパティバーの中身が定義してあるっぽい。
ただしプロパティウィンドウだけは特殊で、property_ほにゃらら.py ってスクリプトに、プロパティウィンドウで表示されるもののほとんどが設定されてるっぽい。
だからメニューとかプロパティバーとかツールバーに、何かのボタンとかメニューとかを追加したい場合は(ってかほとんどの場合そうだろうけど)、ここにあるスクリプトの中の関数を使って、登録すればいいっぽい。
ただちょっと、細かいやり方とかはまだ把握してない。
その他
そもそもPython自体のバージョンが変わってて、しかもそのバージョンアップで互換性捨ててるため、書き直さないと不味いところがちらほら。まぁ具体的にはprint命令ですけども。
あと、まだちょっと未確認なんだけど、確かblender2.4系の頃って、スクリプトでメッシュいじるにしろ何するにしろ、いったんエディットモードとか抜けて、オブジェクトモードから操作しないといけなかった気がするんだけど、今回はそれいらないっぽい?
また、bpy.propsに登録されている型を使ったプロパティを持たせておくと、オペレーターを呼び出す際
bpy.ops.hoge.pyoro(プロパティ名1=値, プロパティ名2=値, ...)といった感じで、プロパティの値を設定することが出来る。
もしこれらのプロパティの値を呼び出し時に直接決めるのではなく、特殊な処理を通して決めたい場合はinvoke()というプロパティ初期化用のメソッドを持たせて、そこにプロパティの内容を決める処理を書く。
その後
bpy.ops.hoge.pyoro('INVOKE_DEFAULT')と呼び出すと、クラス内のexecute()ではなくinvoke()が呼び出される。
ちなみに多分、そのままではinvoke()だけ呼び出されて、execute()を呼んでくれないので、invoke()の内部でexecute()を呼び出す処理を書く必要がある。
なお、ここにあるみたいに
context.window_manager.fileselect_add()や
context.window_manager.invoke_props_dialog()
みたいなやつを呼んでいると、そいつらがexecute()を呼んでくれるみたいだ。
もうひとつ、poll()というメソッドを定義すると、これが事前にOperatorを使えるかどうかチェックしてくれる。
poll()がFalseを返すと、そのOperatorはそこで終了になるので、エラーが起こりそうな条件をチェックして、ここで返してしまえば、エラーを起こさないで済むっぽい。
モジュール
トップレベルにregister()関数とunregister()関数を持っているモジュールを、blenderは読み込むことが出来る。
モジュールがロードされる際register()関数が呼ばれ、破棄される場合unregister()関数が呼ばれる。
先述したとおり、Operatorは bpy.utils.register_class(クラス名) で登録して、bpy.utils.unregister_class(クラス名) で登録を解除することが出来るので、普通は何らかのクラスを作りregister()関数内でbpy.utils.register_class()を呼んで登録し、unregister()関数内でbpy.utils.unregister_class() を呼ぶのが一般的。
更にbl_info という辞書の中身を設定し、モジュールデータをaddonsフォルダにつっこむと、アドオンとして使用することが出来る。
UI周辺
まだちょっと色々分かっていないんだけど、分かってる部分だけ。
これ、概ね .blender/ scripts/ ui/ フォルダに入ってるスクリプトで定義されてるっぽい。
space_ほにゃらら.pyってスクリプトには、各ウィンドウモードのヘッダー部分(メニューとかがある所)と、nキーで呼び出せるプロパティバーの中身が定義してあるっぽい。
ただしプロパティウィンドウだけは特殊で、property_ほにゃらら.py ってスクリプトに、プロパティウィンドウで表示されるもののほとんどが設定されてるっぽい。
だからメニューとかプロパティバーとかツールバーに、何かのボタンとかメニューとかを追加したい場合は(ってかほとんどの場合そうだろうけど)、ここにあるスクリプトの中の関数を使って、登録すればいいっぽい。
ただちょっと、細かいやり方とかはまだ把握してない。
その他
そもそもPython自体のバージョンが変わってて、しかもそのバージョンアップで互換性捨ててるため、書き直さないと不味いところがちらほら。まぁ具体的にはprint命令ですけども。
あと、まだちょっと未確認なんだけど、確かblender2.4系の頃って、スクリプトでメッシュいじるにしろ何するにしろ、いったんエディットモードとか抜けて、オブジェクトモードから操作しないといけなかった気がするんだけど、今回はそれいらないっぽい?
コメント