Search code examples
pythonmaya

Maya Variable Concatenation


Having a few problems basically inserting a bunch of flags generated by a loop:

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

Which I then run with: drawHelix (2.00, 3.00, 5.00)

The problem is that Maya doesn't recognise the "pointStr" as a flag for the curve command, when I print pointStr it does give me exactly what I want, but struggling on how to actually make this work!


Solution

  • I assume this is what you had in mind:

    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
    

    There is just a way much better way to do this. This is how your supposed to use Maya, use nodes to build your stuff. So here goes, a unnecessarily commented and verbose version:

    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  
    

    Now you can change the helixes parameters later, live. You could expose the parameters radius, length and coils for the user, so they can be animated. See Maya factory scripts for example.