Maya プラグイン deformBySurface

社内ツール”deformBySurface"を紹介します。

Mayaにはジオメトリを変形させる様々なデフォーマが用意されていますが、APIを用いて独自のデフォーマを作ることができます。

deformBySurfaceNURBSサーフェスに沿ってジオメトリを変形させるデフォーマで、かつてのSOFTIMAGE|Dの”deformationBySurface”Houdiniの”creep SOP”と同様の機能を持ちます。

 

NURBSサーフェスはパラメトリック曲面の一種で、格子状に配置された制御点などで定義され、曲面上の点pは以下のように格子の縦横オフセットのパラメータ、uvの関数で表すことが出来ます。

mathP.gif

SurfacePuv2.png

u,vの範囲が0.0~1.0であった場合、それぞれの値を0.1ずつ変化させれば11x11=121個、0.01ずつならば101x101=10201個の点が得られます。これらの点列を基にNURBSサーフェスをポリゴンメッシュに変換することも出来ます。

一方xy平面上にある点列のx,y値を上の式のu,vに代入すれば、NURBSサーフェス上に投影された点列が得られ、xy平面の点列がNURBSサーフェス上に変換されます。

また、xy平面から垂直方向、つまりz方向に離れた点はその分をNURBSサーフェスの方線方向に移動するものとします。

NURBSサーフェス上の法線をn (|n|=1)とすればその点qは以下のように表されます。

mathP_7edc44a4.gif

surfaceNormal.png

またpにおける法線nが以下のように求められ、

mathP_m2394fb53.gif

u,vx,yを代入すると

mathP_m15b62293.gif

となり、こうして得られた点qを変形後の座標値にすれば形状は曲面上に沿うように変形されます

つまりx,y,z軸は曲面上のu,v,nに置き換わるわけです。

 

以下、XY平面上にある”DYNAMO”の文字をNURBSサーフェスに沿って変形させた例です。

SurfaceIso3.png deformBySurfAnim1.png

変形前

変形後

deformBySurfAnim30.png deformBySurfAnim80.png

X軸方向に移動

Y軸方向にも移動し、Z軸周りで回転

元のオブジェクトをx軸方向に移動すれば変形後のそれはNURBSサーフェスのu方向に、y軸ならv方向に曲面を這うように移動します。

また、NURBSサーフェスをBlendShapeSkinCluster、その他の方法で変形させれば、当然、元のオブジェクトもそれに伴って変形します。

 

deformBySurfAnim.gif

 

このデフォーマのC++ソースコードの一部を解説します。(説明のため簡略化しています。)

 

このデフォーマを作成するにはまず以下のように

MPxDeformerNode

を継承するクラス作成します。

 

class deformBySurface : public MPxDeformerNode
{
public:
					deformBySurface();
	virtual			~deformBySurface(); 
    
	virtual MStatus		deform(MDataBlock&		block,
								MItGeometry&	iter,
								const MMatrix&	mat,
								unsigned int	multiIndex);
    // 後略

そして実際に変形を行うdeformer()メソッドの中は以下のようになります。

 

MStatus deformBySurface::deform(MDataBlock &block,MItGeometry &iter,const MMatrix& mat,unsigned int multiIndex)
{
	MFnNurbsSurface surfFn // 入力NURBSサーフェス
      //中略

	for (;!iter.isDone();iter.next()) {
		MPoint inPoint = iter.position();
      
		MPoint pPoint;
		surfFn.getPointAtParam(inPoint.x,inPoint.y,pPoint);
		MVector normal = surfFn.normal(inPoint.x,inPoint.y);
        MPoint qPoint = pPoint + inPoint.z * normal;

      // 後略

surfFnはNURBSサーフェスの関数セット、inPointは元オブジェクトの頂点、getPointAtParam()はu,vを入力値として曲面上の座標値を返す関数です。

これで曲面上の点、pPointが得られ、更に法線を normal()関数で求め、pPointからnormal方向にinPoint.zの値分移動した点qPointを変形後の頂点とします。

以上がこのプラグインの概要です。

上記説明以外に元オブジェクトにオフセットを与えるための補助ロケータも導入しています。

 

このプラグインの姉妹ツールとして、オブジェクトをNURBSサーフェスではなく、NURBSカーブに沿って変形させる"deformByCurve”もあります。

deformCrvAnim.gif

以上、"deformBySurface"の紹介でした。