I am creating a simple FK controls generator but I got stuck on a part where I need to parent each offset node under control node before it. Here’s the script so far :
import maya.cmds as mc
#create variable for the selected joints
selected = mc.ls(sl=True)
#clears the selection
mc.select(cl=True)
#create empty list for the new controls
CL = []
#for the joints in selection, run the following code
for s in selected:
#create variable for the position/rotation of the joints
pos = mc.xform(s, q=True, t=True, ws=True)
rot = mc.xform(s, q=True, rotation=True, ws=True)
#create 3lvl controls and position them on top of joints
ctrl = mc.circle(n=str(s + '_ctrl'), radius=0.6,nr=(1,0,0), ch=False)
mc.group(n=str(s + '_sdk'))
offset = mc.group(n=str(s + '_offset'))
#snap the controls to the position of the joint
mc.xform(offset, translation=pos, ws=True)
mc.xform(offset, rotation=rot, ws=True)
#parent constraint joints to ctrls
mc.parentConstraint(ctrl, s)
#append offset nodes to CL
CL.append(offset)
I am fairly new to this and if you know the solution, please do your best to explain the method.
To reiterate, how do I tell Python to do this for all the controls, and in a correct order:
offsets = [......]
controls = [.....]
for offset, control in zip(offsets, controls):
cmds.parent(offset, control)
Zip takes a bunch of lists and emits one item from each of the lists every time you loop over it. Combined with python’s ability to assign multiple values this makes a nice, natiural idiom for keeping pairs of values together. In your original you are offset by one; in this case I’m assuming you can handle that when you put together the two lists. You could also do it using a slice:
for offset, control in zip(offsets[1:] , controls):
cmds.parent(offset, control)
which will zip the whole controls list but takes the 2nd and later objects in offsets
Note that zip will stop when either list runs out, so you’ll need to know how many items there are in each list and adjust accordingly.
[QUOTE=Theodox;28304]
Note that zip will stop when either list runs out, so you’ll need to know how many items there are in each list and adjust accordingly.
[/QUOTE]
If you do have lists that are different lengths, and need to exhaust both, itertools.izip_longest will let you define a default value that will be used for when the shorter one runs out.