2022年5月23日月曜日

mayabatchを実行させるバッチファイル

 大量のシーンに同じ処理を行う場合に便利なのが mayabatch.exeです。
 ただ使用するには、ちょっとしたバッチの知識が必要になるみたいです。
 バッチ処理に使用できる言語はいくつか有るようですが、超古典のMS-DOSで書いてみようと思います。

 まず、mayabatchを使用するためのフォルダ(conv_bat)を作成します。
 そこへ下の.batファイルを作成し実行。

set VERSION=2023
set MAYA_BIN_PATH=C:\Program Files\Autodesk\Maya%VERSION%\bin

set MAYA_APP_DIR=%~dp0
set MAYA_UI_LANGUAGE=en_US

pushd "%MAYA_BIN_PATH%"
mayabatch -noAutoloadPlugins

pause


 すると、バッチファイルと同じフォルダ(conv_bat下)に幾つかのフォルダが作成されます。


 この中で重要なのは scriptsフォルダだけなので、バーション管理ツールなどで共有する場合は他のフォルダは Ignoreします。
 4行目で MAYA_APP_DIRを指定しているため、このようなファルダが出来上がるのですが、この環境変数を指定せずに mayabatchを実行すると、マイドキュメント内の scriptsのスクリプトや userSetupが実行されるので、まっさらな状態でmayaを実行させるためにこうしています。
 そして、このフォルダ内の scriptsフォルダに mayabatchで実行させるスクリプトを配置します。

 まずは、scripts内に startMayabatch.batとして下のバッチファイルを作成します。

@set SRC=%~1
@set CMD=%~2

@set A=%~3
@set B=%~4
@set C=%~5

@set A=%A:\=/%
@set B=%B:\=/%
@set C=%C:\=/%


@pushd "%MAYA_BIN_PATH%"
@mayabatch.exe -noAutoloadPlugins -file "%SRC%" -proj "%PROJ%" -command "%CMD% {\"%A%\",\"%B%\",\"%C%\"}"

 これは、単に mayabatchを実行するだけのバッチファイルで、実行させるスクリプトや開くシーンファイルなどは指定されていません。
 なので、このバッチファイルを呼び出すバッチファイルが必要になります。
 最短の呼び出し方としてはこんな感じです。

@set VERSION=2023
@set MAYA_BIN_PATH=C:\Program Files\Autodesk\Maya%VERSION%\bin

:: プロジェクトパス設定
@set PROJ=%~dp0
@set PROJ=%PROJ:conv_bat\=graphics%

:: バッチ呼び出し
cmd /c "%~dp0scripts\startMayabatch.bat file_path MEL_script argA argB"

pause

 file_pathやMEL_script, argA, argBは仮のものなので、実際のファイル名やスクリプト名、引数などを記述します。
 MELのメインプロシージャの引数は 文字配列型にしておかないとエラーになるので注意が必要。
 MS-DOSは9個までは簡単に引数を渡せるので、MELに渡せる引数は7個くらいまで可変で渡せることになります。その場合、startMayabatch.batには set G=%~9まで追記します。

 行頭に@を記述しているのは、その行を非表示にする為なのですが、echo offを使用すると全体が非表示になってしまうため、デバッグしにくくなるので全行頭に@を入れて表示切り換えを簡単にしています。

 13行目に pushdをしていますが、maya2012までmayabatchで開かれたシーンファイルのフォルダに keybordフォルダが作られるバグが有ったので、その名残り。この行は無くても多分問題ないはずです。

 本格的に使用する場合、ログを残したり、実行対象を指定したりしたいので、もう少し凝ったバッチを作成する必要があります。

@title %~n0
@prompt %~n0$G

:: mayaの確認
@set VERSION=2023
@set MAYA_BIN_PATH=C:\Program Files\Autodesk\Maya%VERSION%\bin
@if not exist "%MAYA_BIN_PATH%" @(
    call :errEnvMaya %VERSION%
    exit /b
)

:: プロジェクトパス
@set PROJ=%~dp0
@set PROJ=%PROJ:conv_bat\=graphics%


::------------------------------------------------------------------------------
:: 引数の確認※含.csvファイルの存在確認
@if ""=="%1" goto :errArg
@if not ".csv"=="%~x1" goto :errExtra
@set CSV_PATH=%1
@if not exist %CSV_PATH% goto :errCsv


