2017年12月12日火曜日

カーブオブジェクトの座標をスクリプトで使いやすくプリントする

昔、カーブオブジェクトのEP座標を表示するスクリプトを作ったのですが、スクリプトに組み込むには少し使い勝手が悪かったので、用途を限定し作り直してみました。

tryPrintCurveEP.mel


こんな感じでカーブオブジェクトを作成したら、選択状態でコマンドラインへ
tryPrintCurveEP 桁数
で実行。


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くらいしか使えないので要注意です。

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");

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


2017年6月29日木曜日

16進数を10進数に変換する。

前回作成したDEC2HEX.melの逆、16進数を10進数に変換するMELを作成してみました。
HEX2DEC.mel

まず、16進数と言うことで a~f までのアルファベットが大文字か小文字かと言う問題がありますが、スクリプト内で
$hex=tolower( $hex );

とする事で小文字のみにして対処しています。


次に16進数とかは接頭辞に「0x」を付けて表すのが習わしだったりしますが、これも付いていたり付いていなかったりするのを解消するため、
$hex=substitute( "0x",$hex,"" );

で計算前に除去。「0x」が無かった場合はスルーなので問題ないはず。

あとは g~z が紛れ込んでいた場合なんですが、何も対策していない・・・。
なにかエラー処理を入れておくべきなのでしょうが、ここは変な文字列が来ないことを祈るしかない。


------

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


2017年6月26日月曜日

10進数を16進数に変換する

10進数を16進数にしたい場合、MELでは計算しないと駄目なんですよねぇ。
まぁ、普通の人には全く不要なんでしょうけど。

作成してみました。
NUM2HEX.mel

一応、それらしい数値はでてくるな。
こうなると、16進数から10進数にするMELも欲しいところ。
あとは、2進数とかね。
HEX2NUM,BIN2HEX,HEX2BIN,NUM2BIN,BIN2NUMあたりか。


2017年6月12日月曜日

ノードを作成する時のTips

createNodeコマンドで作成されたノードは、nodeGraphEditorInfoの削除で一緒に削除されてしまいますが、GUIを使った場合は無事。
裏でmayaが何かしている訳なのです。

これを確認するにはマテリアルを作ってみるのが手っ取り早い。

・HyperShadeのメニューから Create > Materials > Phong
・コマンドラインから createNode "phong"

と、2つの手段で phongマテリアルを追加します。

すると、HyperShadeで変な事が起きます。

createNodeで作成した「phong3」がHyperShadeに表示されません。
この辺に秘密がありそうです。

NodeEditorで接続を見てみます。

メニューから作成された「phong2」には、いろいろ繋がっています。
この中からHyperShadeに関連するノードを調べるために、初期ノードの「phong1」も追加してみます。


「defaultShaderList1」と言うのが怪しそうですね。


「phong2」にならって「phong3」も接続してみます。


無事、HyperShadeに「phong3」が表示されました。
めでたし、めでたし。
とはいかず、createNodeを使う場合、ココまでしないといけない訳ですね。

mayaのメニューではこの一連の工程を、shadingNodeコマンドで行っているようです。
ただ、shadingNodeコマンドには幾つかオプションがあって、作るノードとオプションが合致していないとおかしな事が起こるわけです。

shadingNode -asUtility "phong"

とコマンドラインで実行すると、HypherShadeにはこんな感じでUtiliesタブに登録されてしまいます。


2014とかでは、気にせずcreateNodeを使用してマテリアルなんかを作成していましたが、nodeGraphEditorInfoが出来たせいで面倒くさくなったみたいです。
迷惑なノードだ。

2017年6月1日木曜日

nodeGraphEditorInfoノード。その2

nodeGraphEditorInfoノードを削除したい場合、

{
    string $NGEIs[]=`ls -typ "nodeGraphEditorInfo"`;
    delete $NGEIs;

}


みたいにすると思います。
普通に Node Editor や HyperShade の GUI からノードを作成しているぶんには別段気にすることはないのですが、MELで createNode を使用した場合、nodeGraphEditorInfo ノードの扱いには注意が必要です。


たとえば、

createNode "condition";

で condition ノードを幾つか作成します。
続いて

createNode "locator";

を実行して コレも Node Editor へ表示させます。

そしたら condition ノードの一つと locator の transform ノードを適当に接続します。
こんな感じで。


output側に nodeGraphEditorInfo が接続されているので、選択して削除します。
すると、locator に接続されていない condition ノードが道連れで削除されてしまいました。


utility ノードは、何かに接続されていないとふとした切っ掛けで削除されてしまうようです。

nodeGraphEditorInfoに関して言えば、input側を disconnectAttr してから削除するべきでしょう。

-------------------------------------------------------
回避方法はこちら。

2017年5月30日火曜日

