[Maya Python] コマンドからDeadlineに「スクリプトジョブ」をサブミットする

# はじめに

少し前に以下のような記事を投稿しました。

https://qiita.com/akasaki1211/items/b7f999ac579b06aa7cc8

こちらの続き、というほどでもないですが、今回は「レンダリングジョブ」ではなく「スクリプトジョブ」をコマンドからサブミットしてみます。スクリプトジョブとはつまりPythonスクリプトを実行するジョブです。Pythonでできることなら何でもジョブとしてDeadlineに飛ばせます。

## 公式ドキュメント
https://docs.thinkboxsoftware.com/products/deadline/10.3/1_User%20Manual/manual/manual-submission.html

https://docs.thinkboxsoftware.com/products/deadline/10.3/1_User%20Manual/manual/command.html

## 環境
- Windows 10
- Deadline 10.3.0.13
- Maya 2024 (Python 3.10.8)

# MayaBatchプラグインを使うパターン

Deadlineに備わっているMayaBatchプラグインを使う方法です。通常はこちらでいい気がします。その名の通り、各Workerは`mayabatch.exe`を実行することになります。

以下の3つを用意します。

- Mayaシーンを開いてから実行したいスクリプト
- ジョブ情報ファイル
- プラグイン情報ファイル

```python:script_01.py（シーンで実行したいスクリプト）
# 例）ポリゴンキューブを作りシーンを別名保存する
from maya import cmds

cmds.polyCube(n="cube_01")

cmds.file(rename='path/to/mayabatch_test.ma')
cmds.file(force=True, type='mayaAscii', save=True)
```

```plaintext:info.job（ジョブ情報）
Plugin=MayaBatch
Name=ジョブ名
Pool=プール
SecondaryPool=セカンダリプール
Group=グループ名
Priority=50
ChunkSize=1
Comment=コメント
```

```plaintext:plugin_info.job（プラグイン情報）
Version=2024
Build=64bit
ScriptJob=True
ScriptFilename=path\to\script_01.py
ProjectPath=Mayaプロジェクトパス
SceneFile=Mayaシーンファイル
```

:::note warn
必ず何らかのMayaシーンを開くところから始めないといけないようなので、`SceneFile=`を指定せずサブミットするとエラーになります。
:::

用意したファイルを引数にしてdeadlinecommandを実行します。引数はそのまま渡してもいいのですがtxtにまとめるのも便利です。

```plaintext:args.txt
path\to\info.job
path\to\plugin_info.job
```

以下はpythonでのコマンドの実行の例ですが、`subprocess`だけなのでMayaのスクリプトエディタでなくても問題ありません。

```python:サブミット
import os
import subprocess

DEADLINECOMMAND = os.path.normpath(os.path.join(os.environ['DEADLINE_PATH'], 'deadlinecommand.exe'))
args_path = r'path\to\args.txt'

submit_cmd = [DEADLINECOMMAND, args_path]
subprocess.run(submit_cmd)
```

### 複数ジョブを一括投げする場合

ジョブ引数を以下のようにargs.txtにまとめるだけです。レンダリングジョブのサブミット時と特に変わりはありません。

```plaintext:args.txt
-SubmitMultipleJobs
-job
path\to\info_01.job
path\to\plugin_info_01.job
-job
path\to\info_02.job
path\to\plugin_info_02.job
```

# MayaPyから`maya.standalone`を使うパターン

mayapy.exeで`maya.standalone`をインポートすると、pythonスクリプトからMayaをバックグラウンド起動（UI無しで起動）することができます。

🔗[Maya ヘルプ | Python での初期化と初期化解除 | Autodesk](https://help.autodesk.com/view/MAYAUL/2024/JPN/index.html?guid=GUID-D457D6A0-1E7F-4ED2-B0B4-8B57153B563B)

このパターンをあえて使う機会はあまり無いような気がしますが、前項のMayaBatchプラグインはなんらかのMayaシーンを開くところから始めないといけないため、例えば『NewSceneから何かを始めるスクリプト』や『複数シーンを開くスクリプト』をサブミットしたい場合があったら、こちらのパターンが便利かもしれません。プラグインの仕様に縛られないので一番自由が効きそうな気もします。
各Workerは`mayapy.exe`を実行することになります。

```python:script_02.py（MayaPyで実行するスクリプト）
# 例）「新規シーンでポリゴンキューブを作りシーンを新たに保存する」を10回繰り返す

import maya.standalone # 必須
maya.standalone.initialize() # 必須

# ----▼ここにやりたいことを書く▼-------------
from maya import cmds

cmds.workspace('path/to/maya_project', openWorkspace=True)

for i in range(10):
    cmds.file(new=True, force=True)
    
    n = 'cube_{}'.format(str(i+1).zfill(2))
    cmds.polyCube(name=n)
    
    cmds.file(rename='path/to/standarone_test_{}.ma'.format(n))
    cmds.file(save=True, type='mayaAscii')

# -----------------------------------------

maya.standalone.uninitialize() # 必須
```

用意したpythonファイルを引数にしてmayapyを実行するジョブをdeadlinecommandで投げます。Deadline付属のプラグイン（MayaBachやMayaCmd）は使わずにmayapyコマンドを直接サブミットします。

```python:サブミット
import os
import subprocess

DEADLINECOMMAND = os.path.normpath(os.path.join(os.environ['DEADLINE_PATH'], 'deadlinecommand.exe'))
MAYAPY = os.path.normpath(os.path.join(os.environ['PROGRAMFILES'], 'Autodesk', 'Maya2024', 'bin', 'mayapy.exe'))
python_file = r'path\to\script_02.py'

submit_cmd = [
    DEADLINECOMMAND,
    '-SubmitCommandLineJob',
    '-executable', MAYAPY,
    '-arguments', python_file,
    '-chunksize', '1',
    '-pool', 'プール名',
    '-group', 'グループ名',
    '-priority', '50',
    '-name', 'ジョブ名',
    '-prop', 'Comment=コメント',
    '-prop', 'SecondaryPool=セカンダリプール名'
]

subprocess.run(submit_cmd)
```