Example #1
0
def fkChainBetweenPoints(start, end, name, bias, numCtrls=3, ctrlInterval=3):
    '''
    Creates an fk chain aligned to start finishing at end.
    :param start: beginning of the chain
    :param end: end of the chain
    :param name: prefix for newly created nodes
    :param numCtrls: number of fk ctrls to distribute along the chain
    :param bias: weight of control distribution towards start or end. Positive values favour end, negative favour start
    :param ctrlInterval: number of intermediate transforms between controls
    :return: list of ctrls
    '''
    ctrls = []
    points = coreUtils.pointsAlongVector(start, end, (numCtrls * ctrlInterval),
                                         bias)
    ctrlSize = coreUtils.getDistance(start, end)

    # get axis for control alignment
    axis = coreUtils.getDominantAxis(start, end)

    # Base
    baseCtrl = controls.circleBumpCtrl(radius=ctrlSize * .2,
                                       name='%s_base_ctrl' % name,
                                       axis=axis)
    baseBuffer = coreUtils.addParent(baseCtrl,
                                     'group',
                                     name='%s_base_buffer_srt' % name)
    coreUtils.align(baseBuffer, start)
    ctrls.append(baseCtrl)

    #FK
    for i in range(len(points)):
        num = str(i + 1).zfill(2)
        ctrlNum = str((i / ctrlInterval) + 1).zfill(2)
        c = None
        if i % ctrlInterval == 0 and i != len(points) - 1:
            c = controls.circleBumpCtrl(name='%s_%s_ctrl' % (name, ctrlNum),
                                        axis=axis,
                                        radius=ctrlSize * .1)
        else:
            c = coreUtils.pmc.group(empty=1, name='%s_%s_srt' % (name, num))
            ctrls[-1].t.connect(c.t)
            ctrls[-1].r.connect(c.r)
            ctrls[-1].s.connect(c.s)
        b = coreUtils.addParent(c,
                                'group',
                                name='%s_%s_buffer_srt' % (name, num))
        if i == 0:
            coreUtils.align(b, start)
            b.setParent(baseCtrl)
        else:
            b.t.set(points[i])
            coreUtils.align(b, start, translate=0)
            b.setParent(ctrls[-1])
        ctrls.append(c)
Example #2
0
def addCtrl(anchor, target, name, ctrlSize=1):
    '''
    adds an ik control to anchor's component
    The control will be aligned to target and attached to anchor
    :param name: name for new control e.g. 'shldr_R'
    :return: new control
    '''
    if anchor in pmc.listRelatives(getComponentGroup(anchor, 'interface'),
                                   ad=1):
        print 'anchor is is interface'
        c = controls.boxCtrl(size=ctrlSize,
                             name='%s_%s_ctrl' %
                             (getComponentFromName(anchor), name))
        b = coreUtils.addParent(
            c, 'group',
            '%s_%s_buffer_srt' % (getComponentFromName(anchor), name))
        coreUtils.align(b, target, scale=1)
        b.setParent(anchor)
        return c
    elif anchor in pmc.listRelatives(getComponentGroup(
            anchor, 'input'), ad=1) or anchor in pmc.listRelatives(
                getComponentGroup(anchor, 'rig'), ad=1):
        print 'anchor is in rig or input'
        c = controls.boxCtrl(size=ctrlSize,
                             name='%s_%s_ctrl' %
                             (getComponentFromName(anchor), name))
        b = coreUtils.addParent(
            c, 'group',
            '%s_%s_buffer_srt' % (getComponentFromName(anchor), name))
        coreUtils.align(b, target, scale=1)
        offset = coreUtils.addChild(
            anchor, 'group',
            '%s_%s_offset_srt' % (getComponentFromName(anchor), name))
        coreUtils.align(offset, b, scale=1)
        b.setParent(getComponentGroup(anchor, 'interface'))
        d = coreUtils.isDecomposed(offset)
        coreUtils.connectDecomposedMatrix(d, b)
        return c
    else:
        print 'anchor is not in rig, input or interface'
        return 'You can only attach controls to nodes in the input, interface or rig groups of a component'
Example #3
0
    def buildTwistyLimb(self, numTwistJoints):
        ctrlSize = coreUtils.getDistance(self.resultJoints[0],
                                         self.resultJoints[1]) * .25
        # Add mid ctrl
        self.midBuffer = rigObjects.orientationAverageNode(
            self.resultJoints[0], self.resultJoints[1],
            '%s_mid_buffer' % self.name)
        self.midCtrl = controls.squareCtrl(size=ctrlSize,
                                           axis='x',
                                           name='%s_mid_ctrl' % self.name)
        coreUtils.align(self.midCtrl, self.midBuffer)
        self.midCtrl.setParent(self.midBuffer)
        self.midBuffer.setParent(self.interfaceGrp)
        pmc.addAttr(self.midCtrl,
                    ln='auto_bend',
                    at='double',
                    k=1,
                    h=0,
                    minValue=0.0,
                    maxValue=1.0)
        self.ctrls.append(self.midCtrl)

        # Create twisty segments
        self.upperTwist = drTwistySegment.DrTwistySegment(
            self.fkCtrls[0],
            self.midCtrl,
            name='%sUpper_%s' %
            (self.name.split('_')[0], self.name.split('_')[1]),
            numDivisions=numTwistJoints)
        self.upperTwist.mainGrp.setParent(self.subGrp)

        self.lowerTwist = drTwistySegment.DrTwistySegment(
            self.midCtrl,
            self.fkCtrls[2],
            name='%sLower_%s' %
            (self.name.split('_')[0], self.name.split('_')[1]),
            numDivisions=numTwistJoints)
        self.lowerTwist.mainGrp.setParent(self.subGrp)

        if self.resultJoints[1].tx.get() > 0.0:
            self.lowerTwist.mainGrp.invertTwist.set(1)
            self.upperTwist.mainGrp.invertTwist.set(1)

        upperNonRoll = rigObjects.nonTwistingChild(self.resultJoints[0],
                                                   name='%s_upper' % self.name)
        componentUtils.connectIO(self.upperTwist.startIn, upperNonRoll,
                                 '%s_upperStart' % self.name)
        componentUtils.connectIO(self.upperTwist.endIn, self.midCtrl,
                                 '%s_upperEnd' % self.name)

        componentUtils.connectIO(self.lowerTwist.startIn, self.midCtrl,
                                 '%s_lowerStart' % self.name)
        componentUtils.connectIO(self.lowerTwist.endIn, self.resultJoints[2],
                                 '%s_lowerEnd' % self.name)

        self.midCtrl.auto_bend.connect(self.upperTwist.mainGrp.endAuto)
        self.midCtrl.auto_bend.connect(self.lowerTwist.mainGrp.startAuto)

        pmc.addAttr(self.settingsCtrl,
                    ln='bendyCtrls_vis',
                    at='bool',
                    k=0,
                    h=0)
        pmc.setAttr(self.settingsCtrl.bendyCtrls_vis, cb=1)
        self.settingsCtrl.bendyCtrls_vis.connect(
            self.upperTwist.mainGrp.visibility)
        self.settingsCtrl.bendyCtrls_vis.connect(
            self.lowerTwist.mainGrp.visibility)
