Recurcive square ($iteration=10, $angle=15, $offset=2)
Recurcive square ($iteration=10, $angle=15, $offset=0.2)
Recurcive square ($iteration=15, $angle=33, $offset=0.2)
Recurcive square ($iteration=8, $angle=75, $offset=0.2)
import maya.cmds as cmds
cmds.select(all=True)
cmds.delete()
def recursivesquares(iteration, angle, offset):
rotationpoint = [0,0,0]
for i in range (0, iteration, 1):
cmds.nurbsSquare(n="nurbsSquare%d" %i, sl1=10, sl2=10, c=rotationpoint, nry=1, nrz=0)
cmds.select("topnurbsSquare%d" %i)
cmds.select("nurbsSquare%d" %i)
cmds.rotate(i*angle, i*angle, i*angle, pivot=(rotationpoint))
top = 'topnurbsSquare%d' %i
topposition = cmds.pointPosition('topnurbsSquare%d.cv[0]' %i, world=True)
left = 'leftnurbsSquare%d' %i
leftposition = cmds.pointPosition('leftnurbsSquare%d.cv[0]' %i, world=True)
bottom = 'bottomnurbsSquare%d' %i
bottomposition = cmds.pointPosition('bottomnurbsSquare%d.cv[0]' %i, world=True)
right = 'rightnurbsSquare%d' %i
rightposition = cmds.pointPosition('rightnurbsSquare%d.cv[0]' %i, world=True)
cmds.squareSurface(top, right, bottom, left, n='nurbsSurface%d'%i, ct1=1, ct2=1, ct3=1, ct4=1, po=0)
rotationpoint = cmds.pointOnSurface('nurbsSurface%d'%i, u=offset, v=offset, position=True)
cmds.spaceLocator(p=rotationpoint, n="locator%d" %i)
cmds.delete('nurbsSurface%d'%i)
cmds.delete('nurbsSquare%d' %i)
cmds.curve(n='topviewnurbsSquare%d' %i, d=1, p=[(topposition[0], topposition[1], 0),(leftposition[0], leftposition[1], 0),(bottomposition[0], bottomposition[1], 0),(rightposition[0], rightposition[1], 0), (topposition[0], topposition[1], 0)] )
cmds.curve(n='frontviewnurbsSquare%d' %i, d=1, p=[(topposition[0], 0, topposition[2]),(leftposition[0], 0, leftposition[2]),(bottomposition[0], 0, bottomposition[2]),(rightposition[0], 0, rightposition[2]), (topposition[0], 0, topposition[2])] )
cmds.curve(n='sideviewnurbsSquare%d' %i, d=1, p=[(0, topposition[1], topposition[2]),(0, leftposition[1], leftposition[2]),(0, bottomposition[1], bottomposition[2]),(0, rightposition[1], rightposition[2]), (0, topposition[1], topposition[2])] )
group = cmds.group('topviewnurbsSquare%d' %i, 'frontviewnurbsSquare%d' %i, 'sideviewnurbsSquare%d' %i, 'locator%d' %i, n='Squares%d' %i)
recursivesquares(10,15,0.9)
Hi Alec,
ReplyDeleteNice try! It is interesting how you used a nurbsSquare command to get the pointOnSurface command, in order to use it as the rotation point for the next iteration. And the results are very interesting as well! But there some problems...
1) This is what we can call a "pseudo" recursive function, as it doesnt really call on itself, but relies on a loop to accomplish the recursion. It is fine, it works, but efficiency-wise (in terms of memory and computational power required), the "real" recursion is better. And it is very easy to convert your function to make it "really" recursive: take a look at you for loop, and think about what you exactly it needs in order to to iterate. In your case I guess it is a rotationPoint and the iteration number. These should be arguments to be passed to your function on the first call, and when it is called again within itself. Then all other commands would work fine and you would have a simpler, more efficient code.
2) Some parts of your code are not very flexible. Always when you start typing the same command several times in a row and with almost the same parameters (in your code in line 17-24 and 32-34), you can be sure this can be converted into a loop. Why would you want to do that if it is working this way? Well, in your case, if you want to modify, let's say, in the pointPosition command the flag world from True to False, you would have to replace it only 4 times, which is doable. But imagine if you did not have 4 repetitions, but dozens, or hundreds? Also, the risk of mistyping, or of forgetting something, also increases.
3) I guess one of the main problems here is when you hard-code the names of the curves. When you write topNurbsSquare(...), or nurbsSurface(...), you create a problem about flexibility and re-usability. If anything goes out of your controlled testing environment (your computer and your setup), it might not work. Maybe in the future you'll want to modify something and in the middle of the process you end up adding another nurbsSquare? as we know, this will make all subsequente square have a different numbering, and it will ruin your results. Or if maybe something gets a different name, or if you want to assign different names to things, this will also mess up your code, or will make all the replacement process a bit tedious. So always try to avoid hard-coding object names, by always getting these names via commands such as ls or filterExpand and storing them in lists through which you can easily iterate.
Mostly it is about good practices. Some of the things I explained above are not really needed in your function, as it appears to work the way it is. But you should take it into account as good practice. It works this way, but this is not the best way. So if you can make it cleaner, more efficient and more flexible, by adopting a few tweaks, why not? In the future if you ever get to write very complex code, this will prove very valuable if you grasp it early on the learning process.