[mel] scriptEditorから覚えるmel講座 その1 ~とりあえずMelコマンドにしてみよう~

会社にて 「scriptEditorにログが表示されて、そのままコピペすればいいのは知ってるけど、見てもそこからどうしたら良いかわからない」 という話を聞いたので
ScriptEditorの内容をみつつMelを覚えよう!! ネタを何度かに分けて書いてみます。
写真ばっかりじゃなくて、たまにはCG屋さんっぽいこともカカナイトネ!!

続きを読む

[maya] コマンドの調べ方

複雑なスクリプトを書くときに限らず「Mayaのこの動作のコマンドってなんだろう」や「~ってできたっけか?」というふうに、
自分のやりたいことから、コマンドを探す というケースは多々あります。

そんな時の私なりのコマンドの探し方をご紹介します。
MayaのUI上からできることなんかはこれでほぼ見つかる…はずです。たぶん。

1 MayaのHelp コマンドリストでそれっぽいワードで検索してみる
スクリプト作業でのコマンド(substitute,tokenize,ls,select…)のような基本的なコマンドはこの方法で見つけます。
いわゆる、 数学コマンド・文字列コマンド・UI作成コマンド のようなものですね。
こういうコマンドの場合、どの言語もだいたい似たようなワードでコマンドが作られているのでワード検索でも見つけられるし
大まかな分類分けがされてるので、分類からコマンド一覧を確認して、それっぽいコマンドをかたっぱしから開いてみる…という、まぁある意味地味な見つけ方ですが
これが一番確実なんじゃないかなと思います。
ある程度わかってくると、推測しやすくなるので見つけるのも早くなります。
あと、MayaのScriptEditorに表示されているログも Helpを探せばたいてい見つかります。

2 MayaInstallFolder>Scriptsの中を探す
基本コマンドなら1の方法でも問題ないのですが、そうではない場合(UIにあるMayaの機能を呼び出してるようなもの)は、Mayaのコマンドリストには乗っていません。
そういうものは、Mayaのコマンドではなく、Melで書かれたスクリプトコマンドです。
MayaのUIはすべてMelで書かれているので、とりあえず、Scriptフォルダの下を探せば少なくてもどれかには書かれているわけです。

しかし1つづつ開いては実行して確認するのは無理がある上に、あるていどmelファイルのファイル名で推測はたつけれども そのmelコマンドにある どれかのコマンドだったりすることもあるので
あまり効率的ではありません。

ので、こんな時は VisualC++ を使います。
といっても、C++でコマンドを使うわけではなく VisualC++の検索機能だけを使います。
VisualC++のバージョンはなにでもOKです。

VisualC++を立ち上げたあと CTRL+F で、検索画面を出します。
クイック検索をフォルダーを指定して検索にしたあと、検索対象のフォルダに、 <MayaInstallFolder>/scripts を指定して、検索ワードにそれっぽいものをいれて検索します。
検索すると、そのワードに引っかかるファイルと行数がわかるので、引っかかったものからそれらしいものを開いてコマンドを確認・・・を繰り返します。

「それっぽいもの」を入れる とか 「それっぽいファイルのそれっぽいコマンドを見つける」 というのにはある意味コツが必要ではあるのですが、コツが分かると
この方法で大抵のものは調べがつきます。

その「コツ」ですが、まずは 検索ワードに自分が知りたいMayaのUIの名前やMenuの名前で検索します。
そうすると、 そのままスクリプトのコマンドになっていてHitするか ~.res.mel  ファイルというのに検索が引っかかります。
.res.mel は、それと同じ名前の .mel  ファイルの言語設定ファイルなので、 .resを抜いた その名前のファイルを開けば、UIを作成しているmelファイルが見つかります。
見つかったら、そのファイルを開いて 中で実行しているコマンドを探します。あったら、それを再度検索をかけて絞り込んでいきます。

UIでTemplateを使っている場合とか ちょっとわかりにくいケースもあるのですが概ね私はこの方法でコマンドを探しています。
そのまま使えない場合は、コマンドの実行部分だけ切り出したり一部書き換えたりして別コマンドにしたり…とかでもわりと1から書くよりは手軽にかつ素早くできます。