Example #4
0
    def build(self, joints, alignIkToJointsUpAxis):

        # duplicate joints
        self.resultJoints = coreUtils.duplicateJoints(joints,
                                                      name='%s_result_XX_jnt' %
                                                      self.name)
        self.fkJoints = coreUtils.duplicateJoints(joints,
                                                  name='%s_fk_XX_jnt' %
                                                  self.name)
        self.ikJoints = coreUtils.duplicateJoints(joints,
                                                  name='%s_ik_XX_jnt' %
                                                  self.name)
        self.jointBufferGrp = coreUtils.addChild(
            self.rigGrp, 'group', '%s_jointsBuffer_srt' % self.name)
        coreUtils.align(self.jointBufferGrp, self.resultJoints[0])
        self.resultJoints[0].setParent(self.jointBufferGrp)
        self.fkJoints[0].setParent(self.jointBufferGrp)
        self.ikJoints[0].setParent(self.jointBufferGrp)

        ctrlSize = coreUtils.getDistance(self.resultJoints[0],
                                         self.resultJoints[1]) * .25

        # Orientation for controls and aim constraints
        axis = 'x'
        aimVec = (1, 0, 0)
        if self.resultJoints[1].tx.get() < 0.0:
            axis = '-x'
            aimVec = (-1, 0, 0)

        self.settingsCtrl = controls.squareChamferCtrl(
            name='%s_settings_ctrl' % self.name, size=ctrlSize * .33)
        self.settingsCtrl.setParent(self.interfaceGrp)
        pmc.addAttr(self.settingsCtrl,
                    ln='ik_fk_blend',
                    at='double',
                    k=1,
                    h=0,
                    maxValue=1.0,
                    minValue=0.0)
        settingsBuffer = coreUtils.addParent(
            self.settingsCtrl, 'group', '%s_settings_buffer_srt' % self.name)
        settingsOffset = ctrlSize * 2
        if axis == '-x':
            settingsOffset *= -1
        self.settingsCtrl.ty.set(settingsOffset)
        endSrt = coreUtils.decomposeMatrix(self.resultJoints[2].worldMatrix[0],
                                           name='%s_endWorldMtxToSrt_utl' %
                                           self.name)
        endSrt.outputTranslate.connect(settingsBuffer.t)
        endSrt.outputRotate.connect(settingsBuffer.r)
        endSrt.outputScale.connect(settingsBuffer.s)
        self.ctrls.append(self.settingsCtrl)

        # Create a dummy input to connect parts of the limb to
        self.baseInput = coreUtils.addChild(self.inputGrp,
                                            'group',
                                            name='%s_base_in_srt' % self.name)
        coreUtils.align(self.baseInput, joints[0])
        baseMtx = coreUtils.isDecomposed(self.baseInput)

        # set up blending
        for rj, ij, fj in zip(self.resultJoints, self.ikJoints, self.fkJoints):
            coreUtils.ikFkBlend(ij,
                                fj,
                                rj,
                                blendAttr='%s.ik_fk_blend' % self.settingsCtrl)

        # fk controls
        self.fkCtrlsGrp = coreUtils.addChild(self.interfaceGrp, 'group',
                                             '%s_self.fkCtrls_hrc' % self.name)
        self.settingsCtrl.ik_fk_blend.connect(self.fkCtrlsGrp.visibility)
        buffer = None
        self.fkCtrls = []
        for i in range(len(self.fkJoints) - 1):
            fj = self.fkJoints[i]
            num = str(i + 1).zfill(2)
            c = controls.circleBumpCtrl(name='%s_fk_%s_ctrl' %
                                        (self.name, num),
                                        axis=axis,
                                        radius=ctrlSize)
            coreUtils.align(c, fj)
            buffer = coreUtils.addParent(
                c, 'group', '%s_fk%s_buffer_srt' % (self.name, num))
            if i == 0:
                buffer.setParent(self.fkCtrlsGrp)
                coreUtils.connectAttrs(c, fj, ['t', 'r', 's'])
            else:
                buffer.setParent(self.fkCtrls[-1])
                m = coreUtils.decomposeLocalMatrix(c, depth=1)
                m.outputTranslate.connect(fj.t)
                m.outputScale.connect(fj.s)
                c.rotate.connect(fj.r)
            self.fkCtrls.append(c)
            self.ctrls.append(c)

        # rotate order
        for node in [
                self.fkCtrls[1], self.fkJoints[1], self.ikJoints[1],
                self.resultJoints[1]
        ]:
            node.rotateOrder.set(3)

        # ik controls
        self.ikCtrl = controls.boxCtrl(name='%s_ik_ctrl' % self.name,
                                       size=ctrlSize)
        if alignIkToJointsUpAxis:
            aimAxis = 'x'
            if pmc.xform(joints[2], q=1, t=1, ws=1) > pmc.xform(
                    joints[3], q=1, t=1, ws=1):
                aimAxis = '-x'
            elif pmc.xform(joints[2], q=1, t=1, ws=1) < pmc.xform(
                    joints[3], q=1, t=1, ws=1):
                aimAxis = 'x'
            pmc.xform(self.ikCtrl,
                      ws=1,
                      m=coreUtils.getAimMatrix(
                          start=self.resultJoints[2],
                          end=self.resultJoints[3],
                          axis=aimAxis,
                          upAxis='y',
                          worldUpAxis=alignIkToJointsUpAxis,
                          upNode=self.resultJoints[2]))
        else:
            coreUtils.align(self.ikCtrl, self.ikJoints[2], orient=0)
        self.ikCtrlsGrp = coreUtils.addChild(self.interfaceGrp, 'group',
                                             '%s_ikCtrls_hrc' % self.name)
        self.ikCtrl.setParent(self.ikCtrlsGrp)
        ikBuffer = coreUtils.addParent(self.ikCtrl, 'group',
                                       '%s_ik_buffer_srt' % self.name)
        ikFkRev = coreUtils.reverse(self.settingsCtrl.ik_fk_blend,
                                    '%s_ikFkBlendReverse_UTL' % self.name)
        ikFkRev.outputX.connect(self.ikCtrlsGrp.visibility)
        self.ctrls.append(self.ikCtrl)

        pmc.addAttr(self.ikCtrl,
                    longName='stretch',
                    at='double',
                    minValue=0,
                    maxValue=1,
                    defaultValue=0,
                    keyable=True)
        pmc.addAttr(self.ikCtrl, longName='twist', at='double', keyable=True)
        pmc.addAttr(self.ikCtrl,
                    longName='soft',
                    at='double',
                    minValue=0,
                    defaultValue=0,
                    keyable=True)
        pmc.addAttr(self.ikCtrl,
                    longName='mid_pin',
                    at='double',
                    keyable=True,
                    minValue=0,
                    maxValue=1)
        pmc.addAttr(self.ikCtrl,
                    longName='force_straight',
                    at='double',
                    keyable=True,
                    h=0,
                    minValue=0.0,
                    maxValue=1.0)

        # Soft non-stretchy IK stuff
        ik_grp = coreUtils.addChild(self.rigGrp,
                                    'group',
                                    name='%s_ik_hrc' % self.name)
        self.ikBufferGrp = coreUtils.addChild(ik_grp,
                                              'group',
                                              name='%s_ik_srt' % self.name)
        coreUtils.align(self.ikBufferGrp, self.jointBufferGrp)

        self.softBlend_loc = coreUtils.createAlignedNode(
            self.ikCtrl, 'locator', name='%s_ik_softBlend_loc' % self.name)
        self.softBlend_loc.setParent(ik_grp)

        self.ctrl_loc = coreUtils.createAlignedNode(self.ikCtrl,
                                                    'locator',
                                                    name='%s_ikCtrl_loc' %
                                                    self.name)
        self.ctrl_loc.setParent(ik_grp)
        pmc.parentConstraint(self.ikCtrl, self.ctrl_loc)

        aim_loc = coreUtils.addChild(self.ikBufferGrp,
                                     'locator',
                                     name='%s_softIkaim_loc' % self.name)
        pmc.aimConstraint(self.ctrl_loc, aim_loc, upVector=(0, 0, 0))

        btm_loc = coreUtils.createAlignedNode(self.ikCtrl,
                                              'locator',
                                              name='%s_ikBtm_loc' % self.name)
        btm_loc.setParent(aim_loc)

        chainLen = abs(self.ikJoints[1].tx.get() + self.ikJoints[2].tx.get())

        ctrlDist = coreUtils.distanceBetweenNodes(aim_loc,
                                                  self.ctrl_loc,
                                                  name='%s_ikCtrl_utl' %
                                                  self.name)
        globalScaleDiv = coreUtils.divide(1.0,
                                          baseMtx.outputScaleX,
                                          name='%s_globalScaleDiv_utl' %
                                          self.name)
        isStretchedMult = coreUtils.multiply(ctrlDist.distance,
                                             globalScaleDiv.outputX,
                                             name='%s_isStretched_utl' %
                                             self.name)

        softDist = coreUtils.distanceBetweenNodes(btm_loc,
                                                  self.softBlend_loc,
                                                  name='%s_soft_utl' %
                                                  self.name)
        stretchDist = coreUtils.distanceBetweenNodes(aim_loc,
                                                     self.softBlend_loc,
                                                     name='%s_stretch_utl' %
                                                     self.name)

        chainLenMinusSoft = coreUtils.minus([chainLen, self.ikCtrl.soft],
                                            name='%s_chainLenMinusSoft_utl' %
                                            self.name)

        isStretchedCond = pmc.createNode('condition',
                                         name='%s_isStretched_utl' % self.name)
        isStretchedCond.operation.set(2)
        isStretchedMult.outputX.connect(isStretchedCond.firstTerm)
        chainLenMinusSoft.output1D.connect(isStretchedCond.secondTerm)
        isStretchedMult.outputX.connect(isStretchedCond.colorIfFalseR)

        isSoftCond = pmc.createNode('condition',
                                    name='%s_isSoft_utl' % self.name)
        isSoftCond.operation.set(2)
        self.ikCtrl.soft.connect(isSoftCond.firstTerm)
        isSoftCond.colorIfFalseR.set(chainLen)

        ctrlDistMinusSoftChain = coreUtils.minus(
            [isStretchedMult.outputX, chainLenMinusSoft.output1D],
            name='%s_ctrlDistMinusSoftChain_utl' % self.name)

        divideBySoft = coreUtils.safeDivide(ctrlDistMinusSoftChain.output1D,
                                            self.ikCtrl.soft,
                                            name='%s_divideBySoft_utl' %
                                            self.name)

        invert = coreUtils.multiply(divideBySoft.outputX,
                                    -1,
                                    name='%s_invertSoft_utl' % self.name)

        exp = coreUtils.power(2.718282,
                              invert.outputX,
                              name='%s_exponential_utl' % self.name)

        multiplyBySoft = coreUtils.multiply(exp.outputX,
                                            self.ikCtrl.soft,
                                            name='%s_multiplyBySoft_utl' %
                                            self.name)

        minusFromChainLen = coreUtils.minus([chainLen, multiplyBySoft.outputX],
                                            name='%s_minusFromChainLen_utl' %
                                            self.name)

        minusFromChainLen.output1D.connect(isSoftCond.colorIfTrueR)

        isSoftCond.outColorR.connect(isStretchedCond.colorIfTrueR)

        isStretchedCond.outColorR.connect(btm_loc.tx)

        # IK Solvers
        ikHandleGrp = coreUtils.createAlignedNode(self.ikCtrl,
                                                  'group',
                                                  name='%s_ikHandle_srt' %
                                                  self.name)
        ikHandleGrp.setParent(self.softBlend_loc)
        pmc.orientConstraint(self.ikCtrl, ikHandleGrp, mo=1)

        ikHandle = pmc.ikHandle(solver='ikRPsolver',
                                name='%s_ikHandle' % self.name,
                                startJoint=self.ikJoints[0],
                                endEffector=self.ikJoints[2],
                                setupForRPsolver=1)[0]
        ikHandle.setParent(ikHandleGrp)
        self.ikCtrl.twist.connect(ikHandle.twist)

        endIkHandle = pmc.ikHandle(solver='ikSCsolver',
                                   name='%s_end_ikHandle' % self.name,
                                   startJoint=self.ikJoints[2],
                                   endEffector=self.ikJoints[3],
                                   setupForRPsolver=1)[0]
        endIkHandle.setParent(ikHandleGrp)

        # Pole Vector
        pvAimGrp = coreUtils.addChild(self.ikBufferGrp,
                                      'group',
                                      name='%s_pvAim_srt' % self.name)
        pmc.aimConstraint(btm_loc,
                          pvAimGrp,
                          mo=0,
                          u=(0, 0, 0),
                          aimVector=aimVec)
        self.pvCtrl = controls.crossCtrl(name='%s_pv_ctrl' % self.name,
                                         size=ctrlSize)
        poleOffset = 3
        if '-' in axis:
            poleOffset = -3
        self.pvCtrl.setParent(self.ikJoints[1])
        self.pvCtrl.t.set((0, 0, ctrlSize * poleOffset))
        self.pvCtrl.setParent(self.ikCtrlsGrp)
        self.pvBufferGrp = coreUtils.addParent(self.pvCtrl, 'group',
                                               '%s_pv_buffer_srt' % self.name)
        pmc.poleVectorConstraint(self.pvCtrl, ikHandle)
        self.ctrls.append(self.pvCtrl)

        # stretchy soft IK stuff

        pc = pmc.pointConstraint(btm_loc, self.ctrl_loc, self.softBlend_loc)
        stretchRev = coreUtils.reverse(self.ikCtrl.stretch,
                                       name='%s_stretchReverse_utl' %
                                       self.name)
        stretchRev.outputX.connect('%s.%sW0' %
                                   (pc.nodeName(), btm_loc.nodeName()))
        self.ikCtrl.stretch.connect('%s.%sW1' %
                                    (pc.nodeName(), self.ctrl_loc.nodeName()))

        scaledSoftDist = coreUtils.multiply(globalScaleDiv.outputX,
                                            softDist.distance,
                                            name='%s_scaledSoftDist_utl' %
                                            self.name)

        # Stretchy Mid
        midLen = coreUtils.multiply((self.ikJoints[1].tx.get() / chainLen),
                                    scaledSoftDist.outputX,
                                    name='%s_midLen_utl' % self.name)

        stretchMidLen = coreUtils.multiply(self.ikCtrl.stretch,
                                           midLen.outputX,
                                           name='%s_stretchMidLen_utl' %
                                           self.name)

        stretchMidLenPlusBoneLen = coreUtils.add(
            [self.ikJoints[1].tx.get(), stretchMidLen.outputX],
            name='%s_stretchMidLenPlusBoneLen_utl' % self.name)

        pinUpperDist = coreUtils.distanceBetweenNodes(self.ikBufferGrp,
                                                      self.pvCtrl,
                                                      name='%s_pinUpper_utl' %
                                                      self.name)
        pinMult = 1.0
        if '-' in axis:
            pinMult = -1.0
        pinUpper_uc = coreUtils.convert(pinUpperDist.distance,
                                        pinMult,
                                        name='%s_pinUpperDist_utk' % self.name)
        pinUpperGlobalScale = coreUtils.multiply(
            globalScaleDiv.outputX,
            pinUpper_uc.output,
            name='%s_pinUpperGlobalScale_utl' % self.name)
        pinUpperBlend = coreUtils.blend(
            input1=pinUpperGlobalScale.outputX,
            input2=stretchMidLenPlusBoneLen.output1D,
            blendAttr=self.ikCtrl.mid_pin,
            name='%s_pinUpper_utl' % self.name)

        # Stretchy Bot
        botLen = coreUtils.multiply((self.ikJoints[2].tx.get() / chainLen),
                                    scaledSoftDist.outputX,
                                    name='%s_botLen_utl' % self.name)

        stretchBotLen = coreUtils.multiply(self.ikCtrl.stretch,
                                           botLen.outputX,
                                           name='%s_stretchBotLen_utl' %
                                           self.name)

        stretchBotLenPlusBoneLen = coreUtils.add(
            [self.ikJoints[2].tx.get(), stretchBotLen.outputX],
            name='%s_stretchBotLenPlusBoneLen_utl' % self.name)

        pinLowerDist = coreUtils.distanceBetweenNodes(self.softBlend_loc,
                                                      self.pvCtrl,
                                                      name='%s_pinLower_utl' %
                                                      self.name)
        pinLower_uc = coreUtils.convert(pinLowerDist.distance,
                                        pinMult,
                                        name='%s_pinLowerDist_utl' % self.name)
        pinLowerGlobalScale = coreUtils.multiply(
            globalScaleDiv.outputX,
            pinLower_uc.output,
            name='%s_pinLowerGlobalScale_utl' % self.name)
        pinLowerBlend = coreUtils.blend(
            input1=pinLowerGlobalScale.outputX,
            input2=stretchBotLenPlusBoneLen.output1D,
            blendAttr=self.ikCtrl.mid_pin,
            name='%s_pinLower_utl' % self.name)

        # Add ability to force straight arm
        straightUpper_md = coreUtils.multiply(
            stretchDist.distance,
            self.ikJoints[1].tx.get() / chainLen,
            name='%s_midLenTimesChainLen_utl' % self.name)
        straightLower_md = coreUtils.multiply(
            stretchDist.distance,
            self.ikJoints[2].tx.get() / chainLen,
            name='%s_botLenTimesChainLen_utl' % self.name)
        straightUpperBlend = coreUtils.blend(
            input1=straightUpper_md.outputX,
            input2=pinUpperBlend.outputR,
            blendAttr=self.ikCtrl.force_straight,
            name='%s_straightUpper_utl' % self.name)
        straightLowerBlend = coreUtils.blend(
            input1=straightLower_md.outputX,
            input2=pinLowerBlend.outputR,
            blendAttr=self.ikCtrl.force_straight,
            name='%s_straightLower_utl' % self.name)
        straightUpperBlend.outputR.connect(self.ikJoints[1].tx)
        straightLowerBlend.outputR.connect(self.ikJoints[2].tx)

        # connect to base input
        d = coreUtils.isDecomposed(self.baseInput)
        coreUtils.connectDecomposedMatrix(d, self.jointBufferGrp)
        coreUtils.connectDecomposedMatrix(d, self.ikBufferGrp)

        # Add basic space switching to ik ctrl, pole vector and top fk ctrl - additional spaces can be added at any point
        pvTargets = componentUtils.addSpaceSwitch(self.pvBufferGrp,
                                                  'pv', ['limb'],
                                                  type='parent',
                                                  ctrlNode=self.pvCtrl,
                                                  targetNodes=[pvAimGrp])
        ikTargets = componentUtils.addSpaceSwitch(ikBuffer,
                                                  'ik', ['limb'],
                                                  type='parent',
                                                  ctrlNode=self.ikCtrl,
                                                  targetNodes=[self.baseInput])
        fkTargets = componentUtils.addSpaceSwitch(self.fkCtrls[0].getParent(),
                                                  'fk', ['limb'],
                                                  type='rotate',
                                                  ctrlNode=self.fkCtrls[0],
                                                  targetNodes=[self.baseInput])
        d.outputTranslate.connect(self.fkCtrls[0].getParent().t)
        d.outputScale.connect(self.fkCtrls[0].getParent().s)
