<- Back

●カーブのピボットの位置を調整する


Mayaでカーブを描くと、ピボット(トランスフォームの中心)が、下図のようにXYZ座標の原点にできます。



場合によってはピボットの位置を座標の原点ではなく、カーブの最初のCVの位置とか、別の場所に設定したいことがありますよね。そのときにいちいち編集モードをコンポーネントにしてピボットを選択して移動させるのが面倒だったので、このツールを作成しました。

余談になりますが、Mayaのカーブをスクリーンキャプチャして、その画像に縮小をかけるとカーブがすごく見にくくなるんですよね。特にカーブが選択されて緑色になっていると背景のグレーに溶け込んでしまいます。CG雑誌の記事を書くときはこれでずいぶん悩みました。紙に印刷されるとほとんどカーブが見えなくなるんですよ。なのでMayaのカラーの設定を普段とは違う見えやすい色にしたりとか試してみました。今回はPhotoshopでコントラストをつけて、多少見やすくしています。デフォルトの色だとPC上でもほとんど見えなくなります。

話は逸れましたが、ピボットをカーブ上に持ってくるには、カーブ上の任意の点の座標を取得する必要があります。それには "pointOnCurve" というMELコマンドを次のような方法で使用します。

pointOnCurve -p -pr <カーブ上のポイント> <カーブ名>;

「カーブ上のポイント」とは、カーブのパラメータレンジの中での任意の値です。パラメータレンジとはUV座標の0〜1みたいなもので、カーブの始点から終点までのレンジを表しています。カーブのアトリビュートエディタを開くと赤い矢印で示した "Min Max Value" と書かれたアトリビュートがそうです。



ここにパラメータレンジの最小値・最大値が表示されています。カーブは1次元なのでパラメータレンジはひとつだけですが、Nurbsサーフェスは2次元なのでふたつあります(アトリビュートエディタで確認してみてください)。最小値はカーブの始点の値で、最大値は終点の値になります。上図では最小が0、最大が8になっていますので、カーブのちょうど真ん中の位置のパラメータは4になります。パラメータレンジはカーブのCVの数やそれまでに行った操作などによって異なるので注意が必要です。

ピボットをカーブの始点に置きたい場合は、この例ですとパラメータレンジが0の点のXYZ座標を求め、そこへピボットを移動させれば良いわけです。なのでカーブの名前が "curve1" だとすると

float $p[];
$p = `pointOnCurve -p -pr 0 curve1`;
move -a $p[0] $p[1] $p[2] curve1.rotatePivot;
move -a $p[0] $p[1] $p[2] curve1.scalePivot;
となります。ピボットには回転のピボットとスケールのピボットがありますので、その両方を移動させます。また、"pointOnCurve"はXYZの値を3ついっぺんに返すので、それを格納する変数は浮動小数点の配列かベクトル型にしなければなりません(ここでは配列を使っています)。ピボット位置をカーブの始点ではなく終点にしたい場合は、"-pr 0" のところを "-pr 8" にすれば良いわけです。

このスクリプトを核にして、GUIでインタラクティブに操作できるようにしたのが、ページの一番下にあるスクリプトです。

このスクリプトを実行すると次のようなウィンドウが出てきます。



カーブを1つセレクトしてスライダーバーを動かすと、カーブ上をインタラクティブにピボットが移動します。ツールをMove Toolにしておくとマニピュレータがカーブ上を動いていくのでわかりやすいと思います。




ちなみにスライダーバーのレンジは0〜1に固定されており、これはカーブのパラメータレンジを表しているのではありません。カーブのレンジがどんな値であれ、始点が0、終点が1になるように再計算しています。また、下にある "Move to 0" というのは、例えば "x" をオンにして "Apply" ボタンを押すと、Y、Zの座標はそのままで、Xだけが0になります。なんでこんな機能をつけたのか忘れてしまいましたが、きっと何か必要性があったのでしょう(笑)。

// LNDmoveCurvePivot.mel   by H.Hayashida
//

global proc LNDmoveCurvePivotUI() {

   global string $LNDmoveCurvePivotWin = "LNDmoveCurvePivotWin2";

   if(`window -ex $LNDmoveCurvePivotWin`) {
      deleteUI $LNDmoveCurvePivotWin;
   }

   window -t "Move Pivot" $LNDmoveCurvePivotWin;
      columnLayout c1;
         floatSliderGrp -l "Position of pivot" -v 0 -pre 3 -s 0.1 -min 0 -max 1 -f 1
                        -dc "LNDmoveCurvePivot" -cc "LNDmoveCurvePivot" fs1;
         checkBoxGrp -l "Move to 0" -ncb 3 -l1 "x" -l2 "y" -l3 "z" cb1;
         rowColumnLayout -nr 1 rc1;
            button -w 200 -l "Apply" -c "LNDmoveCurvePivotB" btn1;
            button -w 200 -l "Close" -c ("deleteUI "+$LNDmoveCurvePivotWin) btn2;
   showWindow;

}

global proc LNDmoveCurvePivot() {

   global string $LNDmoveCurvePivotWin;
   float $pos, $min, $max, $unit, $p[];
   float $pos = `floatSliderGrp -q -v ($LNDmoveCurvePivotWin+"|c1|fs1")`;
   string $selected[] = `ls -sl`;

   $min = `getAttr ($selected[0]+".minValue")`;
   $max = `getAttr ($selected[0]+".maxValue")`;

   $unit = ($max-$min)*$pos+$min;

   $p = `pointOnCurve -p -pr $unit $selected[0]`;
   
   move -a $p[0] $p[1] $p[2] ($selected[0]+".scalePivot");
   move -a $p[0] $p[1] $p[2] ($selected[0]+".rotatePivot");

}

global proc LNDmoveCurvePivotB() {

   global string $LNDmoveCurvePivotWin;

   float $x = `checkBoxGrp -q -v1 ($LNDmoveCurvePivotWin+"|c1|cb1")`;
   float $y = `checkBoxGrp -q -v2 ($LNDmoveCurvePivotWin+"|c1|cb1")`;
   float $z = `checkBoxGrp -q -v3 ($LNDmoveCurvePivotWin+"|c1|cb1")`;

   string $selected[] = `ls -sl`;

   $pos = `getAttr ($selected[0]+".translate")`;
   $ppos = `getAttr ($selected[0]+".rotatePivot")`;

   $ppos[0] = $pos[0]+$ppos[0];
   $ppos[1] = $pos[1]+$ppos[1];
   $ppos[2] = $pos[2]+$ppos[2];

   print ($ppos[0]+", "+$ppos[1]+", "+$ppos[2]+"\n");

   if($x == 1) $ppos[0] = 0;
   if($y == 1) $ppos[1] = 0;
   if($z == 1) $ppos[2] = 0;
   
   move -a $ppos[0] $ppos[1] $ppos[2] ($selected[0]+".scalePivot");
   move -a $ppos[0] $ppos[1] $ppos[2] ($selected[0]+".rotatePivot");

}

LNDmoveCurvePivotUI;



<- Back