Blender

bpyモジュールを使ってみよう

BlenderをPythonで操作するシリーズ第2回です。

前回はこちら → Pythonで始めるBlender

今回は、前回用意したBlenderを実際に使って見るので、まだ用意できていない方は前回の記事を参考にBlenderを準備してきて下さい。

※ 2019/08/17 追記
記事の内容をBlender 2.80に対応させました。


Blenderを起動してみよう

早速、Blenderを起動してみましょう。
好きな端末を使ってblenderコマンドを実行することで起動することができます。

-h | --help オプションを付けることで、使用可能なオプションの一覧を確認できます。私がよく使用するのは以下の2つです。

  • -b | --background:GUIを表示せず、バックグラウンド実行する
  • -P | --Python <filename>:実行するPythonスクリプトを指定する

さて、コマンドを実行すると以下のような画面が立ち上がると思います。

Blenderの起動画面

画面のそれぞれのメニューやパネルで何ができるかは、ここでは説明しませんが、画面右上のメニューに、現在編集中のFileに存在しているオブジェクトの一覧が表示されていることは覚えておくと良いと思います。

特に何も設定せずに起動すると、この画像のようにCamera・Cube・Lampが用意されてBlenderが起動します。Cameraはレンダリングやアニメーション動画の撮影をするオブジェクトで、Lampは光源オブジェクトです。

また、Pythonでの操作を行う際に必ず知っておく必要がある事として、GUIの操作とPythonのメソッドとの関連付けがあります。GUI操作と対応するPythonのメソッドを知るためには、操作を知りたいGUIパーツの上にマウスを載せ、しばらくすると対応するPythonのメソッドが書かれたツールチップが表示されることを覚えていて下さい。

python_tooltip
Renderメニューのツールチップ

例えば上の画像は、Cameraオブジェクトを使ってシーンを切り取る時に使用するRenderボタンに対応するPythonコードを調べた例です。

CameraのRenderボタンをクリックしたときと同じ操作を行うには、Pythonではbpy.ops.render.render()と、書けば良いことが分かります。

※ 2019/08/17 追記
Blender 2.80から上記PythonコマンドのTooltipを表示するためにはオプションの有効化が必要になりました。対象のオプションは画面左上の Edit → Preferences をクリックし、Interface → Display → Python Tooltips になります。有効化したい場合はチェックを入れてください。


bpyモジュールとは

先程のRenderの例のように、Blenderでは、GUIで操作できることの殆どは対応するPythonのメソッドが用意されており、bpyという名前のモジュールで提供されています。

bpyには一体何が含まれているのか見てみましょう。bpyモジュールをimportして、以下のようなコードで確認してみます。

import bpy

for attr_bpy in dir(bpy):
    print(attr_bpy)

ファイル名は listup_bpy.pyとしてみました。そして、blenderコマンドを用いて実行すると、以下のような出力が得られました。

> blender -b -P listup_bpy.py
Blender 2.80 (sub 75) (hash f6cb5f54494e built 2019-07-29 09:44 AM)
Read prefs: C:\Users\****\AppData\Roaming\Blender Foundation\Blender\2.80\config\userpref.blend
AL lib: (EE) SetChannelMap: Failed to match front-center channel (2) in channel map
found bundled python: C:\Users\****\scoop\apps\blender\current\2.80\python
__all__
__builtins__
__cached__
__doc__
__file__
__loader__
__name__
__package__
__path__
__spec__
app
context
data
msgbus
ops
path
props
types
utils

Blender quit

実際に使う事になりそうなのは14行目~21行目の8つになります。1つずつどのようなモジュールなのか説明していきます。

app:Application Data (bpy.app) Doc link

appモジュールは実行中に変化しないアプリケーションの値を保持しているモジュールです。ハンドラとかあるみたいなので、Blender起動時や終了時等に実行する関数をフックしたりできるかもしれません。

context:Context Access (bpy.context) Doc link