nodeGraphEditorInfoノード。その1

nodeGraphEditorInfo なるノードが maya2016くらいから追加されたようです。
ノードエディタの配置を記憶するノードなのですが、なかなかゴミっぽくて邪魔です。

まずは、このノードを作るところから。
Node Editor もしくは HyperShade でノードを表示させます。
で、軽くノードを移動させて閉じます。
すると、channelBox のOUTPUTS にノードエディタ用っぽい名称のノードがあらわれます。

これがnodeGraphEditorInfoノードです。
maya ASCIIでノードを見てみると、ノードの配置座標や表示状態が記録されています。


次に、このノードをOutlinerで確認する方法。
とりあえず、Outlinerの DAG Objects Only のチェックを外します。

ただ、nodeGraphEditorInfoノードはコレだけでは Outliner に表示されません。

さらに Show → Show Auxiliary Node にチェックを入れる必要があります。

ここまでして、ようやく nodeGraphEditorInfoノードが見えるようになります。


けっこう下のほうにあります。
このノードも、ふつうにノードなので削除する事が可能です。
ファイルサイズの軽減やリファレンスさせる時のために削除しておきたいですね。

Outlinerで探すのが面倒なら、コマンドラインで

select -r (`ls -type "nodeGraphEditorInfo"`)

とすれば選択できます。
この状態で[Delete]ボタンで削除する事ができるのですが、何も考えずに削除すると困った事が起きてしまうのです。


つづく。

2017年5月18日木曜日

WinMergeのフィルタ

maya2016だったか、ノードにUUIDなるアトリビュートが追加されました。

こんな感じの文字の羅列。
unityなんかでも似たようなユニークIDがあったと思ったけど、似たようなもんかな?

で、スクリプトでリグを組んでいる場合、ノードのUUIDが頻繁に入れ替わったりするので、SVNで差分比較なんかすると、UUIDの存在がとても目障り。

ちなみに、TortoiseUDiff.exeじゃなくてWinMergeを使っています。
なのでWinMergeでの対処方法。

WinMergeには、特定の文字を比較対象に含めないようにするフィルタ機能があるようです。
メニューから、ツール(T) → フィルタ(F) を選びます。


するとフィルタを設定するダイアログが開くので、行フィルタのタブを選びます。
あとは以下のように設定。


これでSVNで差分を確認した時に rename -uid の行の比較が省かれます。

2017年4月20日木曜日

Doxygenで配列の役割を示す

MELの配列は参照渡しになっていますが、コメントに配列の役割を示しておいた方が何かと便利です。
自分の場合、接頭辞にCBR_(Call By Reference)を付けていたりして注意を促したりしていますが、Doxygenで出力する場合 @param に方向属性を付けることであらわすことが可能です。

基本通りに記述するなら、
proc _hogehoge0(
    string $CBR[],
    string $outList[],
    string $list[] )
