[ mel ] 面の垂直方向にロケータを向かせる

ホントはgeometry constraintだかnormal constraintだか忘れたけど、
どっちだったかを使えば面のノーマル方向にオブジェクトを向かせられたはずなんだけど、
諸事情によりMEL書いた。

せっかくなのでコピペ。


—————————————————————————
global proc rot2crossVectorUI()
{
  string $window = “rot2crossVectorUI”;
  string $title = “rot2crossVector”;

  if( `window -q -ex $window` )
    deleteUI $window;

  window -t $title $window;
  {
    string $form, $tfbg1, $tfbg2, $tfbg3, $b1;
    $form = `formLayout -h 300`;
    {
      $tfbg1 = `textFieldButtonGrp -l “Origin ” -cat 1 “right” 0
              -cw3 60 180 40 -tx “” -bl “Pick” “tfbg_origin”`;
      $tfbg2 = `textFieldButtonGrp -l “Point1 ” -cat 1 “right” 0
              -cw3 60 180 40 -tx “” -bl “Pick” “tfbg_pt1″`;
      $tfbg3 = `textFieldButtonGrp -l “Point2 ” -cat 1 “right” 0
              -cw3 60 180 40 -tx “” -bl “Pick” “tfbg_pt2″`;
      $b1 = `button -l “Execute” -c “rot2crossVectorAddapt()” “btn_exec_rot2vect”`;

      textFieldButtonGrp -e -bc (“pickAndSetTgt( 0, \””+$tfbg1+”\”)”) $tfbg1;
      textFieldButtonGrp -e -bc (“pickAndSetTgt( 1, \””+$tfbg2+”\”)”) $tfbg2;
      textFieldButtonGrp -e -bc (“pickAndSetTgt( 1, \””+$tfbg3+”\”)”) $tfbg3;
    }
    formLayout -e
      -attachForm $tfbg1 “left” 5
      -attachForm $tfbg2 “left” 5
      -attachForm $tfbg3 “left” 5
      -attachForm $b1 “left” 5
      -attachForm $tfbg1 “right” 5
      -attachForm $tfbg2 “right” 5
      -attachForm $tfbg3 “right” 5
      -attachForm $b1 “right” 5
      -attachForm $tfbg1 “top” 5
      -attachControl $tfbg2 “top” 5 $tfbg1
      -attachControl $tfbg3 “top” 5 $tfbg2
      -attachForm $b1 “bottom” 5
      $form;
  }
  showWindow $window;
}

global proc pickAndSetTgt( int $mode, string $ctl )
{
  string $trs[], $vtxs[];
  $trs = `ls -sl -type transform`;
  $vtxs = `filterExpand -sm 31`;

  if( $trs[0] == “” && $vtxs[0] == “” )
    error “No object selected”;

  if( $mode == 0 ){
    if( $trs[0] != “” )
      textFieldButtonGrp -e -tx $trs[0] $ctl;
    else
      error “Origin must be transform object”;
  }else{
    if( $trs[0] != “” )
      textFieldButtonGrp -e -tx $trs[0] $ctl;
    else
      textFieldButtonGrp -e -tx $vtxs[0] $ctl;
  }
}

global proc rot2crossVectorAddapt()
{
  string $origin, $tgt1, $tgt2;
  $origin = `textFieldButtonGrp -q -tx “tfbg_origin”`;
  $tgt1 = `textFieldButtonGrp -q -tx “tfbg_pt1″`;
  $tgt2 = `textFieldButtonGrp -q -tx “tfbg_pt2″`;

  if( $origin == “” || $tgt1 == “” || $tgt2 == “” )
    error “set all targets to the field”;
  
  print( “// Execute : rot2corssVector( \””+$origin+”\”, \””+$tgt1+”\”, \””+$tgt2+”\” );\n ” );
  rot2crossVector( $origin, $tgt1, $tgt2 );
}

global proc rot2crossVector( string $origin, string $tgt1, string $tgt2 )
{
  string $res = `createNode transform -n “tmp”`;
  
  float $tr0[3], $tr1[3];
  vector $v1, $v2, $v3;
  $tr0 = `xform -q -ws -a -t $origin`;
  $tr1 = `xform -q -ws -a -t $tgt1`;
  $v1 = << $tr1[0]-$tr0[0], $tr1[1]-$tr0[1], $tr1[2]- $tr0[2] >>;
  $tr1 = `xform -q -ws -a -t $tgt2`;
  $v2 = << $tr1[0]-$tr0[0], $tr1[1]-$tr0[1], $tr1[2]- $tr0[2] >>;
  $v3 = cross( $v1, $v2 );
  setAttr ( $res+”.t” ) -type double3 ($tr0[0]+($v3.x)) ($tr0[1]+($v3.y)) ($tr0[2]+($v3.z));
  string $aim[] = `aimConstraint -o 0 0 0 -w 1 -aim 0 1 0 -u 1 0 0 -wut “vector” -wu 0 1 0 $res $origin`;
  delete $aim $res;
}
—————————————————————————

一部解説。
proc名にUIが付くのは、GUI付きのMELですよ、というのを明示的にするための自己ルール。
基本的にはファイル名と一緒の関数名にUIが付くようになっています。GUIスクリプトなら。
Addaptってのが付く関数も自己ルールにより導入。
これはただのラッパーで、本体の関数をGUI依存なしでも使えるようにするためにくっつけています。
これがあると移植とかその他が楽に行えて素敵です。

そういやMEL公開しますよー、なんつって全然してませんね。
もはや忘れてます。
まぁ、この程度の駄MELなんて別にいらんでしょう。
なんて言い訳してみるテスト。
いずれまとめます。いずれ。

一応使い方を簡単に。
まずorigin,pt1,pt2の3点をGUI上から選択します。
UIのボタンを使って、selectしているオブジェクトをpickしても、名前直打ちでもOKです。
このときoriginは必ずtransformである必要があります。
pt1とpt2はpolygonのvertexでもOKです。
この3点から直行ベクトルを求め、originのYをそのベクトルが重なるようにrotします。
つまりorigin、pt1、pt2からなる三角形の外積を求めて、
originのYとその結果が重なるようにしているだけです。

また気が向いたらなんかUPします。

コメントを残す

メールアドレスが公開されることはありません。