2009年から仕事でMAYAを勉強。MAYAはデフォルトでは使い勝手が悪い。逆にスクリプトを覚えてカスタマイズするとかなり強力なツールになることがわかってきた。

物覚えが悪いので勉強したことはリマインダとしてココに書き留めるようにする。

2009年6月4日木曜日

【MEL】ロード方法による挙動の違い

スクリプトエディターからロードした時と、スクリプトフォルダにMELを入れておいて起動時に読み込ませておくのではスクリプトの挙動が違うようだ。


スクリプトエディターからロードした時にはローカルプロシージャが読めたのに、起動時読み込みだと
見つからなくなる。

ある日急にスクリプトが動かなくなるのはこの辺の挙動の理解が足りていないせいな気がする。


ローカルプロシージャはそのファイル内では呼び出し可能なはずなのに、実際はそうではないのか?
世間で出回っているスクリプトをみても全部グローバルにしちゃっているようだ。
まあ挙動が安定するのは理解できる。しかし他のプロシージャと名前が衝突する危険が高まる。

どーすっかなあこれは。




【MEL】プロシージャ引数についての研究

小規模実験
proc test(string $text,int $val,float $num)
{
 print ($text + "\n");
 print ($val + "\n");
 print ($num + "\n");
}

$temptext = "hello world";
int $onogu;
float $rimo = 3.1415;

test( $temptext, $onogu, $rimo );

これで$onoguや$rimoを変えるとちゃんと結果に表示される。


・引数は数と型があっていれば順番に代入されるので名前の一致は必要ない(ゆえに汎用性が高い。むしろ内容を特定しない名前がいいかも)
・ただし汎用性のために複数の引数をセットしたら、渡す側も同じ数を(空っぽでもいいので)用意しなければいけない
・引数は”使わなきゃいけない”というもんではなく(←ここ勘違いしていた)、用意するかどうかと使うかどうかは全然別個に考えればいい
・returnも書かなければ以降に処理が流れていくだけで特に問題はない。 書けば呼び出した場所に戻る。




2009年6月3日水曜日

【MEL】3桁の数字の任意の桁数を取り出す

せっかく考えたのに作った後で不要なことに気がついたorz
後で必要になるかもしんないのでメモっとく。

//テスト用の3桁の数字
int $gaga = 278;
//100の位抽出
$hyaku = `floor ($gaga/100)`;
print $hyaku + "\n";

//10の位抽出
$juu = `floor (($gaga - ($hyaku *100)) /10)`;
print $juu + "\n";

//1の位抽出
$ichi = $gaga - ($hyaku *100 + $juu *10);
print $ichi + "\n";




しかしこれ、桁が7くらいになるともうきついよな。ちゃんと関数とか命令があると思うんだけど。

【MEL】引数を変数で渡す時の注意

引数を2つ以上要求するフラグに変数で引数を渡す場合

これはダメ
----------------
{
string $col = "0.5 0.8 0.1";
window;
columnLayout;
button -label " test " -bgc $col;
showWindow;
}
----------------


こう書かなくてはいけない
----------------
{
float $colR = "0.5";
float $colG = "0.8";
float $colB = "0.1";
window;
columnLayout;
button -label " test " -bgc $colR $colG $colB;
showWindow;
}
----------------

【MEL】キーが打たれているか判定

キーが打たれているかどうかを判定するスクリプト

$test4 = `findKeyframe -curve -at "rotateX" pCube1`;
print $test4;

string $attex = $test4[0];

if ( $attex != "")
{
   print "移動Xのキーがあります";
}
else
{
   print "キーはありません";
}


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

...でいいと思っていたが、どうやらこれは2008以降でしか通用しないらしい。
8.5以前にはfindKeyframe命令に-curveのフラグが存在していないのだ。

で、古いバージョンでも使える代用処理を考える。


findKeyframe -t "-99:99" -at "rotateX" pCube1;

-timeフラグで-99から99の範囲を探す。キーがなければ-99を返すので-99以外ならキーはあると判断する。



常識的なキーの打ち方をしていれば問題が起こることはないだろう。




