Thursday, May 14, 2009

The serpentine() function

We started the script by defining the main logic behind it, according to the diagrams posted last week.

# Basic logic
# 1) create an initial square (4 sides)
# 2) loop thorugh the sides:
# 2.1) get current line (line1)
# 2.2) get next line (line2)
# 2.3) define the percentages
# 2.4) find the point on curve
# 2.5) connect these points
# 3) After finished, select all 4 new lines and run again


As we see by this logic, what we need to run the loop each time is 4 curves through which we will loop and generate a new set of 4 lines. You can notice that as soon as we reach the initial condition, we can run the whole loop again (3): this is where recursion comes in handy.



#creating initial square
initialSquare = cmds.nurbsSquare( sl1=10, sl2=10 )
isSides = cmds.filterExpand(sm=9)
print isSides


This is how we start everything. With this command we have the 4 initial curve which make our connection loop work. Most important is that, by the way Maya created a nurbsSquare, all curves are selected in the right order on which they compose the square.



#lets connect line after line in a loop
for i in range(0, len(isSides), 1):
print i
#get the name of the current line
line1 = isSides[i]
#get the name of the following line
#but first check if we are already on the last line
#because then we have to pick back the first line
if i == len(isSides)-1:
#this means it is in the last element
#so we have to get the first curve
line2 = isSides[0]
else:
#otherwise, get next curve
line2 = isSides[i+1]

print line1, line2 #to check the line pair
#define the percentages on which to connect the lines
#this could be defined before the loop, because it is fixed
#but in case we wanted to make it variable, we need to
#define them here
perc1 = 1./2
perc2 = 1./3
#get the coordinates on the lines on the percentages
poc1 = cmds.pointOnCurve( line1, pr=perc1, top=True, p=True )
poc2 = cmds.pointOnCurve( line2, pr=perc2, top=True, p=True )
#create the curve to connect both lines
cmds.curve(ep=(poc1, poc2), d=1)


This is the basic main loop we need. Having a set of four consecutive curves selected, it works by going through each one of them and connecting them with a straight line from certain points in each line (define by percentages). By the end of this loop, we have 4 new curves, which we can use to feed the next iteration of the function.



To convert this basic part into a recursive function, we just need some small adjustments. The most important is the if/else statement after the loop which checks for the final condition. This ensures us the loop will not be infinite, and that the function will call itself again in case the end condition is still not met, creating the recursive effect we need.



#turning this into a recursive function
def serpentine(iterations):
#we assume that 4 lines are selected on stage
#and that these lines are in correct order
#this is the initial condition for the loop to work
isSides = cmds.filterExpand(sm=9)
#create a group to store the new lines
#in the end all we need is to select the group
#and we'll have the condition to run the function again
group = cmds.group( n="newCurves", em=True )
#loop through the curves in isSides
for i in range(0, len(isSides),1):
#get first curve name
line1 = isSides[i]
#get second curve name
if i == len(isSides)-1:
#this means it is in the last element
#so I have to get the first
line2 = isSides[0]
else:
#otherwise, get next element
line2 = isSides[i+1]
#print to check the pair
print line1, line2
#define the percentages
perc1 = 1./2
perc2 = 1./3
#get the coordinates on the lines
poc1 = cmds.pointOnCurve( line1, pr=perc1, top=True, p=True )
poc2 = cmds.pointOnCurve( line2, pr=perc2, top=True, p=True )
#create the curve
crv = cmds.curve( ep=(poc1, poc2), d=1 )
#put the curve in the group
cmds.parent( crv, group )

## now the recursive part
#check for the final condition
if iterations == 0:
#finished stop!
return "Done."
else:
#did not finish yet...
#remove one unit form iterations
#(coutdown)
iterations –= 1
#select the group
cmds.select( group, r=True )
#call the function again
serpentine( iterations )

Now, all you need is to create an initial square on stage, select it, and run the function, passing as a parameter the number of iterations you want it to perform.

No comments:

Post a Comment