Example #1
0
    def buildSpan(self, points, index):
        num = str(index + 1).zfill(2)
        main_grp = pmc.group(empty=1, name='%s_span_%s_GRP' % (self.name, num))

        # Create curve and connect curve points
        crv = curveBetweenNodes(points[0], points[2], name='%s_span_%s' % (self.name, num))
        crv.setParent(main_grp)
        locs = connectCurve(crv)
        pmc.pointConstraint(points[0], points[1], locs[1], mo=0)
        pmc.pointConstraint(points[1], points[2], locs[2], mo=0)
        locs[0].setParent(points[0])
        locs[1].setParent(main_grp)
        locs[2].setParent(main_grp)
        locs[3].setParent(points[2])

        # Motionpath node
        mp = nodesAlongCurve(crv, numNodes=1, name='%s_span_%s' % (self.name, str(index)), upNode=points[1])
        npc = pmc.createNode('nearestPointOnCurve', name='%s_span_%s' % (self.name, num))
        points[1].worldPosition[0].connect(npc.inPosition)
        crv.worldSpace[0].connect(npc.inputCurve)
        npc.parameter.connect(mp['mpNodes'][0].uValue)
        mp['mpNodes'][0].fractionMode.set(0)
        mp['grps'][0].setParent(main_grp)

        # Tangents
        tanGrp = coreUtils.addChild(points[1], 'group', '%s_span_%s_tangent_GRP' % (self.name, num))
        pmc.orientConstraint(mp['grps'][0], tanGrp)

        tanDrv = coreUtils.addChild(tanGrp, 'group', '%s_span_%s_tangent_DRV' % (self.name, num))
        points[1].r.connect(tanDrv.r)
        points[1].s.connect(tanDrv.s)

        inTan_grp = coreUtils.addChild(tanDrv, 'group', '%s_span_%s_inTangent_GRP' % (self.name, num))
        inTan_loc = coreUtils.addChild(inTan_grp, 'locator', '%s_span_%s_inTangent_LOC' % (self.name, num))
        inDist = coreUtils.distanceBetweenNodes(points[0], points[1], '%s_span_%s_in_dist' % (self.name, num))

        outTan_grp = coreUtils.addChild(tanDrv, 'group', '%s_span_%s_outTangent_GRP' % (self.name, num))
        outTan_loc = coreUtils.addChild(outTan_grp, 'locator', '%s_span_%s_outTangent_LOC' % (self.name, num))
        outDist = coreUtils.distanceBetweenNodes(points[1], points[2], '%s_span_%s_out_dist' % (self.name, num))

        pmc.addAttr(points[1], ln='tangentWeight', at="float", minValue=0.0, maxValue=1.0, keyable=1, hidden=0,
                    defaultValue=0.25)

        inWeight_md = coreUtils.multiply(inDist.distance, points[1].tangentWeight,
                                         'md_%s_span_%s_inWeight_UTL' % (self.name, num))
        outWeight_md = coreUtils.multiply(outDist.distance, points[1].tangentWeight,
                                          'md_%s_span_%s_outWeight_UTL' % (self.name, num))
        weight_uc = coreUtils.convert(inWeight_md.outputX, -1, 'uc_%s_span_%s_weightInvert_UTL' % (self.name, num))

        outWeight_md.outputX.connect(outTan_grp.tx)
        weight_uc.output.connect(inTan_grp.tx)

        return {
            'inTan': inTan_loc,
            'outTan': outTan_loc,
            'inDist': inDist,
            'outDist': outDist,
            # 'weight_md':weight_md,
            'main_grp': main_grp,
        }
Example #2
0
def exposeDeformation(node, name):
    '''
    creates a joint in the deform group of node's asset witch matches node's worldspace transforms
    :param node: node whose transform to expose
    :return: newly created deform joint
    '''
    d = coreUtils.isDecomposed(node)
    j = coreUtils.addChild(getComponentGroup(node, group='deform'), 'joint',
                           '%s_dfm' % name)
    j.jointOrient.set((0, 0, 0))
    d.outputTranslate.connect(j.t)
    d.outputRotate.connect(j.r)
    d.outputScale.connect(j.s)
    return j
Example #3
0
def exposeOutput(node, name=''):
    '''
    creates a transform in the output group of node's asset which matches node's worldspace transforms
    :param node: node whose transform to expose
    :return: newly created output group
    '''
    if not name:
        name = node.name().split('_')[2]
    d = coreUtils.isDecomposed(node)
    g = coreUtils.addChild(
        getComponentGroup(node), 'group',
        '%s_%s_out_srt' % (getComponentFromName(node), name))
    d.outputTranslate.connect(g.t)
    d.outputRotate.connect(g.r)
    d.outputScale.connect(g.s)

    return g
Example #4
0
def exposeInput(node, source, name):
    '''

    '''
    input = getInput(node, name)
    if not input:
        input = coreUtils.addChild(
            getComponentGroup(node, group='input'), 'group',
            '%s_%s_in_srt' % (getComponentFromName(node), name))
    outSource = getOutput(source)
    if not outSource:
        outSource = exposeOutput(source, name)

    outSource.t.connect(input.t)
    outSource.r.connect(input.r)
    outSource.s.connect(input.s)

    return input
