Simple python object definer

Hi all,

I am trying to get my head around this little exercise but I’m encountering different difficulties.
I am trying to write a small definer in python and my approach is the following:

Given a selection of random objects in the scene, let’s pretend sel = cmds.ls(sl = True). I am looping through it and storing an attribute created in the object previously. This is because I want to start with a template the I import in the scene and its objects contains an id e.g: id = 4

I also created a dictionary containing a definition I want to use later and that I want to update at any time in the script like:

dictionary = {0 : “l_arm”,
1 : “r_arm”,
etc
}

What I’d like to do is to match whoever object which contains an id with one of the same numbers inside the dictionary. For example my left arm control has an id =0 so then I want to assign the matching string of the dictionary to the real object which is containing that matching id. So then I can just simply select l_arm as a string??? cmds.select(‘l_arm’)

Is this approach right? Can anybody help me understanding it with some kind code example too?Some code on how to approach the coding for a definer? I’d like whitin this big procedure to output global variables for all the controls of the rig as last.

Thanks a lot in advance

couple of ways, either another dictionary with the key and values switched, or a small function that returns the key based on the value(and dictionary).
eg.

import maya.cmds as mc

# dictionary
objectNames = {0:'l_arm',1:'r_arm'}

# returns key based on value
def objectNamesId(value,dict=objectNames):
    return [k for k, v in dict.iteritems() if value == v][0]

#function use
objectNamesId('l_arm')

and i wouldnt write the controls as global vars, there are far better alternatives for this sort of thing and it can get messy to edit unless your well organised.
instead, depending on requirements, look into whether writing the dict out as a file, having it stored on a network/local for easy appending/editing etc, or perhaps on an empty node with the rig as a string (perhaps connect the rig to the node via message attr to avoid clashing/future issues etc).

Hi Lee,

Thanks a lot for getting back to me so soon. I think I got what you are doing in there with that code.I’m a bit slow and will work now on a piece of code to post in here too to check if I am doing right.
How would you store all the values in a way that dcitionary strings will becoming selectable and callable objects(controls)? Should I check throught my selection doing something like this? By doing this I store all the id that I can find in objects part of the selection previously stored.

sel = cmds.select(ls = True)

for i in range(0,len(sel),1):
id = cmds.getAttr(sel[i] + “.control_id”,asString = True)

idfound.append(id)

After doing this how can I create the list we are speaking about of selectable objects assigned to the dictionary values? Trying now as well and will try to post morer code asap

thanks :slight_smile:

Ok been trying for a while to get my head around it and trying tio follow your system of search into the dictionary

import maya.cmds as cmds
sel = cmds.ls(sl = True)

idfound = []
i = 0

myobjects = [None]*1000




for i in range(0,len(sel),1):
	if cmds.objExists(sel[i] +".ctl_id"):
		id = cmds.getAttr(sel[i] + ".ctl_id")
		myobjects.insert(id,sel[i])
		
		idfound.append(id)
		 



# dictionary
objectNames = {3:'l_arm_lower',5:'l_arm',34:'l_finger'}

# returns key based on value
def objectNamesId(value,dict=objectNames):
    return [k for k, v in dict.iteritems() if value == v][0]



#function use
selectionvalue = objectNamesId('l_arm_lower')

cmds.select(myobjects[selectionvalue] )

Is it what you meant in the previous post? I am just trying to save in a position of the array which correspond the id found in the object. So if l_arm was with id = 34 I will define the array of things to select objectlist[34] = l_arm
So then with your code I will call objects in the scene accessing names in the dictionary?

Please give me full explanation, correction or better implementation as I am really a newbie with python lol :slight_smile:

thanks a lot

ah i think i gotcha, so you would have a dictionary with id numbers (keys) and controls names (values).
each control object in your scene will have a “ctrl_id” attribute (i dont think it’ll accept underscores) and a value that would match a key in the dictionary (for eg if the setup was to get the upper parent of the selected controls, the knee and ankle controls have ctrlId of 5 - which in the dictionary is the key to the “leg_ctrl”, telling me that the upper parent of the knee and ankle control is the “leg_ctrl”).
Would that be correct?