Example #5
0
    def build(self,
              ankle,
              ball,
              toe,
              inner,
              outer,
              heel,
              settingsNode=None,
              blendAttr=None):
        # duplicate joints
        self.resultJoints = coreUtils.duplicateJoints([ankle, ball, toe],
                                                      name='%s_result_XX_jnt' %
                                                      self.name)
        self.fkJoints = coreUtils.duplicateJoints([ankle, ball, toe],
                                                  name='%s_fk_XX_jnt' %
                                                  self.name)
        self.ikJoints = coreUtils.duplicateJoints([ankle, ball, toe],
                                                  name='%s_ik_XX_jnt' %
                                                  self.name)

        self.resultBuffer = coreUtils.addChild(
            self.rigGrp, 'group', '%s_resultJoints_buffer_srt' % self.name)
        coreUtils.align(self.resultBuffer, self.resultJoints[0])
        self.resultJoints[0].setParent(self.resultBuffer)

        self.fkBuffer = coreUtils.addChild(
            self.rigGrp, 'group', '%s_fkJoints_buffer_srt' % self.name)
        coreUtils.align(self.fkBuffer, self.resultJoints[0])
        self.fkJoints[0].setParent(self.fkBuffer)

        self.ikBuffer = coreUtils.addChild(
            self.rigGrp, 'group', '%s_ikJoints_buffer_srt' % self.name)
        coreUtils.align(self.ikBuffer, self.resultJoints[0])
        self.ikJoints[0].setParent(self.ikBuffer)

        # set up blending
        if not blendAttr:
            pmc.addAttr(self.mainGrp,
                        ln='ik_fk_blend',
                        at='double',
                        minValue=0,
                        maxValue=1,
                        k=1,
                        h=0)
            blendAttr = self.mainGrp.ik_fk_blend
        for rj, ij, fj in zip([self.resultBuffer] + self.resultJoints,
                              [self.ikBuffer] + self.ikJoints,
                              [self.fkBuffer] + self.fkJoints):
            coreUtils.ikFkBlend(ij, fj, rj, blendAttr=blendAttr)

        ctrlSize = coreUtils.getDistance(self.resultJoints[0],
                                         self.resultJoints[1]) * .75

        # Orientation for controls and aim constraints
        axis = 'x'
        aimVec = (1, 0, 0)
        if self.resultJoints[1].tx.get() < 0.0:
            axis = '-x'
            aimVec = (-1, 0, 0)

        # FK ctrl
        self.toeCtrl = controls.circleBumpCtrl(axis='x',
                                               radius=ctrlSize,
                                               name='%s_fkToe_ctrl')
        self.toeCtrlBuffer = coreUtils.addParent(self.toeCtrl,
                                                 'group',
                                                 name='%s_fkToe_buffer_srt')
        coreUtils.align(self.toeCtrlBuffer, ball)
        self.toeCtrlBuffer.setParent(self.interfaceGrp)
        self.toeCtrl.r.connect(self.fkJoints[1].r)
        self.ctrls.append(self.toeCtrl)
        blendAttr.connect(self.toeCtrlBuffer.visibility)

        # ik Driving structure
        self.heel = coreUtils.createAlignedNode(heel, 'group',
                                                '%s_heel_srt' % self.name)
        self.heel.setParent(self.rigGrp)
        self.heelBuffer = coreUtils.addParent(self.heel, 'group',
                                              '%s_heel_buffer_srt' % self.name)

        self.toe = coreUtils.createAlignedNode(toe, 'group',
                                               '%s_toe_srt' % self.name)
        self.toe.setParent(self.heel)

        self.inner = coreUtils.createAlignedNode(inner, 'group',
                                                 '%s_inner_srt' % self.name)
        self.inner.setParent(self.toe)
        innerBuffer = coreUtils.addParent(self.inner, 'group',
                                          '%s_inner_buffer_srt' % self.name)

        self.outer = coreUtils.createAlignedNode(outer, 'group',
                                                 '%s_outer_srt' % self.name)
        self.outer.setParent(self.inner)
        outerBuffer = coreUtils.addParent(self.outer, 'group',
                                          '%s_outer_buffer_srt' % self.name)

        self.ballPivot = coreUtils.createAlignedNode(
            ball, 'group', '%s_ballPivot_srt' % self.name)
        self.ballPivot.setParent(self.outer)
        coreUtils.addParent(self.ballPivot, 'group',
                            '%s_ballPivot_buffer_srt' % self.name)

        pmc.transformLimits(self.inner, rx=(0, 0), erx=(1, 0))

        pmc.transformLimits(self.outer, rx=(0, 0), erx=(0, 1))

        self.ball = coreUtils.createAlignedNode(ball, 'group',
                                                '%s_ball_srt' % self.name)
        self.ball.setParent(self.ballPivot)
        self.ballBuffer = coreUtils.addParent(self.ball, 'group',
                                              '%s_ball_buffer_srt' % self.name)
        self.toeWiggle = coreUtils.addChild(self.ballBuffer, 'group',
                                            '%s_toeWiggle_srt' % self.name)

        componentUtils.connectIO(self.ikBuffer, self.ball, 'ball')

        # ikHandles
        ballIkHandle = pmc.ikHandle(solver='ikRPsolver',
                                    name='%s_ball_ikHandle' % self.name,
                                    startJoint=self.ikJoints[0],
                                    endEffector=self.ikJoints[1],
                                    setupForRPsolver=1)[0]
        ballIkHandle.setParent(self.ball)

        toeIkHandle = pmc.ikHandle(solver='ikRPsolver',
                                   name='%s_toe_ikHandle' % self.name,
                                   startJoint=self.ikJoints[1],
                                   endEffector=self.ikJoints[2],
                                   setupForRPsolver=1)[0]
        toeIkHandle.setParent(self.toeWiggle)

        # IK driving attributes
        if not settingsNode:
            settingsNode = self.mainGrp

        attrList = [
            'heel_roll', 'heel_pivot', 'ball_roll', 'ball_pivot', 'ball_twist',
            'ball_bend', 'toe_roll', 'toe_pivot', 'toe_twist', 'toe_wiggle',
            'toe_bend', 'edge_roll'
        ]

        pmc.addAttr(settingsNode,
                    ln='ik_foot_attributes',
                    k=0,
                    h=0,
                    at='enum',
                    enumName=' ')
        pmc.setAttr(settingsNode.ik_foot_attributes, cb=1, lock=1)

        for attr in attrList:
            pmc.addAttr(settingsNode, ln=attr, at='double', k=1, h=0)

        settingsNode.heel_roll.connect(self.heel.ry)
        settingsNode.heel_pivot.connect(self.heel.rz)
        settingsNode.ball_roll.connect(self.ball.ry)
        settingsNode.ball_pivot.connect(self.ballPivot.rz)
        settingsNode.ball_twist.connect(self.ball.rx)
        settingsNode.ball_bend.connect(self.ball.rz)
        settingsNode.toe_roll.connect(self.toe.ry)
        settingsNode.toe_pivot.connect(self.toe.rz)
        settingsNode.toe_twist.connect(self.toeWiggle.rx)
        settingsNode.toe_wiggle.connect(self.toeWiggle.ry)
        settingsNode.toe_bend.connect(self.toeWiggle.rz)
        settingsNode.edge_roll.connect(self.inner.rx)
        settingsNode.edge_roll.connect(self.outer.rx)

        # Deform joints
        self.dfmJoints = coreUtils.duplicateJoints([ankle, ball, toe],
                                                   name='%s_XX_dfm' %
                                                   self.name)
        self.dfmBufferGrp = coreUtils.addChild(
            self.deformGrp, 'group', '%s_dfmJoints_buffer_srt' % self.name)
        coreUtils.align(self.dfmBufferGrp, self.resultJoints[0])
        self.resultBuffer.t.connect(self.dfmBufferGrp.t)
        self.resultBuffer.r.connect(self.dfmBufferGrp.r)
        self.resultBuffer.s.connect(self.dfmBufferGrp.s)

        self.dfmJoints[0].setParent(self.dfmBufferGrp)
        for i in range(3):
            self.resultJoints[i].t.connect(self.dfmJoints[i].t)
            self.resultJoints[i].r.connect(self.dfmJoints[i].r)
            self.resultJoints[i].s.connect(self.dfmJoints[i].s)
