見出し画像

アーマチュアを調べる

Blenderにはアーマチュア(Armature、骨組み)という仕組みがあって、このアーマチュアをメッシュ・オブジェクトへ紐づけることで、メッシュ・オブジェクトにポーズ(Pose、姿勢)を取らせることができるようだ。

アーマチュア・オブジェクトは、ボーン(Bone、骨)を繋げていって構成されるスケルトン(Skeleton、骨格)と、姿勢を包含している。

もちろんオブジェクト・データなので、メッシュ・オブジェクトと同じようにロケーションやローテーション、スケールも保持している。

用語の由来

アーマチュアという用語は聞き慣れないので由来を調べてみることにした。

元々は石膏や粘土を使う石彫(いしぼり、Stone curving、ストーン・カービング)から来た用語のようだ。

ワイヤーを使って石像の基本的な姿勢を作り、そこへ大雑把に石膏や粘土を盛りつけていき、粘土を削ったり盛ったりするけど、そのワイヤー、あるいはワイヤーで形作られたものこそが、アーマチュアということらしい。

美術由来の用語は、ほかにもスカルプト(Sculpt、彫像を造る)、モデリング(Modeling、塑像、そぞう)などが使われていて、スカルプトは彫像を作成する全般的な作業を実施するという動詞、モデリングは粘土や石膏を盛ったり削ったりする作業のことを指すようだ。

BlenderにはSculptワーク・スペースやModelingワーク・スペースがあるけど、おそらく用語の意味をするところの作業を実施しやすくなるような設定がされているのだと考えられる。

アーマチュアの生成

Blenderを起動したデフォルトの画面にはキューブ、カメラ、ライトしかないので、アーマチュアは新しく作る必要がある。

Blender Pythonからアーマチュア・オブジェクトを作る方法は2種類あって、bpy.ops.object.armature_addから作る方法と、bpy.ops.object.addのタイプにARMATUREを指定して作る方法がある。

Layout画面からアーマチュアを追加すると、Info画面に実行スクリプトが挿入されるけど、こちらはbpy.ops.object.armature_addからアーマチュアが作られる。

bpy.ops.object.armature_add(enter_editmode=False, align='WORLD', location=(000), scale=(111))

もうひとつはbpy.ops.object.addのタイプにARMATUREを指定して作る。

bpy.ops.object.add(radius=1.0, type='ARMATURE', enter_editmode=False, align='WORLD', location=(0.00.00.0), rotation=(0.00.00.0), scale=(0.00.00.0))ぜ

前者と後者の違いを調べてみると、前者はアーマチュア・オブジェクトとともにボーン・データが1つだけ一緒に生成されるけど、後者はアーマチュア・オブジェクトだけが生成されて、ボーン・データが生成されなかった。

ボーン・データの生成をするかしないかというのは、スクリプトの処理目的によって変わるので、両方あるのは利便性を考えてのことなのかもしれない。

ボーンとスケルトン

ボーン・データは、動物で言えば個々の骨に相当する機能を持っている。このボーン・データを繋げていくと骸骨ができあがる。これをスケルトンと呼んでいるらしい。

次のイメージはBlenderで形作られるスケルトンの例。パーツごとの長さと大きさが、大体頭に描く内容に近くなっている。

頭蓋骨や肩甲骨のような丸さや広さを持っているのではなく、ボーン・データへ関連付けたメッシュ・データの動きを制御するための機構を備えているようだ。

このアーマチュア・データは、カーネギー・メロン大学のグラフィック・ラボで作成されたモーション・キャプチャ・データから生成されたもの。2010年7月までに2548個のデータがBVHファイル形式へコンバートされている。

BVHは、BioVisionという企業が定義したデータ形式で、ボーンの階層構造と、モーション・データからなる。アニメーションについては、ボーンのデータ構造を調査した後、別途調査する。

ボーンの向き

ボーンには向きがある。尖っているほうがTail(テイル、尻尾)で、反対側のほうがHead(ヘッド、頭)になっている。TailとHeadの距離で長さが決まり、画面へ表示される大きさもボーンの長さに依存しているようだ。

ボーンへのアクセス

アーマチュア・オブジェクトには、ボーンのアクセサが3種類ある。ひとつめがbones、ふたつめがedit_bones、みっつめがpose.bones。最初の2つはアーマチュア・データに紐づいていて、残り1つはアーマチュア・オブジェクトに紐づいている。

bonesはオブジェクト・モードで利用されることが多いようで、レイアウト画面上のローカル座標などにもアクセスすることができる。

edit_bonesはエディット・アーマチュア・モードで利用する。Blender上のモード表示ではエディット・モードのままだけれど、アーマチュア・オブジェクトを選択してエディット・モードへ切り替えると、アーマチュアを編集するための特別なモードへ切り替わる。

アーマチュア・データとメッシュ・データでは扱うデータ構造が大きく異なるので、こういう隠蔽をしてもらえるのはわかりやすいと思う。

ただ、edit_bonesには不満もある。エディット・アーマチュア・モード以外ではまったくアクセスできないので、たとえば、オブジェクト・モードからアクセスすると、キーが見つからないなどのエラーになる。

>>> bpy.data.objects["01_01"].data.edit_bones["hip"]
Traceback (most recent call last):
 File "<blender_console>", line 1in <module>
KeyError: 'bpy_prop_collection[key]: key "hip" not found'

>>> bpy.context.mode
'OBJECT'

>>> bpy.ops.object.mode_set(mode="EDIT", toggle=True)
{'FINISHED'}

>>> bpy.context.mode
'EDIT_ARMATURE'

>>> bpy.data.objects["01_01"].data.edit_bones["hip"]
bpy.data.armatures['01_01']...EditBone

これは私のようなBlender初心者には厳しい仕様だ。このような仕様になっているのは、edit_bonesがエディット・アーマチュア・モードに切り替わったタイミングで、逐一bonesから編集用のデータを生成するため。

オブジェクト・モードでedit_bonesのデータ・カウントを調べてみると0になるので、逐一生成していることがわかる。

>>> bpy.context.mode
'OBJECT'

>>> len(bpy.data.objects["01_01"].data.edit_bones)
0

一方、pose.bonesはオブジェクト・モードからでも見つけることができる。

この辺りの非対称な仕様はかなり戸惑うので、エディット・アーマチュア・モード以外でedit_bonesへアクセスしたら、エディット・アーマチュア・モードへ切り替える旨を表示するなどしてもらえるとありがたいなと思う。

この記事が気に入ったらサポートをしてみませんか?