Example #5
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 #6
0
def nonTwistingChild(node, name, axis='x'):
    '''
    calls isolateTwist function supplying node's world and inverse parent matrices
    creates a new group parented under node which negates the twisting axis
    :param node: node whose twist you wish to extract
    :param name: prefix for newly created nodes
    :param axis: axis to negate
    :return: [multMatrix, decomposeMatrix, eulerToQuat, newChildGroup]
    '''
    twist = coreUtils.isolateTwist(node.worldMatrix[0],
                                   node.parentInverseMatrix[0],
                                   name,
                                   axis=axis)
    g = coreUtils.addChild(node, 'group', name='%s_noTwist_srt' % name)
    twist.append(g)
    twistSourceAttr = pmc.Attribute('%s.outputRotate%s' %
                                    (twist[2].name(), axis[-1].upper()))
    twistDestAttr = pmc.Attribute('%s.r%s' % (g.name(), axis[-1]))
    c = coreUtils.convert(twistSourceAttr,
                          -1,
                          name='%s_twistInvert_utl' % name)
    c.output.connect(twistDestAttr)
    return g
Example #7
0
    def __init__(self, name):
        #super(DrBaseComponent, self).__init__()

        self.name = name
        self.ctrls = []

        # Create base hierarchy for component
        self.mainGrp = pmc.group(empty=1, name='%s_cmpnt' % self.name)
        self.inputGrp = coreUtils.addChild(self.mainGrp, 'group',
                                           '%s_input' % self.name)
        self.interfaceGrp = coreUtils.addChild(self.mainGrp, 'group',
                                               '%s_interface' % self.name)
        self.outputGrp = coreUtils.addChild(self.mainGrp, 'group',
                                            '%s_output' % self.name)
        self.rigGrp = coreUtils.addChild(self.mainGrp, 'group',
                                         '%s_rig' % self.name)
        self.deformGrp = coreUtils.addChild(self.mainGrp, 'group',
                                            '%s_deform' % self.name)
        self.subGrp = coreUtils.addChild(self.mainGrp, 'group',
                                         '%s_subCmpnt' % self.name)
        pmc.addAttr(self.mainGrp, ln='globalScale', at='double')
        self.mainGrp.globalScale.set(1)