Example #6
0
    def build(self, joints, numJoints, axis, upAxis, worldUpAxis, reverse,
              ctrlInterval):

        # Create curves
        positions = [pmc.xform(joint, q=1, ws=1, t=1) for joint in joints]
        self.fkCrv = curveUtils.curveThroughPoints(positions=positions,
                                                   name='%s_fkCrv' % self.name)
        self.fkCrv.setParent(self.rigGrp)

        self.ikCrv = curveUtils.curveThroughPoints(positions=positions,
                                                   name='%s_ikCrv' % self.name)
        self.ikCrv.setParent(self.rigGrp)

        # controls
        ctrlSize = coreUtils.getDistance(joints[0], joints[-1]) * .5

        #base
        self.baseCtrl = controls.hexCtrl(name='%s_base_ctrl' % self.name,
                                         axis=axis,
                                         radius=ctrlSize)
        self.baseCtrl.setParent(self.interfaceGrp)
        coreUtils.align(self.baseCtrl, joints[0])
        baseBuffer = coreUtils.addParent(self.baseCtrl,
                                         'group',
                                         name='%s_base_buffer_srt' % self.name)
        self.ctrls.append(self.baseCtrl)

        self.baseSubCtrl = controls.hexCtrl(name='%s_baseSub_ctrl' % self.name,
                                            axis=axis,
                                            radius=ctrlSize * .8)
        self.baseSubCtrl.setParent(self.baseCtrl)
        coreUtils.align(self.baseSubCtrl, joints[0])
        self.ctrls.append(self.baseSubCtrl)

        baseMtx = coreUtils.isDecomposed(self.baseSubCtrl)
        # Create offset srt so that spine can be offset from body controls
        baseSrt = coreUtils.addChild(self.rigGrp, 'group',
                                     '%s_base_srt' % self.name)
        offsetSrt = coreUtils.addChild(baseSrt, 'group',
                                       '%s_offset_srt' % self.name)
        coreUtils.connectDecomposedMatrix(baseMtx, baseSrt)
        offsetMtx = coreUtils.isDecomposed(offsetSrt)

        # settings
        self.settingsCtrl = controls.squareChamferCtrl(
            size=ctrlSize * .2, axis=axis, name='%s_settings_ctrl' % self.name)
        self.settingsCtrl.setParent(self.baseSubCtrl)
        b = coreUtils.addParent(self.settingsCtrl,
                                'group',
                                name='%s_settings_buffer_srt' % self.name)
        coreUtils.align(b, self.baseSubCtrl)
        pmc.setAttr('%s.t%s' % (b.name(), upAxis), ctrlSize * -1.5)
        self.ctrls.append(self.settingsCtrl)

        #FK
        self.fkCtrls = []
        fkOffsetSrt = coreUtils.addChild(self.baseSubCtrl, 'group',
                                         '%s_fkOffset_srt' % self.name)
        coreUtils.connectAttrs(offsetSrt, fkOffsetSrt, ['t', 'r', 's'])
        for i in range(len(joints) - 1):
            num = str(i + 1).zfill(2)
            ctrlNum = str((i / ctrlInterval) + 1).zfill(2)
            c = None
            if i % ctrlInterval == 0:
                c = controls.hexCtrl(name='%s_fk_%s_ctrl' %
                                     (self.name, ctrlNum),
                                     axis=axis,
                                     radius=ctrlSize * .5)
                self.ctrls.append(c)
            else:
                c = coreUtils.pmc.group(empty=1,
                                        name='%s_fk_%s_srt' % (self.name, num))
                self.ctrls[-1].t.connect(c.t)
                self.ctrls[-1].r.connect(c.r)
                self.ctrls[-1].s.connect(c.s)
            b = coreUtils.addParent(c,
                                    'group',
                                    name='%s_fk%s_buffer_srt' %
                                    (self.name, num))
            coreUtils.align(b, joints[i])
            if i == 0:
                b.setParent(fkOffsetSrt)
            else:
                b.setParent(self.fkCtrls[-1])
            self.fkCtrls.append(c)
        # reverse fk
        self.fkRevCtrls = []
        if reverse:
            for i in range(len(joints) - 1):
                num = str(i + 1).zfill(2)
                ctrlNum = str((i / ctrlInterval) + 1).zfill(2)
                c = None
                if i % ctrlInterval == 0:
                    c = controls.hexCtrl(name='%s_fkReverse_%s_ctrl' %
                                         (self.name, ctrlNum),
                                         axis=axis,
                                         radius=ctrlSize * .4)
                    self.ctrls.append(c)
                else:
                    c = coreUtils.pmc.group(empty=1,
                                            name='%s_fkReverse_%s_srt' %
                                            (self.name, num))
                    self.ctrls[-1].t.connect(c.t)
                    self.ctrls[-1].r.connect(c.r)
                    self.ctrls[-1].s.connect(c.s)
                b = coreUtils.addParent(c,
                                        'group',
                                        name='%s_fkReverse%s_buffer_srt' %
                                        (self.name, num))
                coreUtils.align(b, joints[len(joints) - i - 1])
                if i == 0:
                    b.setParent(self.fkCtrls[-1])
                else:
                    b.setParent(self.interfaceGrp)
                self.fkRevCtrls.append(c)

            srtList = []
            for i in range(len(self.fkRevCtrls)):
                num = str(i + 1).zfill(2)
                fkCtrl = self.fkCtrls[len(self.fkCtrls) - i - 1]
                revCtrl = self.fkRevCtrls[i]
                multMtx = None
                if i == 0:
                    multMtx = coreUtils.multiplyMatrices(
                        [
                            fkCtrl.worldMatrix[0],
                            revCtrl.parentInverseMatrix[0],
                            revCtrl.worldMatrix[0]
                        ],
                        name='%s_localFkReverseMtx%s_utl' % (self.name, num))
                    d = coreUtils.decomposeMatrix(
                        revCtrl.worldMatrix[0],
                        name='%s_localFkReverseMtx01ToSrt_utl' % self.name)
                    revCtrl.rotateOrder.connect(d.inputRotateOrder)
                    d.outputTranslate.connect(
                        self.fkCrv.controlPoints[len(joints) - 1])
                    d.outputTranslate.connect(
                        self.ikCrv.controlPoints[len(joints) - 1])
                    srtList.append(d)
                elif i == len(self.fkRevCtrls) - 1:
                    multMtx = coreUtils.multiplyMatrices(
                        [
                            offsetSrt.worldMatrix[0],
                            self.fkCtrls[len(self.fkCtrls) -
                                         i].worldInverseMatrix[0],
                            revCtrl.worldMatrix[0]
                        ],
                        name='%s_localFkReverseMtx%s_utl' % (self.name, num))
                else:
                    multMtx = coreUtils.multiplyMatrices(
                        [
                            fkCtrl.worldMatrix[0],
                            self.fkCtrls[len(self.fkCtrls) -
                                         i].worldInverseMatrix[0],
                            revCtrl.worldMatrix[0]
                        ],
                        name='%s_localFkReverseMtx%s_utl' % (self.name, num))
                d = coreUtils.decomposeMatrix(
                    multMtx.matrixSum,
                    name='%s_localFkReverseMtx%sToSrt_utl' % (self.name, num))
                self.baseCtrl.rotateOrder.connect(d.inputRotateOrder)
                if i < len(self.fkRevCtrls) - 1:
                    d.outputTranslate.connect(self.fkRevCtrls[i +
                                                              1].getParent().t)
                    d.outputRotate.connect(self.fkRevCtrls[i +
                                                           1].getParent().r)
                    d.outputScale.connect(self.fkRevCtrls[i + 1].getParent().s)
                d.outputTranslate.connect(
                    self.fkCrv.controlPoints[len(self.fkRevCtrls) - (i + 1)])
                d.outputTranslate.connect(
                    self.ikCrv.controlPoints[len(self.fkRevCtrls) - (i + 1)])
                srtList.append(d)
        else:
            srtList = []
            for i in range(len(self.fkCtrls)):
                num = str(i + 1).zfill(2)
                ctrl = self.fkCtrls[i]
                d = coreUtils.decomposeMatrix(ctrl.worldMatrix[0],
                                              name='%s_localFkMtx%sToSrt_utl' %
                                              (self.name, num))
                ctrl.rotateOrder.connect(d.inputRotateOrder)
                d.outputTranslate.connect(self.fkCrv.controlPoints[i])
                d.outputTranslate.connect(self.ikCrv.controlPoints[i])
                srtList.append(d)

        #IK
        # hip
        self.startCtrl = controls.squareCtrl(name='%s_start_ctrl' % self.name,
                                             axis=axis,
                                             size=ctrlSize)
        coreUtils.align(self.startCtrl, self.baseCtrl)
        startBuffer = coreUtils.addParent(self.startCtrl,
                                          'group',
                                          name='%s_start_buffer_srt' %
                                          self.name)
        if reverse:
            startBuffer.setParent(self.interfaceGrp)
            self.ctrls.append(self.startCtrl)
            srtList[-1].outputTranslate.connect(startBuffer.t)
            srtList[-1].outputRotate.connect(startBuffer.r)
            srtList[-1].outputScale.connect(startBuffer.s)
        else:
            startBuffer.setParent(self.baseSubCtrl)

        # end
        self.endCtrl = controls.squareCtrl(name='%s_end_ctrl' % self.name,
                                           axis=axis,
                                           size=ctrlSize)
        coreUtils.align(self.endCtrl, joints[-1])
        endBuffer = coreUtils.addParent(self.endCtrl,
                                        'group',
                                        name='%s_end_buffer_srt' % self.name)
        if reverse:
            endBuffer.setParent(self.interfaceGrp)
            self.ctrls.append(self.endCtrl)
            srtList[0].outputTranslate.connect(endBuffer.t)
            srtList[0].outputRotate.connect(endBuffer.r)
            srtList[0].outputScale.connect(endBuffer.s)
        else:
            endBuffer.setParent(self.fkCtrls[-1])
            d = coreUtils.decomposeMatrix(endBuffer.worldMatrix[0],
                                          name='%s_endMtxToSrt_utl' %
                                          self.name)
            self.endCtrl.rotateOrder.connect(d.inputRotateOrder)
            d.outputTranslate.connect(self.fkCrv.controlPoints[len(joints) -
                                                               1],
                                      f=1)
            d.outputTranslate.connect(self.ikCrv.controlPoints[len(joints) -
                                                               1],
                                      f=1)
            srtList.append(d)

        # rotate orders for ctrls
        rotateOrderDict = {'x': 0, 'y': 2, 'z': 1}
        for ctrl in self.ctrls:
            ctrl.rotateOrder.set(rotateOrderDict[axis])

        # crvInfo
        crvInfo = pmc.createNode('curveInfo',
                                 name='%s_ikCrvInfo_utl' % self.name)
        crvShape = coreUtils.getShape(self.fkCrv)
        crvShape.worldSpace[0].connect(crvInfo.inputCurve)

        # stretch
        pmc.addAttr(self.mainGrp, longName='stretch', at='double', k=0, h=1)
        restLenMD = coreUtils.multiply(crvInfo.arcLength.get(),
                                       baseMtx.outputScaleX,
                                       name='%s_restLength_utl' % self.name)
        stretchMD = coreUtils.divide(restLenMD.outputX,
                                     crvInfo.arcLength,
                                     name='%s_stretchFactor_utl' % self.name)
        stretchMD.outputX.connect(self.mainGrp.stretch)

        # ik curve skinning
        endGuideJoint = coreUtils.addChild(self.rigGrp, 'joint',
                                           '%s_endGuide_jnt' % self.name)
        endJointBuffer = coreUtils.addParent(endGuideJoint,
                                             'group',
                                             name='%s_endJnt_buffer_srt' %
                                             self.name)
        endJoint = coreUtils.addChild(endJointBuffer, 'joint',
                                      '%s_end_jnt' % self.name)
        srt = srtList[-1]
        if reverse:
            srt = srtList[0]
        srt.outputTranslate.connect(endJointBuffer.t)
        srt.outputRotate.connect(endJointBuffer.r)
        srt.outputScale.connect(endJointBuffer.s)
        self.endCtrl.t.connect(endGuideJoint.t)
        self.endCtrl.r.connect(endGuideJoint.r)
        self.endCtrl.t.connect(endJoint.t)
        self.endCtrl.r.connect(endJoint.r)

        startGuideJoint = coreUtils.addChild(self.rigGrp, 'joint',
                                             '%s_startGuide_jnt' % self.name)
        startJointBuffer = coreUtils.addParent(startGuideJoint,
                                               'group',
                                               name='%s_startJnt_buffer_srt' %
                                               self.name)
        startJoint = coreUtils.addChild(startJointBuffer, 'joint',
                                        '%s_start_jnt' % self.name)
        srt = srtList[-1]
        if not reverse:
            srt = srtList[0]
        srt.outputTranslate.connect(startJointBuffer.t)
        srt.outputRotate.connect(startJointBuffer.r)
        srt.outputScale.connect(startJointBuffer.s)
        self.startCtrl.t.connect(startGuideJoint.t)
        self.startCtrl.r.connect(startGuideJoint.r)
        self.startCtrl.t.connect(startJoint.t)
        self.startCtrl.r.connect(startJoint.r)

        jointScaleMD = coreUtils.divide(1.0,
                                        self.mainGrp.stretch,
                                        name='%s_ikJointScale_utl' % self.name)

        coreUtils.connectAttrToMany(jointScaleMD.outputX, [
            startJoint.sx, startJoint.sy, startJoint.sz, endJoint.sx,
            endJoint.sy, endJoint.sz
        ])

        guideSkin = pmc.skinCluster(endGuideJoint,
                                    startGuideJoint,
                                    self.fkCrv,
                                    dr=1)
        endJointBuffer.worldInverseMatrix[0].connect(
            guideSkin.bindPreMatrix[0])
        startJointBuffer.worldInverseMatrix[0].connect(
            guideSkin.bindPreMatrix[1])

        skin = pmc.skinCluster(endJoint, startJoint, self.ikCrv, dr=2)
        endJointBuffer.worldInverseMatrix[0].connect(skin.bindPreMatrix[0])
        startJointBuffer.worldInverseMatrix[0].connect(skin.bindPreMatrix[1])

        # create attribute on settings control to choose upAxis and avoid flipping
        enumString = ''
        axes = ['x', 'y', 'z']
        for a in axes:
            if a != axis:
                enumString += (a + ':')
        pmc.addAttr(self.settingsCtrl,
                    ln='upAxis',
                    at='enum',
                    enumName=enumString,
                    k=1,
                    h=0)
        upVecCond = pmc.createNode('condition',
                                   name='%s_upVec_utl' % self.name)
        self.settingsCtrl.upAxis.connect(upVecCond.firstTerm)
        if axis == 'x':
            upVecCond.colorIfTrue.set((0, 1, 0))
        else:
            upVecCond.colorIfTrue.set((1, 0, 0))
        if axis == 'y':
            upVecCond.colorIfFalse.set((0, 0, 1))
        else:
            upVecCond.colorIfFalse.set((0, 1, 0))

        upAxisCond = pmc.createNode('condition',
                                    name='%s_upAxis_utl' % self.name)
        self.settingsCtrl.upAxis.connect(upAxisCond.firstTerm)
        if axis == 'x':
            upAxisCond.colorIfTrueR.set(1)
        else:
            upAxisCond.colorIfTrueR.set(0)
        if axis == 'y':
            upAxisCond.colorIfFalseR.set(2)
        else:
            upAxisCond.colorIfFalseR.set(1)

        # pathNodes
        mps = curveUtils.nodesAlongCurve(crv=self.ikCrv,
                                         numNodes=numJoints,
                                         name=self.name,
                                         followAxis=axis,
                                         upNode=self.baseSubCtrl,
                                         upAxis=upAxis,
                                         upVec=worldUpAxis)
        for i in range(len(mps['mpNodes'])):
            mp = mps['mpNodes'][i]
            upVecCond.outColor.connect(mp.worldUpVector)
            upAxisCond.outColorR.connect(mp.upAxis)

            if i < numJoints / 2:
                self.startCtrl.worldMatrix[0].connect(mp.worldUpMatrix, f=1)
            else:
                self.endCtrl.worldMatrix[0].connect(mp.worldUpMatrix, f=1)
            self.baseCtrl.rotateOrder.connect(mp.rotateOrder)
        for grp in mps['grps']:
            grp.setParent(self.rigGrp)
            self.baseCtrl.rotateOrder.connect(grp.rotateOrder)

        # twisting
        self.twistReader = coreUtils.isolateTwist(
            mps['grps'][(numJoints / 2)].worldMatrix[0],
            mps['grps'][(numJoints / 2) - 1].worldInverseMatrix[0],
            name=self.name,
            axis=axis)
        twistAttr = pmc.Attribute('%s.outputRotate%s' %
                                  (self.twistReader[2].name(), axis.upper()))
        twistSrtList = []
        for i in range(numJoints / 2):
            mp = mps['mpNodes'][i]
            grp = mps['grps'][i]
            g = coreUtils.addChild(grp, 'group',
                                   grp.name().replace('grp', 'twist_srt'))
            self.baseCtrl.rotateOrder.connect(g.rotateOrder)
            baseMtx.outputScale.connect(g.s)
            uc = coreUtils.convert(twistAttr, (1.0 / (numJoints - 1)) * i,
                                   name=g.name().replace('_srt', '_utl'))
            uc.output.connect(pmc.Attribute('%s.r%s' % (g.name(), axis)))
            twistSrtList.append(g)
        for i in range(numJoints - (numJoints / 2)):
            index = i + (numJoints / 2)
            mp = mps['mpNodes'][index]
            grp = mps['grps'][index]
            g = coreUtils.addChild(grp, 'group',
                                   grp.name().replace('grp', 'twist_srt'))
            self.baseCtrl.rotateOrder.connect(g.rotateOrder)
            baseMtx.outputScale.connect(g.s)
            uc = coreUtils.convert(twistAttr, (-1.0 / (numJoints - 1)) *
                                   ((numJoints - (numJoints / 2) - i) - 1),
                                   name=g.name().replace('_srt', '_utl'))
            uc.output.connect(pmc.Attribute('%s.r%s' % (g.name(), axis)))
            twistSrtList.append(g)

        # squetch
        for i in range(numJoints):
            attr = pmc.addAttr(self.settingsCtrl,
                               longName='squetch_%s_amount' %
                               str(i + 1).zfill(2),
                               at='double',
                               k=1,
                               h=0)
            blend = coreUtils.blend(self.mainGrp.stretch,
                                    1.0,
                                    name='blend_%s_squetch_%s_UTL' %
                                    (self.name, str(i + 1).zfill(2)),
                                    blendAttr=self.settingsCtrl.attr(
                                        'squetch_%s_amount' %
                                        str(i + 1).zfill(2)))
            scaleDict = {
                'x': mps['grps'][i].sx,
                'y': mps['grps'][i].sy,
                'z': mps['grps'][i].sz
            }
            for key in scaleDict.keys():
                if key != axis:
                    blend.outputR.connect(scaleDict[key])

        # expose joints
        for i in range(numJoints):
            componentUtils.exposeDeformation(
                twistSrtList[i], '%s_%s' % (self.name, str(i + 1).zfill(2)))

        # colorize
        coreUtils.colorize('green',
                           self.fkCtrls + [self.baseCtrl, self.settingsCtrl])
        coreUtils.colorize(
            'yellow',
            self.fkRevCtrls + [self.startCtrl, self.endCtrl, self.baseSubCtrl])
