def toPython(objAttr, lockAttr=False, useLockHide=False): ''' Take previously stored (pickled) data on a Maya attribute (put there via pyToAttr() ) and read it back (unpickle) to valid Python values. Arguments: objAttr : string : A valid object.attribute name in the scene. And of course, it must have already had valid Python data pickled to it. Return : some Python data : The reconstituted, unpickled Python data. ''' # Get the string representation of the pickled data. Maya attrs return # unicode vals, and cPickle wants string, so we convert: stringAttrData = str(cmd.getAttr(objAttr)) # Un-pickle the string data: loadedData = cPickle.loads(stringAttrData) if lockAttr: obj, attr = splitAttr(objAttr) lockUnlockAttr(obj, attr, 1, useLockHide) # And lock it for safety, even on read, because it will reset itself # during file opens. return loadedData
def toAttr(objAttr, data, useLockHide=False): ''' Write (pickle) Python data to the given Maya obj.attr. This data can later be read back (unpickled) via attrToPy(). Arguments: objAttr : string : a valid object.attribute name in the scene. If the object exists, but the attribute doesn't, the attribute will be added. The if the attribute already exists, it must be of type 'string', so the Python data can be written to it. data : some Python data : Data that will be pickled to the attribute ''' obj, attr = splitAttr(objAttr) # Add the attr if it doesn't exist: # if not cmd.objExists(objAttr): # Gives false positives on shape nodes, the same as getAttr if not mel.eval('attributeExists %s %s' % (attr, obj)): cmd.addAttr(obj, longName=attr, dataType='string') # Make sure it is the correct type before modifing: if cmd.getAttr(objAttr, type=True) != 'string': raise Exception("Object '%s' already has an attribute called '%s', but it isn't type 'string'" % (obj, attr)) # Pickle the data and return the corresponding string value: stringData = cPickle.dumps(data) # Make sure attr is unlocked before edit: lockUnlockAttr(obj, attr, 0, useLockHide) # Set attr to string value: cmd.setAttr(objAttr, stringData, type='string') # And lock it for safety: lockUnlockAttr(obj, attr, 1, useLockHide)
def resetAttributeState(attribute, lock=True, hide=True): ''' Resets the lock/hidden state on the given attribute. Cleanup is handled in saveAttributeState.''' node, attribute = selectedAttributes.splitAttr(attribute) attributeStates = getAttributeStates(node) if attribute in attributeStates.keys(): kwargs = {'lock': -1, 'hide': -1} if lock: kwargs['lock'] = attributeStates[attribute].initialLockState if hide: kwargs['hide'] = attributeStates[attribute].initialHideState lockHideAttribute('%s.%s' % (node, attribute), **kwargs)
def selectSimilarAttributes(detectCursor=True): """Selects the same attributes already selected on every node in the Graph Editor. When detectCursor is true, if your cursor is not over the Graph Editor, the Channel Box attributes are synced to the Graph Editor using the method syncGraphEditor(). """ # Where is the cursor? useGraphEditor, panel = selectedAttributes.isGraphEditorActive() # Select similar attributes. if useGraphEditor or not detectCursor: # Get selected nodes and attributes attributes = selectedAttributes.getGraphEditor(panel, expandObjects=False) nodes = cmd.ls(sl=1, l=1) # Clear graph editor attributes selectionConnection = selectedAttributes.getSelectionConnection(panel) cmd.selectionConnection(selectionConnection, e=1, clr=1) # Process attributes # Get the attribute part of node.attribute and separate out # selected objects. objs = [] for x in reversed(range(len(attributes))): if "." in attributes[x]: # This works for compound attributes too. Trust me. null, attributes[x] = selectedAttributes.splitAttr(attributes[x]) else: objs.append(attributes.pop(x)) attributes = list(set(attributes)) # Select the attributes on every node selected for attr in attributes: for node in nodes: try: cmd.selectionConnection(selectionConnection, edit=True, select="%s.%s" % (node, attr)) except RuntimeError: # That attribute probably didn't exist on that node. pass # reselect objects for obj in objs: cmd.selectionConnection(selectionConnection, edit=True, select=obj) else: syncGraphEditor()
def lockHideAttribute(fullAttribute, lock=-1, hide=-1, override=False): ''' Can lock, hide or unlock and unhide referenced attributes using the custom lockHideAttribute command. Assumes that all attributes are on a referenced object. Has a saftey feature in place to not unlock or unhide any previously locked or hidden attribute. The override parameter will override this, however the restoreAllAttributeStates method will erase any state saved this way on file-load. Therefore THE OVERRIDE METHOD IS ONLY AVALIABLE TO DEVELOPERS. Pass lock or hide 1 or 0 to set an attribute as locked or hidden. Pass -1 to not affect the current state. resetAttributeState and resetNodeState should be used to restore prior states. Attributes set back to their original values will be cleaned automatically. ''' node, attribute = selectedAttributes.splitAttr(fullAttribute) # Saftey check to stop unhiding or unlocking locked referenced attributes # to help maintain asset integrity. if not override: attributeStates = getAttributeStates(node) if attribute in attributeStates.keys(): if lock == 0 and attributeStates[attribute].initialLockState == 1: om.MGlobal.displayWarning(( "Lock 'n Hide: Skipping %s because it was initially " "locked. Use the override flag if you still want to " "unlock this attribute.") % fullAttribute) return if hide == 0 and attributeStates[attribute].initialHideState == 1: om.MGlobal.displayWarning(( "Lock 'n Hide: Skipping %s because it was initially " "hidden. Use the override flag if you still want to " "unhide this attribute.") % fullAttribute) return # Apply command saveAttributeState(node, attribute, lock, hide) callLockHideCommand(node, attribute, lock, hide)
def getFirstConnection(node, attribute=None, inAttr=1, outAttr=None, findAttribute=0): """An quick way to get a single object from an incoming or outgoing connection.""" if attribute is None: node, attribute = selectedAttributes.splitAttr(node) if not attribute: om.MGlobal.displayInfo( "Node %s has no attribute passed. An attribute is needed to find a connection!" % node ) if outAttr == None: outAttr = not inAttr else: inAttr = not outAttr try: nodes = cmd.listConnections("%s.%s" % (node, attribute), d=outAttr, s=inAttr, scn=1, p=findAttribute) if nodes: return nodes[0] except RuntimeError: om.MGlobal.displayWarning("%s has no attribute %s" % (node, attribute))
def toAttr(objAttr, data, useLockHide=False): ''' Write (pickle) Python data to the given Maya obj.attr. This data can later be read back (unpickled) via attrToPy(). Arguments: objAttr : string : a valid object.attribute name in the scene. If the object exists, but the attribute doesn't, the attribute will be added. The if the attribute already exists, it must be of type 'string', so the Python data can be written to it. data : some Python data : Data that will be pickled to the attribute ''' obj, attr = splitAttr(objAttr) # Add the attr if it doesn't exist: # if not cmd.objExists(objAttr): # Gives false positives on shape nodes, the same as getAttr if not mel.eval('attributeExists %s %s' % (attr, obj)): cmd.addAttr(obj, longName=attr, dataType='string') # Make sure it is the correct type before modifing: if cmd.getAttr(objAttr, type=True) != 'string': raise Exception( "Object '%s' already has an attribute called '%s', but it isn't type 'string'" % (obj, attr)) # Pickle the data and return the corresponding string value: stringData = cPickle.dumps(data) # Make sure attr is unlocked before edit: lockUnlockAttr(obj, attr, 0, useLockHide) # Set attr to string value: cmd.setAttr(objAttr, stringData, type='string') # And lock it for safety: lockUnlockAttr(obj, attr, 1, useLockHide)