Example #8
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 #9
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 #10
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 #11
0
    def build(self, start, end, numFkCtrls, jointsPerCtrl, numIkCtrls,
              numSegments, axis, upAxis, bias):
        start, end = coreUtils.getStartAndEnd(start, end)
        ctrlSize = coreUtils.getDistance(start, end) * .3 / numSegments
        # Build ik curves
        ikCrv = curveUtils.curveBetweenNodes(start,
                                             end,
                                             numCVs=numIkCtrls,
                                             name='%s_ik_crv' % self.name)
        ikCrv.setParent(self.rigGrp)

        # main control
        baseCtrl = controls.circleBumpCtrl(radius=ctrlSize * 1.25,
                                           name='%s_base_ctrl' % self.name,
                                           axis=axis)
        baseSrt = coreUtils.decomposeMatrix(baseCtrl.worldMatrix[0],
                                            name='%s_baseWorldMtxToSrt_utl' %
                                            baseCtrl)
        baseBuffer = coreUtils.addParent(baseCtrl,
                                         'group',
                                         name='%s_base_buffer_srt' % self.name)
        baseBuffer.setParent(self.interfaceGrp)

        pmc.addAttr(baseCtrl,
                    ln='stretch',
                    at='double',
                    k=1,
                    h=0,
                    minValue=0.0,
                    maxValue=1.0)

        self.ctrls.append(baseCtrl)

        aimMtx = coreUtils.getAimMatrix(start=start,
                                        end=end,
                                        axis=axis,
                                        upAxis=upAxis,
                                        worldUpAxis=upAxis)
        startSrt = coreUtils.matrixToSrt(aimMtx)
        baseBuffer.t.set(startSrt['translate'])
        baseBuffer.r.set(startSrt['rotate'])

        # ik ctrls
        cvs = ikCrv.getCVs(space='world')
        self.ikCtrls = []

        for i in range(numIkCtrls):
            num = str(i).zfill(2)
            if i > 0:
                c = controls.ballCtrl(radius=ctrlSize - (i * .25),
                                      name='%s_ik_%s_ctrl' % (self.name, num))
                b = coreUtils.addParent(
                    c, 'group', '%s_ik_buffer_%s_srt' % (self.name, num))
                b.t.set(cvs[i])
                b.setParent(self.interfaceGrp)
                d = coreUtils.decomposeMatrix(
                    c.worldMatrix[0],
                    name='%s_ikWorldMtxToSrt_%s_utl' % (self.name, num))
                d.outputTranslate.connect(ikCrv.controlPoints[i])
                componentUtils.addSpaceSwitch(node=b,
                                              name='ik_%s' % num,
                                              spaces=['base'],
                                              type='parent',
                                              ctrlNode=c,
                                              targetNodes=[baseCtrl])
                self.ctrls.append(c)
                self.ikCtrls.append(c)
            else:
                baseSrt.outputTranslate.connect(ikCrv.controlPoints[0])

        # Arclen stuff for stretching vs maintaining length
        stretch = curveUtils.getCurveStretch(ikCrv, name='%s_A' % self.name)
        blendCond = pmc.createNode('condition',
                                   name='%s_stretchIsNegative_utl' % self.name)
        stretch['stretchFactor'].outputX.connect(blendCond.firstTerm)
        self.mainGrp.globalScale.connect(stretch['globalScaleFactor'].input1X)
        # self.mainGrp.globalScale.connect(blendCond.secondTerm)
        blendCond.operation.set(2)
        blendCond.secondTerm.set(1.0)
        blendCond.colorIfTrueR.set(1)
        baseCtrl.stretch.connect(blendCond.colorIfFalseR)

        mpList = []
        settingsCtrls = []
        allBuffers = []
        upNode = baseCtrl
        # Motion Path nodes
        for x in range(numSegments):
            segNum = str(x + 1).zfill(2)

            settingsCtrl = controls.squareChamferCtrl(
                size=ctrlSize - (x * .1),
                axis=upAxis,
                name='%s_seg_%s_settings_ctrl' % (self.name, segNum))
            pmc.addAttr(settingsCtrl,
                        ln='extend',
                        at='double',
                        k=1,
                        h=0,
                        minValue=0.0,
                        maxValue=1.0)
            pmc.addAttr(settingsCtrl, ln='twist', at='double', k=1, h=0)
            pmc.addAttr(settingsCtrl, ln='width', at='double', k=1, h=0)
            pmc.addAttr(settingsCtrl, ln='taper', at='double', k=1, h=0)
            settingsCtrls.append(settingsCtrl)
            settingsCtrl.extend.set(1)

            if x != 0:
                upNode = buffers[-1]
            minRange = (1.0 / numSegments) * x
            maxRange = (1.0 / numSegments) * (x + 1)
            mpList.append(
                curveUtils.nodesAlongCurve(ikCrv,
                                           numNodes=numFkCtrls * jointsPerCtrl,
                                           name='%s_%s' % (self.name, segNum),
                                           followAxis=axis,
                                           upAxis=upAxis,
                                           upNode=upNode,
                                           follow=1,
                                           groups=0,
                                           progressive=1,
                                           sampleRange=(minRange, maxRange)))

            # Parameter values
            paramVals = [mp.uValue.get() for mp in mpList[-1]['mpNodes']]
            if bias:
                for x in range(len(paramVals)):
                    paramVals[x] += paramVals[x] - pow(paramVals[x], 1 + bias)

            pairBlends = {'pb': [], 'pbMtx': [], 'pbInverseMtx': []}

            for i in range(numFkCtrls * jointsPerCtrl):
                num = str(i + 1).zfill(2)
                mp = mpList[-1]['mpNodes'][i]
                uc = coreUtils.convert(
                    settingsCtrl.twist,
                    ((.0174533 / numFkCtrls * jointsPerCtrl) * i),
                    name='%s_seg_%s_twistMult_%s_utl' %
                    (self.name, segNum, num))
                uc.output.connect(mp.frontTwist)

                if i != 0:
                    paramExtendMult = pmc.createNode(
                        'multDoubleLinear',
                        name='%s_seg_%s_paramExtendMult_%s_utl' %
                        (self.name, segNum, num))
                    paramMult = pmc.createNode(
                        'multDoubleLinear',
                        name='%s_seg_%s_paramMult_%s_utl' %
                        (self.name, segNum, num))
                    if x != 0:
                        paramExtendMult.input1.set(paramVals[i] - minRange)
                    else:
                        paramExtendMult.input1.set(paramVals[i])
                    settingsCtrl.extend.connect(paramExtendMult.input2)

                    paramExtendMult.output.connect(paramMult.input1)
                    stretch['stretchFactor'].outputX.connect(paramMult.input2)
                    #paramMult.input2.set(1)

                    blend = pmc.createNode(
                        'blendTwoAttr',
                        name='%s_seg_%s_stretchBlend_%s_utl' %
                        (self.name, segNum, num))
                    if x != 0:
                        paramExtendOffset = coreUtils.add(
                            [
                                paramMult.output,
                                mpList[-1]['mpNodes'][0].uValue
                            ],
                            name='%s_seg_%s_paramExtendOffset_%s_utl' %
                            (self.name, segNum, num))
                        paramExtendOffset.output1D.connect(blend.input[0])

                        paramMultOffset = coreUtils.add(
                            [
                                paramMult.input1,
                                mpList[-1]['mpNodes'][0].uValue
                            ],
                            name='%s_seg_%s_paramMultOffset_%s_utl' %
                            (self.name, segNum, num))
                        paramMultOffset.output1D.connect(blend.input[1])
                    else:
                        paramMult.output.connect(blend.input[0])
                        paramMult.input1.connect(blend.input[1])

                    blendCond.outColorR.connect(blend.attributesBlender)
                    blend.output.connect(mp.uValue)
                else:
                    if x != 0:
                        mpList[-2]['mpNodes'][-1].uValue.connect(mp.uValue)

                mtx = pmc.createNode('composeMatrix',
                                     name='%s_seg_%s_worldMtx_%s_utl' %
                                     (self.name, segNum, num))
                mp.allCoordinates.connect(mtx.inputTranslate)
                mp.rotate.connect(mtx.inputRotate)
                baseSrt.outputScale.connect(mtx.inputScale)
                inverseMtx = pmc.createNode(
                    'inverseMatrix',
                    name='%s_seg_%s_worldInverseMtx_%s_utl' %
                    (self.name, segNum, num))
                mtx.outputMatrix.connect(inverseMtx.inputMatrix)

                pairBlends['pbMtx'].append(mtx)
                pairBlends['pbInverseMtx'].append(inverseMtx)

            # Build matrix chain and fk controls
            self.fkCtrls = []
            buffers = []
            d = None
            srtList = []

            for i in range(numFkCtrls * jointsPerCtrl):
                num = str(i + 1).zfill(2)
                ctrlNum = str((i / jointsPerCtrl) + 1).zfill(2)
                b = coreUtils.addChild(
                    self.interfaceGrp, 'group',
                    '%s_seg_%s_fk_buffer_%s_srt' % (self.name, segNum, num))
                buffers.append(b)
                allBuffers.append(b)
                if i % jointsPerCtrl == 0:
                    c = controls.circleBumpCtrl(name='%s_seg_%s_fk_%s_ctrl' %
                                                (self.name, segNum, ctrlNum),
                                                radius=ctrlSize * .5 -
                                                (i * .02) - (x * .1),
                                                axis=axis)

                    c.setParent(b)
                    self.fkCtrls.append(c)
                    self.ctrls.append(c)
                else:
                    b.setParent(self.rigGrp)

                if i != 0:
                    multMtx = None
                    ctrl = self.fkCtrls[-1]
                    if i % jointsPerCtrl == 0:
                        ctrl = self.fkCtrls[-2]
                    multMtx = coreUtils.multiplyMatrices(
                        [
                            pairBlends['pbMtx'][i].outputMatrix,
                            pairBlends['pbInverseMtx'][i - 1].outputMatrix,
                            ctrl.matrix, buffers[-2].worldMatrix[0]
                        ],
                        name='%s_localIkToFkMtx_%s_utl' % (self.name, num))

                    d = coreUtils.decomposeMatrix(
                        multMtx.matrixSum,
                        name='%s_seg_%s_ikToFkMtxToSrt_%s_utl' %
                        (self.name, segNum, num))
                else:
                    if x == 0:
                        d = coreUtils.decomposeMatrix(
                            pairBlends['pbMtx'][0].outputMatrix,
                            name='%s_seg_%s_ikToFkMtxToSrt_%s_utl' %
                            (self.name, segNum, num))
                    else:
                        d = coreUtils.decomposeMatrix(
                            allBuffers[-2].worldMatrix[0],
                            name='%s_seg_%s_ikToFkMtxToSrt_%s_utl' %
                            (self.name, segNum, num))
                    settingsCtrl.setParent(b)
                d.outputTranslate.connect(b.t)
                d.outputRotate.connect(b.r)
                d.outputScale.connect(b.s)
                srtList.append(d)

            widthOffset = coreUtils.add(
                [settingsCtrl.width, settingsCtrl.taper, 1],
                name='%s_%s_widthOffset_utl' % (self.name, segNum))
            widthMult = pmc.createNode('multDoubleLinear',
                                       name='%s_%s_widthMult_utl' %
                                       (self.name, segNum))
            widthOffset.output1D.connect(widthMult.input1)
            baseSrt.outputScaleX.connect(widthMult.input2)

            # Create joints
            for i in range(numFkCtrls * jointsPerCtrl):
                num = str(i + 1).zfill(2)
                j = coreUtils.addChild(
                    self.deformGrp, 'joint',
                    '%s_seg_%s_%s_dfm' % (self.name, segNum, num))
                srtList[i].outputTranslate.connect(j.t)
                srtList[i].outputRotate.connect(j.r)
                taperMult = coreUtils.convert(settingsCtrl.taper,
                                              i * .1,
                                              name='%s_%s_taperMult_%s_utl' %
                                              (self.name, segNum, num))
                taperAmount = coreUtils.add(
                    [widthOffset.output1D, taperMult.output],
                    name='%s_%s_taperAmount_%s_utl' % (self.name, segNum, num))
                taperAmount.output1D.connect(j.sx)
                taperAmount.output1D.connect(j.sy)
                taperAmount.output1D.connect(j.sz)
                scaleAttr = pmc.Attribute('%s.s%s' % (j.name(), axis[-1]))
                srtList[i].outputScaleX.connect(scaleAttr, f=1)
