returns None. So you have to modify it to print a value such as follows
children = [1,2,3]
numChild = len(children)
print (numChild)
However, this does not work on my script. The script below creates a curve based on a joint chain. The script works. No errors. My question here is purely speculative.
I have 3 joints in a chain selected. It should return a value of 2. However, when I try to execute the printlen command, it runs 0 or none.
Is there something I am missing out?
children=[]
def joint_positions(j):
pos = [cmds.xform(j,q=True, t=True, ws=True)]
children = cmds.listRelatives(j, c=True) or []
for child in children:
pos.extend(joint_positions(child))
return pos
numChild = len(children)
print (numChild) #this line prints out zero. it should print out 2
joints = joint_positions('spine01_jnt')
crv = cmds.curve(d = 1, p=joints)
cmds.rebuildCurve( crv, rt=0, s=len(children), d=3 )
The code above is modified from a post in Stack Overflow
I donāt think that was the correct take-away from the first Stack Overflow post. print(len(children)) is just fine, and prints what youād expect. The print statement itself doesnāt have a return value (returns None), so if you did something like word = print('Hello') then word would have no value, but the print function would still work properly. But in Python 2.7, which Maya uses, that doesnāt matter anyway, itās a syntax errorā¦ thatās getting beside the point. I think the real take-away is about the difference between a statement returning something and printing something.
To debug this, instead of printing the length, I would just print the whole children list. print(children). In my test, your listRelatives command works, but only on the immediate child. Youāll need the allDescendents flag set to True as well.
But the real reason that your print statement prints 0 is the sequence that the commands are executed in. children is defined as empty, then your function is defined (but it hasnāt been called yet). Then you evaluate the length of children (still empty), since those statements arenāt inside the function. Then you call your function with āspine01_jntā afterwards.
Hope that helps!
Edit: Finally, Iām not sure a recursive function is necessary here, I think itās a bit overly complicated. The allDescendents flag will return a list of everything, in which case you can just iterate on the list without calling the function recursively.
You are right about number (1). I guess I was just overthinking thinking it.
With regard to (3) " the sequence that the commands are executed in. children is defined as empty, then your function is defined (but it hasnāt been called yet)"
Oh. Gotcha. That makes senses. However, I tried moving the print command after the definition is called for (i.e. after the joints = , and crv = statement)
But I still get a zero or an empty list whenever I run the print function.
This is really weird to me since the spans flag takes in number values. And it does not error out.
So I 'm wondering why Iām still not getting a 2 whenever I run the print function.
If you put the print command outside the function, even after it is called, I believe it gets into problems with the scope of the variable children. children is modified in the scope of the function, but after the function finishes, I could be wrong, but I donāt believe that the new values are accessible from outside. Someone else might be able to explain better. Put the print statement inside the function.
With respect to the spans argument, the command still works with span=0. 0 seems to be a valid number for spans (see the options box GUI).
Edit: To avoid this issue, why donāt you use the length of joints (divided by 3??) instead of children?
This - @bentrajechildren is defined outside the scope of the function, so youāll need to parse it into the function or by reference. Your returning a list of positions anyway so just get their length.
Can you not just call this:
print (len(joint_positions(j)))
If you need the children:
children=[]
def joint_positions(j, children):
# because children is a mutable list you need to
# append to it or extend it.
pos = [cmds.xform(j,q=True, t=True, ws=True)]
children.extend(cmds.listRelatives(j, c=True) or [])
for child in children:
pos.extend(joint_positions(child, children))
return pos
positions = joint_positions(j, children)
numChild = len(children)
RE: spans = 0
Yea, I didnāt realize it until you pointed it out. Hahaha. I ended going for the chalkās suggestion.
RE: To avoid this issue, why donāt you use the length of joints (divided by 3??) instead of children?
You are right! Same with chalkās response. I initially thought by ālengthā you mean the actual length of joints in the scene, but its actually the python len command. So I was not really sure how to respond at that time.
Thanks!
RE: The allDescendents flag will return a list of everything,
You are right! Will revise it accordingly. Thanks for the suggestion!