Maya プラグイン deformBySurface
社内ツール”deformBySurface"を紹介します。
Mayaにはジオメトリを変形させる様々なデフォーマが用意されていますが、APIを用いて独自のデフォーマを作ることができます。
deformBySurfaceはNURBSサーフェスに沿ってジオメトリを変形させるデフォーマで、かつてのSOFTIMAGE|3Dの”deformationBySurface”、Houdiniの”creep SOP”と同様の機能を持ちます。
NURBSサーフェスはパラメトリック曲面の一種で、格子状に配置された制御点などで定義され、曲面上の点pは以下のように格子の縦横オフセットのパラメータ、uとvの関数で表すことが出来ます。
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は以下のように表されます。
またpにおける法線nが以下のように求められ、
u,vにx,yを代入すると
となり、こうして得られた点qを変形後の座標値にすれば形状は曲面上に沿うように変形されます
つまりx,y,z軸は曲面上のu,v,nに置き換わるわけです。
以下、XY平面上にある”DYNAMO”の文字をNURBSサーフェスに沿って変形させた例です。
変形前 |
変形後 |
X軸方向に移動 |
Y軸方向にも移動し、Z軸周りで回転 |
元のオブジェクトをx軸方向に移動すれば変形後のそれはNURBSサーフェスのu方向に、y軸ならv方向に曲面を這うように移動します。
また、NURBSサーフェスをBlendShape、SkinCluster、その他の方法で変形させれば、当然、元のオブジェクトもそれに伴って変形します。
このデフォーマの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”もあります。
以上、"deformBySurface"の紹介でした。