0

In Maya 2015, I can get the arclen of a curve using this command:

cmds.arclen('bezier1')

But now I want to get the arclen of two points in my curve. Is there anyway to get this?

4

2 回答 2

1

Using the Maya API, you can use the MFnNurbsCurve::findLengthFromParam (Maya 2016+ only). If you need it between two points, then call this function with each parameters and subtract.

If you don't want to use the api, then the other option is create a duplicate of your original curve and use "detach" it at the needed points and then use the arclen command on that new curve to get your length. So that is another way.

Note that when detaching a curve, it appears to try to keep the curvature as close the original as possible, but this isn't exact so the length may not be the same compared to the original curve. Maybe rebuilding the curve to have more points may increase the accuracy if that is an important factor for you.

于 2016-11-09T06:15:59.940 回答
0

Using Maya's API is surely the best way to do it as @scottiedoo said, but here is a function I made when I didn't know API and which gives you the same results.

from maya import cmds

def computeCrvLength(crv, startParam = None, endParam = None):
    '''
    Compute the length of a curve between the two given UParameters. If the both
    UParameters arguments are set to None (default), will compute the length of
    the whole curve.

    Arguments:
    - crv = string; an existing nurbCurve
    - startParam = 0 <= float <= 1 or None; default = None; point parameter
      value, if not None, will compute the points only between the startPt and
      EndPt values.
    - endParam = 0 <= float <= 1 or None; default = None; point parameter
      value, if not None, will compute the points only between the startPt and
      EndPt values.

    Returns:
    - The length of the curve between the given UParameters
    - The length of the curve from its start to the startParam
    - The length of the curve from its start to the endParam
    '''

    ###### Exceptions
    if cmds.objExists(crv) == False:
        cmds.error ('The curve "%s" does\'nt exists.' % crv)

    if cmds.filterExpand (crv, sm = 9) == None:
        cmds.error ('The object "%s" is not a nurbCurve.' % crv)

    if startParam != None:
        if (0 <= startParam <= 1) == False:
            cmds.error ('The start point parameter value must be between 0 and 1.')

    if endParam != None:
        if (0 <= endParam <= 1) == False:
            cmds.error ('The end point parameter value must be between 0 and 1.')

    if (startParam == None and endParam != None) or (startParam != None and endParam == None):
        cmds.error ('The start and end points parameters must be both None or ' + 
                    'both have values.')

    if startParam != None and endParam != None:
        if endParam < startParam:
            cmds.error ('The end point parameter value cannot be less or ' + 
                        'equal to start point parameter value.')

    ###### Function
    if startParam == None and endParam == None:

        crvLength = cmds.arclen (crv, ch = False)
        distCrvToStartParam = 0
        distCrvToEndParam = crvLength

    else:

        tmpArclenDim = cmds.arcLengthDimension (cmds.listRelatives(crv, s = True)[0]
                                                + '.u[0]')
        cmds.setAttr (cmds.listRelatives(tmpArclenDim, p = True)[0] +
                      '.uParamValue', startParam)
        distCrvToStartParam = cmds.getAttr (tmpArclenDim + '.al')
        cmds.setAttr (cmds.listRelatives(tmpArclenDim, p = True)[0] +
                      '.uParamValue', endParam)
        distCrvToEndParam = cmds.getAttr (tmpArclenDim + '.al')
        cmds.delete (tmpArclenDim)
        crvLength = (distCrvToEndParam - distCrvToStartParam)

    return crvLength, distCrvToStartParam, distCrvToEndParam
于 2016-11-17T11:31:38.540 回答