Example #7
0
    def build(self, fingerDict, addTranslateJoints):
        self.baseInput = coreUtils.addChild(self.inputGrp, 'group', '%s_base_in_srt' % self.name)
        coreUtils.align(self.baseInput, fingerDict['base'])

        ctrlsGrp = coreUtils.addChild(self.interfaceGrp, 'group', '%s_ctrls_srt' % self.name)
        d = coreUtils.isDecomposed(self.baseInput)
        coreUtils.connectDecomposedMatrix(d, ctrlsGrp)

        deformGrp = coreUtils.addChild(self.deformGrp, 'group', '%s_deform_srt' % self.name)
        d = coreUtils.isDecomposed(self.baseInput)
        coreUtils.connectDecomposedMatrix(d, deformGrp)

        ctrlSize = None


        fingerKeys = [k for k in fingerDict.keys() if not k == 'base']
        for finger in fingerKeys:
            joints = []
            fingerList = fingerDict[finger]
            axis = coreUtils.getDominantAxis(fingerList[0], fingerList[1])
            if not ctrlSize:
                ctrlSize = coreUtils.getDistance(fingerList[0], fingerList[1]) * .25
            for i in range(len(fingerList)):
                guide = fingerList[i]
                num = str(i+1).zfill(2)
                c = controls.circleBumpCtrl(radius=ctrlSize, axis=axis, name='%s_%s_%s_ctrl' % (self.name, finger, num))
                coreUtils.align(c, guide)
                buffer = coreUtils.addParent(c, 'group', '%s_%s_%s_buffer_srt' % (self.name, finger, num))
                if i == 0:
                    buffer.setParent(ctrlsGrp)
                else:
                    buffer.setParent(self.ctrls[-1])
                self.ctrls.append(c)

                if addTranslateJoints:

                    b = coreUtils.addChild(deformGrp, 'group', '%s_%s_%s_dfmBuffer_srt' % (self.name, finger, num))
                    coreUtils.align(b, buffer)
                    jt = coreUtils.addChild(b, 'joint', '%s_%s_%s_translate_dfm' % (self.name, finger, num))
                    jr = coreUtils.addChild(jt, 'joint', '%s_%s_%s_rotate_dfm' % (self.name, finger, num))
                    self.ctrls[-1].t.connect(jt.t)
                    self.ctrls[-1].r.connect(jr.r)
                    self.ctrls[-1].s.connect(jr.s)

                    if i != 0:
                        b.setParent(joints[-1])
                    joints.append(jr)

                    pmc.setAttr('%s.type' % jt, 18)
                    jt.otherType.set('translateJoint')
                    pmc.setAttr('%s.type' % jr, 18)
                    jr.otherType.set('rotateJoint')
                else:
                    b = coreUtils.addChild(deformGrp, 'group', '%s_%s_%s_dfmBuffer_srt' % (self.name, finger, num))
                    coreUtils.align(b, buffer)
                    j = coreUtils.addChild(b, 'joint', '%s_%s_%s_dfm' % (self.name, finger, num))
                    self.ctrls[-1].t.connect(j.t)
                    self.ctrls[-1].r.connect(j.r)
                    self.ctrls[-1].s.connect(j.s)
                    if i != 0:
                        b.setParent(joints[-1])
                    joints.append(j)
