Dictionary help

133 views
Skip to first unread message

flaye

unread,
Oct 13, 2014, 7:32:20 PM10/13/14
to python_in...@googlegroups.com

I'd like to get your feedback to see if I'm approaching this correctly.

I'm writing an autorigger that takes care of the GUI (calling an external UI class) along with setting up the controls and attributes of the different rig elements. I've also written a limb class that accepts the selected objects from the autorigger and generates an IK/FK limb for either legs or arms.



Since both of those have basically the same setup (shoulder, elbow, wrist and hip,knee,ankle), the limb class does very similar things.

My question is: I'd like to be able to call the various rig-joints generated by the the limb class. My thought is to create a dictionary with a key identifying the limb, and the values are lists of the left and/or right IK and/or FK rig-joints that get generated.

For example (pseudocode):

From autorigger ---> pass to limb class:  lmb.prepLimb(self,"leg",legJnts,checkIK,checkFK,checkMirror)

class Limbs(object):
   
def __init__(self):
       
       
       
       
self.ikHandles=[]
       
self.IKrigJnts=[]
       
self.FKrigJnts=[]
       
self.pvPos=[]
       
       
# dictionaries
       
self.dHandles={}
       
self.dIkjnts={}
       
self.dFkjnts={}
       
self.dPvPos={}
       
       
   
   
def prepLimb(self,limbName,rigJoints,IK,FK,mirror):
       
       
       
if mirror:
           
           
#split the rigJoints list into separate sublists
           
for i,mirroredJnts in enumerate(rigJoints):
               
               
               
self.buildLimb(limbName,mirroredJnts, IK, FK)
               
       
else:
           
self.buildLimb(limbName,rigJoints, IK, FK)
           
               
       
   
def buildLimb(self,limbName,rigJoints,IK,FK):

# create the limbs


The full class is here: http://pastebin.com/skBZf4TS

I'd like to know how to get the following result in,for example, the dIkjnts dictionary:

self.dIkjnts={"leg":[[IK_L_upLeg_JNT,IK_L_knee_JNT,IK_L_ankle_JNT],[IK_R_upLeg_JNT,IK_R_knee_JNT,IK_R_ankle_JNT]],"arm":[[IK_L_shoulder_JNT,IK_L_elbow_JNT,IK_L_wrist_JNT],[IK_R_shoulder_JNT,IK_R_elbow_JNT,IK_R_wrist_JNT]]}

This way, if I have to access the relevant rig joints, I can call:

# arm setup

limb="arm"

armIkjnts=self.dIkjnts[limb]




I'm assuming that there has got to be a direct relationship between the lists and the dictionaries to be populated. It works fine if it's only, say, the legs. But as soon as the other set of limbs get generated by the limb class, the new key (i.e. "arm":) gets both the legs and the arm values.

The only way so far I found to somewhat fix this was to clear the lists, but I don't think that's the proper way.

I hope I'm explaining myself clearly. Your help and feedback is appreciated.

Justin Israel

unread,
Oct 14, 2014, 5:16:30 AM10/14/14
to python_in...@googlegroups.com
I didn't extensively examine your pastebin, but one thing that stands out is that you seem to be appending sets of lists to your ikHandles list, and then assigning that list as the value to every limbName in your dHandles dict:

self.ikHandles.append(allHandles)
self.dHandles[limbName]=self.ikHandles

And you do the same for the other lists and dicts. So each limbName ends up referencing the entirely same list, if I am reading it correctly.
Any reason to keep discreet lists and dicts instead of just dicts, where you manage the list of each dict key?

self.ikHandles = {}
...
self.ikHandles[limbName] = handles




--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/ad86e5eb-5875-4d9c-b03b-2ece26f59fa7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

flaye

unread,
Oct 14, 2014, 9:45:02 AM10/14/14
to python_in...@googlegroups.com
Hi Justin,

Thanks for that tip. So I'm guessing then I don't need to append the objects to the list?

From this:
                #self.ikHandles.append(allHandles)
               
               
# update ikHandle dictionary
               
self.dHandles[limbName]=self.ikHandles
               
               
               
self.IKrigJnts.append(IKjoints)
               
               
# update IK dictionary
               
self.dIkjnts[limbName]=self.IKrigJnts


to this?
                self.dHandles[limbName]=allHandles
               
               
             
               
self.dIkjnts[limbName]=IKjoints


Thanks,



On Tuesday, October 14, 2014 5:16:30 AM UTC-4, Justin Israel wrote:
I didn't extensively examine your pastebin, but one thing that stands out is that you seem to be appending sets of lists to your ikHandles list, and then assigning that list as the value to every limbName in your dHandles dict:

self.ikHandles.append(allHandles)
self.dHandles[limbName]=self.ikHandles

