Exemplo n.º 1
0
class FKChainComponentRig(FKChainComponent):
    """FK Chain Leg Rig"""
    def __init__(self, name='FKChain', parent=None):

        Profiler.getInstance().push("Construct FK Chain Rig Component:" + name)
        super(FKChainComponentRig, self).__init__(name, parent)

        # =========
        # Controls
        # =========
        # FK
        self.fkCtrlSpaces = []
        self.fkCtrls = []
        self.setNumControls(4)

        # Add Component Params to IK control
        legSettingsAttrGrp = AttributeGroup("DisplayInfo_ChainSettings",
                                            parent=self.fkCtrls[0])
        legdrawDebugInputAttr = BoolAttribute('drawDebug',
                                              value=False,
                                              parent=legSettingsAttrGrp)

        # Connect IO to controls
        self.drawDebugInputAttr.connect(legdrawDebugInputAttr)

        # ==========
        # Deformers
        # ==========
        deformersLayer = self.getOrCreateLayer('deformers')
        self.defCmpGrp = ComponentGroup(self.getName(),
                                        self,
                                        parent=deformersLayer)
        self.deformerJoints = []
        self.boneOutputsTgt = []
        self.setNumDeformers(4)

        # =====================
        # Create Component I/O
        # =====================

        # Set IO Targets
        self.boneOutputs.setTarget(self.boneOutputsTgt)

        # ==============
        # Constrain I/O
        # ==============
        # Constraint inputs
        self.rootInputConstraint = PoseConstraint('_'.join([
            self.fkCtrlSpaces[0].getName(), 'To',
            self.rootInputTgt.getName()
        ]))
        self.rootInputConstraint.setMaintainOffset(True)
        self.rootInputConstraint.addConstrainer(self.rootInputTgt)
        self.fkCtrlSpaces[0].addConstraint(self.rootInputConstraint)

        # ===============
        # Add Splice Ops
        # ===============
        # Add Output Splice Op
        self.outputsToControlsKLOp = KLOperator('fkChainOutputKLOp',
                                                'MultiPoseConstraintSolver',
                                                'Kraken')
        self.addOperator(self.outputsToControlsKLOp)

        # Add Att Inputs
        self.outputsToControlsKLOp.setInput('drawDebug',
                                            self.drawDebugInputAttr)
        self.outputsToControlsKLOp.setInput('rigScale', self.rigScaleInputAttr)

        # Add Xfo Inputs
        self.outputsToControlsKLOp.setInput('constrainers', self.fkCtrls)

        # Add Xfo Outputs
        self.outputsToControlsKLOp.setOutput('constrainees',
                                             self.boneOutputsTgt)

        # Add Deformer Splice Op
        self.deformersToOutputsKLOp = KLOperator('fkChainDeformerKLOp',
                                                 'MultiPoseConstraintSolver',
                                                 'Kraken')
        self.addOperator(self.deformersToOutputsKLOp)

        # Add Att Inputs
        self.deformersToOutputsKLOp.setInput('drawDebug',
                                             self.drawDebugInputAttr)
        self.deformersToOutputsKLOp.setInput('rigScale',
                                             self.rigScaleInputAttr)

        # Add Xfo Inputs
        self.deformersToOutputsKLOp.setInput('constrainers',
                                             self.boneOutputsTgt)

        # Add Xfo Outputs
        self.deformersToOutputsKLOp.setOutput('constrainees',
                                              self.deformerJoints)

        Profiler.getInstance().pop()

    def setNumControls(self, numControls):

        # Add more controls
        if numControls > len(self.fkCtrlSpaces):
            for i in xrange(len(self.fkCtrlSpaces), numControls):
                if i == 0:
                    parent = self.ctrlCmpGrp
                else:
                    parent = self.fkCtrls[i - 1]

                boneName = 'bone' + str(i + 1).zfill(2) + 'FK'
                boneFKCtrlSpace = CtrlSpace(boneName, parent=parent)

                boneFKCtrl = Control(boneName,
                                     parent=boneFKCtrlSpace,
                                     shape="cube")
                boneFKCtrl.alignOnXAxis()
                boneFKCtrl.lockScale(x=True, y=True, z=True)
                boneFKCtrl.lockTranslation(x=True, y=True, z=True)

                self.fkCtrlSpaces.append(boneFKCtrlSpace)
                self.fkCtrls.append(boneFKCtrl)

        # Remove extra ctrls
        elif numControls < len(self.fkCtrlSpaces):
            numExtraCtrls = len(self.fkCtrls) - numControls
            for i in xrange(numExtraCtrls):
                extraCtrlSpace = self.fkCtrlSpaces.pop()
                extraCtrl = self.fkCtrls.pop()
                extraCtrlSpace.getParent().removeChild(extraCtrlSpace)
                extraCtrl.getParent().removeChild(extraCtrl)

    def setNumDeformers(self, numDeformers):

        # Add more deformers and outputs
        if numDeformers > len(self.boneOutputsTgt):
            for i in xrange(len(self.boneOutputsTgt), numDeformers):
                name = 'bone' + str(i + 1).zfill(2)

                legOutput = ComponentOutput(name, parent=self.outputHrcGrp)
                self.boneOutputsTgt.append(legOutput)

                boneDef = Joint(name, parent=self.defCmpGrp)
                boneDef.setComponent(self)
                self.deformerJoints.append(boneDef)

        # Remove extra deformers and outputs
        elif numDeformers < len(self.boneOutputsTgt):
            numExtraOutputs = len(self.boneOutputsTgt) - numDeformers
            numExtraDefs = len(self.deformerJoints) - numDeformers

            for i in xrange(numExtraOutputs):
                extraOutput = self.boneOutputsTgt.pop()
                extraDef = self.deformerJoints.pop()

                extraOutput.getParent().removeChild(extraOutput)
                extraDef.getParent().removeChild(extraDef)

        return True

    def loadData(self, data=None):
        """Load a saved guide representation from persisted data.

        Arguments:
        data -- object, The JSON data object.

        Return:
        True if successful.

        """

        super(FKChainComponentRig, self).loadData(data)

        boneXfos = data['boneXfos']
        boneLengths = data['boneLengths']
        numJoints = data['numJoints']

        # Add extra controls and outputs
        self.setNumControls(numJoints)
        self.setNumDeformers(numJoints)

        for i in xrange(numJoints):
            self.fkCtrlSpaces[i].xfo = boneXfos[i]
            self.fkCtrls[i].xfo = boneXfos[i]
            self.fkCtrls[i].scalePoints(
                Vec3(boneLengths[i], boneLengths[i] * 0.45,
                     boneLengths[i] * 0.45))

        # ==========================
        # Create Output Constraints
        # ==========================
        # This needs to be done here since the 'numJoints' attribute resizes the
        # number of controls and outputs

        self.chainEndXfoOutputConstraint = PoseConstraint('_'.join([
            self.chainEndXfoOutputTgt.getName(), 'To',
            self.boneOutputsTgt[-1].getName()
        ]))
        self.chainEndXfoOutputConstraint.setMaintainOffset(True)
        self.chainEndXfoOutputConstraint.addConstrainer(
            self.boneOutputsTgt[-1])
        self.chainEndXfoOutputTgt.addConstraint(
            self.chainEndXfoOutputConstraint)

        self.chainEndPosOutputConstraint = PositionConstraint('_'.join([
            self.chainEndPosOutputTgt.getName(), 'To',
            self.boneOutputsTgt[-1].getName()
        ]))
        self.chainEndPosOutputConstraint.setMaintainOffset(True)
        self.chainEndPosOutputConstraint.addConstrainer(
            self.boneOutputsTgt[-1])
        self.chainEndPosOutputTgt.addConstraint(
            self.chainEndPosOutputConstraint)

        # ============
        # Set IO Xfos
        # ============
        self.rootInputTgt.xfo = boneXfos[0]

        for i in xrange(numJoints):
            self.boneOutputsTgt[i].xfo = boneXfos[i]

        self.chainEndXfoOutputTgt.xfo = data['endXfo']
        self.chainEndPosOutputTgt.xfo = data['endXfo']

        # =============
        # Set IO Attrs
        # =============

        # ====================
        # Evaluate Splice Ops
        # ====================
        # Eval Outputs to Controls Op to evaulate with new outputs and controls
        self.outputsToControlsKLOp.evaluate()

        # evaluate the output splice op to evaluate with new outputs and deformers
        self.deformersToOutputsKLOp.evaluate()

        # evaluate the constraints to ensure the outputs are now in the correct location.
        self.rootInputConstraint.evaluate()
        self.chainEndXfoOutputConstraint.evaluate()