Example #8
0
    def build(self, numDivisions, start, end, addMidControls, addEndControls):
        axisDict = {0:'x', 1:'y', 2:'z'}
        ctrlSize = coreUtils.getDistance(start, end) * .25

        # create inputs - these should be connected to the nodes you wish to drive the twistSegment
        self.startIn = coreUtils.addChild(self.inputGrp, 'group', '%s_start_in_srt' % self.name)
        coreUtils.align(self.startIn, start)
        self.endIn = coreUtils.addChild(self.startIn, 'group', '%s_end_in_srt' % self.name)
        coreUtils.align(self.endIn, end)
        endTranslateList = [abs(attr.get()) for attr in [self.endIn.tx, self.endIn.ty, self.endIn.tz]]
        axis = axisDict[endTranslateList.index(max(endTranslateList))]
        upAxis = 'x'
        if axis in upAxis:
            upAxis = 'y'
        if pmc.getAttr('%s.t%s' % (self.endIn.name(), axis)) < 0.0:
            axis = '-%s' % axis
        self.endIn.setParent(self.inputGrp)

        print 'Axis = %s' % axis


        # build curve
        crv = curveUtils.curveBetweenNodes(start=self.startIn, end=self.endIn, name='%s_crv' % self.name)
        crv.setParent(self.rigGrp)

        # create attributes on main grp
        pmc.addAttr(self.mainGrp, ln='startAuto', at='double', minValue=0, maxValue=1, k=1, h=0)
        pmc.addAttr(self.mainGrp, ln='endAuto', at='double', minValue=0, maxValue=1, k=1, h=0)
        pmc.addAttr(self.mainGrp, ln='twist', at='double')
        pmc.addAttr(self.mainGrp, ln='invertTwist', at=bool, k=0, h=0)

        # world space srt of start and end
        startToSrt = coreUtils.decomposeWorldMatrix(self.startIn)
        endToSrt = coreUtils.decomposeWorldMatrix(self.endIn)

        # Vector representing direction from start to end
        cmpntVec = None
        if '-' in axis:
            cmpntVec = coreUtils.minus([startToSrt.outputTranslate, endToSrt.outputTranslate],'%s_cmpntVector_utl' % self.name)
        else:
            cmpntVec = coreUtils.minus([endToSrt.outputTranslate, startToSrt.outputTranslate], '%s_cmpntVector_utl' % self.name)


        # matrix representing cmpntVec using start as upnode
        cmpntVecNorm = coreUtils.normalizeVector(cmpntVec.output3D, name='%s_cmpntVectorNormalized_utl' % self.name)
        cmpntUpVec = coreUtils.matrixAxisToVector(self.startIn, axis=upAxis, name='%s_cmpntUpVec_utl' % self.name)
        normVec = coreUtils.cross(cmpntVecNorm.output, cmpntUpVec.output, name='%s_localNormalVec_utl' % self.name)

        orderDict = {'x': 0, 'y': 1, 'z': 2, '-x': 0, '-y': 1, '-z': 2}
        matrixList = ['', '', '']
        matrixList[orderDict[axis]] = 'X'
        matrixList[orderDict[upAxis]] = 'Y'

        localOrientMtx = pmc.createNode('fourByFourMatrix', name='%s_localOrientMatrix_utl' % self.name)
        cmpntVecNorm.outputX.connect(pmc.Attribute('%s.in%s0' % (localOrientMtx.name(), matrixList.index('X'))))
        cmpntVecNorm.outputY.connect(pmc.Attribute('%s.in%s1' % (localOrientMtx.name(), matrixList.index('X'))))
        cmpntVecNorm.outputZ.connect(pmc.Attribute('%s.in%s2' % (localOrientMtx.name(), matrixList.index('X'))))

        cmpntUpVec.outputX.connect(pmc.Attribute('%s.in%s0' % (localOrientMtx.name(), matrixList.index('Y'))))
        cmpntUpVec.outputY.connect(pmc.Attribute('%s.in%s1' % (localOrientMtx.name(), matrixList.index('Y'))))
        cmpntUpVec.outputZ.connect(pmc.Attribute('%s.in%s2' % (localOrientMtx.name(), matrixList.index('Y'))))

        normVec.outputX.connect(pmc.Attribute('%s.in%s0' % (localOrientMtx.name(), matrixList.index(''))))
        normVec.outputY.connect(pmc.Attribute('%s.in%s1' % (localOrientMtx.name(), matrixList.index(''))))
        normVec.outputZ.connect(pmc.Attribute('%s.in%s2' % (localOrientMtx.name(), matrixList.index(''))))

        startToSrt.outputTranslateX.connect(localOrientMtx.in30)
        startToSrt.outputTranslateY.connect(localOrientMtx.in31)
        startToSrt.outputTranslateZ.connect(localOrientMtx.in32)


        # matrix representing positional offset of first control
        startEndDist = coreUtils.distanceBetweenNodes(self.startIn, self.endIn, name='%s_startEndDist_utl' % self.name)
        mult = .333
        if '-' in axis:
            mult = -.333
        startLocalOffsetMult = coreUtils.multiply(startEndDist.distance, mult, name='%s_startLocalOffsetMult_utl' % self.name)
        startLocalOffsetMtx = pmc.createNode('fourByFourMatrix', name='%s_startLocalOffsetMtx_utl' % self.name)
        startLocalOffsetMult.outputX.connect('%s.in3%s' % (startLocalOffsetMtx.name(), orderDict[axis[-1]]))

        # Matrices that convert local positional offset into either local orient space or start space
        startLocalMtx = coreUtils.multiplyMatrices([startLocalOffsetMtx.output, localOrientMtx.output],
                                                    name='%s_startLocalMtx_utl' % self.name)
        startLocalMtxToSrt = coreUtils.decomposeMatrix(startLocalMtx.matrixSum, name='%s_startLocalMtxToSrt_utl' % self.name)

        startAutoMtx = coreUtils.multiplyMatrices([startLocalOffsetMtx.output, self.startIn.worldMatrix[0]],
                                                   name='%s_startAutoMtx_utl' % self.name)
        startAutoMtxToSrt = coreUtils.decomposeMatrix(startAutoMtx.matrixSum, name='%s_startAutoMtxToSrt_utl' % self.name)

        startBlend = coreUtils.pairBlend(startLocalMtxToSrt.outputTranslate,
                                         startLocalMtxToSrt.outputRotate,
                                         startAutoMtxToSrt.outputTranslate,
                                         startAutoMtxToSrt.outputRotate,
                                         name = '%s_startAutoBlend_utl' % self.name,
                                         blendAttr=self.mainGrp.startAuto)

        # matrix representing positional offset of second control
        mult = mult *-1
        endLocalOffsetMult = coreUtils.multiply(startEndDist.distance, mult,
                                                  name='%s_endLocalOffsetMult_utl' % self.name)
        endLocalOffsetMtx = pmc.createNode('fourByFourMatrix', name='%s_endLocalOffsetMtx_utl' % self.name)
        endLocalOffsetMult.outputX.connect('%s.in3%s' % (endLocalOffsetMtx.name(), orderDict[axis[-1]]))

        # Matrices that convert local positional offset into either local orient space or start space
        endLocalMtx = coreUtils.multiplyMatrices([endLocalOffsetMtx.output, localOrientMtx.output],
                                                   name='%s_endLocalMtx_utl' % self.name)
        endLocalMtxToSrt = coreUtils.decomposeMatrix(endLocalMtx.matrixSum,
                                                       name='%s_endLocalMtxToSrt_utl' % self.name)

        endLocalPos = pmc.createNode('plusMinusAverage', name='%s_endLocalPos_utl' % self.name)
        if '-' in axis:
            endLocalPos.operation.set(2)
        endLocalMtxToSrt.outputTranslate.connect(endLocalPos.input3D[0])
        cmpntVec.output3D.connect(endLocalPos.input3D[1])

        endAutoMtx = coreUtils.multiplyMatrices([endLocalOffsetMtx.output, self.endIn.worldMatrix[0]],
                                                  name='%s_endAutoMtx_utl' % self.name)
        endAutoMtxToSrt = coreUtils.decomposeMatrix(endAutoMtx.matrixSum,
                                                      name='%s_endAutoMtxToSrt_utl' % self.name)

        endBlend = coreUtils.pairBlend(endLocalPos.output3D,
                                       endLocalMtxToSrt.outputRotate,
                                       endAutoMtxToSrt.outputTranslate,
                                       endAutoMtxToSrt.outputRotate,
                                       name='%s_endAutoBlend_utl' % self.name,
                                       blendAttr=self.mainGrp.endAuto)



        # Motion path
        mps = curveUtils.nodesAlongCurve(crv=crv,
                                         numNodes=numDivisions,
                                         name=self.name,
                                         followAxis=axis,
                                         upAxis=upAxis,
                                         upNode=self.startIn,
                                         upVec=upAxis,
                                         follow=1,
                                         groups=0)

        # twist inversion
        cond = pmc.createNode('condition', name='%s_twistIsInverted_utl' % self.name)
        self.mainGrp.twist.connect(cond.colorIfFalseR)
        uc = coreUtils.convert(self.mainGrp.twist, -1, name='%s_twistInvert_utl' % self.name)
        uc.output.connect(cond.colorIfTrueR)
        self.mainGrp.invertTwist.connect(cond.firstTerm)
        cond.secondTerm.set(1)

        # joints
        for i in range(numDivisions):
            num = str(i + 1).zfill(2)
            mp = mps['mpNodes'][i]
            j = pmc.joint(name='%s_%s_dfm' % (self.name, num))
            j.setParent(self.deformGrp)
            mp.allCoordinates.connect(j.t)
            mp.rotate.connect(j.jointOrient)
            twistBlend = pmc.createNode('animBlendNodeAdditiveRotation', name='%s_%s_twistBlend_utl' % (self.name, num))
            attr = pmc.Attribute('%s.inputA%s' % (twistBlend.name(), axis[-1].upper()))
            cond.outColorR.connect(attr)
            if not '-' in axis:
                twistBlend.weightA.set(mp.uValue.get() * -1)
            else:
                twistBlend.weightA.set(mp.uValue.get())
            twistBlend.output.connect(j.r)

        #twisting
        orientInverseMtx = pmc.createNode('inverseMatrix', name='%s_localOrientInverseMatrix_utl' % self.name)
        localOrientMtx.output.connect(orientInverseMtx.inputMatrix)
        twist = coreUtils.isolateTwist(self.endIn.worldMatrix[0], orientInverseMtx.outputMatrix, name=self.name, axis=axis)
        twistAttr = pmc.Attribute('%s.outputRotate%s' % (twist[2].name(), axis[-1].upper()))
        twistAttr.connect(self.mainGrp.twist)

        crvShape = pmc.listRelatives(crv, c=1, s=1)[0]
        startToSrt.outputTranslate.connect(crvShape.controlPoints[0])
        endToSrt.outputTranslate.connect(crvShape.controlPoints[3])

        # bend controls
        if addMidControls:
            startCtrl = controls.squareCtrl(name='%s_start_ctrl' % self.name, axis=axis[-1], size=ctrlSize)
            startBuffer = coreUtils.addParent(startCtrl, 'group', '%s_startCtrl_buffer_srt' % self.name)
            startBuffer.setParent(self.interfaceGrp)
            startCtrlToSrt = coreUtils.decomposeMatrix(startCtrl.worldMatrix[0], name='%s_startCtrlWorldMtxToSrt_utl' % self.name)
            startBlend.outTranslate.connect(startBuffer.t)
            startBlend.outRotate.connect(startBuffer.r)
            self.ctrls.append(startCtrl)

            endCtrl = controls.squareCtrl(name='%s_end_ctrl' % self.name, axis=axis[-1], size=ctrlSize)
            endBuffer = coreUtils.addParent(endCtrl, 'group', '%s_endCtrl_buffer_srt' % self.name)
            endBuffer.setParent(self.interfaceGrp)
            endCtrlToSrt = coreUtils.decomposeMatrix(endCtrl.worldMatrix[0], name='%s_startendCtrlWorldMtxToSrt_utl' % self.name)
            endBlend.outTranslate.connect(endBuffer.t)
            endBlend.outRotate.connect(endBuffer.r)
            self.ctrls.append(endCtrl)

            startCtrlToSrt.outputTranslate.connect(crvShape.controlPoints[1])
            endCtrlToSrt.outputTranslate.connect(crvShape.controlPoints[2])
        else:
            startBlend.outTranslate.connect(crvShape.controlPoints[1])
            endBlend.outTranslate.connect(crvShape.controlPoints[2])

        if addEndControls:
            self.btmCtrl = controls.circleBumpCtrl(name='%s_btm_ctrl' % self.name, axis=axis, radius=ctrlSize)
            coreUtils.align(self.btmCtrl, self.startIn)
            btmBuffer = coreUtils.addParent(self.btmCtrl, 'group', '%s_btm_buffer_srt' % self.name)
            btmBuffer.setParent(self.interfaceGrp)
            d = coreUtils.isDecomposed(self.btmCtrl)
            coreUtils.connectDecomposedMatrix(d, self.startIn)
            self.ctrls.append(self.btmCtrl)

            self.topCtrl = controls.circleBumpCtrl(name='%s_top_ctrl' % self.name, axis=axis, radius=ctrlSize)
            coreUtils.align(self.topCtrl, self.endIn)
            topBuffer = coreUtils.addParent(self.topCtrl, 'group', '%s_top_buffer_srt' % self.name)
            topBuffer.setParent(self.interfaceGrp)
            d = coreUtils.isDecomposed(self.topCtrl)
            coreUtils.connectDecomposedMatrix(d, self.endIn)
            self.ctrls.append(self.topCtrl)