I think that’s it… not sure if I understand right :frowning:
How do you usually define all the controls in the scene as a big list depends on id? I’d like to know the right way of doing things.It’s really my first time and wasn’t able to think of any other solution :frowning:

The main future implementation would be GUI functionality. I’d like to define all controls of the rig and depends on what I find, to connect certain button of the GUI to the objects found accordingly.

hmm, there may be better solutions if that’s the implementation your after.

It might be better to create an empty node (network node?), with an attribute for each control in your rig you want to be able to retrieve. You can then (first create) connect a new message attribute from each control to its relative attribute on the empty node.
That way you can get (and then select) any of the stored controllers from that one node by querying its attributes, which is also stored within the rig file.

No need to write any dictionaries or export any text files.

I am just throwing ideas though, I dont think I’m 100% on the same page atm, would be good to hear what other people come up with too.

hmm, I thought of using the message attribute link system before and perhaps that’s what I’ll go for… :frowning: Using dictionary and hard coding like the one we were doing above what could it be useful for? Just to have more implementation ideas :slight_smile:

Ah almost forgot…What do you mean witn network node?

Attributes is the simplest thing for this, it handles persistence and makes the data accessible using simple commands – otherwise you have to worry about updating your dictionary everytime an object is deleted, renamed or whatever.

You can quickly list objects that have an attributes with ls -o:
cmds.ls("*.myCustomAttrib", o=True) will give you all the objects with a ‘myCustomAttribute’ on them (the o=True flag returns the object names, instead of the attribs). It’s common do these sorts of things as enum attributes so you narrow to a list of objects and then use getAttrs to test for the precise kind thing you want.

Another good trick is to use sets: sets are really just a specialised kind of message connection, with a little less typing than node-linking… but with the extra ability to operations like ‘give me everything in the right_controls set and the left_controls set’ or ‘give me everything on the right side that’s not in the IK set’. The main drawback of sets is that they show up in the outliner, which can lead to clutter.

For network nodes, the whole shebang can be gotten here:

[QUOTE=Theodox;16527]Attributes is the simplest thing for this, it handles persistence and makes the data accessible using simple commands – otherwise you have to worry about updating your dictionary everytime an object is deleted, renamed or whatever.

You can quickly list objects that have an attributes with ls -o:
cmds.ls("*.myCustomAttrib", o=True) will give you all the objects with a ‘myCustomAttribute’ on them (the o=True flag returns the object names, instead of the attribs). It’s common do these sorts of things as enum attributes so you narrow to a list of objects and then use getAttrs to test for the precise kind thing you want.

Another good trick is to use sets: sets are really just a specialised kind of message connection, with a little less typing than node-linking… but with the extra ability to operations like ‘give me everything in the right_controls set and the left_controls set’ or ‘give me everything on the right side that’s not in the IK set’. The main drawback of sets is that they show up in the outliner, which can lead to clutter.

For network nodes, the whole shebang can be gotten here:

Yes! I wish I’d known the power of sets sooner. They’re like tags, and aren’t mutually exclusive. I like them better than layers because they don’t care about hierarchies / visibility. I just wish Maya had a more polished interface for 'em. (you can drag stuff INTO a set, in the outliner… but you can’t remove anything from a set there)

Thanks for the ‘ls -o’ tip. I’d just been looping through every object in the scene manually to find custom attrs.

mmm I’d like to avoid sets… nothing against them really but don’t like them particularly. I will stick to the attribute on objects :slight_smile: . As the dictionaries as told previously are not great, how would you create a tidy list of all possible types of objects and attribute? I will try to avoid the dictionary stuff I was doing, but still would love to store as a big rule sheets all types of stuff in this definer to use in some way from other functions. Going to download from the link you posted right now :slight_smile: