0

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!

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
Shannon Hochkins
  • 11,763
  • 15
  • 62
  • 95
  • Why did it matter that you removed "Cheers Shannon" @NullPointer , merely thanking anyone that took the time to read it? – Shannon Hochkins Jan 13 '13 at 11:38
  • 1
    That is common practice Shannon. You should really not include that in your post. We will assume you're thankful. Have a read through [this discussion on Meta SO](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). – Bart Jan 13 '13 at 11:46
  • @ShannonHochkins Not sure it helps you much, but it's a worksforme? As in, using your code and dumping it into Maya, I get a NURBS curve in a helix, and the only warning is about history being off for the command. Are you getting a specific error with the command? – tanantish Jan 13 '13 at 13:12

2 Answers2

2

The Python interpreter will not expand your strings before calling the function (you could achieve this using eval but this is generally considered bad practice -- see this post on SO).

It should work when passing the arguments as a dict of keywords. Look it up here:

So instead of:

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

You should do

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) 

Apart from that there are a few other issues in your code:

float((360 / numPoints)) will evaluate differently in Python2.x and Python3.x. This is what happens in 2.x:

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

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

In If you wanted to ensure that floating point division is performed in your case use degrees = 360. / numPoints. The potential implications are worse in this line of your code: yOffset = float(((length / coils) / numPoints)).

You declare float and int constants just by writing them either with or without a decimal point. No need to wrap them in a call to float() or int()

Community
  • 1
  • 1
tzelleke
  • 15,023
  • 5
  • 33
  • 49
  • I know that you can declare them without wrapping them, although when the number is dynamic and is in-putted by a user and needs to be a float required by some arguments, then this is needed. – Shannon Hochkins Jan 14 '13 at 20:59
1

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.

joojaa
  • 4,354
  • 1
  • 27
  • 45
  • 3
    Maya itself is a programming language. As a rule unless you make nodes with the API bindings, you don't do a lot of direct manipulation of anything. What you do is you use the nodes which are the building blocks of Maya and make them do something for you. This way you gain more. What the later code does make a cylinder hide it make a curve on the surface of the said cylinder and copy it into normal space. I will annotate this better. The other just clarifies python syntax. – joojaa Jan 13 '13 at 20:48
  • I understand how to hook on the radius and the height/length but how can I hinge off the Coils? @joojaa – Shannon Hochkins Jan 13 '13 at 22:19
  • You make a extra attribute connect a multiply divide node to it to get the spans of the cylinder multiplied by your coil value attribute you created. Then connect the output for this the the curve on surfaces last vertex Y value. – joojaa Jan 14 '13 at 10:08
  • Thankyou @joojaa :) That's perfect! You wouldn't be able to help me with one other problem I'm having are you? http://stackoverflow.com/questions/14315215/maya-local-direction – Shannon Hochkins Jan 14 '13 at 10:24
  • I get a cycle when doing this, That's if I've done this correctly that is! http://jsfiddle.net/dAEn8/ – Shannon Hochkins Jan 15 '13 at 03:37
  • No Maya at hand. Even the code example above has been written without testing in Maya. – joojaa Jan 17 '13 at 09:36
  • Oh bummer, thankyou anyway, I have managed to get everything working but editing the amount of coils, if you could find the time that would be great but if not thanks for your help so far! – Shannon Hochkins Jan 17 '13 at 22:47