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

レンダリングの効率化

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

ここで作るユーティリティは、以下のような手順で実行してゆきます。

  1. Maya 上からレンダリングするシーンファイル名をデータファイルに書き出す。 (renderScript1)
  2. そのデータファイルに書かれたシーンファイルを、 ひとつづつレンダリングする。
  3. データファイルからシーンファイル名を読み出して(renderScript2)、 シーンファイル名の削除・追加を行ない、もう一度書き込む(renderScript1)。

ファイルの入出力

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

  1. ファイルのオープン
  2. ファイルへの入出力
  3. ファイルのクローズ

ファイルからの入力

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

ファイルへの出力

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

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

まず、レンダリングしたいシーンファイル名を、 ファイルに書き出すプロシージャー renderScript1 と、 そのファイルに書き込まれているシーンファイル名を、 読み出すプロシージャー renderScript2 を作ってみましょう。

  1. 以下の MEL スクリプトを renderScript1.mel という名前で作ります。
    global proc renderScript1()
    {
    	string $files[] = {"test1.mb", "test2.mb"};
    	string $myRenderLst = (`internalVar -uwd` + "render.lst");
    
    	int $fp = `fopen $myRenderLst "w"`;
    	if($fp == 0)
    	{
    		warning ($myRenderLst + " can not Open\n");
    		return;
    	}
    	for($f in $files)
    	{
    		fprint $fp ($f + "\n");
    	}
    	fclose $fp;
    }
    
  2. Script EditorFile → Source Script によって renderScript1.mel を読み込みます。
  3. Script Editor のインプットウインドウで、renderScript1() を実行します。
    プロジェクトディレクトリの render.lst というファイルに $files のシーンファイル名が、 以下のように書き込まれているはずです。
    test1.mb
    test2.mb
    
    プロジェクトディレクトリは internalVar -uwd という MEL コマンドで調べてください。
  4. 以下の MEL スクリプトを renderScript2.mel という名前で作ります。
    global proc renderScript2()
    {
    	string $files[];
    	string $myRenderLst = (`internalVar -uwd` + "render.lst");
    
    	int $fp = `fopen $myRenderLst "r"`;
    	if($fp == 0)
    	{
    		warning ($myRenderLst + " can not Open\n");
    		return;
    	}
    	int $i = 0;
    	while(!`feof $fp`)
            {
    		$files[$i] = `fgetword $fp`;
    		$i++;
    	}
    	fclose $fp;
    	for($f in $files)
    	{
    		print ($f + "\n");
    	}
    }
    
  5. Script EditorFile → Source Script によって renderScript2.mel を読み込みます。
  6. Script Editor のインプットウインドウで、renderScript2() を実行します。
    render.lst から読み込まれたシーンファイル名が Script Editor のヒストリウインドウに表示されます。
    [renderScript2() 実行図]

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

global proc renderScript1()
renderScript1() というプロシージャーの宣言です。
string $files[] = {"test1.mb", "test2.mb"};
ファイルに出力するシーンファイル名が入った文字列の配列 $files の宣言です。
ここでは、テスト用に 2 つのシーンファイル名を使っています。
string $myRenderLst = (`internalVar -uwd` + "render.lst");
シーンファイル名を書き込むためのファイル名を文字列変数 $myRenderLst に代入しています。
internalVar -uwd はプロジェクトディレクトリを調べるコマンドです。
このコマンドを使うことによって、どの OS でも同じスクリプトが変更無しで実行できるようになります。
プロジェクトディレクトリは、デフォールトで以下のようになります。
int $fp = `fopen $myRenderLst "w"`;
変数 $myRenderLst に入っているファイル名によって、ファイルを書き込みモードでオープンします。
if($fp == 0)
オープンされたファイルの番号 $fp が 0 の場合は、 オープンに失敗しているので、以下の 2 つのコマンドを実行します。
warning ($myRenderLst + " can not Open\n");
Script Editor のヒストリーウインドウに Warning の表示を行ないます。
return;
以下のコマンドを実行しないで、プロシージャー renderScript1 から帰ります。
for($f in $files)
{
  fprint $fp ($f + "\n");
}
変数 $files に代入されているシーンファイル名を、 番号 $fp のファイルに書き出します。
各ファイル名の後に改行("\n")を追加しているので、1 行に 1 つづつシーンファイル名が書き込まれます。
fclose $fp;
ファイル番号 $fp のファイルをクローズします。

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

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

レンダリング用シェルスクリプト (Linux)

以下の内容のファイルを、myrender.sh という名前で render.lst と同じディレクトリに作成しておきます。

foreach f (`cat render.lst`)
	Render $f
end

このスクリプトを使用して、レンダリングを実行する場合は、 myrender.sh のあるディレクトリで、コマンドラインから以下のように実行します。

% csh myrender.sh

レンダリング用バッチファイル (Windows)

以下の内容のファイルを、myrender.bat という名前で render.lst と同じディレクトリに作成しておきます。

for /f "delims=" %%d in (render.lst) do Render "%%d"

このスクリプトを使用して、レンダリングを実行する場合は、 myrender.bat のあるディレクトリで、 コマンドプロンプトから以下のように実行します。

Z:\myDocument\maya\projects> myrender

エクスプローラーなどから、 myrender.bat のアイコンをクリックして実行しても良いでしょう。

Tips (より簡単・便利にレンダリングを実行する)

レンダリングコマンド Render の実行時オプションや、 実行ファイルのアイコン化などによって、 より簡単にすばやくレンダリングを実行できるようになります。

練習

練習課題

参考


Prev | Next
Home | Contents
Mail