レンダーシーンを構築するツール「msJobPitcher」をリリースしました。

# はじめに
早速脱線しますが、[ショートムービー「unmoral」](https://unmoral.cgmovie.art/)を2019年1月23日に公開します！

unmoralの制作を支えたレンダーシーンを構築するツール「msJobPitcher」をリリースしたので、この記事で紹介します。
ツールは[GitHub](https://github.com/paty-0004/msJobPitcher/releases)からダウンロードできますのでぜひ！
とは言ったもののかなり限定的な使い方が前提となってしまいます。。。（この話は後ほど

合わせてショートムービー「unmoral」の宣伝もさせてください。
[ショートムービー「unmoral」公式サイト](https://unmoral.cgmovie.art/)
[unmoralの制作を支えたツールたち](https://qiita.com/paty-6991/private/b56a5e13cc4efb85696d)


# 概要
サーバ上にある、カメラやステージ、キャラのアニメーションデータなどを収集し、レンダー設定・AOVs設定を行い、Deadlineへjobの送信までを行うツールです。
![ui.png](https://qiita-image-store.s3.amazonaws.com/0/255056/174b0e75-9172-19b1-f867-5dad3bda7faa.png)
収集するプロジェクトディレクトリや各種設定ファイルのディレクトリをconfig.jsonで指定します。
指定ディレクトリ外のデータも **brows** ボタンから選択が可能です。

```json:config.json
{
  "projectPath": "//172.29.44.4/cg/ms06/renderProj",
  "stagePath": "//172.29.44.4/cg/ms06/renderProj/scenes/stage/amorRoom.v1.mb",
  "renderSettingPath": "//172.29.44.4/cg/ms06/msJobPitcher/renderSettings/RenderDefault.json",
  "AOVsSettingPath": "//172.29.44.4/cg/ms06/msJobPitcher/AOVs/defaultAOV.json",
  "timerangePath": "//172.29.44.4/cg/ms06/msJobPitcher/timerange.csv",
  "submitDeadlineMelPath": "//172.29.44.4/cg/ms06/msJobPitcher/SubmitDeadline.mel"
}
```

## shotID
カット固有のIDを本ツールではshotIDと呼んでいます。
恐らくどんなCG制作の現場でも名前は違えどプロジェクト名やシーン名、カット番号を用いてカット固有のIDをつけてると思います。
カメラやアニメーションデータにshotIDを用いた命名規則を策定し、アニメーターが決まった場所にアップロードすることでツール側からデータの収集を可能にしています。

UI下部の **Set shotID** を実行するとshotIDを元にカメラとアニメーションデータは自動的にファイルパスがセットされます。
また今回、unmoralの制作においてはGoogleスプレッドシートを用いて各カットのタイムコード及び担当と進捗を管理していました。
このタイムコードを元にレンダリングするレンジなどを取得しています。
![timecode.png](https://qiita-image-store.s3.amazonaws.com/0/255056/2baee9a6-bd4c-48ab-aa7b-032c4e3db887.png)
これら全カットのshotID, フレームレンジ, スタートフレーム, エンドフレームを別のシートにまとめてcsv出力したものを `config.json` の `timerangePath` として参照させています。

ツール概要については[README](https://github.com/patriot6991/msJobPitcher/blob/master/README.md)にも記載していますので合わせてみて頂けると幸いです。

## Build Render Scene
データパスのセット完了後、 **Build Render Scene** を実行するとチェックボックスの入った項目が上から順に実行されます。(save Sceneを除く)

|項目|実行内容|
|:--|:--|
|New Scene|新規シーンのオープン|
|Open Stage|セットされたファイルをオープン|
|Camera|セットされたファイルをインポート|
|Animation|同上|
|Extra|同上|
|Render Settings|既存のレンダー設定を削除しセットされたパスのレンダー設定をインポート|
|AOVs Settings|既存のAOVs設定を削除しセットされたパスのAOVs設定をインポート|
|Submit to Deadline10|Deadline Repositoryへjobの送信|
|save Scene|Submit to Deadline10が実行される前にビルドされたシーンを保存|
|log Level|デバッグ用のログをスクリプトエディタへ出力|

## myLogger
開発にあたってデバッグ作業はつきものです。
msJobPitcherの開発を始めるまで私はprintデバッグを行っていましたが、printデバッグに限界を感じてきたのでloggingモジュールを使ったmyLoggerを実装しました。

```Python:myLogger.py
import logging


class MyLogger(object):
    def __init__(self, mc):
        logging.basicConfig(level=logging.INFO)
        self.my_logger = logging.getLogger()
        self.mc = mc

    def changeToInfo(self, *args):
        self.my_logger.setLevel(logging.INFO)
        logging.info('change to info mode')

    def changeToDebug(self, *args):
        self.my_logger.setLevel(logging.DEBUG)
        logging.info('change to debug mode')

    def createCheckbox(self, v, *args):
        return self.mc.checkBox(l='log Level', v=v, onc=self.changeToDebug, ofc=self.changeToInfo)
```

cmdsのチェックボックスを表示する関数 `createCheckbox` を実行するとUI上からも簡単にログレベルを変更できます。
他の開発でも必要であればこの `myLogger.py` にラジオボタンやスライダーなどの機能を追記していくことで必要なUIからログレベルを変更することが出来ます。

# 開発背景
私は専門学校の4年生で、卒業制作としてunmoralの監督兼TAをつとめました。
プリプロの段階で総カット数が200弱に対して、主要メンバーは8名であったため、とても人海戦術で対応できる範囲ではないと判断し、このツールを開発しました。
インターンやアルバイトなどでCG制作の実務作業に触れる機会があり、現場ではどういったパイプラインツールやジョブのビルドツールがあるのかを学習し、msJobPitcherの参考にしました。
学校で自主的にリグやPythonの勉強会を開いていたのもあり、その勉強会の集大成として後輩2名に協力を仰いで各機能を実装してもらいました。また複数人での開発が初めてであったため、友人からGitを教わりました。おかげで開発を円滑に進めることが出来ました。この場を借りて協力して頂いた方にお礼を伝えたいです！ありがとう！！！

# 今後の展望
実制作と並行しての開発だったのもあり、各データの格納先などは決め打ちで処理している部分もまだまだ多いです。より柔軟なプロジェクトに対応できるよう改良を重ねたいと思っています。（需要があるかはまた別の話
また最近PySide2に手を出し始めたので、お粗末なUIを刷新したいです。

現場で使われているビルドツールの足元にも及びませんが、学生の自主制作などで活用される未来が訪れるよう時間をつくって改良を重ねていきます。