Ejemplo n.º 1
0
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