このモジュールで取得できる利用可能なコンテキストのメンバは、現在アクセスされているBlenderのエリアによって異なります。 全てのコンテキストの値は読み取り専用ですが、後に説明するdataモジュールやopsモジュールを使用した操作の実行によって値が変化するかもしれません。

data:Data Access (bpy.data) Doc Link

このモジュールは全てのBlender/Pythonのアクセスに使用され、Blenderの内部データにアクセスする際に使用します。 本当によく使います。

ops:Operators (bpy.ops) Doc Link

Blender内での操作を提供するモジュールになります。先程例に上げたrender()もこのモジュールに含まれていましたね。間違ったコンテキストでこのモジュールを使用すると、RuntimeErrorraiseされてプログラムが停止します。このErrorをcatchするためにはpoll()メソッドを使用すれば良いらしいですが、使ったことないので詳しくは知りません。

path:Path Utilities (bpy.path) Doc Link

このモジュールは、Pythonの標準に含まれているos.pathと似たようなスコープを持っており、Blenderのパスを扱うためのユーティリティ関数を含んでいます。Blenderでは編集中のデータを.blend拡張子のファイルで保存できるのですが、ざっと見た感じそれらの操作関連の関数が纏められてるみたいです。

props:Property Definitions (bpy.props) Doc Link

使ったことないので詳しくは分かりませんが、Blenderの内部データを拡張するためのプロパティが定義されているようです。サンプルを眺めた感じだと、既存のクラスに新しいプロパティを追加したり、他のモジュールの関数からも呼べるようにこのモジュールを使ってプロパティが定義された独自のクラスを作成したりできるようです。

types:Types (bpy.types) Doc Link

Blenderを構成するデータの定義が纏められてるみたいです。プログラムの中で直接使うことは少なさそうですが、このリファレンスページはよく見に来ることになりそうです。

utils:Utilities (bpy.utils) Doc Link

読んで字の如くといった感じもしますが、一応説明すると、Blenderに固有ではあるが、Blenderの内部データとは関連しない様なユーティリティ関数が纏められているようです。

ざっと説明しましたが、とりあえずdataモジュールとopsモジュールを押さえてもらえれば良いと思います。

※ 2019/08/17 追記
2.80からmsgbusというモジュールが増えていますがDocumentも見当たらず詳細が分かりませんでした。分かり次第追記するかもしれません。


bpyモジュールを使ってみる

それでは試しに、bpyモジュールを使用して、先程表示した起動画面のオブジェクトの一覧を確認してみましょう。その後、Cubeオブジェクトを消去してみましょう。

CubeやCamera等のBlender内で管理されるものの多くはObjectクラスとして管理されており、その一覧はbpy.data.objectsで管理されています。以下のソースコードで確認してみましょう。

import bpy

for obj in bpy.data.objects:
    print(obj)

実行できましたか?フォーマットは整っていませんが、先程挙げたCamera・Cube・Lampの文字が確認できたと思います。この中からCubeを削除してみましょう。削除の方法は幾つかありますが、今回はbpy.data.objects.remove()を使用してみましょう。このメソッドを使ってオブジェクトを消去するには、消去したいオブジェクトのインスタンスを引数に渡す必要があります。インスタンスはbpy.data.objects[key]で取得できます。keyには'Camera''Cube''Lamp'等を指定しましょう。

さて、実際に消去できるか以下のコードで実験してみましょう。

import bpy


def print_objects():
    for obj in bpy.data.objects:
        print(obj)


print('--- before remove ---')
print_objects()
bpy.data.objects.remove(bpy.data.objects['Cube'])
print('--- after remove ---')
print_objects()

削除後には一覧からCubeのオブジェクトが消えているのを確認できましたか?-bオプションを付けずに実行して、実際にGUIでも消えているのを確認しても良いです。

rm_cube_scene
Cube削除スクリプトの実行結果

まとめ

今回はBlenderの実行から、BlenderをPythonで操作する際に必要となるbpyモジュールの紹介と実際に使って見るところまでやりました。

次回はカメラオブジェクトについてと、注視点を位置ベクトルで指定してカメラの方向を操作する方法について説明します。