自動生成したVMDモーションの確認用にBlenderでバッチレンダリングを行う

## 目的

動画や写真からVMDフォーマットのモーションデータを生成する[VMD-Lifting](https://github.com/errno-mmd/VMD-Lifting) や[readfacevmd](https://github.com/errno-mmd/readfacevmd) というプログラムを公開しているのですが、これらのプログラムを開発するうえで「モーションデータ生成→後処理(スムージングなど)→レンダリングして結果確認」という一連の処理を複数の入力データあるいは複数のパラメータに対して行うことがあります。
モーションデータ生成と後処理はバッチ処理で行うことができるのですが、レンダリングは、VMDファイルをMikuMikuDance(MMD)に読み込ませ、MMDのGUIを操作することで行っていました。しかしこれでは、いろいろなデータ等を試したい場合に手間がかかります。

そこで、寝ている間(または仕事をしている間)に放っておいてもひととおりの結果が得られるように、VMDファイルを読み込んでレンダリングを行う部分のバッチ処理化を目指します。

そのために、コマンドラインからレンダリングでき、かつPythonスクリプトにより制御可能で、VMDファイルのインポートも可能な blender を使うことにしました。なお操作手順は blender 2.79b に準拠していますが、blender 2.80 beta でも同様に実行できることを確認してあります。OS は Linux を前提としていますが、Windows でもcygwin等を使って実行可能だと思います。

## 動作環境の準備

1. [blender](https://www.blender.org/) をインストール
1. [mmd_tools](https://github.com/powroupi/blender_mmd_tools) をインストール

mmd_tools の設定方法は、https://blender-cg.net/mmd-pmd-pmx-vmd/ を参照。

## .blend ファイルの準備

1. blenderを起動して、モデルを読み込む。
1. カメラや照明を設定する。
1. モデルのボーンを選択した状態で .blend ファイルを保存する。ファイル名は例えば model.blend とする。

## スクリプトの作成

下記の内容のスクリプトを作る。ファイル名は例えば addmotion.py とする。
VMDファイル名は、実行時に環境変数 VMDFILE としてスクリプトに渡すことにする。

```
import bpy
import os

# mmd_toolsアドオンを有効化する
bpy.ops.wm.addon_enable(module="mmd_tools")

# VMDモーションをインポートする
vmd_file=os.environ['VMDFILE']
bpy.ops.mmd_tools.import_vmd(filepath=vmd_file)
```

## 実行手順

下記のコマンドを実行することで、blender に addmotion.py のスクリプトを実行させてVMDモーションをインポートし、レンダリングを行う。VMDFILEの値は、使いたいVMDファイル名に合わせる。

```
$ VMDFILE=motion.vmd blender -b model.blend -P addmotion.py -o result -F PNG -f 10
```
これで、10フレーム目がレンダリングされて result0010.png に保存される。フレーム番号やファイルタイプなどを変更したい場合は blender のヘルプを参照。

以上で、自動生成したVMDモーションの確認用にバッチ処理でレンダリングを行えるようになりました。下の画像は、実際にVMD-Liftingで生成したVMDモーションを上記の方法でblenderにインポートしてレンダリングした画像を、元の写真とともにImageMagickのmontageで連結したものです。
![result_small.png](https://qiita-image-store.s3.amazonaws.com/0/47287/a8c602ef-6825-78e6-4985-668892734b31.png)

## TIPS 1

GUIのボタンやメニューをクリックしたときにコールされるBlender Python APIのコマンドは、ボタンやメニューの右クリックメニューから "Copy Python Command" を選ぶとクリップボードにコピーされる。

![右クリックメニュー](https://qiita-image-store.s3.amazonaws.com/0/47287/e9f82093-6e51-3028-6b8d-b72ae4ea4580.png)

例えば "Save As" メニューの場合、下記のコマンドがコピーされるので、ファイルに名前を付けて保存したい場合はこの関数をコールすればよいと分かる。

```
bpy.ops.wm.save_as_mainfile()
```

関数の使い方は、同じく右クリックメニューから "Online Python Reference" を選ぶとブラウザでオンラインリファレンスを見ることができる。
ただし、アドオンの関数などはオンラインリファレンスが無い場合もある。その場合も、Python console に関数名を入力して、”Autocomplete" ボタンを押すと、その関数が受け取る引数が表示される。

![Autocommplete](https://qiita-image-store.s3.amazonaws.com/0/47287/74644c43-5de6-839f-195c-57da12df8fa3.png)

## TIPS 2

Windows上のblenderで作った.blendファイルをLinuxに持っていく場合、メニューから File → External Data → Automatically Pack into .blend でテクスチャなどの外部データを.blendファイルに含めておく。

![autopack](https://qiita-image-store.s3.amazonaws.com/0/47287/0ec08eec-a078-a048-1ebd-26415c324840.png)

## TIPS 3

blender で IK を無効化するには、IK によって拘束されているボーン(例えばひざ.L、足首.L、ひざ.R、足首.R)の Bone Constraints 編集でIKを無効化(disable)する。

![disable IK](https://qiita-image-store.s3.amazonaws.com/0/47287/28cd9420-5b2e-2ea0-a87d-4e29cc6c7696.png)

## 参考文献・参考URL

[Blender Python API Documentation 2.80版](https://docs.blender.org/api/blender2.8/)
[mmd_toolsの使い方](https://blender-cg.net/mmd-pmd-pmx-vmd/)