2016-11-08 164 views

回答

0

使用Maya的API肯定是做@scottiedoo所說的最好的方式,但這是我在不知道API時給出的一個函數,它給了你相同的結果。

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 
1

使用Maya API,您可以使用MFnNurbsCurve::findLengthFromParam(僅適用於Maya 2016+)。如果兩點之間需要它,則用每個參數調用該函數並減去。

如果您不想使用api,那麼另一個選項是創建您的原始曲線的副本,並在需要的點使用「分離」它,然後在該新曲線上使用arclen命令來獲得您的長度。那是另一種方式。

請注意,分離曲線時,似乎嘗試儘量保持曲率儘可能接近原始值,但這並不準確,所以與原始曲線相比,長度可能不同。也許重建曲線以獲得更多點可能會提高精度,如果這對您而言是一個重要因素。

+0

感謝您的回答,所以在Maya2015中沒有這樣的api? –

+0

看着文檔,它並不是如此。你可以自己寫一個,但如果研究近似b樣條的長度,則會更復雜一些 – scottiedoo

相關問題