/**************************************************************************//**
    @protected
    @brief test procedure.
    @param[in,out] $CBR 説明※参照渡し
    @param[out] $outList 説明※参照渡し、初期化あり
    @param[in] $list リスト
 ******************************************************************************/
{
    

これが、こんな感じになります。


param コマンドを書くのが面倒な場合は、
proc _hogehoge1(
    string $CBR[],                      //!< [in,out] 説明※参照渡し
    string $outList[],                  //!< [out] 説明※参照渡し、初期化あり
    string $list[] )                    //!< [in] リスト
/**************************************************************************//**
    @protected
    @brief test procedure.
 ******************************************************************************/
{
    


こんな風に引数の後ろへ記述する事も可能。
上のとほぼ同じように出力されます。


ただし下のように混在させると
proc _hogehoge2(
    string $test,                       //!< test comment.
    string $CBR[],
    string $outList[],
    string $list[] )
/**************************************************************************//**
 @protected
 @brief test procedure.
    @param[in,out] $CBR 説明※参照渡し
    @param[out] $outList 説明※参照渡し、初期化あり
    @param[in] $list リスト
 ******************************************************************************/
{
 


引数が複数に分割されてしまうので注意。


参照渡しは結構説明が長くなりがちなので、@pre や @post なんかも合わせると良いかも。



2017年4月18日火曜日

DoxygenのコメントデバッグTips4MEL

ローカルプロシージャにDoxygenコマンドの @private を付けると関数から見えなくする事が出来ます。
で、表示する時には Expert - Build の EXTRACT_PRIVATE にチェックを入れればよいということも。


けれども、ローカルプロシージャのコメントを修正した時、大量に並ぶ関数の中から修正した部分を選ぶのが大変になります。

これでは、修正したプロシージャを探すの大変です。

で、これを回避するTips。
編集しドキュメントを確認したいローカルプロシージャの @private を @protected というコマンドへ書き換えます。
Expert - Build の EXTRACT_PRIVATE はチェックを外します。
これでhtmlを出力。

@protected に変えたローカルプロシージャだけが表示されるようになりました。
編集を確認したら @private にしておくのを忘れずに。

ただし、EXTRACT_LOCAL_CLASSES のチェックが付いていること!
初期状態から変えなていなければ大丈夫です。


2017年3月30日木曜日

warningとerrorにオプションが新設されたみたい

なんか、warning と error に新しいオプションが追加されたようです。

まずは通常の動作。

上のように、スクリプトエディタの History でエラー時ライン番号を表示する設定をしている場合に、下のスクリプトを実行すると、

global proc assert()
{
    warning "warning:hogehoge";
    error "error:hogehoge";
    print "hogehoge";
}




こんな風に、スクリプトのパスと行番号に続いてメッセージが表示されます。

で、このスクリプトパスと行番号を出さないようにする為に、今まではひと手間かけていました。

こんな感じ。
global proc assert2()
{
    int $buf=`commandEcho -q -ln`;
    commandEcho -ln off;
    
    warning "warning:hogehoge";
    catch(`error "error:hogehoge"`);
    
    commandEcho -ln $buf;
    print "hogehoge";
    
}



commandEcho というのが Line number in errors のこと。
3行目でバッファリングしておいて一旦オフにします。
error コマンドでスクリプトが停止してしまわないように catch も使用しています。
コレを実行すると Line number in errors にチェックが入っていても、スクリプトパスと行番号が表示されなくなります。

catch のおかげで print コマンドも実行されていますね。
ま、意外と面倒です。

で、warning と error に新しく追加されたオプション。
-noContext(-n) 警告メッセージにコンテキスト情報を出さないようにできるらしい。
これを使ってみます。

global proc assert3()
{
    warning -noContext "warning:hogehoge";
    error -noContext "error:hogehoge";
    print "hogehoge";
    
}



その結果、

commandEcho の操作をしなくても行番号が表示されなくなりました!
さすがに error コマンドはスクリプトが止まってしまうので catch は使用しないと駄目ですが、便利かも。



2017年3月28日火曜日

回転順序を文字列で指定する

リグを組んでいる時、けっこう回転順序を変更したりするのですが、指定方法が数値なんですよね~。
いちいちアトリビュートを変更してログから調べたりするのは面倒です。
なので"zxy"みたいな文字列で変更するスクリプトを作成します。

trySetRotateOrder.mel
global proc trySetRotateOrder(
    string $node,                       // ノード名
    string $order )                     // 回転順序
{
    if(!`attributeExists "ro" $node`) return;
    $order=tolower( $order );
    
    int $ro;
    switch( $order )
    {
    case "xyz": $ro=0; break;
    case "yzx": $ro=1; break;
    case "zxy": $ro=2; break;
    case "xzy": $ro=3; break;
    case "yxz": $ro=4; break;
    case "zyx": $ro=5; break;
    default: $ro=-1; break;
    }
    if( $ro<0 ) return;
    
    evalEcho("setAttr "+$node+".rotateOrder "+$ro);
    
}


ノード名と回転順序を渡すと指定した回転順序を設定します。

6行目で小文字に変えているので大文字を渡すなどしても問題ないはず。

ノードに rotateOrder のアトリビュートが無かったり、回転順序が "xyz","yzx","zxy","xzy","yxz","zyx" 意外だと無反応です。

21行目の evalEcho は普通に eval で良いかも・・・。


2017年3月23日木曜日

Doxygenでローカルプロシージャを隠す

Doxygenの特殊コマンドを眺めていてローカルプロシージャを隠せそうなコマンドを見つけたのでテスト。

ローカルプロシージャを使っているMELのサンプルは、カーブポイントの座標を表示するのスクリプトを使ってみます。

使うコマンドは@private
保護レベルをサポートしていない言語向けのコマンドらしいです。

proc string _round(
       int $digit,                      //!< 区切る桁数
    string $mode,                       //!< 出力モード
     float $value )                     //!< 区切る値
/**************************************************************************//**
    @private
    @brief 指定の桁数で四捨五入する。
    @return 四捨五入  [string型] を返す。
 ******************************************************************************/
{
    float $mlt=pow( 10, $digit );

tryPrintCurvePointPositions.melから抜粋

こんな感じで、隠したいプロシージャに記述しておくと、
こんな風に、出力されたドキュメントには _round() のローカルプロシージャが表示されなくなります。
このコマンドが書かれているブロック単位で消してくれるようですね。


で、リファクタリングなんかする場合にはローカルプロシージャも確認したくなるので、そんな時には Export - Build の EXTRACT_PRIVATE にチェックを入れて出力します。

すると今度は、こんな感じでローカルプロシージャも見えるようになります。

この _round の詳解を見てみると・・・
[private]のアイコンが追加されています。
なかなか良いんじゃないでしょうか。

このほかに @defgroup と @{ @} を使った方法も試してみましたが、こちらは挙動が安定しないみたいで出力結果が安定しませんでした。

余計なことせず @private を使うのが手っ取り早いようです。


2017年3月16日木曜日

uiConfigrationScriptNodeを無効化する

uiConfigrationScriptNode を作らせないようなスクリプトとか作らない方法とかを記事にしてみたりもしましたが、九条バリアは余裕で突破されてしまいます。FAQです。


なので最近はもっぱら積極的防衛に切りかえています。

まず、uiConfigrationScriptNode というのは当たり前ですがScriptNodeの一種です。
で、File Open ダイアログの右側を見てみると General Options に、こんなチェックボックスがあります。

初期状態ではココにチェックが入っていて、スクリプトノードを実行するようになっているのです。その為 uiConfigrationScriptNodeに記述されているスクリプトが実行されてしまう訳なのですね。チェックを外せば uiConfigrationScriptNode に何が書かれていようとも実行されないと云う案配。

平和な日常を獲得できたかに思えますが、ひとつ問題がっ!

mayaが常時保存しているスクリプトノードに sceneConfigrationScriptNode というものが存在します。これが何かというと、タイムスライダーのレンジを復旧させるコマンドが記述されているスクリプトノードなのです。
Execute script nodesを無効にするとタイムスライダーのレンジが復旧されなくなってしまうのですわ。アニメータとして、これはかなりの痛手です。

 uiConfigrationScriptNode は実行させたくないけど sceneConfigurationScriptNode は動作して欲しいアンビバレントな心境。

ここは、sceneConfigurationScriptNode を復帰させるスクリプトで回避しようと思います。

global proc tryRecoverSceneConfiguration()
{
    string $scNode[]=`ls -typ "script" "*sceneConfigurationScriptNode*"`;
    if( 1==`size $scNode` )
    {
        string $cmd=`scriptNode -q -bs $scNode[0]`;
        if(""!=$cmd) evalEcho( $cmd );
        
    }
    
}

referenceしていた場合、sceneConfigurationScriptNodeが複数リストされてしまうので、カレントシーンのスクリプトノードだけを拾うようにするのがミソ。

単体実行でも良いですが、maya 起動時に
scriptJob -event "SceneOpened" tryRecoverSceneConfiguration;

とすることで使い勝手が良くなります。

2017年2月27日月曜日

SVNの更新

SVNの更新をするとき、普通の人はフォルダを右クリックして、コンテキストメニューから更新していると思います。
こんな感じで。


で、毎日、何回も更新しているとフォルダを開いて右クリックするのが面倒になるわけです。

そこで、活躍するのが TortoiseProc.exe のショートカット。
まず、Tortoiseをインストールしたフォルダを開き、コンテキストメニュー「送る」から「デスクトップ(ショートカットを作成)」


作ったショートカットのプロパティを開いて、「リンク先(T):」にコマンドと更新するパスを追加します。
追加するのは
/command:update /path "更新するフォルダ"


これを、ツールバーやランチャーなんかに登録しておけばワンクリックで更新できます。

けれども、しばらくすると、登録されているファイルの数や容量の増加で更新に掛かる時間が長くなってきます。
4K時代の.psdファイルなんか100MB超えはザラですし・・・。
なので、自分の関係するフォルダのみ更新を掛けたくなってくるのです。

そんな時のための更新バッチを考察。
@echo off
title %~n0 %1

set TPROC="C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe"

:: ファイルをD&Dした場合
set PATH_LIST=%1
set COMMAND=%~x1
set COMMAND=%COMMAND:.=%

:: ファイルのD&Dが無かった場合
if ""=="%PATH_LIST%" set PATH_LIST=%~dpn0.update & set COMMAND=update
if not exist %PATH_LIST% echo "%PATH_LIST%" is Not Found. & pause & goto :EOF

:: 更新実行
for /f %%a in (%PATH_LIST%) do echo %COMMAND%: & echo "%%a" & %TPROC% /command:%COMMAND% /path:"%%a"


このバッチファイルと同じフォルダに、バッチファイルと同じ名前で拡張子が.updateというファイルに書かれているファイルやフォルダの更新を行います。

上のバッチファイル名だとtsvnExecution.updateですね。
で、.updateファイルの中身は
D:\myProjects\maya\scripts*D:\myProjects\batch

こんな感じでパスを*でつなげると更新ログが1つにまとまります。

複数行にすると行数分だけログウィンドウが出てきてしまうので要注意です。

追加機能としては、バッチファイルへドラッグアンドドロップするファイルの拡張子にTortoiseのコマンドを指定すれば、ソレを実行するようになっています。
lockとかremoveとかね。