And you do the same for the other lists and dicts. So each limbName ends up referencing the entirely same list, if I am reading it correctly.
Any reason to keep discreet lists and dicts instead of just dicts, where you manage the list of each dict key?

self.ikHandles = {}
...
self.ikHandles[limbName] = handles



Eduardo Grana

unread,
Oct 14, 2014, 11:16:26 AM10/14/14
to python_in...@googlegroups.com
Hello Flaye,

Maybe a little off topic, but, still about getting and setting data for rigs

Have you cheked out what the guy from red9 is doing?



I was using some of this ideas in the past, but this guy's stuff is really polished.
Check out how he saves the data for the classes in the scene as network nodes,
and how the python classes wrap around them.
As a plus, since you can connect objects to the network node, you dont have to rely so much in node names.

Hope this is usefull
Cheers!
Eduardo




--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Eduardo Graña
www.eduardograna.com.ar

Justin Israel

unread,
Oct 14, 2014, 2:47:18 PM10/14/14
to python_in...@googlegroups.com


On 15/10/2014 2:45 AM, "flaye" <eyal...@gmail.com> wrote:
>
> Hi Justin,
>
> Thanks for that tip. So I'm guessing then I don't need to append the objects to the list?
>
> From this:
>                 #self.ikHandles.append(allHandles)
>                
>                 # update ikHandle dictionary
>                 self.dHandles[limbName]=self.ikHandles
>                
>                
>                 self.IKrigJnts.append(IKjoints)
>                
>                 # update IK dictionary
>                 self.dIkjnts[limbName]=self.IKrigJnts
>
>
> to this?
>                 self.dHandles[limbName]=allHandles
>                
>            

Pretty much, yea. Instead of trying to maintain both a list and a dictionary that just associates a name with the list... just maintain the dictionary

   
>              
>                 self.dIkjnts[limbName]=IKjoints
>
>
> Thanks,
>
>
>
> On Tuesday, October 14, 2014 5:16:30 AM UTC-4, Justin Israel wrote:
>>
>> I didn't extensively examine your pastebin, but one thing that stands out is that you seem to be appending sets of lists to your ikHandles list, and then assigning that list as the value to every limbName in your dHandles dict:
>>
>> self.ikHandles.append(allHandles)
>> self.dHandles[limbName]=self.ikHandles
>>
>> And you do the same for the other lists and dicts. So each limbName ends up referencing the entirely same list, if I am reading it correctly.
>> Any reason to keep discreet lists and dicts instead of just dicts, where you manage the list of each dict key?
>>
>> self.ikHandles = {}
>> ...
>> self.ikHandles[limbName] = handles
>>
>>
>>
>>
>>

> --
> You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

> To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/fce358ea-06a9-4467-b00a-7dc119a33cfe%40googlegroups.com.

flaye

unread,
Oct 14, 2014, 10:16:36 PM10/14/14
to python_in...@googlegroups.com


Solved it:

Tried initially
self.dHandles[limbName]=allHandles

but the dictionary kept returning only one value list.

Tried also
self.dHandles[limbName].append(allHandles)

with the same result.

Finally, got this to work like a charm:


self.dHandles.setdefault(limbName,[]).append(allHandles)



Had to do some digging, but happy with the result, and a lot cleaner than my original code. Justin, thanks again for pointing out the redundancy.

@Eduardo: Thanks for the red9 links. Great stuff indeed. I'm on purpose trying to get my own code in place. I'm writing an introductory primer on rigging for those who want to learn how to be a TD. Part of the trial and error process.
As for the message nodes, definitely something to explore, but that's a more advanced stage.


               

Justin Israel

unread,
Oct 15, 2014, 1:41:35 AM10/15/14
to python_in...@googlegroups.com
On Wed, Oct 15, 2014 at 3:16 PM, flaye <eyal...@gmail.com> wrote:


Solved it:

Tried initially
self.dHandles[limbName]=allHandles

but the dictionary kept returning only one value list.

Tried also
self.dHandles[limbName].append(allHandles)

with the same result.

Finally, got this to work like a charm:


self.dHandles.setdefault(limbName,[]).append(allHandles)


Cool. Glad you figured that out. I had thought I clarified that bit already when I was saying to first check if the key exists, and if not, set it to an empty list. But you discovered the setdefault bit anyways. Also this has been abstracted into something called "defaultdict" in the standard lib

from collections import defaultdict
d = defaultdict(list)
d['foo"].append("bar")


 

Had to do some digging, but happy with the result, and a lot cleaner than my original code. Justin, thanks again for pointing out the redundancy.

@Eduardo: Thanks for the red9 links. Great stuff indeed. I'm on purpose trying to get my own code in place. I'm writing an introductory primer on rigging for those who want to learn how to be a TD. Part of the trial and error process.
As for the message nodes, definitely something to explore, but that's a more advanced stage.


               

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages