制御構造(ループ)

コマンドを繰り返し実行する方法

MEL のスクリプトを作っていると、 同じコマンドや、似たようなコマンドを何度も繰り返し実行しなければならない場合がよくあります。
MEL において、 そのように同じコマンドを繰り返して実行しなければならない場合には for, while, do while などのループを使用します。
ループを終了するための条件には、条件演算子を使用します。

for, while, do while の文法

for
for 文は、一番よく使用されるループの構文です。
for(初期化のための式 ; 条件式 ; 式)
{
	MEL文;
}
for 文では、以下のように実行が進みます。
  1. "初期化のための式" が最初に 1 度だけ実行されます。
  2. "条件式" が成り立つかどうか調べます。
    成り立っていれば 3. に進みます。
    成り立っていなければループを終了します。
  3. ブロック ( { から } まで) の中の MEL 文を実行します。
  4. "式" を実行します。
  5. 2. に戻ります。
while
while 文は、 for 文から "初期化のための式" と "式" の部分を省略したものになっています。
while(条件式)
{
	MEL文;
}
while では、以下のように処理が進みます。
  1. "条件式" が成り立つかどうか調べます。
    成り立っていれば 3. に進みます。
    成り立っていなければループを終了します。
  2. ブロック ( { から } まで) の中の MEL 文を実行します。
  3. 1. に戻ります。
do while
条件式が成り立っているかどうか調べる前に、 最低 1 度ブロック内を実行しておきたい場合に使用します。
do
{
	MEL文;
} while(条件式);
do while では、以下のように処理が進みます。
  1. ブロック の中の MEL 文を実行します。
  2. "条件式" が成り立つかどうか調べます。
    成り立っていれば 1. に戻ります。
    成り立っていなければループを終了します。
for( in )
for( in ) は、リストの中の要素を 1 つづつ変数に代入してコマンドを実行するものです。
リストとは、具体的にいうと変数・配列などのことです。
たとえば、選択されたオブジェクトのリストから 1 つづつオブジェクトを取り出して、 何かのコマンドを実行したい場合に便利です。
for( 変数 in リスト )
{
	MEL文;
}
for( in ) では以下のように処理が進みます。
  1. "リスト" から要素を 1 つだけ取り出します。
    もし取り出す要素が無ければループを終了します。
  2. 取り出した要素を "変数" に代入します。
  3. ブロック ( { から } まで) の中の MEL 文を実行します。
  4. 1. に戻ります。

continue と break

ループの途中で、処理の流れを変更するために continuebreak が使用されます。

continue
ループ内の処理を中断して、 ループの最初から処理を実行し直します。
break
ループ内の処理を中断して、 ループをただちに終了します。

条件演算子

上の説明に出てきた条件式の部分には、以下のような条件演算子を使用します。
これらの演算子の左右に数値(int, float)、文字列(string)、変数やグループ化された条件式を書いて条件式を表します。

==
左右が等しい = が 2 つ並んでいます。
代入演算子の = と間違わないでください。
!=
左右が等しくない
<
左が右より小さい
>
左が右より大きい
<=
左が右より小さいか等しい
>=
左が右より大きいか等しい
&&
左右の条件がどちらも成り立つ場合
||
左右の条件がどちらかが成り立つ場合
( )
条件式のグループ化

条件演算子の例

$i < 10
$i が 10 未満の場合に条件が成り立ちます。
10 を含まないことに注意してください。
$x <= 5
$x が 5 以下の場合に条件が成り立ちます。
5 を含むことに注意してください。
$x >= 7.5
$x が 7.5 以上の場合に条件が成り立ちます。
7.5 を含むことに注意してください。
$y == $z
$y$z が等しい場合に条件が成り立ちます。
$s != "test"
$s が文字列 "test" と等しくない場合に条件が成り立ちます。
$a == $b && $c == $d
$a$b と等しいという条件と、 $c$d と等しいという条件が、 同時に成り立つ場合に条件が成り立ちます。
$e != $f || $g != $h
$e$f と等しくないか、 または、$g$h と等しくない場合に条件が成り立ちます。
両方の条件のどちらか一方が成り立てばよいのですが、 両方が同時に成り立っていてもかまわないことに注意してください。

Tips

条件演算子を使用する場合は、必ずいつかは条件が成り立たなくなるように条件式を組み立ててください。
そうしないとループが永久に終らなくなり、Maya で他の処理ができなくなってしまいます。 そうなると最悪の場合 Maya を強制終了しなくてはならなくなります。

しかし、時にはわざと永久ループを作る必要がある場合もあります。
そのような場合には、以下のような文を使用します。

for, while, do while の使用例

以下の例では、いづれも変数 $i をループの実行回数をかぞえるカウンターとして使っています。

ループの使用例

for 文を使って、 球体を原点(0, 0, 0)中心に半径 $rad の円上に、 $num 個並べる MEL スクリプトを作ってみましょう。

  1. 以下の MEL スクリプトを circleSphere1.mel という名前で作ります。
    global proc circleSphere1(float $rad, int $num)
    {
    	int $i;
    	float $r = 0.0;
    	float $add = 360.0 / $num;
    
    	for($i = 0; $i < $num; $i++)
    	{
    		sphere;
    		move $rad 0 0;
    		rotate -ws -p 0 0 0  0 $r 0;
    		$r += $add;
    	}
    }
    
  2. スクリプト エディタ の ファイル → ソーススクリプト によって circleSphere1.mel を読み込みます。
  3. スクリプト エディタ のインプットウインドウで circleSphere1(5.0, 6) と打ち込んで実行します。
  4. 半径1の球体が半径 5 の円上に 6 個作られます。
    [circleSphere1(5, 6)の実行結果]

スクリプトの解説

global proc circleSphere1(float $rad, int $num)
円の半径を表す float の引数($rad)と、 球体の個数を表す int の引数($num)をとるプロシージャです。
int $i;
for 文のカウンタとして使うための変数です。
float $r = 0.0;
球体を回転させるための角度を入れておく変数です。
最初は回転させないので 0.0 を代入しておきます。
float $add = 360.0 / $num;
角度の増分を入れておくための変数です。
円 1 周分の角度 360 度を、球体の個数($num)で除算しています。
for($i = 0; $i < $num; $i++)
$numfor ループを実行します。
以下は for ループ内の処理です。
sphere;
NURBS の球体を作ります。
move $rad 0 0;
球体を($rad, 0, 0)の位置に移動します。
rotate -ws -p 0 0 0 0 $r 0;
移動された球体を、 ワールド空間で(0, 0, 0)を中心として Y 軸周りに $r だけ回転します。
各フラグの意味は、以下の通りです。
-ws
ワールド空間で回転させます。
オブジェクト空間で回転させても意味の無いことに注意してください。
-p 0 0 0
回転の中心を(0, 0, 0)にします。
0 $r 0
X 軸周りに 0 度、Y 軸周りに $r 度、Z 軸周りに 0 度回転させます。
$r += $add;
球体の、次の回転角度を求めます。

練習

まとめ

練習課題

参考


Prev | Next
Home | Contents
Mail