Example #12
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 #13
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
Example #14
0
def connectIO(dest, source, connectionName):
    '''
    checks for an output from source. If it finds one, creates a corresponding input on dest's component input group
    If an input already exists it will be used instead. Also creates an offset group under the input which
    is the node to decompose and connect things to within the component
    :param dest: node to drive from the new input (usually a ctrl's buffer_srt
    :param source: node to connect the input to
    :param connectionName: name for the new input connection
    :return: offset group under new input node
    '''
    if dest.getParent() == getComponentGroup(dest, 'input'):
        # check whether source is in worldspace. If so apply a direct connection
        offset = coreUtils.addChild(
            getComponentGroup(dest, 'input'), 'group',
            '%s_%s_in_srt' % (getComponentFromName(dest), connectionName))
        if source.worldMatrix.get() == source.matrix.get():
            source.t.connect(offset.t)
            source.r.connect(offset.r)
            source.s.connect(offset.s)
        else:
            d = coreUtils.isDecomposed(source)
            coreUtils.connectDecomposedMatrix(d, offset)
        dest.setParent(offset)
    elif getComponentFromName(dest) == getComponentFromName(source):
        if dest.getParent() == getComponentGroup(
                dest, 'interface') or dest.getParent() == getComponentGroup(
                    dest, 'rig'):

            print 'creating rig input'
            # This means source and dest are in the same component and a target can be added to the rig group
            offset = coreUtils.createAlignedNode(
                dest, 'group', '%s_%s_%sOffset_srt' %
                (getComponentFromName(dest), connectionName,
                 dest.name().split('_')[2]))
            rels = pmc.listRelatives(getComponentGroup(dest, 'rig'), ad=1, c=1)
            if source in rels:
                offset.setParent(source)
            else:
                input = coreUtils.addChild(
                    getComponentGroup(dest, 'rig'), 'group', '%s_%s_%s_srt' %
                    (getComponentFromName(dest), connectionName,
                     dest.name().split('_')[2]))
                if source.worldMatrix.get() == source.matrix.get():
                    source.t.connect(input.t)
                    source.r.connect(input.r)
                    source.s.connect(input.s)
                else:
                    d = coreUtils.isDecomposed(source)
                    coreUtils.connectDecomposedMatrix(d, input)
                offset.setParent(input)
            d = coreUtils.isDecomposed(offset)
            coreUtils.connectDecomposedMatrix(d, dest)
    else:
        output = getOutput(source)
        if not output:
            output = exposeOutput(source)
        input = getInput(dest, output)
        print 'creating new input'
        input = exposeInput(dest, output, connectionName)
        conns = pmc.listConnections(dest.t, d=0, type='decomposeMatrix')
        offset = None
        if conns:
            offset = pmc.listConnections(conns[0].inputMatrix, d=0)[0]
            if offset.getParent() != input:
                offset.setParent(input)
                offset.rename(offset.getParent().name().replace(
                    '_srt', '_%sOffset_srt' % dest.name().split('_')[2]))
        else:
            offset = coreUtils.createAlignedNode(
                dest, 'group', '%s_%s_in_%sOffset_srt' %
                (getComponentFromName(dest), connectionName,
                 dest.name().split('_')[2]))
            offset.setParent(input)

            # Check whether dest is in worldspace. If so, use a direct connection. Otherwise, multiply by parent mtx
            if dest.worldMatrix.get() != dest.matrix.get():
                m = coreUtils.multiplyMatrices(
                    [
                        offset.worldMatrix[0],
                        dest.getParent().worldInverseMatrix
                    ], '%s_%s_localMtx_utl' %
                    (getComponentFromName(dest), connectionName))
                d = coreUtils.decomposeMatrix(
                    m.matrixSum, '%s_%s_localMtxToSrt_utl' %
                    (getComponentFromName(dest), connectionName))
                coreUtils.connectDecomposedMatrix(d, dest)
            else:
                d = coreUtils.isDecomposed(offset)
                coreUtils.connectDecomposedMatrix(d, dest)
        return offset
