2017年11月20日月曜日

melでフォルダのリストを作成する

たまにしか使用しないため備忘録。

melから指定パス内のファイルやフォルダのリストを作成するためのコマンド
getFileList

-folder(-fld)で調べたいパスを指定すると、そのパス内のフォルダ名とファイル名がリストで返されます。
getFileListには-filespec(-fs)という検索用のフラグがあり、ワイルドカードである程度返ってくるファイルを絞れます。

ここでちょっとつまづきます。
リストをフォルダだけに絞りたい場合は・・?

まぁ返ってきたリストをfiletest -dで判定すれば良いのかも知れませんが、スマートではないのでfilespecで何とかしたいところです。
で、フォルダって言うのは拡張子が無いってことなので、"*."を指定するわけです。こんな風に。

string $list[]=`getFileList -fld $path -fs "*."`;

このリストにはパスが付いていないので、使用する場合には
($path+"/"+$list[0])

みたいにする必要があります。


2017年10月23日月曜日

数値を四捨五入する

mayaで作業をしていると、数値を四捨五入したい事が結構でてきます。
そんな時のためのスクリプトを作成してみました。

ROUND.mel

シチュエーションに合わせて専用に作るのもなんなので、四捨五入しかしない単体機能です。

アニメーションを作っている時なんかは、こんな感じのスクリプトで呼び出すと良いかもしれないです。

{
    string $sel[]=`ls -sl -typ "transform"`;
    
    for( $e in $sel )
    {
        string $attrs[]=`listAttr -k -se -w $e`;
        for( $attr in $attrs )
        {
            string $NA=($e+"."+$attr);
            float $v=ROUND(`getAttr $NA`,2);
            
            setAttr $NA $v;
            
        }
        
    }
    
}

上のスクリプトを実行すると、channelBoxの数値がこんな感じになります。



まぁ、.maファイルへ保存すると希望の桁数で保存されているとは限らないので気休め程度なのですがね・・・。

------
pythonコマンドを使用することで簡単に処理する事ができます。

2017年9月11日月曜日

良く使う処理はコマンドで

dirnameなんかもそうですが、良く使う処理は既にコマンド化されていたりするみたいです。

