2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MayaAdvent Calendar 2024

Day 1

motionPathノードのパラメーターを変換したい

Last updated at Posted at 2024-11-30

motionPathノードをよく使うのですが、若干こまったことがありまして。

image.png

パラメトリック長(Parametric Length)
Maya においてカーブ沿いにオブジェクトが移動するときの配置方法を指定します。パラメトリック空間とパラメトリック長の 2 つの方法があります。パラメトリック長(Parametric Length)を選択すると、パラメトリック長方法がアクティブになり、選択解除すると、パラメトリック空間方法がアクティブになります。
パラメトリック空間方法では、カーブの U パラメトリック空間における位置がマーカーによって表されます。パラメトリック長方法では、カーブの全長に対する割合(%)で位置がマーカーによって表されます。パラメトリック長方法は、割合のモード方法ともいいます。これは、パス カーブの長さの割合に基づいてパスの評価が行われるためです。
2 つの方法の違いを理解するため、パラメータ設定は均一であっても CV の間隔が均等でないカーブを考えてみます。

このパラメーター、位置をそのままで切り替えたい時がたまにありまして。
ただその場合、uValueについても変換してあげないと位置が動いてしまいます。

image.png

image.png

調査

A:Parametric Length = True (fractionMode = False)
カーブの全長に対する割合(%)

B:Parametric Length = False (fractionMode = True)
カーブ上のパラメーター位置

※アトリビュートエディタ上の値と、実際のアトリビュートの値が逆なので混乱しますね。

B に関しては、nearestPointOnCurveノードなどで取れそうな気はします。

問題はAに関してですが、
全体の長さは出せますが、カーブの始点から現在位置までの長さをどうにか求められれば・・・

困ったのでAPIを眺めます。

こんなのがありました
OpenMaya.MFnNurbsCurve.findLengthFromParam()

まさにこれですね欲していたのは。

実装

import maya.cmds as cmds
import maya.api.OpenMaya as om



def getDagNode(target):    
    try:
        sellist = om.MGlobal.getSelectionListByName(target)
        return sellist.getDagPath(0)
    except:
        return None

def getShapeFn(dagPath):
    FnShape = None

    if dagPath.hasFn(om.MFn.kMesh):
        FnShape = om.MFnMesh(dagPath)        

    elif dagPath.hasFn(om.MFn.kNurbsSurface):
        FnShape = om.MFnNurbsSurface(dagPath)

    elif dagPath.hasFn(om.MFn.kNurbsCurve):
        FnShape = om.MFnNurbsCurve(dagPath)

    return FnShape


def convertToParametricPoint(motionPath):

    inputs = cmds.listConnections(motionPath + ".geometryPath",s =True,d =False) or []

    if len(inputs) == 0:
        return
    
    curve = inputs[0]
    dagPath = getDagNode(curve)
    shapeFn = getShapeFn(dagPath)


    curMode = cmds.getAttr(motionPath + ".fractionMode")

    ## getcur
    curPosition = cmds.getAttr(motionPath + ".allCoordinates")[0]
    curParam = shapeFn.getParamAtPoint(om.MPoint(curPosition))
    curLengthParam = shapeFn.findLengthFromParam(curParam) / shapeFn.length()

    if curLengthParam > 1.0:
        curLengthParam = 1.0


    if curMode:        
        cmds.setAttr(motionPath + ".fractionMode", 0)
        cmds.setAttr(motionPath + ".uValue", curParam)

    else:        
        cmds.setAttr(motionPath + ".fractionMode", 1)
        cmds.setAttr(motionPath + ".uValue", curLengthParam)

     
    cmds.refresh()
    return
    

この状態で実行してみると

image.png

上手くいってそうですね。
もう一回実行してみると

image.png

元に戻りました!

image.png

何に使えるかはさておき、位置をキープしたまま切り替えができるようになりました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?