Example #15
0
    def build(self):
        self.dnt_grp = pmc.group(empty=1, name='%s_doNotTouch' % self.name)
        self.dnt_grp.inheritsTransform.set(0)
        numSpans = len(self.points) - 2
        self.cv_locs = []
        self.spans = []
        for i in range(len(self.points)):
            num = str(i + 1).zfill(2)
            loc = coreUtils.createAlignedNode(self.points[i], 'locator', '%s_cv_%s_loc' % (self.name, num))
            self.cv_locs.append(loc)
        for i in range(numSpans):
            span = self.buildSpan(self.cv_locs[i:i + 3], i)
            span['main_grp'].setParent(self.dnt_grp)
            self.spans.append(span)

        if not self.closed:
            # Build start tangent
            tanGrp = coreUtils.addChild(self.cv_locs[0], 'group', '%s_startTangent_GRP' % self.name)
            pmc.aimConstraint(self.spans[0]['inTan'], tanGrp, wut='objectrotation', wuo=self.cv_locs[0])

            outTan_loc = coreUtils.addChild(tanGrp, 'locator', '%s_outTangent_LOC' % self.name)

            pmc.addAttr(self.cv_locs[0], ln='tangentWeight', at="float", minValue=0.0, maxValue=1.0, keyable=1,
                        hidden=0, defaultValue=0.25)

            weight_md = coreUtils.multiply(self.spans[0]['inDist'].distance, self.cv_locs[0].tangentWeight,
                                           'md_%s_start_weight_UTL' % self.name)
            weight_md.outputX.connect(outTan_loc.tx)

            # Build end tangent
            tanGrp = coreUtils.addChild(self.cv_locs[-1], 'group', '%s_endTangent_GRP' % self.name)
            pmc.aimConstraint(self.spans[-1]['outTan'], tanGrp, wut='objectrotation', wuo=self.cv_locs[-1])

            inTan_loc = coreUtils.addChild(tanGrp, 'locator', '%s_inTangent_LOC' % self.name)

            pmc.addAttr(self.cv_locs[-1], ln='tangentWeight', at="float", minValue=0.0, maxValue=1.0, keyable=1,
                        hidden=0, defaultValue=0.25)

            weight_md = coreUtils.multiply(self.spans[-1]['outDist'].distance, self.cv_locs[-1].tangentWeight,
                                           'md_%s_end_weight_UTL' % self.name)
            weight_md.outputX.connect(inTan_loc.tx)

            self.spans.append({
                'endTan': inTan_loc,
                'startTan': outTan_loc,
            })

            # Collect points for curve
            self.crv_points = [self.cv_locs[0], self.spans[-1]['startTan']]
            for i in range(len(self.spans) - 1):
                self.crv_points.append(self.spans[i]['inTan'])
                # self.crv_points.append(self.cv_locs[i+1])
                self.crv_points.append(self.spans[i]['outTan'])
            self.crv_points.append(self.spans[-1]['endTan'])
            self.crv_points.append(self.cv_locs[-1])

            # Create curve and connect points
            self.crv = curveThroughPoints(positions=[p.worldPosition[0].get() for p in self.crv_points], name=self.name)
            self.crv.setParent(self.dnt_grp)

            for i in range(len(self.crv_points)):
                self.crv_points[i].worldPosition[0].connect(self.crv.controlPoints[i])

        else:
            self.spans.append(self.buildSpan([self.cv_locs[-2], self.cv_locs[-1], self.cv_locs[0]], numSpans + 1))
            self.spans.append(self.buildSpan([self.cv_locs[-2], self.cv_locs[-1], self.cv_locs[0]], numSpans + 2))