まずは親のオブジェクト名を取得する処理。
{
   string $p[]=listRelatives -p $current`;
   print("\n"+$p[0]+"\n");

}
listRelativesは文字配列を返すため、いったん配列に代入しないといけないのは頂けません。
コレの代替コマンドは
{
    string $p = firstParentOf( $current );
    print("\n"+$p+"\n");

}
文字列で返ってくるのは中々良いのですが、オブジェクト名がロングネームでしか返ってこないので注意。


こういう時など、ロング名をショート名に変更したい場合、
{
    string $tmp[]= stringToStringArray( $long,"|" );
    string $short=$tmp[size($tmp)-1];

    print("\n"+$short+"\n");

}
こんな感じで配列の最後に入った値を取得するみたいな、なかなかの面倒くささ。
ネームスペースも外したい場合、更に複雑になりますね。

でも、この処理にも、こんなそのまんまの名称のコマンドが・・・。
{
    string $short = shortNameOf( $long );

    print("\n"+$short+"\n");
}
ただし、ネームスペースは分離できないようなので、その部分は自前で処理するしかなさそうです。

plugNodeStrippedを使用するとDAGパスとネームスペースを一気に除去できます。
2017/09/20追記


で、いちばん欲しいコマンドなのですが、指定したオブジェクトがどんなタイプなのかを調べる処理。
nodeTypeで調べても大抵 "transform"と返ってきます。
なので、子のshapeノードからタイプを調べる必要があるわけですが、これに専用のコマンドは無いようで、自力で行う必要があるみたいなのですね。
こんな風に。
{
    string $shape[]=`listRelatives -c -pa -ni -s $target`;
    string $type=`nodeType $shape[0]`;

    print("\n"+$type+"\n");

}

まぁ、transformノードに色々ブラ下げていると、nodeTypeに渡す値が$shape[0]に特定できないというのが原因だとは思います。


2017年8月31日木曜日

配列の行と列を入れ替える

ロケータを4つほど作成し、それぞれ適当に移動させます。
そして、下のスクリプトを実行。

{
    string $lines[];
    $lines[0]="nodeName\ttranslateX\ttranslateY\ttranslateZ\tvisibility";
    
    string $lcts[]={"locator1","locator2","locator3","locator4"};
    
    for( $lct in $lcts )
    {
        float $tr[]=`getAttr ($lct+".t")`;
        string $vis=(`getAttr ($lct+".v")`) ? "on": "off";
        
        $lines[size($lines)]=($lct+"\t"+$tr[0]+"\t"+$tr[1]+"\t"+$tr[2]+"\t"+$vis);
        
    }
    
    print $lines;
    
    
}


スクリプトエディタの履歴をコピーしてエクセルへ貼り付けてみます。

エクセルはタブで区切られているとセルに分割された状態で貼り付けられます。
便利ですね。

上では、まだ列が少ないので良いのですが、アトリビュート値を大量にリスト化した場合、アトリビュートのヘッダーを列方向ではなく行方向に並べたい場合があります。
エクセルであれば、いったんセルをコピーして、ホームの「貼り付け」から「形式を選択して貼り付け」を選びます。

出てきたダイアログから「行列を入れ替える」にチェックを入れて[OK]します。

すると、行列が入れ替わった状態で貼り付けされました。

で、これを何回も行う場合、面倒なので行列の入れ替をMEL側で行いたい。
そんなスクリプトを作成。


引数に「文字配列」と「セパレータの文字」を渡すと行列を入れ替えてくれます。
冒頭のスクリプトであれば、print $lines;の下に


    print("\n-- new lines --\n");
    string $newLines[]=stringArrayTranspose( $lines,"\t");
    print $newLines;
    


を追加すれば、
うまく入れ替わってくれているようです。



2017年8月21日月曜日

日本語と英語のフォントサイズ

ツールを作る場合、ウィンドウに項目を並べたい場合があります。
サンプルスクリプトとしてはこんな感じ。

proc string _createLabelFrame(
       int $w ,                         // 幅px
    string $align,                      // 位置合わせ"left","right","center"
    string $label )                     // ラベル文字
{
    string $frame=`frameLayout -lv 0 -bv 1 -w $w -mw 6`;
        text -l $label -al $align;
        setParent ..;
    
    return $frame;
    
}


global proc labelTest()
{
    string $win="testWindow";
    
    if(`window -q -ex $win`) deleteUI $win;
    window $win;
    
        rowLayout -nc 4;
            _createLabelFrame( 46,"center","項目A" );
            _createLabelFrame( 96,"center","けっこう長い項目B" );
            _createLabelFrame( 96,"left","項目C" );
            _createLabelFrame( 96,"right","項目D" );
    
    window -e -w 342 -h 32 $win;
    
    showWindow $win;
    
}


実行するとこんな感じのウィンドウになります。


で自分は普段英語版を使うわけですが、世の中にはmaya日本版と言う物があるのです。
同じスクリプトを日本語版で実行した結果。


ギリギリを攻めていた「項目A」と「けっこう長い項目B」が枠からハミ出ています。
良く見ると高さも若干広まっていますね。

どうやら英語版と日本語版ではフォントサイズが違っているようで、レイアウトが崩れてしまう様子。
けれどもMELにはフォントサイズを変更するオプションはありませんが、フォントスタイルを、
「boldLabelFont」
「smallBoldLabelFont」
「tinyBoldLabelFont」
「plainLabelFont」
「smallPlainLabelFont」
「obliqueLabelFont」
「smallObliqueLabelFont」
「fixedWidthFont」
「smallFixedWidthFont」
から指定できるようです。

ただ、それぞれを指定して比較するのは中々面倒です。
実はmayaのインストールフォルダのresourcesに MayaStrings というファイルがあります。
そのファイルの中から s_TschemeResourcesFlatUI という単語を検索すると、

こんな感じで各言語のフォントサイズらしき物を発見できました。

で、全言語同じフォントで同じサイズの「smallFixedWidthFont」を指定します。
text -l $label -al $align -fn "smallFixedWidthFont";


編集して日本語mayaで実行した結果


英語と同じになりました。
配置に凝ったUIを組む時はFixedWidthFontくらいしか使えないので要注意です。