2009年6月2日火曜日

【MELメモ】端数を0か5に

小数点以下任意の最後の桁を「0」か「5」にするロジックのメモ

・任意小数点の桁だけ抽出し1桁の整数にする
・この1桁の整数を3.33で割る
 →もし結果が2以上だったら切り上げ
 →もし結果が2未満1以上だったらこの桁は5である
 →もし結果が1未満だったら切り捨て


小数点以下任意の最後の桁をとりだすやりかたがわからんけど。
あとで検証するので思いついたアイデアをメモしておく。


・・・いやまて、任意の桁を取り出せるなら”その値が3,4,5,6,7のいずれかなら5”
でいいじゃん(汗

2009年5月29日金曜日

外部ファイルの存在チェック

外部ファイルを読み込もうとしてファイルがないとMAYAがハングするので回避コード。

俺はこうやった。

$fileExCheck = `filetest -f $fname`;

if ($fileExCheck == 0)
   {
      print "ファイルが見つかりません\n";
   }
   else
   {

      int $fid = `fopen $fname "r"`;
      ファイルが開いた後の処理をする
   }


一方プログラマーからもらったサンプルはこうだった。


// リストファイルを開く
int $fid = `fopen $fname "r"`;
   // 開けた?
   if( $fid != 0 )
   {

   ファイルを開いた後の処理をする
   }

   else
   {
   // ファイルが開けなかったエラー
   print ("ファイルを開けませんでした。"+$fname + "\n");

   }



おかしいな、俺がやるとint $fid = `fopen $fname "r"`; の時点でハングするのに・・・
これでいいならわざわざファイルチェック専用のルーチン作らなくていいからシンプルだよね。



.

ラジオボタンの謎 2

昨日は解決した(というか、正解ではないが回避策がわかった)ラジオボタン問題。

mixiのコミュニティで正しい解決法を聞いてみようと思いうまくいかない例
作ってみたが、なぜかうまく動いてしまう。

いろいろ試すうちに”ウィンドウをたくさん作って消す”ような動作をさせていると
おかしくなる事がわかった。

つまり“MAYA操作中にできるゴミデータが変数に残っている”のが原因じゃなかろうか?

★★★★これでウィンドウをたくさん出しては消し、とやるとおかしくなる★★★★

global proc makePrimitive()
{
global string $radioCollection1;
string $selected;

$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
   polySphere;
}
else if($selected == "rB2")
{
   polyCube;
}
}

global proc btn()
{
   string $windowName = `window -title "test"`;
   columnLayout;
   text -label "make Primitive";
   string $radioCollection1 = `radioCollection`;
   radioButton -label "make Sphere" -select rB1;
   radioButton -label "make Cube" rB2;
   button -label " Aplly " -command "makePrimitive()";
   showWindow;
}

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

なので変数をクリアするおまじないを入れてみた。

★★★★★★★★おまじないをいれた改良版★★★★★★★★

global proc makePrimitive()
{
global string $radioCollection1;
string $selected;

$selected = `radioCollection -q -select $radioCollection1`;
if($selected == "rB1")
{
   polySphere;
}
else if($selected == "rB2")
{
   polyCube;
}
}

global proc btn()
{
   global string $radioCollection1;
   $radioCollection1 = "";

   string $windowName = `window -title "test"`;
   columnLayout;
   text -label "make Primitive";
   string $radioCollection1 = `radioCollection`;
   radioButton -label "make Sphere" -select rB1;
   radioButton -label "make Cube" rB2;
   button -label " Aplly " -command "makePrimitive()";
   showWindow;
}

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★


いまのところうまく動作しているようだ。昔作って今動かなくなっている別の
スクリプトにも組み込んでみたが正しく動作した。

どうやらこれが正解のようだ。 こういう仕様はアレかね、動的な扱いができるスクリプトで
あるが故に、ある物体の名前が同じならそれは絶対同一の物体であることを保証できないっつう
ことですかねえ。

なんにせよ変数の初期化やウィンドウの存在確認は懇ろにやっておくにこしたことはないようだ。


.