Example #16
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 #17
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 #18
0
    def build(self, start, end, numFkCtrls, jointsPerCtrl, numIkCtrls, axis,
              upAxis, bias, doubleIkChain):
        start, end = coreUtils.getStartAndEnd(start, end)
        ctrlSize = coreUtils.getDistance(start, end) * .2
        # Build ik curves
        ikCrvA = curveUtils.curveBetweenNodes(start,
                                              end,
                                              numCVs=numIkCtrls,
                                              name='%s_ik_A_crv' % self.name)
        ikCrvA.setParent(self.rigGrp)
        if doubleIkChain:
            ikCrvB = curveUtils.curveBetweenNodes(start,
                                                  end,
                                                  numCVs=numIkCtrls,
                                                  name='%s_ik_B_crv' %
                                                  self.name)
            ikCrvB.setParent(self.rigGrp)

        # main control
        baseCtrl = controls.circleBumpCtrl(radius=ctrlSize,
                                           name='%s_base_ctrl' % self.name,
                                           axis=axis)
        baseSrt = coreUtils.decomposeMatrix(baseCtrl.worldMatrix[0],
                                            name='%s_baseWorldMtxToSrt_utl' %
                                            baseCtrl)
        baseBuffer = coreUtils.addParent(baseCtrl,
                                         'group',
                                         name='%s_base_buffer_srt' % self.name)
        baseBuffer.setParent(self.interfaceGrp)
        self.ctrls.append(baseCtrl)

        aimMtx = coreUtils.getAimMatrix(start=start,
                                        end=end,
                                        axis=axis,
                                        upAxis=upAxis,
                                        worldUpAxis=upAxis)
        startSrt = coreUtils.matrixToSrt(aimMtx)
        baseBuffer.t.set(startSrt['translate'])
        baseBuffer.r.set(startSrt['rotate'])

        if doubleIkChain:
            pmc.addAttr(baseCtrl,
                        ln='A_B_blend',
                        at='double',
                        k=1,
                        h=0,
                        minValue=0.0,
                        maxValue=1.0)
        pmc.addAttr(baseCtrl,
                    ln='stretch',
                    at='double',
                    k=1,
                    h=0,
                    minValue=0.0,
                    maxValue=1.0)
        pmc.addAttr(baseCtrl,
                    ln='pin',
                    at='enum',
                    enumName='head:tail',
                    k=1,
                    h=0)
        pmc.addAttr(baseCtrl,
                    ln='extend',
                    at='double',
                    k=1,
                    h=0,
                    minValue=0.0,
                    maxValue=1.0)
        pmc.addAttr(baseCtrl, ln='twist', at='double', k=1, h=0)
        pmc.addAttr(baseCtrl,
                    ln='upVector',
                    at='enum',
                    enumName='x:y:z',
                    k=1,
                    h=0)
        baseCtrl.extend.set(1)

        # ik ctrls
        cvsA = ikCrvA.getCVs(space='world')
        self.ikACtrls = []
        if doubleIkChain:
            cvsB = ikCrvB.getCVs(space='world')
            self.ikBCtrls = []
        for i in range(numIkCtrls):
            num = str(i).zfill(2)
            if i > 0:
                c = controls.squareCtrl(size=ctrlSize * 1.5,
                                        name='%s_ik_%s_A_ctrl' %
                                        (self.name, num),
                                        axis=axis)
                b = coreUtils.addParent(
                    c, 'group', '%s_ik_buffer_A_%s_srt' % (self.name, num))
                b.t.set(cvsA[i])
                b.setParent(self.interfaceGrp)
                d = coreUtils.decomposeMatrix(
                    c.worldMatrix[0],
                    name='%s_ikWorldMtxToSrt_A_%s_utl' % (self.name, num))
                d.outputTranslate.connect(ikCrvA.controlPoints[i])
                componentUtils.addSpaceSwitch(node=b,
                                              name='ik_%s' % num,
                                              spaces=['base'],
                                              type='parent',
                                              ctrlNode=c,
                                              targetNodes=[baseCtrl])
                self.ctrls.append(c)
                self.ikACtrls.append(c)

                if doubleIkChain:
                    c = controls.squareCtrl(size=ctrlSize * 1.25,
                                            name='%s_ik_%s_B_ctrl' %
                                            (self.name, num),
                                            axis=axis)
                    b = coreUtils.addParent(
                        c, 'group', '%s_ik_buffer_B_%s_srt' % (self.name, num))
                    b.t.set(cvsB[i])
                    b.setParent(self.interfaceGrp)
                    d = coreUtils.decomposeMatrix(
                        c.worldMatrix[0],
                        name='%s_ikWorldMtxToSrt_B_%s_utl' % (self.name, num))
                    d.outputTranslate.connect(ikCrvB.controlPoints[i])
                    componentUtils.addSpaceSwitch(node=b,
                                                  name='ik_%s' % num,
                                                  spaces=['base'],
                                                  type='parent',
                                                  ctrlNode=c,
                                                  targetNodes=[baseCtrl])

                    self.ikBCtrls.append(c)
                    self.ctrls.append(c)
            else:
                baseSrt.outputTranslate.connect(ikCrvA.controlPoints[0])
                if doubleIkChain:
                    baseSrt.outputTranslate.connect(ikCrvB.controlPoints[0])

        # Arclen stuff for stretching vs maintaining length
        stretchA = curveUtils.getCurveStretch(ikCrvA, name='%s_A' % self.name)
        blendACond = pmc.createNode('condition',
                                    name='%s_stretchIsNegativeA_utl' %
                                    self.name)
        stretchA['stretchFactor'].outputX.connect(blendACond.firstTerm)
        self.mainGrp.globalScale.connect(stretchA['globalScaleFactor'].input1X)
        #self.mainGrp.globalScale.connect(blendACond.secondTerm)
        blendACond.operation.set(2)
        blendACond.secondTerm.set(1.0)
        blendACond.colorIfTrueR.set(1)
        baseCtrl.stretch.connect(blendACond.colorIfFalseR)
        if doubleIkChain:
            stretchB = curveUtils.getCurveStretch(ikCrvB,
                                                  name='%s_B' % self.name)
            blendBCond = pmc.createNode('condition',
                                        name='%s_stretchIsNegativeB_utl' %
                                        self.name)
            stretchB['stretchFactor'].outputX.connect(blendBCond.firstTerm)
            self.mainGrp.globalScale.connect(
                stretchB['globalScaleFactor'].input1X)
            #self.mainGrp.globalScale.connect(blendBCond.secondTerm)
            blendBCond.secondTerm.set(1.0)
            blendBCond.operation.set(2)
            blendBCond.colorIfTrueR.set(1)
            baseCtrl.stretch.connect(blendBCond.colorIfFalseR)

        # Motion Path nodes
        upVecX = pmc.createNode('colorConstant',
                                name='%s_upVecX_utl' % self.name)
        upVecX.inColor.set((1, 0, 0))
        upVecY = pmc.createNode('colorConstant',
                                name='%s_upVecY_utl' % self.name)
        upVecY.inColor.set((0, 1, 0))
        upVecZ = pmc.createNode('colorConstant',
                                name='%s_upVecZ_utl' % self.name)
        upVecZ.inColor.set((0, 0, 1))
        upVecChoice = pmc.createNode('choice',
                                     name='%s_upVecChoice_utl' % self.name)
        upVecX.outColor.connect(upVecChoice.input[0])
        upVecY.outColor.connect(upVecChoice.input[1])
        upVecZ.outColor.connect(upVecChoice.input[2])

        baseCtrl.upVector.connect(upVecChoice.selector)
        mpsA = curveUtils.nodesAlongCurve(ikCrvA,
                                          numNodes=numFkCtrls * jointsPerCtrl,
                                          name='%s_A' % self.name,
                                          followAxis=axis,
                                          upAxis=upAxis,
                                          upNode=baseCtrl,
                                          follow=1,
                                          groups=0)

        if doubleIkChain:
            mpsB = curveUtils.nodesAlongCurve(ikCrvB,
                                              numNodes=numFkCtrls *
                                              jointsPerCtrl,
                                              name='%s_B' % self.name,
                                              followAxis=axis,
                                              upAxis=upAxis,
                                              upNode=baseCtrl,
                                              follow=1,
                                              groups=0)
        # Parameter values
        paramVals = [mp.uValue.get() for mp in mpsA['mpNodes']]
        if bias:
            for i in range(len(paramVals)):
                paramVals[i] += paramVals[i] - pow(paramVals[i], 1 + bias)

        pairBlends = {'pb': [], 'pbMtx': [], 'pbInverseMtx': []}

        for i in range(numFkCtrls * jointsPerCtrl):
            num = str(i + 1).zfill(2)
            mpA = mpsA['mpNodes'][i]
            baseCtrl.upVector.connect(mpA.upAxis)
            upVecChoice.output.connect(mpA.worldUpVector)
            uc = coreUtils.convert(
                baseCtrl.twist, ((.0174533 / numFkCtrls * jointsPerCtrl) * i),
                name='%s_twistMult_%s_utl' % (self.name, num))
            uc.output.connect(mpA.frontTwist)
            paramExtendMult = pmc.createNode(
                'multDoubleLinear',
                name='%s_paramExtendMult_%s_A_utl' % (self.name, num))
            paramMult = pmc.createNode('multDoubleLinear',
                                       name='%s_paramMult_%s_A_utl' %
                                       (self.name, num))
            paramExtendMult.input1.set(paramVals[i])
            baseCtrl.extend.connect(paramExtendMult.input2)
            paramExtendMult.output.connect(paramMult.input1)
            stretchA['stretchFactor'].outputX.connect(paramMult.input2)
            blendA = pmc.createNode('blendTwoAttr',
                                    name='%s_stretchBlend_%s_A_utl' %
                                    (self.name, num))
            paramMult.output.connect(blendA.input[0])
            paramMult.input1.connect(blendA.input[1])

            blendACond.outColorR.connect(blendA.attributesBlender)
            blendA.output.connect(mpA.uValue)

            if doubleIkChain:
                mpB = mpsB['mpNodes'][i]
                baseCtrl.upVector.connect(mpB.upAxis)
                upVecChoice.output.connect(mpB.worldUpVector)
                uc.output.connect(mpB.frontTwist)
                paramMult = pmc.createNode('multDoubleLinear',
                                           name='%s_paramMult_%s_B_utl' %
                                           (self.name, num))
                paramExtendMult.output.connect(paramMult.input1)
                stretchB['stretchFactor'].outputX.connect(paramMult.input2)
                blendB = pmc.createNode('blendTwoAttr',
                                        name='%s_stretchBlend_%s_B_utl' %
                                        (self.name, num))
                paramMult.output.connect(blendB.input[0])
                paramMult.input1.connect(blendB.input[1])
                blendBCond.outColorR.connect(blendB.attributesBlender)
                blendB.output.connect(mpB.uValue)

                rv = pmc.createNode('remapValue',
                                    name='%s_blendRemap_%s_utl' %
                                    (self.name, num))
                baseCtrl.A_B_blend.connect(rv.inputValue)
                rv.value[0].value_Interp.set(2)
                startPos = (1.0 / (numFkCtrls * jointsPerCtrl - 1)) * i * .67
                endPos = startPos + .33
                rv.value[0].value_Position.set(startPos)
                rv.value[1].value_Position.set(endPos)

                pb = coreUtils.pairBlend(mpA.allCoordinates,
                                         mpA.rotate,
                                         mpB.allCoordinates,
                                         mpB.rotate,
                                         '%s_curveBlend_%s_utl' %
                                         (self.name, num),
                                         blendAttr=rv.outValue)
                pbMtx = pmc.createNode('composeMatrix',
                                       name='%s_worldMtx_%s_utl' %
                                       (self.name, num))
                pb.outTranslate.connect(pbMtx.inputTranslate)
                pb.outRotate.connect(pbMtx.inputRotate)
                baseSrt.outputScale.connect(pbMtx.inputScale)
                pbInverseMtx = pmc.createNode(
                    'inverseMatrix',
                    name='%s_worldInverseMtx_%s_utl' % (self.name, num))
                pbMtx.outputMatrix.connect(pbInverseMtx.inputMatrix)

                pairBlends['pb'].append(pb)
                pairBlends['pbMtx'].append(pbMtx)
                pairBlends['pbInverseMtx'].append(pbInverseMtx)
            else:
                mtx = pmc.createNode('composeMatrix',
                                     name='%s_worldMtx_%s_utl' %
                                     (self.name, num))
                mpA.allCoordinates.connect(mtx.inputTranslate)
                mpA.rotate.connect(mtx.inputRotate)
                baseSrt.outputScale.connect(mtx.inputScale)
                inverseMtx = pmc.createNode('inverseMatrix',
                                            name='%s_worldInverseMtx_%s_utl' %
                                            (self.name, num))
                mtx.outputMatrix.connect(inverseMtx.inputMatrix)

                pairBlends['pbMtx'].append(mtx)
                pairBlends['pbInverseMtx'].append(inverseMtx)

        # Build matrix chain and fk controls
        self.fkCtrls = []
        buffers = []
        d = None
        srtList = []

        for i in range(numFkCtrls * jointsPerCtrl):
            num = str(i + 1).zfill(2)
            ctrlNum = str((i / jointsPerCtrl) + 1).zfill(2)
            b = coreUtils.addChild(self.interfaceGrp, 'group',
                                   '%s_fk_buffer_%s_srt' % (self.name, num))
            buffers.append(b)
            if i % jointsPerCtrl == 0:
                c = controls.circleBumpCtrl(name='%s_fk_%s_ctrl' %
                                            (self.name, ctrlNum),
                                            radius=ctrlSize * .5,
                                            axis=axis)

                c.setParent(b)
                self.fkCtrls.append(c)
                self.ctrls.append(c)
            else:
                b.setParent(self.rigGrp)

            if i != 0:
                multMtx = None
                ctrl = self.fkCtrls[-1]
                if i % jointsPerCtrl == 0:
                    ctrl = self.fkCtrls[-2]
                multMtx = coreUtils.multiplyMatrices(
                    [
                        pairBlends['pbMtx'][i].outputMatrix,
                        pairBlends['pbInverseMtx'][i - 1].outputMatrix,
                        ctrl.matrix, buffers[-2].worldMatrix[0]
                    ],
                    name='%s_localIkToFkMtx_%s_utl' % (self.name, num))

                d = coreUtils.decomposeMatrix(multMtx.matrixSum,
                                              name='%s_ikToFkMtxToSrt_%s_utl' %
                                              (self.name, num))
            else:
                d = coreUtils.decomposeMatrix(
                    pairBlends['pbMtx'][0].outputMatrix,
                    name='%s_ikToFkMtxToSrt_%s_utl' % (self.name, num))
            d.outputTranslate.connect(b.t)
            d.outputRotate.connect(b.r)
            d.outputScale.connect(b.s)
            srtList.append(d)

        # Create joints
        for i in range(numFkCtrls * jointsPerCtrl):
            num = str(i + 1).zfill(2)
            j = coreUtils.addChild(self.deformGrp, 'joint',
                                   '%s_%s_dfm' % (self.name, num))
            srtList[i].outputTranslate.connect(j.t)
            srtList[i].outputRotate.connect(j.r)
            srtList[i].outputScale.connect(j.s)