頂点を別オブジェクトに投射してsnap

ポリゴンを作成した後に頂点を増やした場合、法線などが歪になってしまうことがありますが、これらをスムースにするのではなく、スムースな任意の位置に配置しなおしたいと思うのが人の常。
はっきり言って、このscriptは力技過ぎてスマートさもインテリジェンスさも持ち合わせていません。
でも僕は結構使う機会が多いです・・・。

説明
選択されたpolygonVerticesを指定されたobjectに指定された軸方向から投射された位置に近いところに移動します。
第1引数 許容誤差範囲
第2引数 計算する回数のリミット
第3引数 参照すべきモデル(NURBsSurface&Curve、PolygonMesh)
第4引数 投射したい方向(-x、-y、-zの三方向が指定可能)

入力例
polygonVtxSnapToObjectsAxisArg 0.01 10 nurbsPlane1 -y;

global proc polygonVtxSnapToObjectsAxisArg(float $CHRatio,int $loopLimit,string $targetObjName,string $method){
 string $meshList[]=`filterExpand -sm 12`;
 string $vtxList[]=`filterExpand -sm 31`;
 string $locatorNames[]=`spaceLocator`;
 select $meshList;
 string $tmpList[];
 int $methodFlg;
 if($method=="-x"){
  $methodFlg=0;
 }else if($method=="-y"){
  $methodFlg=1;
 }else if($method=="-z"){
  $methodFlg=2;
 }

 if(`size $meshList`!=0){
  ConvertSelectionToVertices;
  $tmpList=`filterExpand -sm 31`;
 }
 $vtxList=`stringArrayCatenate $vtxList $tmpList`;
 $vtxList=`stringArrayRemoveDuplicates $vtxList`;
 float $tmpFL[];
 float $tmpFL2[];
 float $tmpFL3[];
 float $tmpLen;
 int $stopCount;
 select -r $targetObjName;
 select -tgl $locatorNames[0];
 geometryConstraint -weight 1;
 switch($methodFlg){
  case 0:
  for($work in $vtxList){
   $tmpFL=`pointPosition $work`;
   $tmpFL3=`pointPosition $work`;
   move $tmpFL[0] $tmpFL[1] $tmpFL[2] $locatorNames[0];
   for($stopCount=0;$stopCount<$loopLimit;$stopCount++){
    $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
    $tmpLen=`pow ($tmpFL2[0]-$tmpFL3[0]) 2`+`pow($tmpFL2[1]-$tmpFL3[1]) 2`+`pow ($tmpFL2[2]-$tmpFL3[2]) 2`;
    $tmpLen=`sqrt $tmpLen`;
    if($tmpLen<$CHRatio){
     break;
    }
    $tmpFL3={$tmpFL2[0],$tmpFL[1],$tmpFL[2]};
    move $tmpFL2[0] $tmpFL[1] $tmpFL[2] $locatorNames[0];
   }
   $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
   move $tmpFL2[0] $tmpFL2[1] $tmpFL2[2] $work;
  }
  break;
  case 1:
  for($work in $vtxList){
   $tmpFL=`pointPosition $work`;
   $tmpFL3=`pointPosition $work`;
   move $tmpFL[0] $tmpFL[1] $tmpFL[2] $locatorNames[0];
   for($stopCount=0;$stopCount<$loopLimit;$stopCount++){
    $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
    $tmpLen=`pow ($tmpFL2[0]-$tmpFL3[0]) 2`+`pow($tmpFL2[1]-$tmpFL3[1]) 2`+`pow ($tmpFL2[2]-$tmpFL3[2]) 2`;
    $tmpLen=`sqrt $tmpLen`;
    if($tmpLen<$CHRatio){
     break;
    }
    $tmpFL3={$tmpFL[0],$tmpFL2[1],$tmpFL[2]};
    move $tmpFL[0] $tmpFL2[1] $tmpFL[2] $locatorNames[0];
   }
   $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
   move $tmpFL2[0] $tmpFL2[1] $tmpFL2[2] $work;
  }
  break;
  case 2:
  for($work in $vtxList){
   $tmpFL=`pointPosition $work`;
   $tmpFL3=`pointPosition $work`;
   move $tmpFL[0] $tmpFL[1] $tmpFL[2] $locatorNames[0];
   for($stopCount=0;$stopCount<$loopLimit;$stopCount++){
    $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
    $tmpLen=`pow ($tmpFL2[0]-$tmpFL3[0]) 2`+`pow($tmpFL2[1]-$tmpFL3[1]) 2`+`pow ($tmpFL2[2]-$tmpFL3[2]) 2`;
    $tmpLen=`sqrt $tmpLen`;
    if($tmpLen<$CHRatio){
     break;
    }
    $tmpFL3={$tmpFL[0],$tmpFL[1],$tmpFL2[2]};
    move $tmpFL[0] $tmpFL[1] $tmpFL2[2] $locatorNames[0];
   }
   $tmpFL2=`getAttr ($locatorNames[0]+".translate")`;
   move $tmpFL2[0] $tmpFL2[1] $tmpFL2[2] $work;
  }
  break;
 }
 delete $locatorNames;
 clear $vtxList;
 clear $tmpList;
}

このscriptのミソはこの行です。
geometryConstraint -weight 1;
コンストレインを利用して最適な投影位置に近づけようという野望がこの一行に現れています。
また、投影する方向を指定できるようにしてありますが、軸指定をせずに一番近いところに設定したい場合は、一部改変(僕的には先祖がえり)すれば出来ますが、形状についてはよほど近い形にしてないと綺麗にならないかもしれません。

最初は物体とベクトルとの交点を求めて・・・とか考えていたのですが「そんなに高度で厳密なものが要らないのが僕の仕事」だと割り切ったらこうなりました。
でもって、一部switch処理をして無駄なコードがたくさんあるように見えますが、evalなどに渡すために分岐させて命令を作る時間がもったいないので展開してあります。

 

広告
カテゴリー: Modeling関係 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

w

%s と連携中