Example #9
0
def buildBaseRig(name='eye', numTweaks=7, tweaks=1):
    '''
    Create the bezier setup with corner, top and bottom controls.
    Radius sets the distance from the spin pivots to the rig
    Spread sets the width of the corners (in degrees from the centre)
    '''
    # Base structure
    rootGrp = pmc.group(empty=1, name='%s_cmpnt' % name)
    pmc.addAttr(rootGrp, ln='rigParent', dt='string')
    rootGrp.rigParent.set('components_GRP')

    inputGrp = coreUtils.addChild(rootGrp, 'group', name='%s_input' % name)
    pmc.select(inputGrp)
    pmc.addAttr(ln='rigInputs', dt='string', multi=1)
    pmc.addAttr(inputGrp, at='matrix', ln='head_in_mtx')
    pmc.addAttr(inputGrp, at='matrix', ln='jaw_in_mtx')

    controlsGrp = coreUtils.addChild(rootGrp, 'group', name='%s_controls' % name)
    pmc.select(controlsGrp)
    pmc.addAttr(ln='rigInputs', dt='string', multi=1)
    controlsGrp.rigInputs[0].set('options_CTL.all_ctls_vis>>visibility')

    rigGrp = coreUtils.addChild(rootGrp, 'group', name='%s_rig' % name)
    rigGrp.visibility.set(0)

    outputGrp = coreUtils.addChild(rootGrp, 'group', name='%s_output' % name)
    addOutputAttrs(outputGrp)

    pmc.addAttr(outputGrp, ln='outputType', dt='string')
    # in case there is a discrepancy between the neck joint and the head control
    pmc.addAttr(outputGrp, ln='ctrl2Joint_offset_mtx', at='matrix')
    outputGrp.outputType.set('eye')

    # Config node
    config = coreUtils.addChild(controlsGrp, 'group', name='%s_config' % name)
    pmc.addAttr(config, ln='radius', at='double', k=0, h=0)
    config.radius.set(configDict['radius'])

    pmc.addAttr(config, ln='spread', at='doubleAngle', k=0, h=0)
    config.spread.set(configDict['spread'])

    pmc.addAttr(config, ln='height', at='double', k=0, h=0)
    config.height.set(configDict['height'])

    # Base srts
    rootSrt = coreUtils.addChild(controlsGrp, 'group', name='%s_root_srt' % name)
    headSrt = coreUtils.decomposeMatrix(inputGrp.head_in_mtx, name='%s_head_in_mtx2Srt_utl' % name)
    coreUtils.connectDecomposedMatrix(headSrt, rootSrt)

    centreSrt = coreUtils.addChild(rootSrt, 'group', name='%s_centre_srt' % name)
    negScaleSrt = coreUtils.addChild(centreSrt, 'group', name='%s_negScale_srt' % name)
    negScaleSrt.sx.set(-1)

    # Set up jaw blending stuff
    jawOffset = pmc.createNode('composeMatrix', name='%s_jawOffsetMtx_utl' % name)
    jawResultMtx = pmc.createNode('multMatrix', name='%s_jawResultMtx_utl' % name)
    jawOffset.outputMatrix.connect(jawResultMtx.matrixIn[0])
    inputGrp.jaw_in_mtx.connect(jawResultMtx.matrixIn[1])
    centreSrt.worldInverseMatrix[0].connect(jawResultMtx.matrixIn[2])
    jawSrt = coreUtils.decomposeMatrix(jawResultMtx.matrixSum, name='%s_jawResultMtx2Srt_utl' % name)
    jawRotConvert = coreUtils.convert(jawSrt.outputRotateX, 1.0, name='%s_jawRotAngle2Float_utl' % name)

    # Spin srt + Ctrl structure
    ctrls = []
    constGrps = []
    for i in ['R', 'T', 'L', 'B']:
        aimDict = {'T':'up', 'L':'left', 'B':'down', 'R':'left'}
        constSrt = coreUtils.addChild(centreSrt, 'group', name='%s_%s_const_srt' % (name, i))
        constGrps.append(constSrt)
        spinSrt = coreUtils.addChild(constSrt, 'group', name='%s_%s_spin_srt' % (name, i))

        bufferSrt = coreUtils.addChild(spinSrt, 'group', name='%s_%s_ctrlBufferSrt' % (name, i))
        negSrt = coreUtils.addChild(bufferSrt, 'group', name='%s_%s_xNegSrt' % (name, i))
        ctrl = controls.triCtrl(size=config.radius.get()*.2, aim=aimDict[i], name='%s_%s_ctrl' % (name, i))
        pmc.addAttr(ctrl, ln='follow_jaw', minValue=0.0, maxValue=1.0, k=1, h=0, at='double')
        ctrl.setParent(negSrt)
        config.radius.connect(bufferSrt.tz)
        if i == 'T':
            config.height.connect(bufferSrt.ty)
        elif i == 'B':
            heightInvert = coreUtils.convert(config.height, -1, name='%s_heightInvert_utl' % name)
            heightInvert.output.connect(bufferSrt.ty)

        # Negate x & y translate and connect to spin
        conv = coreUtils.convert(ctrl.tx, -1, name='%s_%s_invertTX_utl' % (name, i))
        conv.output.connect(negSrt.tx)
        spinFac = coreUtils.convert(config.radius, 6.283, name='%s_%s_spinFactor_utl' % (name, i))
        spinAmount = coreUtils.divide(ctrl.tx, spinFac.output, name='%s_%s_spinAmountX_utl' % (name, i))
        spinConv = coreUtils.convert(spinAmount.outputX, 6.283, name='%s_%s_spinX_utl' % (name, i))

        conv = coreUtils.convert(ctrl.ty, -1, name='%s_%s_invertTY_utl' % (name, i))
        conv.output.connect(negSrt.ty)
        spinAmountY = coreUtils.divide(ctrl.ty, spinFac.output, name='%s_%s_spinAmountY_utl' % (name, i))
        spinConvY = coreUtils.convert(spinAmountY.outputX, -6.283, name='%s_%s_spinY_utl' % (name, i))


        if i == 'R':
            negScaleSrt.setParent(constSrt)
            spinSrt.setParent(negScaleSrt)
            spinSrt.s.set(1,1,1)
            spinSrt.r.set(0,0,0)
        if i == 'L' or i == 'R':
            spinOffset = pmc.createNode('animBlendNodeAdditiveDA', name='%s_%s_spinOffset_utl' % (name, i))
            spinConv.output.connect(spinOffset.inputA)
            config.spread.connect(spinOffset.inputB)
            spinOffset.output.connect(spinSrt.ry)
        else:
            spinConv.output.connect(spinSrt.ry)
        spinConvY.output.connect(spinSrt.rx)
        spinSrt.ro.set(2)

        # set up jaw blending
        jawBlend = coreUtils.pairBlend((0,0,0), (0,0,0), jawSrt.outputTranslate, jawSrt.outputRotate, name='%s_%s_jawBlend_utl' % (name, i), blendAttr=ctrl.follow_jaw)
        jawBlend.outTranslate.connect(constSrt.t)
        jawBlend.outRotate.connect(constSrt.r)

        # set up corner push on jaw open
        if i == 'R' or i =='L':
            pmc.addAttr(bufferSrt, ln='jawOpenPush', at='double', k=0, h=0)
            rv = pmc.createNode('remapValue', name='%s_%s_jawPushRemap_utl' % (name, i))
            jawAdd = pmc.createNode('animBlendNodeAdditive', name='%s_%s_jawOpenAdd_utl' % (name, i))
            config.radius.connect(jawAdd.inputB)
            rv.outValue.connect(jawAdd.weightA)
            ctrl.follow_jaw.connect(rv.inputValue)
            jawPushMult = coreUtils.multiplyDouble(jawRotConvert.output, bufferSrt.jawOpenPush, name='%s_%s_jawPushMult' % (name, i))
            jawPushMult.output.connect(jawAdd.inputA)
            jawAdd.output.connect(bufferSrt.tz, f=1)
            rv.value[1].value_Position.set(.5)
            rv.value[2].value_FloatValue.set(0)
            rv.value[2].value_Position.set(1)
            rv.value[0].value_Interp.set(2)
            rv.value[1].value_Interp.set(2)


        ctrls.append(ctrl)

    # Distance nodes for auto scaling of tangents
    dist_R_T = coreUtils.distanceBetweenNodes(ctrls[0], ctrls[1], name='%s_dist_R_T_utl' % name)
    scaledDist_R_T = coreUtils.divide(dist_R_T.distance, headSrt.outputScaleX, name='%s_scaledDist_R_T_utl' % name)

    dist_L_T = coreUtils.distanceBetweenNodes(ctrls[2], ctrls[1], name='%s_dist_L_T_utl' % name)
    scaledDist_L_T = coreUtils.divide(dist_L_T.distance, headSrt.outputScaleX, name='%s_scaledDist_L_T_utl' % name)

    dist_R_B = coreUtils.distanceBetweenNodes(ctrls[0], ctrls[3], name='%s_dist_R_B_utl' % name)
    scaledDist_R_B = coreUtils.divide(dist_R_B.distance, headSrt.outputScaleX, name='%s_scaledDist_R_B_utl' % name)

    dist_L_B = coreUtils.distanceBetweenNodes(ctrls[2], ctrls[3], name='%s_dist_L_B_utl' % name)
    scaledDist_L_B = coreUtils.divide(dist_L_B.distance, headSrt.outputScaleX, name='%s_scaledDist_L_B_utl' % name)

    scaledHeight = coreUtils.divide(config.height, headSrt.outputScaleY, name='%s_scaledHeight_utl' % name)


    # Build curves
    points = [(0,0,0) for i in range(7)]
    knots = [0,0,0,1,1,1,2,2,2]
    topCrv = pmc.curve(d=3, p=points, k=knots, name='%s_T_macro_crv' % name)
    topCrv.setParent(rigGrp)
    btmCrv = pmc.curve(d=3, p=points, k=knots, name='%s_B_macro_crv' % name)
    btmCrv.setParent(rigGrp)

    p1 = coreUtils.pointMatrixMult((0,0,0), ctrls[0].worldMatrix[0], name='%s_R_pos_utl' % name)

    p2TanLen = coreUtils.multiplyDouble(headSrt.outputScaleY, scaledHeight.outputX, name='%s_R_outTan_len_utl' % name)
    p2 = coreUtils.pointMatrixMult((0,0,0), ctrls[0].worldMatrix[0], name='%s_R_outTan_pos_utl' % name)
    p2TanLen.output.connect(p2.input1Y)

    p3TanLen = coreUtils.multiply(scaledDist_R_T.outputX, -.5, name='%s_T_inTan_len_utl' % name)
    p3 = coreUtils.pointMatrixMult(p3TanLen.output, ctrls[1].worldMatrix[0], name='%s_T_inTan_pos_utl' % name)

    p4 = coreUtils.pointMatrixMult((0,0,0), ctrls[1].worldMatrix[0], name='%s_T_pos_utl' % name)

    p5TanLen = coreUtils.multiply(scaledDist_L_T.outputX, .5, name='%s_T_outTan_len_utl' % name)
    p5 = coreUtils.pointMatrixMult(p5TanLen.output, ctrls[1].worldMatrix[0], name='%s_T_outTan_pos_utl' % name)

    p6 = coreUtils.pointMatrixMult((0,0,0), ctrls[2].worldMatrix[0], name='%s_L_inTan_pos_utl' % name)
    p2TanLen.output.connect(p6.input1Y)

    p7 = coreUtils.pointMatrixMult((0,0,0), ctrls[2].worldMatrix[0], name='%s_L_pos_utl' % name)

    p8TanLen = coreUtils.convert(p2TanLen.output, -1, name='%s_L_outTan_len_utl' % name)
    p8 = coreUtils.pointMatrixMult((0,0,0), ctrls[2].worldMatrix[0], name='%s_L_outTan_pos_utl' % name)
    p8TanLen.output.connect(p8.input1Y)

    p9TanLen = coreUtils.multiply(scaledDist_L_B.outputX, .5, name='%s_B_inTan_len_utl' % name)
    p9 = coreUtils.pointMatrixMult(p9TanLen.output, ctrls[3].worldMatrix[0], name='%s_B_inTan_pos_utl' % name)

    p10 = coreUtils.pointMatrixMult((0,0,0), ctrls[3].worldMatrix[0], name='%s_B_pos_utl' % name)

    p11TanLen = coreUtils.multiply(scaledDist_R_B.outputX, -.5, name='%s_B_outTan_len_utl' % name)
    p11 = coreUtils.pointMatrixMult(p11TanLen.output, ctrls[3].worldMatrix[0], name='%s_B_outTan_pos_utl' % name)

    p12 = coreUtils.pointMatrixMult((0,0,0), ctrls[0].worldMatrix[0], name='%s_R_inTan_pos_utl' % name)
    p8TanLen.output.connect(p12.input1Y)

    p1.output.connect(topCrv.controlPoints[0])
    p2.output.connect(topCrv.controlPoints[1])
    p3.output.connect(topCrv.controlPoints[2])
    p4.output.connect(topCrv.controlPoints[3])
    p5.output.connect(topCrv.controlPoints[4])
    p6.output.connect(topCrv.controlPoints[5])
    p7.output.connect(topCrv.controlPoints[6])

    p1.output.connect(btmCrv.controlPoints[0])
    p12.output.connect(btmCrv.controlPoints[1])
    p11.output.connect(btmCrv.controlPoints[2])
    p10.output.connect(btmCrv.controlPoints[3])
    p9.output.connect(btmCrv.controlPoints[4])
    p8.output.connect(btmCrv.controlPoints[5])
    p7.output.connect(btmCrv.controlPoints[6])

    returnDict = {
        'root':rootSrt,
        'topCrv':topCrv,
        'btmCrv':btmCrv,
        'tangents':[p2, p8],
        'rigGrp':rigGrp
    }

    if not tweaks:
        return returnDict

    ##------------------------------TWEAKS-----------------------------------------##

    # Create motions path nodes
    tweakCtrls = []
    tweakGrp = coreUtils.addChild(centreSrt, 'group', name='%s_tweakControls_hrc' % name)
    for i in range(numTweaks):
        num = str(i+1).zfill(2)
        mp = pmc.createNode('motionPath', name='%s_T_%s_tweakMotionPath_utl' % (name, num))
        topCrv.worldSpace[0].connect(mp.geometryPath)
        mp.uValue.set(1.0 / (numTweaks-1) * i)
        bfr = pmc.group(empty=1, name='%s_tweak_%s_bufferSrt' % (name, num))
        aim = 'up'
        if i==numTweaks-1 or i == 0:
            aim='left'
        ctrl = controls.triCtrl(size = configDict['radius']*.075, aim=aim, name='%s_tweak_%s_ctrl' % (name, num))
        ctrl.setParent(bfr)
        bfrLocalPos = coreUtils.pointMatrixMult(mp.allCoordinates, centreSrt.worldInverseMatrix[0], name='%s_tweakLocalPos_%s_utl' % (name, num))
        bfrLocalPos.output.connect(bfr.t)
        bfrAngle = pmc.createNode('angleBetween', name='%s_tweakAngle_%s_utl' % (name, num))
        bfrLocalPos.output.connect(bfrAngle.vector2)
        bfrAngle.vector1.set((0,0,1))
        euler2Quat = pmc.createNode('eulerToQuat', name='%s_tweakAngleEuler2Quat_%s_utl' % (name, num))
        bfrAngle.euler.connect(euler2Quat.inputRotate)
        quatToEuler = pmc.createNode('quatToEuler', name='%s_tweakAngleQuat2Euler_%s_utl' % (name, num))
        euler2Quat.outputQuat.connect(quatToEuler.inputQuat)
        quatToEuler.inputRotateOrder.set(2)
        bfr.ro.set(2)
        quatToEuler.outputRotateX.connect(bfr.rx)
        quatToEuler.outputRotateY.connect(bfr.ry)
        mp.fractionMode.set(1)
        tweakCtrls.append(ctrl)
        d = coreUtils.decomposeMatrix(ctrl.worldMatrix[0], name='%s_tweak_%s_mtx2Srt_utl' % (name, num))
        if i==(numTweaks-1):
            tanMult = coreUtils.convert(p8.input1Y, -0.5, name='%s_T_tweakInTan_utl' % name)
            b = coreUtils.addChild(tweakCtrls[-1], 'group', name=bfr.name().replace('bufferSrt', 'inTan_bufferSrt'))
            tanMult.output.connect(b.ty)
            c = controls.triCtrl(size = configDict['radius']*.05, aim='up', name='%s_tweak_%s_inTan_ctrl' % (name, num))
            coreUtils.align(c, b, parent=1)
            tweakCtrls.append(c)
        if i==0:
            tanMult = coreUtils.convert(p2.input1Y, 0.5, name='%s_T_tweakOutTan_utl' % name)
            b = coreUtils.addChild(tweakCtrls[0], 'group', name=bfr.name().replace('bufferSrt', 'outTan_bufferSrt'))
            tanMult.output.connect(b.ty)
            c = controls.triCtrl(size = configDict['radius']*.05, aim='up', name='%s_tweak_%s_outTan_ctrl' % (name, num))
            coreUtils.align(c, b, parent=1)
            tweakCtrls.append(c)

        if d.outputTranslateX.get() < 0.0:
            bfr.sx.set(-1)

        bfr.setParent(tweakGrp)

    for i in range(numTweaks)[1:-1]:
        num = str(i+numTweaks).zfill(2)
        mp = pmc.createNode('motionPath', name='%s_B_%s_tweakMotionPath_utl' % (name, num))
        btmCrv.worldSpace[0].connect(mp.geometryPath)
        mp.uValue.set(1.0 / (numTweaks-1) * i)
        bfr = pmc.group(empty=1, name='%s_tweak_%s_bufferSrt' % (name, num))
        ctrl = controls.triCtrl(size = configDict['radius']*.075, aim='down', name='%s_tweak_%s_ctrl' % (name, num))
        ctrl.setParent(bfr)
        bfrLocalPos = coreUtils.pointMatrixMult(mp.allCoordinates, centreSrt.worldInverseMatrix[0], name='%s_tweakLocalPos_%s_utl' % (name, num))
        bfrLocalPos.output.connect(bfr.t)
        bfrAngle = pmc.createNode('angleBetween', name='%s_tweakAngle_%s_utl' % (name, num))
        bfrLocalPos.output.connect(bfrAngle.vector2)
        bfrAngle.vector1.set((0,0,1))
        euler2Quat = pmc.createNode('eulerToQuat', name='%s_tweakAngleEuler2Quat_%s_utl' % (name, num))
        bfrAngle.euler.connect(euler2Quat.inputRotate)
        quatToEuler = pmc.createNode('quatToEuler', name='%s_tweakAngleQuat2Euler_%s_utl' % (name, num))
        euler2Quat.outputQuat.connect(quatToEuler.inputQuat)
        quatToEuler.inputRotateOrder.set(2)
        bfr.ro.set(2)
        quatToEuler.outputRotateX.connect(bfr.rx)
        quatToEuler.outputRotateY.connect(bfr.ry)
        mp.fractionMode.set(1)
        d = coreUtils.decomposeMatrix(ctrl.worldMatrix[0], name='%s_tweak_%s_mtx2Srt_utl' % (name, num))
        if i==1:
            tanMult = coreUtils.convert(p2.input1Y, -0.5, name='%s_B_tweakOutTan_utl' % name)
            b = coreUtils.addChild(tweakCtrls[0], 'group', name=tweakCtrls[0].name().replace('ctrl', 'inTan_bufferSrt'))
            tanMult.output.connect(b.ty)
            c = controls.triCtrl(size = configDict['radius']*.05, aim='down', name=tweakCtrls[0].name().replace('ctrl', 'inTan_ctrl'))
            coreUtils.align(c, b, parent=1)
            tweakCtrls.append(c)
        tweakCtrls.append(ctrl)
        if i==(numTweaks-2):
            tanMult = coreUtils.convert(p8.input1Y, 0.5, name='%s_B_tweakInTan_utl' % name)
            b = coreUtils.addChild(tweakCtrls[numTweaks], 'group', name=tweakCtrls[numTweaks].name().replace('ctrl', 'outTan_bufferSrt'))
            tanMult.output.connect(b.ty)
            c = controls.triCtrl(size = configDict['radius']*.05, aim='down', name=tweakCtrls[numTweaks].name().replace('ctrl', 'outTan_ctrl'))
            coreUtils.align(c, b, parent=1)
            tweakCtrls.append(c)

        if d.outputTranslateX.get() < 0.0:
            bfr.sx.set(-1)

        bfr.setParent(tweakGrp)

    ctrlSet = pmc.sets(ctrls + tweakCtrls, name='%s_ctls_SEL' % name)


    # CLEAN UP
    coreUtils.attrCtrl(nodeList=[ctrls[0], ctrls[2]], attrList=['sx', 'sz', 'visibility'])
    coreUtils.attrCtrl(nodeList=[ctrls[1], ctrls[3]], attrList=['sy', 'sz', 'visibility'])
    coreUtils.attrCtrl(nodeList=tweakCtrls, attrList=['sx', 'sy', 'sz', 'visibility'])
    coreUtils.attrCtrl(nodeList=ctrls + tweakCtrls, attrList=['aiRenderCurve', 'aiCurveWidth', 'aiSampleRate', 'aiCurveShaderR', 'aiCurveShaderG', 'aiCurveShaderB'])

    addOutputAttrs(outputGrp)
    joints = []
    # top joints
    for i in range(len(tweakCtrls)):
        num = str(i+1).zfill(2)
        ctrl = tweakCtrls[i]
        t = pmc.xform(ctrl, ws=1, q=1, t=1)[0]
        unMirror=0
        if t < 0.0:
            unMirror=1
        faceRigging.exposeOutput(ctrl, outputGrp, 'eye', unMirror=unMirror, createJoint=0)

        pmc.select(None)
        j = pmc.joint(name='%s_T_%s_Out_Jnt' % (name, num))
        joints.append(j)

        j.segmentScaleCompensate.set(0)
        pmc.addAttr(j, ln='jointIndex', at='short', k=0)
        j.jointIndex.set(i)
        pmc.addAttr(j, ln='rigType', dt='string')
        j.rigType.set('eye')

        d = coreUtils.decomposeMatrix(outputGrp.outMatrix[i], name='%s_outMtx2Srt_%s_utl' % (name, num))
        coreUtils.connectDecomposedMatrix(d, j)
