Reputation: 12175
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!
Upvotes: 0
Views: 1103
Reputation: 4434
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.
Upvotes: 1
Reputation: 15345
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()
Upvotes: 2