レンダリング・ユーティリティ

レンダリングの効率化

ここでは、バッチレンダリングを効率的に、簡単な操作で行なうことができるようなツールを作ってみましょう。
Maya において、バッチレンダリングを実行するときは、 メモリの有効利用という面と、 Maya だけではできない処理も行なうことができるので、 コマンドラインからレンダリングした方が便利で効率的なことがあります。
コマンドラインからのレンダリングには Render コマンドを使用しますが、 複数のシーンをまとめてレンダリングする場合には、 Windows ではバッチファイル、 Linux などの UNIX 系 OS ではシェルスクリプトなどを作成して、 レンダリングを実行します。 このバッチファイルやシェルスクリプトなどは、 通常、テキストエディタによって作成します。 これらの作成は、決して難しいものではないのですが、 Maya 上からバッチファイル・シェルスクリプトを作成できようにしておくと、 より手軽にレンダリングが実行できるでしょう。

今回の目標

ここでは、以下のような MEL スクリプトの作成を目標にしてみましょう。

  1. レンダリングするためのバッチファイルをデスクトップに書き出す MEL スクリプト
  2. 書き出したバッチファイル中のシーンファイル名を読み込む MEL スクリプト
  3. これら 2 つの MEL スクリプトを利用して、 レンダリングしたいシーンファイル名をバッチファイルに追加・削除する MEL スクリプト

2. のスクリプトを利用してシーンファイル名を読み込み、 3. のスクリプトでシーンファイル名を変更して、 1. のスクリプトで変更したシーンファイル名を書き込むという MEL スクリプトが最終的な目標になります。

ファイルの入出力

MEL において、ファイルからデータの入出力を行なう場合の手順に付いて解説します。
ファイルの入出力は、どちらの場合も以下のような手順で行います。

  1. ファイルのオープン (fopen)
  2. ファイルからの入力 (fgetword など)
    または
    ファイルへの出力 (fprint など)
  3. ファイルのクローズ (fclose)

ファイルからの入力

  1. ファイルのオープン
    int $fp = `fopen "ファイル名" "r"`;
    変数 $fp にはファイルを区別する番号が代入されます。
    "r" は読み取りモードを表します。
    読み取りモードは省略できます。
    以下のコマンドで、Z ドライブの tmp.txt というファイルを、 読み込むために開いています。
    int $fp = `fopen "Z:/tmp.txt" "r"`;
  2. ファイルからの読み込み
    ファイルからデータを読み込むためのコマンドには、 以下のようなものがあります。
    fread
    int, float, string, vector を読み込みます。
    バイナリデータ読み込み用のコマンドです。
    以下のように実行すると、文字列変数 $s に NULL 文字まで、 または、 ファイルの最後までの文字列が読み込まれます。 (ただし、最大 1024 文字まで)
    string $s;
    $s = `fread $fp`;
    fgetword
    単語を読み込みます。
    ここでいう単語とは、スペース・タブ・改行によって区切られた文字列です。
    string $s;
    $s = `fgetword $fp`;
    fgetline
    行単位の読み込みを行ないます。
    string $s;
    $s = `fgetline $fp`;
  3. ファイルのクローズ
    fclose $fp;

