日本でハリウッドVFXを制作! 「経産省アイディアボックス」 結果:  
●まとめエントリはこちら ●FAQ ●お問い合わせは左のメールフォームから

2009年5月9日土曜日

lsコマンドと-slフラグ

melスクリプトにおいて、頻繁に使われる手順を習い始めに習得しておくことは、
後の学習を容易にしてくれるし、即戦力になるスクリプトを早い時期から造ることが出来るようになるのではないかと思う。

そこで、そういった手順は何かを考えてみた。


通常、作業をするときは、
1)オブジェクトを作成し、何かの形状を作る。
2)パーティクル/エミッターを作成し、その動きを作る。
3)アトリビュートにキーをつけ、アニメーションを作る。
4)シェーダーを適用し、そのアトリビュートを変更する。
5)ライトを作成し、そのアトリビュートを変更する。

などが主な内容となる


ここに共通する事柄は
1) 現在、シーン内に存在していないもの(ノード)を創る
2) 現在、シーン内に存在している物(ノード)に対して何らかの変更をする。

の二点である。


Melスクリプトで何かを作成するのは、それを作成するコマンドを実行すればよいので簡単だ。
二つ目の「何らかの変更」というのはアトリビュート値を変更するということがほとんどだと思う。
(二つのノードのアトリビュートをコネクトするというのも「変更」ということにする)


このアトリビュート値の変更という作業に不可欠なものが対象となるオブジェクトの選択である。


オブジェクトを選択しなくても機能するスクリプトもあるが、
通常の作業では特定の物に対して何らかの作業をするためのスクリプトを使うことが多い。
それには、オブジェクトの選択という作業が最初に来る。

選択したオブジェクト名は
ls -sl
というコマンドで表示できる。
lsはリスト
「-sl」フラグはセレクション(選択対象)という意味になる。



ここで、以前Melスクリプトを利用したときのことを思い返してみると、
便利な物と、使いにくい物があることを思い出した。

1)便利な物は選択したオブジェクトの名前に関係なく機能する。
2)使いにくい物はオブジェクトの名前が限定されており、決められた名前になっていないと機能しない。

とくに「2」に関してはMelスクリプトを習い始めの時には、よく突き当たる問題だった。
これが解決できれば、名前にしばられず、選択さえすれば機能するスクリプトができる。

要するに、この「ls -sl」をうまく使うことで、オブジェクトの名前に関係なく機能できるスクリプトを作ることができるということだ。


--------------------
<「ls」コマンドについて>


lsコマンドはLinuxやMacにもあり、それらの元祖であるUnixにも当然ある。
Windowsでは「dir」というコマンドがそれに相当するが、「ls」に比べると機能は少ない。
(例外として「Windows Power Shell」をインストールすればWindowsでも「ls」が利用可能になる)


OS上では、lsコマンドは「現在のディレクトリ(フォルダ)内にあるファイル名をすべて表示」するために使われる。

Mayaのlsコマンドもこれと似ているが、Mayaのlsコマンドは「現在のシーン内にあるオブジェクト名をすべて表示」する
Maya オンラインヘルプ: lsコマンド


ためしに、まだ何も作成していない新規のシーンでlsコマンドを実行すると、すでにいろいろなオブジェクトが存在していることがわかる。


そのままlsコマンドを実行すると表示が非常にわかりづらいので、
1)オブジェクト名を一つづつ改行して表示し、
2)最後に総数を表示するスクリプトを作ってみた。

参考になったのは、Learning Maya(MEL Fundamentals)の「変数」の項目。
ここに書かれていたsizeコマンドがとても重要な働きをしてくれた。

sizeコマンドは、「配列の要素数または文字列の文字数を返す」働きを持つ

{
string $name[] = `ls`;
$size = size($name);
for ($i=0;$i<$size;$i++) {
string $printName = ($name[$i]+"\n");
print $printName;}
print ("total Number = " + $size + "\n");
}


スクリプトを簡単に説明すると、
1)lsコマンドで返された値を$name配列に格納。
  配列の一つのindexへ、一つの値が格納され、値の数だけ配列のindexは自動的に増える。

2)sizeコマンドで$name配列の要素数を調べ、返された値を$size変数へ格納。

3)$sizeの値の数だけ、for文を繰り返す。

4)for文は$sizeの値、すなわち配列の要素数(例:55)より1少ない数(例:54)で終了する。
  for文の初期値は$=0とゼロから始まっているので、繰り返す回数は要素数(例:55)と一致している。

5)for文の中身は、$name配列の要素を一つ表示する。要素のindexはFor文の$iを利用し、
  indexが[0]から始まり、一回ごとにindexが1つづつ増加する。([1],[2],[3]・・・・)

6)最後にすべての要素数(すなわちシーン内のオブジェクトの数)を表示する。(例:total Number = 55)


これを新規シーンで実行すると55個のオブジェクトがすでに存在していることがわかる。
中には「persp」や「top」といったシーン内のデフォルトカメラを示す名前やそのShapeノードが見て取れる。
OutlinerでDagオブジェクトとシェイプノードを表示すれば、この内30個のノードは、アイコンで見ることができるので、よりそれらの存在を感じられるだろう。


ここまではlsコマンドをフラグなしで使った場合で、Mayaの作業では当然ながらすべてのオブジェクトを対象にして操作をすることはほとんど無く、lsコマンドをフラグ無しで使うことはあまり意味をなさない。


実際の作業に役立てるためには、選択したもののみに絞る必要があるので、
-selectionフラグを利用する。(省略形: -sl)
これはUnixのlsコマンドにはない、Maya独自の物だ。

Unixではファイルを選択してそれに対して何かをするということはないからだろう。
それは裏を返せばMaya(3dソフト)では「選択」という作業がとても重要だということだろう。

上記のスクリプトの最初の行
string $name[] = `ls`;

string $name[] = `ls -sl`;
に変えてやるだけで現在選択している物の名前と数を表示するスクリプトになる。



--------------------

今回の方法で、「ls -sl」で選択したオブジェクトの名前を得ることができるようになった。

その返値を配列に代入すれば、配列は自動的にすべての値を格納してくれる

sizeコマンドによって選択していたオブジェクトの総数を知ることができる。

またその数をfor文で利用すれば、オブジェクトの総数だけアクションを実行できる



他にもlsコマンドには便利なフラグがあるので選択した対象をさらに絞り込むのにも使えそうだ。
そうすることで、ランダムに選択した中から、もしくはシーン全体の中から、
任意のオブジェクトの名前を抽出することができるようになる。

 

0 件のコメント:

コメントを投稿