0

有一些问题基本上是插入一堆由循环生成的标志:

def drawHelix(radius, length, coils): 
    numPoints = int(8)
    degrees = float((360 / numPoints))
    centerX = float(0)
    centerZ = float(0)
    xLoc = float(0)
    zLoc  = float(0)
    yLoc  = float(0)
    yOffset = float(((length / coils) / numPoints))
    vectorIndex = int(0)
    pointStr = ""
    knotStr = ""
    for i in range(1, (360 * coils), 20):
        t = i + degrees
        xLoc = centerX + (math.cos(t) * radius)
        zLoc = centerZ - (math.sin(t) * radius)
        pointStr = (pointStr + " p=(" + str(xLoc) + "," +  str(yLoc) + "," +  str(zLoc) + "),")
        knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")
        vectorIndex = i + 1
        yLoc = yLoc + yOffset
    print pointStr        
    spiral = cmds.curve(d=float(1.0), pointStr, knotStr)
    cmds.rebuildCurve (spiral, ch=1, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=0, kt=0, s=0, d=3, tol=0.001)
    return spiral

然后我运行:drawHelix (2.00, 3.00, 5.00)

问题是 Maya 没有将“pointStr”识别为曲线命令的标志,当我打印 pointStr 时,它确实给了我想要的东西,但在如何实际完成这项工作上却苦苦挣扎!

4

2 回答 2

2

Python 解释器在调用函数之前不会扩展您的字符串(您可以使用来实现这一点,eval但这通常被认为是不好的做法——请参阅SO 上的这篇文章)。

当将参数作为关键字的字典传递时,它应该可以工作。在这里查看:

所以而不是:

pointStr = (pointStr + " p=(" + str(xLoc) + "," +  str(yLoc) + "," +  str(zLoc) + "),")
knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")

你应该做

kwargs['d'] = 1.0
kwargs['p'] = []
for i in range(1, (360 * coils), 20):
    ...
    kwargs['p'].append((xloc, yloc, zloc))
    kwargs['k'].append(vectorIndex)

spiral = cmds.curve(**kwargs) 

除此之外,您的代码中还有一些其他问题:

float((360 / numPoints))将在 Python2.x 和 Python3.x 中进行不同的评估。这是 2.x 中发生的情况:

In [5]: float(7 / 6)
Out[5]: 1.0

In [6]: 7. / 6
Out[6]: 1.1666666666666667

如果您想确保在您的案例中执行浮点除法,请使用degrees = 360. / numPoints. 这行代码的潜在影响更糟:yOffset = float(((length / coils) / numPoints)).

您只需通过编写带或不带小数点的常量来声明float和常量。int无需将它们包装在对float()或的调用中int()

于 2013-01-13T11:44:14.297 回答
1

我想这就是你的想法:

from maya import cmds
import math
def drawHelix(radius, length, coils): 
    numPoints = int(8)
    degrees = float((360 / numPoints))
    centerX = float(0)
    centerZ = float(0)
    xLoc = float(0)
    zLoc  = float(0)
    yLoc  = float(0)
    yOffset = float(((length / float(coils)) / float(numPoints)))
    vectorIndex = int(0)
    pointStr = []
    knotStr = []
    yLoc = 0
    for i in range(1, (360 * coils), 20):
        t = i + degrees
        xLoc = centerX + (math.cos(t) * radius)
        zLoc = centerZ - (math.sin(t) * radius)
        pointStr.append((xLoc, yLoc,zLoc))
        knotStr.append(vectorIndex)
        vectorIndex = i + 1
        yLoc = yLoc + yOffset
    print pointStr        
    spiral = cmds.curve(p= pointStr, k=knotStr,d=float(1.0))
    cmds.rebuildCurve (spiral, ch=1, rpo=1, 
                       rt=0, end=1, kr=1, kcp=0, kep=0, 
                       kt=0, s=0, d=3, tol=0.001)
    return spiral

有一种更好的方法可以做到这一点。这就是你应该如何使用 Maya,使用节点来构建你的东西​​。所以这里是一个不必要的评论和冗长的版本:

from maya import cmds

def getHistoryShape(name):
    history = cmds.listHistory(name)
    filteredShape = cmds.ls(history, shapes=1)[0]
    return filteredShape 

def drawHelix(radius, length, coils): 
    cyl = cmds.cylinder( ch=True, radius=radius, ax=(0,1,0),
                         hr=float(length)/float(radius) )

    # build a curve on the cylinders surface
    crv = cmds.curveOnSurface(cyl[0], d=1, 
                              uv=[(0,0),(length, coils*4)],
                              k=[0,1]) 
    # make a duplicate that is visible 
    crv = cmds.duplicateCurve(ch=1, rn=0, local=1)

    # tell maya to ignore the cylinder as a piece of geometry
    shape = getHistoryShape(cyl[0])
    cmds.setAttr(shape+'.intermediateObject', 1)

    cmds.rename(cyl[0],'helix1')
    return crv  

现在您可以稍后更改螺旋参数,实时。您可以为用户公开参数半径、长度和线圈,以便它们可以动画。例如,请参见 Maya 工厂脚本。

于 2013-01-13T12:36:11.187 回答