def createLineOfActionMenu( controls, joints ): ''' deals with adding a "draw line of action" menu to each control in the controls list. the line is drawn through the list of joints passed ''' if not joints: return if not isinstance( controls, (list, tuple) ): controls = [ controls ] joints = list( joints ) jParent = getNodeParent( joints[ 0 ] ) if jParent: joints.insert( 0, jParent ) for c in controls: cTrigger = Trigger( c ) spineConnects = [ cTrigger.connect( j ) for j in joints ] Trigger.CreateMenu( c, "draw line of action", "zooLineOfAction;\nzooLineOfAction_multi { %s } \"\";" % ', '.join( '"%%%d"'%idx for idx in spineConnects ) )
def add(src, tgt, name=None, space=None, maintainOffset=True, nodeWithParentAttr=None, skipTranslationAxes=(), skipRotationAxes=(), constraintType=CONSTRAINT_PARENT): global AXES AXES = list(AXES) if space is None: space = listRelatives(src, p=True, pa=True)[0] if nodeWithParentAttr is None: nodeWithParentAttr = src if not name: name = getNiceName(tgt) if name is None: name = camelCaseToNice(str(tgt)) #if there is an existing constraint, check to see if the target already exists in its target list - if it does, return the condition used it uses attrState(space, ('t', 'r'), lock=False) existingConstraint = findConstraint(src) if existingConstraint: constraintType = nodeType(existingConstraint) constraintFunc = getattr(cmd, constraintType) targetsOnConstraint = constraintFunc(existingConstraint, q=True, tl=True) if tgt in targetsOnConstraint: idx = targetsOnConstraint.index(tgt) aliases = constraintFunc(existingConstraint, q=True, weightAliasList=True) cons = listConnections('%s.%s' % (existingConstraint, aliases[idx]), type='condition', d=False) return cons[0] #when skip axes are specified maya doesn't handle things properly - so make sure #ALL transform channels are connected, and remove unwanted channels at the end... preT, preR = getAttr('%s.t' % space)[0], getAttr('%s.r' % space)[0] if existingConstraint: chans = CONSTRAINT_CHANNELS[constraintType] for channel, constraintAttr in zip(*chans): for axis in AXES: spaceAttr = '%s.%s%s' % (space, channel, axis) conAttr = '%s.%s%s' % (existingConstraint, constraintAttr, axis) if not isConnected(conAttr, spaceAttr): connectAttr(conAttr, spaceAttr) #get the names for the parents from the parent enum attribute cmdOptionKw = {'mo': True} if maintainOffset else {} if objExists('%s.parent' % nodeWithParentAttr): srcs, names = getSpaceTargetsNames(src) addAttr('%s.parent' % nodeWithParentAttr, e=True, enumName=':'.join(names + [name])) #if we're building a pointConstraint instead of a parent constraint AND we already #have spaces on the object, we need to turn the -mo flag off regardless of what the #user set it to, as the pointConstraint maintain offset has different behaviour to #the parent constraint if constraintType in (CONSTRAINT_POINT, CONSTRAINT_ORIENT): cmdOptionKw = {} else: addAttr(nodeWithParentAttr, ln='parent', at="enum", en=name) setAttr('%s.parent' % nodeWithParentAttr, keyable=True) #now build the constraint constraintFunction = getattr(cmd, constraintType) constraint = constraintFunction(tgt, space, **cmdOptionKw)[0] weightAliasList = constraintFunction(constraint, q=True, weightAliasList=True) targetCount = len(weightAliasList) constraintAttr = weightAliasList[-1] condition = shadingNode('condition', asUtility=True, n='%s_to_space_%s#' % (getShortName(src), getShortName(tgt))) setAttr('%s.secondTerm' % condition, targetCount - 1) setAttr('%s.colorIfTrue' % condition, 1, 1, 1) setAttr('%s.colorIfFalse' % condition, 0, 0, 0) connectAttr('%s.parent' % nodeWithParentAttr, '%s.firstTerm' % condition) connectAttr('%s.outColorR' % condition, '%s.%s' % (constraint, constraintAttr)) #find out what symbol to use to find the parent attribute parentAttrIdx = 0 if not apiExtensions.cmpNodes(space, src): parentAttrIdx = triggered.addConnect(src, nodeWithParentAttr) #add the zooObjMenu commands to the object for easy space switching Trigger.CreateMenu(src, "parent to %s" % name, ChangeSpaceCmd.Create(targetCount - 1, parentAttrIdx)) #when skip axes are specified maya doesn't handle things properly - so make sure #ALL transform channels are connected, and remove unwanted channels at the end... for axis, value in zip(AXES, preT): if axis in skipTranslationAxes: attr = '%s.t%s' % (space, axis) delete(attr, icn=True) setAttr(attr, value) for axis, value in zip(AXES, preR): if axis in skipRotationAxes: attr = '%s.r%s' % (space, axis) delete(attr, icn=True) setAttr(attr, value) #make the space node non-keyable and lock visibility attrState(space, ['t', 'r', 's'], lock=True) attrState(space, 'v', *control.HIDE) return condition