Example #10
0
def addSpaceSwitch(node,
                   name,
                   spaces,
                   type='parent',
                   ctrlNode=None,
                   targetNodes=[]):

    enumString = ''
    startIndex = 0
    asset = getComponentFromName(node)
    choice = hasSpaceSwitch(node)[type]
    attr = None
    add = 0
    if choice:
        add = 1
        ctrlNode = pmc.listConnections(choice.selector, d=0)[0]
        attr = pmc.listConnections(choice.selector, d=0, p=1)[0]
        attrName = attr.name().split('.')[-1]
        enumString = pmc.attributeQuery(attrName, node=ctrlNode,
                                        listEnum=1)[0] + ':'
        startIndex = len(enumString.split(':')) - 1
        pmc.deleteAttr(attr)
    else:
        choice = pmc.createNode('choice',
                                name='%s_%s_%sSpaceChoice_utl' %
                                (asset, name, type))
        if not ctrlNode:
            ctrlNode = node

    for space in spaces:
        enumString += (space + ':')
    pmc.addAttr(ctrlNode,
                ln='%sSpace' % type,
                at='enum',
                enumName=enumString,
                k=1,
                h=0)
    attr = pmc.Attribute('%s.%sSpace' % (ctrlNode.name(), type))
    attr.connect(choice.selector)

    targets = []
    for i in range(len(spaces)):
        space = spaces[i]
        g = coreUtils.addChild(getComponentGroup(node, group='input'),
                               'group',
                               name='%s_%s_%s_%s_in_srt' %
                               (asset, name, space, type))
        #coreUtils.align(g, node)
        #g.worldMatrix[0].connect(pmc.Attribute('%s.input[%s]' % (choice.name(), i + startIndex)))
        targets.append(g)
        if len(targetNodes) == len(spaces):
            targetNode = targetNodes[i]
            if getComponentFromName(node) == getComponentFromName(targetNode):
                if targetNode in pmc.listRelatives(
                        getComponentGroup(targetNode, 'rig'), c=1,
                        ad=1) or targetNode in pmc.listRelatives(
                            getComponentGroup(targetNode, 'input'), c=1, ad=1):
                    g.setParent(targetNode)
                elif targetNode in pmc.listRelatives(getComponentGroup(
                        targetNode, 'interface'),
                                                     c=1,
                                                     ad=1):
                    g.setParent(getComponentGroup(targetNode, 'rig'))
                    d = coreUtils.isDecomposed(targetNode)
                    coreUtils.connectDecomposedMatrix(d, g)
            else:
                connectIO(g, targetNode, space)
        offset = coreUtils.addChild(g,
                                    'group',
                                    name='%s_%s_%s_%s_offset_srt' %
                                    (asset, name, space, type))
        coreUtils.align(offset, node)
        offset.worldMatrix[0].connect(
            pmc.Attribute('%s.input[%s]' % (choice.name(), i + startIndex)))

    if not add:
        d = coreUtils.decomposeMatrix(choice.output,
                                      name='%s_%s_%sSpaceMtxToSrt_utl' %
                                      (asset, name, type))
        if type == 'parent':
            coreUtils.connectDecomposedMatrix(d, node)
        elif type == 'translate':
            d.outputTranslate.connect(node.t)
        elif type == 'rotate':
            d.outputRotate.connect(node.r)

    return targets