と、参考になるかはわかりませんが 私のコマンドの探し方はだいたいこんなかんじです。
調べ方とか書きつつも 方法1 慣れ9 ぐらいです。
スクリプトの逆引き辞典書いててもおもいますが、自分が知りたいものから答えを探すのは難しいです(´・ω・`)

MayaのCurveの色を変える

1日1回Mayaのことを書くのを習慣にしたいなぁとか思うけど、そんなにネタがないというオチ。

Mayaを使い始めて、専門含めれば6年ぐらい立つのですが、割りと最近になって初めて知ったのが Curveの色の変更方法。
DisplayLayerに入れてから表示色をかえれば変わるけど、それだとなぁ…とずっと思ってたのですが人に「できるよ?」と言われて衝撃を受けました。

設定場所
CurveのShpaeノード->Drawing Overrides -> Enable Overridesにチェックを入れて、ColorのIndexのバーを変えると色が変わる。
設定方法は、0から31までの整数にそれぞれ色が割り振られていて そのパターンの中から選択する(AttributeEditorからは、数値は見えず バーの移動だけで色を選ぶ)
数字入力したい場合は、SetAttrで値をセット。
0  グレー
1 黒 
6 青 
13 赤 
16 白
17 黄色 
31 ワインレッド 
などなど。全部書こうと思ったけどやめました(´・ω・`)
 
Attributeの正式な名前は、 「overrideColor 」なので、数値で入れるときは、
setAttr “<ノード名 >.overrideColor” <数値>;
で、OK。

追記。
もう1つ方法があるようで、Display -> wireFrameColor で、色を変えたいCurveを選択して 変更する色を選び Apply でも変わるようです。
この場合は、選べる色は8色のみで、Shapeノードに値をセットしにいっているのではなく また別のAttributeに値をセットしている模様。
優先度が高いのはShapeノード側。
ShapeノードのEnableOverridesが入っている場合は、wireFrameColorを設定していても、overrideColor側の色になります。
EnableOverridesのチェックを外すと、wireFrameColorに戻ります。
じゃあ、woreFrameColorでセットした値はどこに保存されてるんだろう(´・ω・`)? とか思いましたが、そのへん調べてると夜が明けそうなのでやりません。はい。
 

以上、知らなくても別に困らないけど 知ってるといろいろ便利な小ネタでした。 

filePathをsubstituteする時の注意点

Windowsの場合、ファイルパスを区切るには、 / の二種類があり、どちらでもファイルパスは認識されます。
が、スクリプトを使用したときにはやや違いがあり、 スクリプト的には、ノードのテキストボックス上では マークで区切られていても、内部的には / として保持されています。

これが、問題になるのが、ファイルパスを一括で置換しようとするスクリプトを書く場合。
書き換えるパスを、テキストボックス(表に出ている) で区切られたパスで置換しようとすると、エラーになります。
凄い分かりにくい。

さらに、テクスチャパスを置換しようとすると1つ問題が発生します。
手でパスを書き換えた場合 無効なパスであったとしても、パスの書き換えは可能ですが、(その場合テクスチャは読み込まれなくなる)setAttrで値をセットしようとすると、Result的には書き換わりましたとかかれはするのですが、実際のパスは書き換わりません。

もう一つの特性として、もとのパスにファイルがない場合 projectフォルダのsourceimagesをチェックしに行き、同じファイル名があった場合、setAttrで与えたパスではなく、sourceimagesの中のファイルにパスは書き換わります。

まとめると

fileTextureNameのパスが通っている場合、
1 setAttrしたPathが通っていれば、そのパスに書き換わる
2 通っていない場合、置換はされずそのままのパスになる

fileTextureNameのパスが通っていない場合
1 setAttrしたPathが正しい物ならば、そのパスに書き換わる
2 正しくない場合、同名のファイルがprojectFolder内のsourceimagesにあるかどうかチェックし、
あった場合は、そのパスに書き換わる
3 sourceimagesにもない場合、書き換わらない

と、setAttr時にこんな挙動をとります。非常に美味しくない

まぁ、正しくないパスに書き換えることができないというのは 理屈としては間違っていないのですが。
イマイチこのへんの挙動がよくわからなくて、パス書き換え系のスクリプトを書くのに困ります。要検討

とりあえず↓は、簡単なテクスチャの一括変換スクリプト

[cpp] global proc replaceTextureFilePath(string $before,string $after){

string $node[] = ls -type file;

for ($fileNode in $node){

string $path = getAttr ($fileNode + ".fileTextureName");
string $changePath = substitute $before $path $after;
setAttr -type "string" ($fileNode + ".fileTextureName") $changePath;
}

}
[/cpp]