ファイルへの出力

  1. ファイルのオープン
    int $fp = `fopen "ファイル名" "モード"`;
    変数 $fp には、入力の場合と同じように、ファイルを区別する番号が代入されます。
    モードは、以下のどちらかになります。
    "w"
    書き込みモード
    ファイルが存在しない場合は、新しくファイルが作成されます。
    同じ名前のファイルが存在した場合は、そのファイルの元の内容は消去されます。
    以下のコマンドは、Z ドライブの tmp.txt というファイルを書き込むために開いています。
    int $fp = `fopen "Z:/tmp.txt" "w"`;
    "a"
    追加モード
    同じ名前のファイルが存在した場合は、そのファイルの元の内容に追加して書き込みます。
  2. ファイルへの書き込み
    ファイルにデータを書き込むためのコマンドには、 以下のようなものがあります。
    fwrite
    int, float, string, vector を書き込みます。
    バイナリデータ書き込み用のコマンドです。
    以下のコマンドは 2.5 という整数データを書き込んでいます。
    float $x = 2.5;
    fwrite $fp $x`;
    ファイルに書き込むデータが string の場合は、最後に NULL 文字を追加します。
    fprint
    文字列(string)を書き込みます。
    string $s = "test";
    fprint $fp $s;
  3. ファイルのクローズ
    fclose $fp;

レンダリング・ユーティリティの例

まず、レンダリングするためのバッチファイルを、 ファイルに書き出すプロシージャー renderScript1 と、 そのファイルに書き込まれているデータを読み出すプロシージャー renderScript2 を作ってみましょう。
ここで作成する 2 つのスクリプトは今回の目標で説明した 1. と 2. にあたるものですが、 目標のスクリプトとしては未完成なものです。
目標を達するための改良は練習問題で行ってゆきます。

  1. 以下の MEL スクリプトを renderScript1.mel という名前で作ります。
    
    global proc renderScript1()
    {
    	string $scenes[] = {"test1.mb", "test2.mb"};
    	string $myRenderBat = "Z:/デスクトップ/myrender.bat";
    
    	int $fp = `fopen $myRenderBat "w"`;
    	if($fp == 0)
    	{
    		warning ($myRenderBat + " can not Open\r\n");
    		return;
    	}
    	fprint $fp "Z:\r\n";
    	fprint $fp "cd Z:/myDocument/maya/projects/default/scenes\r\n";
    	for($f in $scenes)
    	{
    		fprint $fp ("Render " + $f + "\r\n");
    	}
    	fclose $fp;
    }
    
    
  2. Script EditorFile → Source Script によって renderScript1.mel を読み込みます。
  3. Script Editor のインプットウインドウで、renderScript1(); を実行します。
    デスクトップの myrender.bat というファイルに Render コマンドやシーンファイル名が、 以下のように書き込まれているはずです。
    
    Z:
    cd Z:/myDocuments/maya/projects/default/scenes
    Render test1.mb
    Render test2.mb
    
    
  4. 以下の MEL スクリプトを renderScript2.mel という名前で作ります。
    
    global proc renderScript2()
    {
    	string $scenes[];
    	string $myRenderBat = "Z:/デスクトップ/myrender.bat";
    
    	int $fp = `fopen $myRenderBat "r"`;
    	if($fp == 0)
    	{
    		warning ($myRenderBat + " can not Open\n");
    		return;
    	}
    	int $i = 0;
    	while(!`feof $fp`)
            {
    		$scenes[$i] = `fgetword $fp`;
    		$i++;
    	}
    	fclose $fp;
    	for($f in $scenes)
    	{
    		print ($f + "\n");
    	}
    }
    
  5. Script EditorFile → Source Script によって renderScript2.mel を読み込みます。
  6. Script Editor のインプットウインドウで、renderScript2() を実行します。
    myrender.bat から読み込まれたシーンファイル名や Render コマンドなどが Script Editor のヒストリウインドウに表示されます。
    [renderScript2() 実行図]
    ここで表示された単語の中で、私たちの目的に必要なものはシーンファイル名だけです。 不要な cdRender などを出力しないようにする方法は練習問題で考えます。

スクリプトの解説 ( renderScript1.mel )

global proc renderScript1()
renderScript1() というプロシージャーの宣言です。
string $files[] = {"test1.mb", "test2.mb"};
ファイルに出力するシーンファイル名が入った文字列の配列 $files の宣言です。
ここでは、テスト用に 2 つのシーンファイル名を使っています。
string $myRenderBat = "Z:/デスクトップ/myrender.bat";
文字列変数 $myRenderBat にバッチファイルの場所とファイル名を入れておきます。
int $fp = `fopen $myRenderBat "w"`;
変数 $myRenderBat に入っているファイル名によって、 ファイルを書き込みモードでオープンします。
if($fp == 0)
オープンされたファイルの番号 $fp が 0 の場合は、 ファイルのオープンに失敗しているので、以下の 2 つのコマンドを実行します。
warning ($myRenderBat + " can not Open\n");
Script Editor のヒストリーウインドウに Warning の表示を行ないます。
return;
以下のコマンドを実行しないで、プロシージャー renderScript1 を終了します。
fprint $fp "Z:\r\n";
番号 $fp のファイルに、移動するドライブ名を書き込みます。
ここで、\r\n は改行を表す特別な記号です。
fprint $fp "cd Z:/myDocument/maya/projects/default/scenes\r\n";
番号 $fp のファイルに、移動するフォルダ名を書き込みます。
for($f in $files)
{
  fprint $fp ("Render " + $f + "\r\n");
}
Render コマンドと変数 $files に代入されているシーンファイル名を、 番号 $fp のファイルに書き出します。
各ファイル名の後に改行("\r\n")を追加しているので、 1 行に 1 つづつRender コマンドとシーンファイル名が書き込まれます。
fclose $fp;
ファイル番号 $fp のファイルをクローズします。

スクリプトの解説 ( renderScript2.mel )

global proc renderScript2()
renderScript2() というプロシージャーの宣言です。
string $scenes[];
シーンファイル名を代入するための文字列配列 $scenes の宣言です。
string $myRenderBat = "Z:/デスクトップ/myrender.bat";
シーンファイル名を読み込むためのファイル名を、 文字列変数 $myRenderBat に代入しています。
int $fp = `fopen $myRenderBat "r"`;
変数 $myRenderBat に入っているファイル名によって、 ファイルを読み込みモードでオープンします。
if($fp == 0)
オープンされたファイルの番号 $fp が 0 の場合は、 オープンに失敗しているので、以下の 2 つのコマンドを実行します。
warning ($myRenderBat + " can not Open\n");
Script Editor のヒストリーウインドウに Warning の表示を行ないます。
return;
以下のコマンドを実行しないで、プロシージャー renderScript2 を終了します。
int $i = 0;
カウンター用変数 $i に 0 を代入します。
while(!`feof $fp`)
番号 $fp のファイルが、最後まで読み込まれたかどうかを調べています。
コマンド feof は、 ファイルの途中では 0 を返し、ファイルの最後まで読み込むと 1 を返すので、 ! 演算子によって 0 と 1 を反転させて、 ファイルの最後ではない場合に while のブロック内を実行させています。
$scenes[$i] = `fgetword $fp`;
文字列の配列 $scenes$i 番目に、 ファイルからひとつの単語を読み込んで代入しています。
$i++;
カウンター用変数 $i に 1 を加算しておきます。
fclose $fp;
ファイル番号 $fp のファイルをクローズします。
for($f in $scenes)
{
  print ($f + "\n");
}
文字列配列 $scenes に入っている単語を、 Script Editor のヒストリーウインドウに 1 つづつ表示します。

練習

さらに、この 1. 2. 3. のスクリプトを GUI を使って、 マウスの操作のみでできるようにすると便利でしょう。

課題

追加課題

参考


Prev
Home | Contents
Mail