::------------------------------------------------------------------------------
:: 日付の作成
@set YYYYMMDD=%date%
@set YYYYMMDD=%YYYYMMDD:/=%
@set HHMMSS=%TIME%
@set HHMMSS=%HHMMSS:~0,5%
@set HHMMSS=%HHMMSS::=%
@set HHMMSS=%HHMMSS: =0%


::------------------------------------------------------------------------------
:: ログファイルの作成
@set CNV_LOG_FILE=%~dp1%YYYYMMDD%_%HHMMSS%@%~nx1.log
@type nul>%CNV_LOG_FILE%
@echo //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/>>%CNV_LOG_FILE%
@echo // START %~dpnx1>>%CNV_LOG_FILE%
@echo //                                                           %DATE% %TIME:~0,-3%>>%CNV_LOG_FILE%

::------------------------------------------------------------------------------
:: mayaの環境変数を設定
@set MAYA_APP_DIR=%~dp0
@set MAYA_UI_LANGUAGE=en_US


::------------------------------------------------------------------------------
:: .csvファイルの行数をカウント
@set LINE_COUNT=0
@for /f %%z in (%CSV_PATH%) do @set /a LINE_COUNT+=1


@setlocal enabledelayedexpansion
::------------------------------------------------------------------------------
:: 変換開始
@for /f "delims=, tokens=1*"  %%A in (%CSV_PATH%) do @(
    set /a LINE_COUNT-=1
    @echo /*******************************************************************************>>%CNV_LOG_FILE%
    :: */
    echo [!LINE_COUNT!] mayabatch %%B^<%%~nA  [!TIME:~0,-3!]
    cmd /c "%~dp0scripts\startMayabatch.bat %%A %%B">>%CNV_LOG_FILE%
)
@echo // %DATE% %TIME:~0,-3%>>%CNV_LOG_FILE%
@echo [%TIME:~0,-3%]
@goto :end



::==============================================================================
:: エラー表示
::==============================================================================
:errEnvMaya
    @echo.
    @echo ## 指定バージョン( %1 )の maya がインストールされていません。
    @goto :end

:errArg
    @echo.
    @echo ## 引数を指定してください。
    @goto :end

:errExtra
    @echo.
    @echo ## 引数が csvファイルではありません。
    @goto :end

:errCsv
    @echo.
    @echo ## 指定の csvファイルが見つかりません。
    @goto :end



::==============================================================================
:: 終了待機
::==============================================================================
:end
    @echo.
    @pause

 .csvファイルの各行から開くファイルや実行するスクリプトなんかを指定しています。
 ついでに.csvファイルと同じパスにログファイルも作成していたり。
 ログを綺麗に出力させるにはMELの方にも仕込みが必要で、

global proc test(string $args[])
/***************************************************************************//**
    @brief main procedure.
 ******************************************************************************/
{
    $startTime = `timerX`;
    print("*******************************************************************************/\r");
    
    
    //------------------------------------------------------------------------------
    // 処理
    print("\r-- args --\r");
    print $args;
    
    
    
    //------------------------------------------------------------------------------
    // 終了
    $totalTime = `timerX -startTime $startTime`;
    print("\r");
    print("//------------------------------------------------------------------------------\r");
    print("// Total Time: "+$totalTime+"\r");
    print("//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    
    pause -sec 5;
    
    
}

こんな感じでログ用のコードを仕込んでおきます。
 特に重要なのが最後の pauseコマンドで、これで少しの時間処理を止めておかないと、ログファイルへの書き込み中にmayaが終了してしまいログが途中で途切れてしまいます。

 実行用の .csvファイルは、

dir /s /b *.ma>maya_list.csv

 みたいな感じで出力し、エクセルなどでコマンドや引数を記入していけば楽に作成できます。
 あとは、その.csvファイルを callMayabatch.batへドラッグ&ドロップするとDOS窓が開いて処理が実行されます。

 最後にmayabatch用に環境を作っているため、普段使用しているスクリプトなどはmayabatch実行時にはロードされないので、必要なスクリプトなどは scriptsにコピーするか userSetupでsourceするなどしないと使用できません。
 プリセットなども別なので、そのあたりも考慮して実行する必要があります。



謝辞:
天埜零士@低音 さん




0 件のコメント:

コメントを投稿