Blender のデータベースとシーングラフについて
データベース
Blender のあらゆる情報はデータベースに格納されている。python からは bpy.data を使ってこれらのデータベースにアクセスできる。例えばオブジェクトなら bpy.data.objects、レンダリング設定は bpy.data.scenes、メッシュなら bpy.data.meshes でアクセスできる。
シーングラフ
データの中にはそれ自身のパラメータとほかのデータへの参照(リンクのような機能)を持つものがある。例えばオブジェクトは位置・回転・拡縮などの情報と、メッシュやアーマチュアなどのデータへの参照を持つ。これらのリンク構造をシーングラフと呼ぶ。
Blender でトップレベルにあるデータはシーンだ。シーングラフのイメージは下図のようになる。データベースとは別にシーングラフというデータがあるのではないということに注意する必要がある。下図はデータベースのデータを人間にとってわかりやすく配置しただけだ。
キューブを作成したときの内部動作
何もないシーンにオブジェクトモードでキューブを追加したとき、データベースやシーングラフはそれぞれ以下のようになる。
データベース
データベースにはキューブオブジェクトとキューブメッシュとが追加される。
シーングラフ
追加されたキューブオブジェクトの参照にキューブメッシュが追加され、現在のシーンにキューブオブジェクトへの参照が追加される。
スクリプトを使ってデータベースを操作する
データベースのそれぞれのコンテナ(bpy.data.objects や bpy.data.scenes など)には new メソッドが用意されている。これを使えばデータベースに新規にデータを追加できる。メッシュを追加するには以下のようにする。
bpy.data.meshes.new(name='new_mesh')
これで空のメッシュがデータベースに追加された。
次にオブジェクトを追加する。オブジェクトは作成時にメッシュを指定する必要がある。
bpy.data.objects.new(name='new_object', object_data=bpy.data.meshes['new_mesh'])
これでデータベースに new_object が追加された。しかしシーンから参照されていないのでアウトライナには表示されない。
シーンから参照するにはシーンの objects から link メソッドを使って参照する必要がある。
bpy.data.scenes['Scene'].objects.link(bpy.data.objects['new_object'])
もしくはコンテクストを使って現在のシーンにアクセスする。
bpy.context.scene.objects.link(bpy.data.objects['new_object'])
これでシーンから参照され、アウトライナに new_object が表示される。シーンからオブジェクトを削除したい時は unlink() を使う。
オブジェクト複製時の効率
bpy.ops.object.duplicate() はオブジェクトとデータ(メッシュやアーマチュアなど)と両方複製するため、効率が悪い。duplicate() は本当にデータの複製が必要な場合のみ使う方がいいだろう。
オブジェクトだけを複製したい場合は copy() を使う。これはオブジェクトだけを複製するので大量に実行しても高速に動作する。
o = bpy.data.objects['Cube'].copy() bpy.context.scene.objects.link(o)
シーンの複製
シーングラフとデータベースとが理解できていればシーンを作成するときの、フルコピー・オブジェクトをリンク・オブジェクトデータをリンクの使い分けができる。
フルコピー
フルコピーすると、シーン内のオブジェクトのすべてのコピーとオブジェクトの参照するデータのすべてのコピーと新規に作成したシーンとがデータベースに追加される。これが必要になる状況はまずない。
オブジェクトをリンク
オブジェクトをリンクした場合、データベースに追加されるのは新規に作成したシーンだけだ。これは主にレンダリング設定のみを変更したい場合に使う。
オブジェクトデータをリンク
オブジェクトデータをリンクした場合は、オブジェクトのコピーと新規に作成したシーンとがデータベースに追加される。オブジェクトの参照するデータはコピーされない。これが一番一般的なシーンの作成オプションだろう。シーンのオブジェクトを利用して別のアニメーションを作成するときに使う。
マテリアル
マテリアルはオブジェクトからもメッシュからも参照できる。たいていはメッシュにマテリアルを設定する。オブジェクトにマテリアルを設定するとメッシュのマテリアルは無視される。これはリンクでメッシュを読み込んだとき、メッシュを変更せずにマテリアルを変更したい時に便利だ。