2017年7月31日月曜日

stringToStringArrayコマンドで注意すること

stringToStringArray、文字列を指定した文字で分割するコマンド 。
で.csvファイルを分割する時に大活躍するコマンドです。

ただ、特定の条件下で想定しない挙動を示します。
ちなみに.csvファイルとは、カンマで区切られた値の集合。

string $csv="A,B,C,D,E,F,";
を分割する場合、
string $array[]=stringToStringArray( $csv,"," );

と書き、戻ってきた$arrayは、こんな感じになります。
0: A
1: B
2: C
3: D
4: E
5: F

しかし、渡す文字列の「C」を削って、
string $csv="A,B,,D,E,F,";
こういう風にカンマが連続している場合の$arrayは
0: A
1: B
2: D
3: E
4: F

と、「C」に当たる$array[2]がブランクではなく「D」以降の文字が繰上げで代入されています。

string $csv="A,B, ,D,E,F,";
とスペースを入れてあったりする場合は、
0: A
1: B
2:  
3: D
4: E
5: F

と、$array[2]にはスペースが入ります。
stringToStringArrayと似たようなコマンド、tokenizeでも同じ事が起きます。
これがバグなのか仕様なのかは不明。

回避するためには自分でナントカするしかないようです。
で、ナントカしたスクリプト。

引数の文字数を2回ループさせているので、処理速度的に1回で済ますようにした方が良いのかなぁ・・・。
1回にするとifを挟むので、それがネックになりそうだし。
難しい。

2017年7月24日月曜日

ノードをレイヤーに登録させない

表示/非表示を簡単に切り替えたりするのに便利なレイヤーですが、モーションなどを外注に出したりした場合、まれにコチラで作成したリグをレイヤーに登録しやがる不届き者が居たりします。
コレをやられると、リグのcurveShapeに設定した overrideColor がレイヤーの色で上書きされてしまい復元できなくなります。要するにリグを破壊されてしまうと言うわけですね。

多くの人は、階層をレイヤーへ登録する場合、なにげなく Select Hierarchy でオブジェクトを選択して、なんとなくレイヤーへ Add Selected Objects で追加していると思います。


意外と忘れられがちですが、こういう風に選択すると shapeノードも選択していることになります。

nodeEditorで確認すると・・・


レイヤーから shapeノードへ素敵なサムシングが接続されています。
Relationsip Editorでも確認できますね。

こうしない為には、Select Hierarchyの後に、

select -d (`ls -sl -s`);

をコマンドラインで実行させる必要があるのです。

面倒です。

発注書とかでネガティブリストを作っても、まぁ守られることはありません。
で、防衛の為にレイヤーへノードを登録させないように細工をしておく必要があるのです。

要は接続できないようにアトリビュートをロックしておけば良い訳です。
どのアトリビュートに接続されているかを確認。


drowOverrideと云うアトリビュートらしい。
いったん全てのオブジェクトをレイヤーから外して、アトリビュートをロックするためのコマンド

setAttr -lock on "locatorShape1.drawOverride";

を実行します。
すると、先ほどの手順でレイヤーへ追加しようとしても

// Error: line 0: Connection not made: 'layer1.drawInfo' -> 'locatorShape.drawOverride'.  Destination is locked. // 

と、エラーでレイヤーへの追加処理が止まりました。
最低でも shapeノード、できればリグのノードの全部のアトリビュートをロックしておけば、レイヤーへ登録しようとしている輩の心をへし折る事ができるでしょう。

こういう事をしておくと、たまに闘志を燃やす変態さんも居たりしますけどね。

ここに・・・。

2017年7月21日金曜日

MELの保存先を調べる

.melファイルが保存されているパスを調べたい場合には、whatIs コマンドを使うと良いようです。
humanIk関係のスクリプトなんかで whatIs を使いアイコンの保存されているフォルダを探していたりしています。

{
    string $whatIs=`whatIs "MEL command"`;
    string $path=`substitute "Mel procedure found in: " $whatIs ""`;
    $path=dirname( $path );
}

こんな感じ。

whatIs コマンドの注意点としては、maya起動後に1度も実行していないMELコマンドの場合、戻り値の"Mel procedure found in: " 部分が変化するので要注意。
1度も実行していない場合、"Script found in: " となります。

この辺を踏まえてスクリプトにすると、
{
    string $script="hogehoge";/* 調べたいコマンドへ変更 */
    
    string $whatIs=`whatIs $script`;
    // 不明の場合停止
    if("Unknown"==$whatIs) error -n "Unknown";
    
    // 不要部分の削除
    string $path;
    $path=`substitute "Script found in: " $whatIs ""`;
    $path=`substitute "Mel procedure found in: " $path ""`;
    
    $path=dirname($path);
    print $path;
    
}
こんな感じになるでしょうかね。

----------
最新記事の方が楽かも知れません。

2017年7月11日火曜日

ノード名とアトリビュート名を分離する

connectionInfo listConnections を使っていると、返ってきた文字列をノード名とアトリビュート名に分離したい事が良くあります。
一般的には tokenize、ちょっと知っている人なんかは stringToStringArray を使ってピリオドを指定して文字配列にします。

そんなふうに考えていた時期が俺にもありました。


string $nodeAttr="locator1.translateX";// 本来は`connectionInfo -dfs`とか
string $tmp[]=stringToStringArray($nodeAttr,".");
string $node=$tmp[0];
string $attr=$tmp[1];

みたいな感じでしょうか。

シェーダーとかユーティリティーノードの接続なんかを調べている時、頻繁に打ち込んでいる気がします。
いくら秀丸の単語補完stringToStringArray が簡単に入力できるとは言っても、見た目が美しくありません。

そんな折、ふと、

( ´ー`)。о(node.attributeってファイル名みたいだなぁ)

と思ってしまいました。
で、

string $nodeAttr="locator1.translateX";
string $node=basenameEx( $nodeAttr );
string $attr=fileExtension( $nodeAttr );
print ("\n-- "+$nodeAttr+"----\n");
print ($node+"\n");
print ($attr+"\n");

ふつうに分離できました。
Σ(゚д゚;) マジカ