def resizeDigits(self, numJoints): initNumJoints = numJoints for finger in self.fingers.keys(): if finger == "thumb": numJoints = 3 else: numJoints = initNumJoints if numJoints + 1 == len(self.fingers[finger]): continue elif numJoints + 1 > len(self.fingers[finger]): for i in xrange(len(self.fingers[finger]), numJoints + 1): prevDigit = self.fingers[finger][i - 1] digitCtrl = Control(finger + str(i + 1).zfill(2), parent=prevDigit, shape='sphere') digitCtrl.setColor('orange') digitCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) digitCtrl.lockScale(True, True, True) self.fingers[finger].append(digitCtrl) elif numJoints + 1 < len(self.fingers[finger]): numExtraCtrls = len(self.fingers[finger]) - (numJoints + 1) for i in xrange(numExtraCtrls): removedJoint = self.fingers[finger].pop() removedJoint.getParent().removeChild(removedJoint) self.placeFingers()
def updateNumDeformers(self, count): """Generate the guide controls for the variable outputes array. Arguments: count -- object, The number of joints inthe chain. Return: True if successful. """ if count == 0: raise IndexError("'count' must be > 0") vertebraeOutputs = self.tailVertebraeOutput.getTarget() if count > len(vertebraeOutputs): for i in xrange(len(vertebraeOutputs), count): debugCtrl = Control('spine' + str(i+1).zfill(2), parent=self.outputHrcGrp, shape="vertebra") debugCtrl.rotatePoints(0, -90, 0) debugCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) debugCtrl.setColor('turqoise') vertebraeOutputs.append(debugCtrl) elif count < len(vertebraeOutputs): numExtraCtrls = len(vertebraeOutputs) - count for i in xrange(numExtraCtrls): extraCtrl = vertebraeOutputs.pop() self.outputHrcGrp.removeChild(extraCtrl) return True
def resizeDigits(self, numJoints): initNumJoints = numJoints for finger in self.fingers.keys(): if finger == "thumb": numJoints = 3 else: numJoints = initNumJoints if numJoints + 1 == len(self.fingers[finger]): continue elif numJoints + 1 > len(self.fingers[finger]): for i in xrange(len(self.fingers[finger]), numJoints + 1): prevDigit = self.fingers[finger][i - 1] digitCtrl = Control(finger + str(i + 1).zfill(2), parent=prevDigit, shape='sphere') digitCtrl.setColor('orange') digitCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) digitCtrl.lockScale(True, True, True) self.fingers[finger].append(digitCtrl) elif numJoints + 1 < len(self.fingers[finger]): numExtraCtrls = len(self.fingers[finger]) - (numJoints + 1) for i in xrange(numExtraCtrls): removedJoint = self.fingers[finger].pop() removedJoint.getParent().removeChild(removedJoint) self.placeFingers()
def updateNumDeformers(self, count): """Generate the guide controls for the variable outputes array. Arguments: count -- object, The number of joints inthe chain. Return: True if successful. """ if count == 0: raise IndexError("'count' must be > 0") vertebraeOutputs = self.tailVertebraeOutput.getTarget() if count > len(vertebraeOutputs): for i in xrange(len(vertebraeOutputs), count): debugCtrl = Control('spine' + str(i+1).zfill(2), parent=self.outputHrcGrp, shape="vertebra") debugCtrl.rotatePoints(0, -90, 0) debugCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) debugCtrl.setColor('turqoise') vertebraeOutputs.append(debugCtrl) elif count < len(vertebraeOutputs): numExtraCtrls = len(vertebraeOutputs) - count for i in xrange(numExtraCtrls): extraCtrl = vertebraeOutputs.pop() self.outputHrcGrp.removeChild(extraCtrl) return True
def updateNumLowDeformers(self, countLow): if countLow == 0: raise IndexError("'count' must be > 0") #Lip Low lidLowOutputs = self.eyelidLowOutput.getTarget() if countLow > len(lidLowOutputs): for i in xrange(len(lidLowOutputs), countLow): debugLowCtrl = Control('Lid_Low_' + str(i+1).zfill(2), parent=self.outputHrcGrp, shape="sphere") debugLowCtrl.rotatePoints(90, -90, 180) debugLowCtrl.scalePoints(Vec3(0.01, 0.01, 0.01)) debugLowCtrl.setColor("yellowLight") lidLowOutputs.append(debugLowCtrl) elif countLow < len(lidLowOutputs): numExtraLowCtrls = len(lidLowOutputs) - countLow for i in xrange(numExtraLowCtrls): extraLowCtrl = lidLowOutputs.pop() self.outputHrcGrp.removeChild(extraLowCtrl) return True
class SpineComponentGuide(SpineComponent): """Spine Component Guide""" def __init__(self, name='spine', parent=None): Profiler.getInstance().push("Construct Spine Guide Component:" + name) super(SpineComponentGuide, self).__init__(name, parent) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.numDeformersAttr = IntegerAttribute('numDeformers', value=1, minValue=0, maxValue=20, parent=guideSettingsAttrGrp) # Guide Controls self.cog = Control('cogPosition', parent=self.ctrlCmpGrp, shape="sphere") self.cog.scalePoints(Vec3(1.2, 1.2, 1.2)) self.cog.setColor('red') self.spine01Ctrl = Control('spine01Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine02Ctrl = Control('spine02Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine03Ctrl = Control('spine03Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine04Ctrl = Control('spine04Position', parent=self.ctrlCmpGrp, shape='sphere') self.loadData({ 'name': name, 'location': 'M', 'cogPosition': Vec3(0.0, 11.1351, -0.1382), 'spine01Position': Vec3(0.0, 11.1351, -0.1382), 'spine02Position': Vec3(0.0, 11.8013, -0.1995), 'spine03Position': Vec3(0.0, 12.4496, -0.3649), 'spine04Position': Vec3(0.0, 13.1051, -0.4821), 'numDeformers': 6 }) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(SpineComponentGuide, self).saveData() data['cogPosition'] = self.cog.xfo.tr data['spine01Position'] = self.spine01Ctrl.xfo.tr data['spine02Position'] = self.spine02Ctrl.xfo.tr data['spine03Position'] = self.spine03Ctrl.xfo.tr data['spine04Position'] = self.spine04Ctrl.xfo.tr data['numDeformers'] = self.numDeformersAttr.getValue() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(SpineComponentGuide, self).loadData(data) self.cog.xfo.tr = data["cogPosition"] self.spine01Ctrl.xfo.tr = data["spine01Position"] self.spine02Ctrl.xfo.tr = data["spine02Position"] self.spine03Ctrl.xfo.tr = data["spine03Position"] self.spine04Ctrl.xfo.tr = data["spine04Position"] self.numDeformersAttr.setValue(data["numDeformers"]) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(SpineComponentGuide, self).getRigBuildData() data['cogPosition'] = self.cog.xfo.tr data['spine01Position'] = self.spine01Ctrl.xfo.tr data['spine02Position'] = self.spine02Ctrl.xfo.tr data['spine03Position'] = self.spine03Ctrl.xfo.tr data['spine04Position'] = self.spine04Ctrl.xfo.tr data['numDeformers'] = self.numDeformersAttr.getValue() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return SpineComponentRig
class FabriceHeadGuide(FabriceHead): """Fabrice Head Component Guide""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Guide Component:" + name) super(FabriceHeadGuide, self).__init__(name, parent) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape="circle") self.headCtrl.rotatePoints(90.0, 0.0, 0.0) self.headCtrl.scalePoints(Vec3(3.5, 3.5, 3.5)) self.jawCtrl = Control('jaw', parent=self.ctrlCmpGrp, shape="cube") self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(2.0, 0.5, 2.0)) self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.setColor('orange') data = { "name": name, "location": "M", "headXfo": Xfo(Vec3(0.0, 1.67, 1.75)), "headCtrlCrvData": self.headCtrl.getCurveData(), "jawPosition": Vec3(0.0, 1.2787, 2.0078), "jawCtrlCrvData": self.jawCtrl.getCurveData(), } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(FabriceHeadGuide, self).saveData() data['headXfo'] = self.headCtrl.xfo data['headCtrlCrvData'] = self.headCtrl.getCurveData() data['jawPosition'] = self.jawCtrl.xfo.tr data['jawCtrlCrvData'] = self.jawCtrl.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(FabriceHeadGuide, self).loadData(data) self.headCtrl.xfo = data['headXfo'] self.headCtrl.setCurveData(data['headCtrlCrvData']) self.jawCtrl.xfo.tr = data['jawPosition'] self.jawCtrl.setCurveData(data['jawCtrlCrvData']) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(FabriceHeadGuide, self).getRigBuildData() data['headXfo'] = self.headCtrl.xfo data['headCtrlCrvData'] = self.headCtrl.getCurveData() data['jawPosition'] = self.jawCtrl.xfo.tr data['jawCtrlCrvData'] = self.jawCtrl.getCurveData() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return FabriceHeadRig
class mjEyelidComponentGuide(mjEyelidComponent): """Eyelid Component Guide""" def __init__(self, name='mjEyelid', parent=None): Profiler.getInstance().push("Construct Eyelid Guide Component:" + name) super(mjEyelidComponentGuide, self).__init__(name, parent) # ========= # Attributes // Create Attributes Controls. # ========= guideUpSettingsAttrGrp = AttributeGroup("Eyelid Up", parent=self) guideLowSettingsAttrGrp = AttributeGroup("Eyelid Low", parent=self) self.numUpDeformersAttr = IntegerAttribute( 'Num Deformers', value=10, minValue=1, maxValue=50, parent=guideUpSettingsAttrGrp) self.upMedialFactorAttr = ScalarAttribute( 'Medial Blink Factor', value=0.25, minValue=0, maxValue=1, parent=guideUpSettingsAttrGrp) self.upLateralFactorAttr = ScalarAttribute( 'Lateral Blink Factor', value=0.65, minValue=0, maxValue=1, parent=guideUpSettingsAttrGrp) self.numLowDeformersAttr = IntegerAttribute( 'Num Deformers', value=10, minValue=1, maxValue=50, parent=guideLowSettingsAttrGrp) self.lowMedialFactorAttr = ScalarAttribute( 'Medial Blink Factor', value=0.25, minValue=0, maxValue=1, parent=guideLowSettingsAttrGrp) self.lowLateralFactorAttr = ScalarAttribute( 'Lateral Blink Factor', value=0.65, minValue=0, maxValue=1, parent=guideLowSettingsAttrGrp) self.numUpDeformersAttr.setValueChangeCallback( self.updateNumUpDeformers) self.numLowDeformersAttr.setValueChangeCallback( self.updateNumLowDeformers) # ========= # Controls // Create the Guide Controls, Name them, give them a shape, a color and scale it. # ========= self.eyeballCtrl = Control('eyeball', parent=self.ctrlCmpGrp, shape="sphere") self.eyeballCtrl.scalePoints(Vec3(0.35, 0.35, 0.35)) self.eyeballCtrl.setColor("red") self.lidMedialCtrl = Control('lidMedial', parent=self.eyeballCtrl, shape="sphere") self.lidMedialCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidMedialCtrl.setColor("peach") self.lidLateralCtrl = Control('lidLateral', parent=self.eyeballCtrl, shape="sphere") self.lidLateralCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidLateralCtrl.setColor("peach") self.lidUpCtrl = Control('lidUp', parent=self.eyeballCtrl, shape="sphere") self.lidUpCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidUpCtrl.setColor("peach") self.lidUpMedialCtrl = Control('lidUpMedial', parent=self.eyeballCtrl, shape="sphere") self.lidUpMedialCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidUpMedialCtrl.setColor("peach") self.lidUpLateralCtrl = Control('lidUpLateral', parent=self.eyeballCtrl, shape="sphere") self.lidUpLateralCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidUpLateralCtrl.setColor("peach") self.lidLowCtrl = Control('lidLow', parent=self.eyeballCtrl, shape="sphere") self.lidLowCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidLowCtrl.setColor("peach") self.lidLowMedialCtrl = Control('lidLowMedial', parent=self.eyeballCtrl, shape="sphere") self.lidLowMedialCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidLowMedialCtrl.setColor("peach") self.lidLowLateralCtrl = Control('lidLowLateral', parent=self.eyeballCtrl, shape="sphere") self.lidLowLateralCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) self.lidLowLateralCtrl.setColor("peach") # =============== # Add Debug Splice Ops # =============== # Add Lid Up Canvas Op self.debugLidUpCanvasOp = CanvasOperator( 'Debug_Canvas_Eyelid_Up_Op', 'MJCG.Solvers.mjEyelidDebugSolver') self.addOperator(self.debugLidUpCanvasOp) # Add Attributes Inputs self.debugLidUpCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) self.debugLidUpCanvasOp.setInput('rigScale', self.rigScaleInputAttr) self.debugLidUpCanvasOp.setInput('Deformer_Count', self.numUpDeformersInputAttr) # Add Xfo Inputs self.debugLidUpCanvasOp.setInput('Eye_Center', self.eyeballCtrl) self.debugLidUpCanvasOp.setInput('Lid_Medial', self.lidMedialCtrl) self.debugLidUpCanvasOp.setInput('Lid_MedialCen', self.lidUpMedialCtrl) self.debugLidUpCanvasOp.setInput('Lid_Center_Ref', self.lidUpCtrl) self.debugLidUpCanvasOp.setInput('Lid_Center_Ctrl', self.lidUpCtrl) self.debugLidUpCanvasOp.setInput('Lid_LateralCen', self.lidUpLateralCtrl) self.debugLidUpCanvasOp.setInput('Lid_Lateral', self.lidLateralCtrl) # Add Xfo Outputs self.debugLidUpCanvasOp.setOutput('result', self.eyelidUpOutput.getTarget()) # Add Lid Low Canvas Op self.debugLidLowCanvasOp = CanvasOperator( 'Debug_Canvas_Eyelid_Low_Op', 'MJCG.Solvers.mjEyelidDebugSolver') self.addOperator(self.debugLidLowCanvasOp) # Add Attributes Inputs self.debugLidLowCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) self.debugLidLowCanvasOp.setInput('rigScale', self.rigScaleInputAttr) self.debugLidLowCanvasOp.setInput('Deformer_Count', self.numLowDeformersInputAttr) # Add Xfo Inputs self.debugLidLowCanvasOp.setInput('Eye_Center', self.eyeballCtrl) self.debugLidLowCanvasOp.setInput('Lid_Medial', self.lidMedialCtrl) self.debugLidLowCanvasOp.setInput('Lid_MedialCen', self.lidLowMedialCtrl) self.debugLidLowCanvasOp.setInput('Lid_Center_Ref', self.lidLowCtrl) self.debugLidLowCanvasOp.setInput('Lid_Center_Ctrl', self.lidLowCtrl) self.debugLidLowCanvasOp.setInput('Lid_LateralCen', self.lidLowLateralCtrl) self.debugLidLowCanvasOp.setInput('Lid_Lateral', self.lidLateralCtrl) # Add Xfo Outputs self.debugLidLowCanvasOp.setOutput('result', self.eyelidLowOutput.getTarget()) # ========= # Position Data // Get the Guide Controls Position data, else set them at their initial position. # ========= self.default_data = { "name": name, "location": "L", "eyeballXfo": Xfo(Vec3(0.322, 15.500, 0.390)), "lidMedialXfo": Xfo(Vec3(0.168, 15.445, 0.520)), "lidLateralXfo": Xfo(Vec3(0.465, 15.47, 0.465)), "lidUpXfo": Xfo(Vec3(0.322, 15.585, 0.605)), "lidUpMedialXfo": Xfo(Vec3(0.203, 15.515, 0.525)), "lidUpLateralXfo": Xfo(Vec3(0.432, 15.55, 0.538)), "lidLowXfo": Xfo(Vec3(0.322, 15.434, 0.6)), "lidLowMedialXfo": Xfo(Vec3(0.24, 15.45, 0.513)), "lidLowLateralXfo": Xfo(Vec3(0.413, 15.44, 0.525)), "lidUpMedialBlink": self.upMedialFactorAttr.getValue(), "lidUpLateralBlink": self.upLateralFactorAttr.getValue(), "lidLowMedialBlink": self.lowMedialFactorAttr.getValue(), "lidLowLateralBlink": self.lowLateralFactorAttr.getValue(), "numUpDeformers": self.numUpDeformersAttr.getValue(), "numLowDeformers": self.numLowDeformersAttr.getValue(), } self.loadData(self.default_data) Profiler.getInstance().pop() # ========== # Callbacks # ========== def updateNumUpDeformers(self, countUp): if countUp == 0: raise IndexError("'count' must be > 0") #Lip Up lidUpOutputs = self.eyelidUpOutput.getTarget() if countUp > len(lidUpOutputs): for i in xrange(len(lidUpOutputs), countUp): debugUpCtrl = Control('Lid_Up_' + str(i + 1).zfill(2), parent=self.outputHrcGrp, shape="sphere") debugUpCtrl.rotatePoints(90, -90, 180) debugUpCtrl.scalePoints(Vec3(0.01, 0.01, 0.01)) debugUpCtrl.setColor("yellowLight") lidUpOutputs.append(debugUpCtrl) elif countUp < len(lidUpOutputs): numExtraUpCtrls = len(lidUpOutputs) - countUp for i in xrange(numExtraUpCtrls): extraUpCtrl = lidUpOutputs.pop() self.outputHrcGrp.removeChild(extraUpCtrl) return True def updateNumLowDeformers(self, countLow): if countLow == 0: raise IndexError("'count' must be > 0") #Lip Low lidLowOutputs = self.eyelidLowOutput.getTarget() if countLow > len(lidLowOutputs): for i in xrange(len(lidLowOutputs), countLow): debugLowCtrl = Control('Lid_Low_' + str(i + 1).zfill(2), parent=self.outputHrcGrp, shape="sphere") debugLowCtrl.rotatePoints(90, -90, 180) debugLowCtrl.scalePoints(Vec3(0.01, 0.01, 0.01)) debugLowCtrl.setColor("yellowLight") lidLowOutputs.append(debugLowCtrl) elif countLow < len(lidLowOutputs): numExtraLowCtrls = len(lidLowOutputs) - countLow for i in xrange(numExtraLowCtrls): extraLowCtrl = lidLowOutputs.pop() self.outputHrcGrp.removeChild(extraLowCtrl) return True # ============= # Data Methods # ============= def saveData(self): data = super(mjEyelidComponentGuide, self).saveData() data['eyeballXfo'] = self.eyeballCtrl.xfo data['lidMedialXfo'] = self.lidMedialCtrl.xfo data['lidLateralXfo'] = self.lidLateralCtrl.xfo data['lidUpXfo'] = self.lidUpCtrl.xfo data['lidUpMedialXfo'] = self.lidUpMedialCtrl.xfo data['lidUpLateralXfo'] = self.lidUpLateralCtrl.xfo data['lidLowXfo'] = self.lidLowCtrl.xfo data['lidLowMedialXfo'] = self.lidLowMedialCtrl.xfo data['lidLowLateralXfo'] = self.lidLowLateralCtrl.xfo data['numUpDeformers'] = self.numUpDeformersAttr.getValue() data['numLowDeformers'] = self.numLowDeformersAttr.getValue() data['lidUpMedialBlink'] = self.upMedialFactorAttr.getValue() data['lidUpLateralBlink'] = self.upLateralFactorAttr.getValue() data['lidLowMedialBlink'] = self.lowMedialFactorAttr.getValue() data['lidLowLateralBlink'] = self.lowLateralFactorAttr.getValue() return data def loadData(self, data): super(mjEyelidComponentGuide, self).loadData(data) self.eyeballCtrl.xfo = data['eyeballXfo'] self.lidMedialCtrl.xfo = data['lidMedialXfo'] self.lidLateralCtrl.xfo = data['lidLateralXfo'] self.lidUpCtrl.xfo = data['lidUpXfo'] self.lidUpMedialCtrl.xfo = data['lidUpMedialXfo'] self.lidUpLateralCtrl.xfo = data['lidUpLateralXfo'] self.lidLowCtrl.xfo = data['lidLowXfo'] self.lidLowMedialCtrl.xfo = data['lidLowMedialXfo'] self.lidLowLateralCtrl.xfo = data['lidLowLateralXfo'] self.numUpDeformersAttr.setValue(data["numUpDeformers"]) self.numLowDeformersAttr.setValue(data["numLowDeformers"]) self.numUpDeformersInputAttr.setValue(data["numUpDeformers"]) self.numLowDeformersInputAttr.setValue(data["numLowDeformers"]) self.upMedialFactorInputAttr.setValue(data['lidUpMedialBlink']) self.upLateralFactorInputAttr.setValue(data['lidUpLateralBlink']) self.lowMedialFactorInputAttr.setValue(data['lidLowMedialBlink']) self.lowLateralFactorInputAttr.setValue(data['lidLowLateralBlink']) self.debugLidUpCanvasOp.evaluate() self.debugLidLowCanvasOp.evaluate() return True def getRigBuildData(self): data = super(mjEyelidComponentGuide, self).getRigBuildData() eyeballPosition = self.eyeballCtrl.xfo.tr eyeballOriXfo = Xfo() eyeballOriXfo.tr = eyeballPosition eyeballOriOffset = Quat(Vec3(0.0, 0.894, 0.0), -0.448) if self.getLocation() == "R": eyeballOriXfo.ori.subtract(eyeballOriOffset) data['eyeballXfo'] = eyeballOriXfo eyelidUpVOffset = Vec3(0.0, 0.2, 0.0) eyelidUpVXfo = Xfo() eyelidUpVXfo.tr = eyeballPosition.add(eyelidUpVOffset) data['eyelidUpVXfo'] = eyelidUpVXfo data['lidMedialXfo'] = self.lidMedialCtrl.xfo data['lidLateralXfo'] = self.lidLateralCtrl.xfo data['lidUpXfo'] = self.lidUpCtrl.xfo data['lidUpMedialXfo'] = self.lidUpMedialCtrl.xfo data['lidUpLateralXfo'] = self.lidUpLateralCtrl.xfo data['lidLowXfo'] = self.lidLowCtrl.xfo data['lidLowMedialXfo'] = self.lidLowMedialCtrl.xfo data['lidLowLateralXfo'] = self.lidLowLateralCtrl.xfo data['numUpDeformers'] = self.numUpDeformersAttr.getValue() data['numLowDeformers'] = self.numLowDeformersAttr.getValue() data['lidUpMedialBlink'] = self.upMedialFactorAttr.getValue() data['lidUpLateralBlink'] = self.upLateralFactorAttr.getValue() data['lidLowMedialBlink'] = self.lowMedialFactorAttr.getValue() data['lidLowLateralBlink'] = self.lowLateralFactorAttr.getValue() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): return 'Guide' @classmethod def getRigComponentClass(cls): return mjEyelidComponentRig
class NeckComponentGuide(NeckComponent): """Neck Component Guide""" def __init__(self, name='neck', parent=None, *args, **kwargs): Profiler.getInstance().push('Construct Neck Component:' + name) super(NeckComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= # Guide Controls self.neckCtrl = Control('neck', parent=self.ctrlCmpGrp, shape='sphere') self.neckCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckMidCtrl = Control('neckMid', parent=self.ctrlCmpGrp, shape='sphere') self.neckMidCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckEndCtrl = Control('neckEnd', parent=self.ctrlCmpGrp, shape='sphere') self.neckEndCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckCtrlShape = Control('neck', parent=self.ctrlCmpGrp, shape='pin') self.neckCtrlShape.rotatePoints(90.0, 0.0, 0.0) self.neckCtrlShape.rotatePoints(0.0, 90.0, 0.0) self.neckCtrlShape.setColor('orange') self.neckMidCtrlShape = Control('neckMid', parent=self.ctrlCmpGrp, shape='pin') self.neckMidCtrlShape.rotatePoints(90.0, 0.0, 0.0) self.neckMidCtrlShape.rotatePoints(0.0, 90.0, 0.0) self.neckMidCtrlShape.setColor('orange') # Guide Operator self.neckGuideKLOp = KLOperator(name + 'GuideKLOp', 'NeckGuideSolver', 'Kraken') self.addOperator(self.neckGuideKLOp) # Add Att Inputs self.neckGuideKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.neckGuideKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Source Inputs self.neckGuideKLOp.setInput( 'sources', [self.neckCtrl, self.neckMidCtrl, self.neckEndCtrl]) # Add Target Outputs self.neckGuideKLOp.setOutput( 'targets', [self.neckCtrlShape, self.neckMidCtrlShape]) # Calculate default values neckVec = Vec3(0.0, 16.00, -0.75) neckMidVec = Vec3(0.0, 16.50, -0.50) neckEndVec = Vec3(0.0, 17.00, -0.25) upVector = Vec3(0.0, 0.0, -1.0) neckOri = Quat() neckOri.setFromDirectionAndUpvector( (neckMidVec - neckVec).unit(), ((neckVec + upVector) - neckVec).unit()) neckMidOri = Quat() neckMidOri.setFromDirectionAndUpvector( (neckEndVec - neckMidVec).unit(), ((neckMidVec + upVector) - neckMidVec).unit()) self.default_data = { "name": name, "location": "M", "neckXfo": Xfo(tr=neckVec, ori=neckOri), "neckMidXfo": Xfo(tr=neckMidVec, ori=neckMidOri), "neckEndXfo": Xfo(tr=neckEndVec, ori=neckMidOri), "neckCrvData": self.neckCtrlShape.getCurveData(), "neckMidCrvData": self.neckMidCtrlShape.getCurveData() } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(NeckComponentGuide, self).saveData() data['neckXfo'] = self.neckCtrl.xfo data['neckMidXfo'] = self.neckMidCtrl.xfo data['neckEndXfo'] = self.neckEndCtrl.xfo data['neckCrvData'] = self.neckCtrlShape.getCurveData() data['neckMidCrvData'] = self.neckMidCtrlShape.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data (object): The JSON data object. Returns: bool: True if successful. """ super(NeckComponentGuide, self).loadData(data) self.neckCtrl.xfo = data.get('neckXfo') self.neckMidCtrl.xfo = data.get('neckMidXfo') self.neckEndCtrl.xfo = data.get('neckEndXfo') self.neckCtrlShape.setCurveData(data.get('neckCrvData')) self.neckMidCtrlShape.setCurveData(data.get('neckMidCrvData')) # Evaluate guide operators self.neckGuideKLOp.evaluate() return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(NeckComponentGuide, self).getRigBuildData() neckEndXfo = Xfo(tr=self.neckEndCtrl.xfo.tr, ori=self.neckMidCtrlShape.xfo.ori) data['neckXfo'] = self.neckCtrlShape.xfo data['neckCrvData'] = self.neckCtrlShape.getCurveData() data['neckMidXfo'] = self.neckMidCtrlShape.xfo data['neckMidCrvData'] = self.neckMidCtrlShape.getCurveData() data['neckEndXfo'] = neckEndXfo return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Returns: bool: Whether the component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class. Returns: class: The rig component class. """ return NeckComponentRig
def addFinger(self, name): digitSizeAttributes = [] fingerGuideCtrls = [] firstDigitCtrl = Control(name + "01", parent=self.handCtrl, shape='sphere') firstDigitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) firstDigitShapeCtrl = Control(name + "Shp01", parent=self.guideCtrlHrcGrp, shape='square') firstDigitShapeCtrl.setColor('yellow') firstDigitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) firstDigitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) fingerGuideCtrls.append(firstDigitShapeCtrl) firstDigitCtrl.shapeCtrl = firstDigitShapeCtrl firstDigitVisAttr = firstDigitShapeCtrl.getVisibilityAttr() firstDigitVisAttr.connect(self.ctrlShapeToggle) triangleCtrl = Control('tempCtrl', parent=None, shape='triangle') triangleCtrl.rotatePoints(90.0, 0.0, 0.0) triangleCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) triangleCtrl.translatePoints(Vec3(0.0, 0.0875, 0.0)) firstDigitCtrl.appendCurveData(triangleCtrl.getCurveData()) firstDigitCtrl.lockScale(True, True, True) digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=firstDigitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) # Set Finger self.fingers[name] = [] self.fingers[name].append(firstDigitCtrl) parent = firstDigitCtrl numJoints = self.numJointsAttr.getValue() if name == "thumb": numJoints = 3 for i in xrange(2, numJoints + 2): digitCtrl = Control(name + str(i).zfill(2), parent=parent, shape='sphere') if i != numJoints + 1: digitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) digitCtrl.appendCurveData(triangleCtrl.getCurveData()) digitShapeCtrl = Control(name + 'Shp' + str(i).zfill(2), parent=self.guideCtrlHrcGrp, shape='circle') digitShapeCtrl.setColor('yellow') digitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) digitShapeCtrl.getVisibilityAttr().connect(self.ctrlShapeToggle) digitCtrl.shapeCtrl = digitShapeCtrl if i == 2: digitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) else: digitShapeCtrl.rotatePoints(0.0, 0.0, 90.0) fingerGuideCtrls.append(digitShapeCtrl) # Add size attr to all but last guide control digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=digitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) else: digitCtrl.scalePoints(Vec3(0.0875, 0.0875, 0.0875)) digitCtrl.lockScale(True, True, True) self.fingers[name].append(digitCtrl) parent = digitCtrl # =========================== # Create Canvas Operators # =========================== # Add Finger Guide Canvas Op fingerGuideCanvasOp = CanvasOperator(name + 'FingerGuide', 'Kraken.Solvers.Biped.BipedFingerGuideSolver') self.addOperator(fingerGuideCanvasOp) # Add Att Inputs fingerGuideCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) fingerGuideCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs fingerGuideCanvasOp.setInput('controls', self.fingers[name]) fingerGuideCanvasOp.setInput('planeSizes', digitSizeAttributes) # Add Xfo Outputs fingerGuideCanvasOp.setOutput('result', fingerGuideCtrls) fingerGuideCanvasOp.setOutput('forceEval', firstDigitCtrl.getVisibilityAttr()) return firstDigitCtrl
class NeckComponentGuide(NeckComponent): """Neck Component Guide""" def __init__(self, name='neck', parent=None, *args, **kwargs): Profiler.getInstance().push('Construct Neck Component:' + name) super(NeckComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= # Guide Controls self.neckCtrl = Control('neck', parent=self.ctrlCmpGrp, shape='sphere') self.neckCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckMidCtrl = Control('neckMid', parent=self.ctrlCmpGrp, shape='sphere') self.neckMidCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckEndCtrl = Control('neckEnd', parent=self.ctrlCmpGrp, shape='sphere') self.neckEndCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.neckCtrlShape = Control('neck', parent=self.ctrlCmpGrp, shape='pin') self.neckCtrlShape.rotatePoints(90.0, 0.0, 0.0) self.neckCtrlShape.rotatePoints(0.0, 90.0, 0.0) self.neckCtrlShape.setColor('orange') self.neckMidCtrlShape = Control('neckMid', parent=self.ctrlCmpGrp, shape='pin') self.neckMidCtrlShape.rotatePoints(90.0, 0.0, 0.0) self.neckMidCtrlShape.rotatePoints(0.0, 90.0, 0.0) self.neckMidCtrlShape.setColor('orange') # Guide Operator self.neckGuideKLOp = KLOperator(name + 'GuideKLOp', 'NeckGuideSolver', 'Kraken') self.addOperator(self.neckGuideKLOp) # Add Att Inputs self.neckGuideKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.neckGuideKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Source Inputs self.neckGuideKLOp.setInput('sources', [self.neckCtrl, self.neckMidCtrl, self.neckEndCtrl]) # Add Target Outputs self.neckGuideKLOp.setOutput('targets', [self.neckCtrlShape, self.neckMidCtrlShape]) # Calculate default values neckVec = Vec3(0.0, 16.00, -0.75) neckMidVec = Vec3(0.0, 16.50, -0.50) neckEndVec = Vec3(0.0, 17.00, -0.25) upVector = Vec3(0.0, 0.0, -1.0) neckOri = Quat() neckOri.setFromDirectionAndUpvector((neckMidVec - neckVec).unit(), ((neckVec + upVector) - neckVec).unit()) neckMidOri = Quat() neckMidOri.setFromDirectionAndUpvector((neckEndVec - neckMidVec).unit(), ((neckMidVec + upVector) - neckMidVec).unit()) self.default_data = { "name": name, "location": "M", "neckXfo": Xfo(tr=neckVec, ori=neckOri), "neckMidXfo": Xfo(tr=neckMidVec, ori=neckMidOri), "neckEndXfo": Xfo(tr=neckEndVec, ori=neckMidOri), "neckCrvData": self.neckCtrlShape.getCurveData(), "neckMidCrvData": self.neckMidCtrlShape.getCurveData() } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(NeckComponentGuide, self).saveData() data['neckXfo'] = self.neckCtrl.xfo data['neckMidXfo'] = self.neckMidCtrl.xfo data['neckEndXfo'] = self.neckEndCtrl.xfo data['neckCrvData'] = self.neckCtrlShape.getCurveData() data['neckMidCrvData'] = self.neckMidCtrlShape.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data (object): The JSON data object. Returns: bool: True if successful. """ super(NeckComponentGuide, self).loadData(data) self.neckCtrl.xfo = data.get('neckXfo') self.neckMidCtrl.xfo = data.get('neckMidXfo') self.neckEndCtrl.xfo = data.get('neckEndXfo') self.neckCtrlShape.setCurveData(data.get('neckCrvData')) self.neckMidCtrlShape.setCurveData(data.get('neckMidCrvData')) # Evaluate guide operators self.neckGuideKLOp.evaluate() return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(NeckComponentGuide, self).getRigBuildData() neckEndXfo = Xfo(tr=self.neckEndCtrl.xfo.tr, ori=self.neckMidCtrlShape.xfo.ori) data['neckXfo'] = self.neckCtrlShape.xfo data['neckCrvData'] = self.neckCtrlShape.getCurveData() data['neckMidXfo'] = self.neckMidCtrlShape.xfo data['neckMidCrvData'] = self.neckMidCtrlShape.getCurveData() data['neckEndXfo'] = neckEndXfo return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Returns: bool: Whether the component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class. Returns: class: The rig component class. """ return NeckComponentRig
class MainSrtComponentRig(MainSrtComponent): """MainSrt Component Rig""" def __init__(self, name='mainSrt', parent=None): Profiler.getInstance().push("Construct MainSrt Rig Component:" + name) super(MainSrtComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Add Controls self.mainSRTCtrlSpace = CtrlSpace('SRT', parent=self.ctrlCmpGrp) self.mainSRTCtrl = Control('SRT', shape='circle', parent=self.mainSRTCtrlSpace) self.mainSRTCtrl.lockScale(x=True, y=True, z=True) self.offsetCtrlSpace = CtrlSpace('Offset', parent=self.mainSRTCtrl) self.offsetCtrl = Control('Offset', shape='circle', parent=self.offsetCtrlSpace) self.offsetCtrl.setColor("orange") self.offsetCtrl.lockScale(x=True, y=True, z=True) # Add Component Params to IK control mainSrtSettingsAttrGrp = AttributeGroup('DisplayInfo_MainSrtSettings', parent=self.mainSRTCtrl) self.rigScaleAttr = ScalarAttribute('rigScale', value=1.0, parent=mainSrtSettingsAttrGrp, minValue=0.1, maxValue=100.0) self.rigScaleOutputAttr.connect(self.rigScaleAttr) # ========== # Deformers # ========== # ============== # Constrain I/O # ============== # Constraint inputs # Constraint outputs srtConstraint = PoseConstraint('_'.join( [self.srtOutputTgt.getName(), 'To', self.mainSRTCtrl.getName()])) srtConstraint.addConstrainer(self.mainSRTCtrl) self.srtOutputTgt.addConstraint(srtConstraint) offsetConstraint = PoseConstraint('_'.join( [self.offsetOutputTgt.getName(), 'To', self.mainSRTCtrl.getName()])) offsetConstraint.addConstrainer(self.offsetCtrl) self.offsetOutputTgt.addConstraint(offsetConstraint) # =============== # Add Splice Ops # =============== #Add Rig Scale Splice Op self.rigScaleSpliceOp = SpliceOperator('rigScaleSpliceOp', 'RigScaleSolver', 'Kraken') self.addOperator(self.rigScaleSpliceOp) # Add Att Inputs self.rigScaleSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.rigScaleSpliceOp.setInput('rigScale', self.rigScaleOutputAttr) # Add Xfo Inputs # Add Xfo Outputs self.rigScaleSpliceOp.setOutput('target', self.mainSRTCtrlSpace) Profiler.getInstance().pop() 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(MainSrtComponentRig, self).loadData(data) # ================ # Resize Controls # ================ self.mainSRTCtrl.scalePoints( Vec3(data["mainSrtSize"], 1.0, data["mainSrtSize"])) self.offsetCtrl.scalePoints( Vec3(data["mainSrtSize"] - 0.5, 1.0, data["mainSrtSize"] - 0.5)) # ======================= # Set Control Transforms # ======================= self.mainSRTCtrlSpace.xfo = data["mainSrtXfo"] self.mainSRTCtrl.xfo = data["mainSrtXfo"] self.offsetCtrlSpace.xfo = data["mainSrtXfo"] self.offsetCtrl.xfo = data["mainSrtXfo"] # ============ # Set IO Xfos # ============ self.srtOutputTgt = data["mainSrtXfo"] self.offsetOutputTgt = data["mainSrtXfo"]
def addFinger(self, name): digitSizeAttributes = [] fingerGuideCtrls = [] firstDigitCtrl = Control(name + "01", parent=self.handCtrl, shape='sphere') firstDigitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) firstDigitShapeCtrl = Control(name + "Shp01", parent=self.guideCtrlHrcGrp, shape='square') firstDigitShapeCtrl.setColor('yellow') firstDigitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) firstDigitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) fingerGuideCtrls.append(firstDigitShapeCtrl) firstDigitCtrl.shapeCtrl = firstDigitShapeCtrl firstDigitVisAttr = firstDigitShapeCtrl.getVisibilityAttr() firstDigitVisAttr.connect(self.ctrlShapeToggle) triangleCtrl = Control('tempCtrl', parent=None, shape='triangle') triangleCtrl.rotatePoints(90.0, 0.0, 0.0) triangleCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) triangleCtrl.translatePoints(Vec3(0.0, 0.0875, 0.0)) firstDigitCtrl.appendCurveData(triangleCtrl.getCurveData()) firstDigitCtrl.lockScale(True, True, True) digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=firstDigitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) # Set Finger self.fingers[name] = [] self.fingers[name].append(firstDigitCtrl) parent = firstDigitCtrl numJoints = self.numJointsAttr.getValue() if name == "thumb": numJoints = 3 for i in xrange(2, numJoints + 2): digitCtrl = Control(name + str(i).zfill(2), parent=parent, shape='sphere') if i != numJoints + 1: digitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) digitCtrl.appendCurveData(triangleCtrl.getCurveData()) digitShapeCtrl = Control(name + 'Shp' + str(i).zfill(2), parent=self.guideCtrlHrcGrp, shape='circle') digitShapeCtrl.setColor('yellow') digitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) digitShapeCtrl.getVisibilityAttr().connect(self.ctrlShapeToggle) digitCtrl.shapeCtrl = digitShapeCtrl if i == 2: digitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) else: digitShapeCtrl.rotatePoints(0.0, 0.0, 90.0) fingerGuideCtrls.append(digitShapeCtrl) # Add size attr to all but last guide control digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=digitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) else: digitCtrl.scalePoints(Vec3(0.0875, 0.0875, 0.0875)) digitCtrl.lockScale(True, True, True) self.fingers[name].append(digitCtrl) parent = digitCtrl # =========================== # Create Canvas Operators # =========================== # Add Finger Guide Canvas Op fingerGuideCanvasOp = CanvasOperator(name + 'FingerGuideOp', 'Kraken.Solvers.Biped.BipedFingerGuideSolver') self.addOperator(fingerGuideCanvasOp) # Add Att Inputs fingerGuideCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) fingerGuideCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs fingerGuideCanvasOp.setInput('controls', self.fingers[name]) fingerGuideCanvasOp.setInput('planeSizes', digitSizeAttributes) # Add Xfo Outputs fingerGuideCanvasOp.setOutput('result', fingerGuideCtrls) fingerGuideCanvasOp.setOutput('forceEval', firstDigitCtrl.getVisibilityAttr()) return firstDigitCtrl
class SpineComponentGuide(SpineComponent): """Spine Component Guide""" def __init__(self, name='spine', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Spine Guide Component:" + name) super(SpineComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.numDeformersAttr = IntegerAttribute('numDeformers', value=1, minValue=0, maxValue=20, parent=guideSettingsAttrGrp) # Guide Controls self.cog = Control('cogPosition', parent=self.ctrlCmpGrp, shape="sphere") self.cog.scalePoints(Vec3(1.2, 1.2, 1.2)) self.cog.setColor('red') self.spine01Ctrl = Control('spine01Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine02Ctrl = Control('spine02Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine03Ctrl = Control('spine03Position', parent=self.ctrlCmpGrp, shape='sphere') self.spine04Ctrl = Control('spine04Position', parent=self.ctrlCmpGrp, shape='sphere') data = { 'name': name, 'location': 'M', 'cogPosition': Vec3(0.0, 11.1351, -0.1382), 'spine01Position': Vec3(0.0, 11.1351, -0.1382), 'spine02Position': Vec3(0.0, 11.8013, -0.1995), 'spine03Position': Vec3(0.0, 12.4496, -0.3649), 'spine04Position': Vec3(0.0, 13.1051, -0.4821), 'numDeformers': 6 } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(SpineComponentGuide, self).saveData() data['cogPosition'] = self.cog.xfo.tr data['spine01Position'] = self.spine01Ctrl.xfo.tr data['spine02Position'] = self.spine02Ctrl.xfo.tr data['spine03Position'] = self.spine03Ctrl.xfo.tr data['spine04Position'] = self.spine04Ctrl.xfo.tr data['numDeformers'] = self.numDeformersAttr.getValue() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(SpineComponentGuide, self).loadData( data ) self.cog.xfo.tr = data["cogPosition"] self.spine01Ctrl.xfo.tr = data["spine01Position"] self.spine02Ctrl.xfo.tr = data["spine02Position"] self.spine03Ctrl.xfo.tr = data["spine03Position"] self.spine04Ctrl.xfo.tr = data["spine04Position"] self.numDeformersAttr.setValue(data["numDeformers"]) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(SpineComponentGuide, self).getRigBuildData() data['cogPosition'] = self.cog.xfo.tr data['spine01Position'] = self.spine01Ctrl.xfo.tr data['spine02Position'] = self.spine02Ctrl.xfo.tr data['spine03Position'] = self.spine03Ctrl.xfo.tr data['spine04Position'] = self.spine04Ctrl.xfo.tr data['numDeformers'] = self.numDeformersAttr.getValue() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return SpineComponentRig
class FabriceHeadRig(FabriceHead): """Fabrice Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(FabriceHeadRig, self).__init__(name, parent) # ========= # Controls # ========= # Head Aim self.headAimCtrlSpace = CtrlSpace('headAim', parent=self.ctrlCmpGrp) self.headAimCtrl = Control('headAim', parent=self.headAimCtrlSpace, shape="sphere") self.headAimCtrl.scalePoints(Vec3(0.35, 0.35, 0.35)) self.headAimCtrl.lockScale(x=True, y=True, z=True) self.headAimUpV = Locator('headAimUpV', parent=self.headAimCtrl) self.headAimUpV.setShapeVisibility(False) # Head self.headAim = Locator('headAim', parent=self.ctrlCmpGrp) self.headAim.setShapeVisibility(False) self.headCtrlSpace = CtrlSpace('head', parent=self.ctrlCmpGrp) self.headCtrl = Control('head', parent=self.headCtrlSpace, shape="circle") self.headCtrl.lockTranslation(x=True, y=True, z=True) self.headCtrl.lockScale(x=True, y=True, z=True) # Jaw self.jawCtrlSpace = CtrlSpace('jawCtrlSpace', parent=self.headCtrl) self.jawCtrl = Control('jaw', parent=self.jawCtrlSpace, shape="cube") self.jawCtrl.lockTranslation(x=True, y=True, z=True) self.jawCtrl.lockScale(x=True, y=True, z=True) self.jawCtrl.setColor("orange") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) headDef = Joint('head', parent=defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=defCmpGrp) jawDef.setComponent(self) # ============== # Constrain I/O # ============== self.headToAimConstraint = PoseConstraint('_'.join([self.headCtrlSpace.getName(), 'To', self.headAim.getName()])) self.headToAimConstraint.setMaintainOffset(True) self.headToAimConstraint.addConstrainer(self.headAim) self.headCtrlSpace.addConstraint(self.headToAimConstraint) # Constraint inputs self.headAimInputConstraint = PoseConstraint('_'.join([self.headAimCtrlSpace.getName(), 'To', self.headBaseInputTgt.getName()])) self.headAimInputConstraint.setMaintainOffset(True) self.headAimInputConstraint.addConstrainer(self.headBaseInputTgt) self.headAimCtrlSpace.addConstraint(self.headAimInputConstraint) # # Constraint outputs self.headOutputConstraint = PoseConstraint('_'.join([self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) self.headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(self.headOutputConstraint) self.jawOutputConstraint = PoseConstraint('_'.join([self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) self.jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(self.jawOutputConstraint) # ============== # Add Operators # ============== # Add Aim Canvas Op # ================= self.headAimCanvasOp = CanvasOperator('headAimCanvasOp', 'Kraken.Solvers.DirectionConstraintSolver') self.addOperator(self.headAimCanvasOp) # Add Att Inputs self.headAimCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) self.headAimCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.headAimCanvasOp.setInput('position', self.headBaseInputTgt) self.headAimCanvasOp.setInput('upVector', self.headAimUpV) self.headAimCanvasOp.setInput('atVector', self.headAimCtrl) # Add Xfo Outputs self.headAimCanvasOp.setOutput('constrainee', self.headAim) # Add Deformer KL Op # ================== self.deformersToOutputsKLOp = KLOperator('headDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.deformersToOutputsKLOp) # Add Att Inputs self.deformersToOutputsKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsKLOp.setInput('constrainers', [self.headOutputTgt, self.jawOutputTgt]) # Add Xfo Outputs self.deformersToOutputsKLOp.setOutput('constrainees', [headDef, jawDef]) Profiler.getInstance().pop() 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(FabriceHeadRig, self).loadData( data ) headXfo = data['headXfo'] headCtrlCrvData = data['headCtrlCrvData'] jawPosition = data['jawPosition'] jawCtrlCrvData = data['jawCtrlCrvData'] self.headAimCtrlSpace.xfo.ori = headXfo.ori self.headAimCtrlSpace.xfo.tr = headXfo.tr.add(Vec3(0, 0, 4)) self.headAimCtrl.xfo = self.headAimCtrlSpace.xfo self.headAimUpV.xfo.ori = self.headAimCtrl.xfo.ori self.headAimUpV.xfo.tr = self.headAimCtrl.xfo.tr.add(Vec3(0, 3, 0)) self.headAim.xfo = headXfo self.headCtrlSpace.xfo = headXfo self.headCtrl.xfo = headXfo self.headCtrl.setCurveData(headCtrlCrvData) self.jawCtrlSpace.xfo.tr = jawPosition self.jawCtrl.xfo.tr = jawPosition self.jawCtrl.setCurveData(jawCtrlCrvData) # ============ # Set IO Xfos # ============ self.headBaseInputTgt.xfo = headXfo self.headOutputTgt.xfo = headXfo self.jawOutputTgt.xfo.tr = jawPosition # ==================== # Evaluate Splice Ops # ==================== # evaluate the constraint op so that all the joint transforms are updated. self.headAimCanvasOp.evaluate() self.deformersToOutputsKLOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.headToAimConstraint.evaluate() self.headAimInputConstraint.evaluate() self.headOutputConstraint.evaluate() self.jawOutputConstraint.evaluate()
class SpineComponentRig(SpineComponent): """Spine Component""" def __init__(self, name="spine", parent=None): Profiler.getInstance().push("Construct Spine Rig Component:" + name) super(SpineComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # COG self.cogCtrlSpace = CtrlSpace('cog', parent=self.ctrlCmpGrp) self.cogCtrl = Control('cog', parent=self.cogCtrlSpace, shape="circle") self.cogCtrl.scalePoints(Vec3(6.0, 6.0, 6.0)) self.cogCtrl.setColor("orange") self.cogCtrl.lockScale(True, True, True) # Spine01 self.spine01CtrlSpace = CtrlSpace('spine01', parent=self.cogCtrl) self.spine01Ctrl = Control('spine01', parent=self.spine01CtrlSpace, shape="circle") self.spine01Ctrl.scalePoints(Vec3(4.0, 4.0, 4.0)) self.spine01Ctrl.lockScale(True, True, True) # Spine02 self.spine02CtrlSpace = CtrlSpace('spine02', parent=self.spine01Ctrl) self.spine02Ctrl = Control('spine02', parent=self.spine02CtrlSpace, shape="circle") self.spine02Ctrl.scalePoints(Vec3(4.5, 4.5, 4.5)) self.spine02Ctrl.lockScale(True, True, True) self.spine02Ctrl.setColor("blue") # Spine04 self.spine04CtrlSpace = CtrlSpace('spine04', parent=self.cogCtrl) self.spine04Ctrl = Control('spine04', parent=self.spine04CtrlSpace, shape="circle") self.spine04Ctrl.scalePoints(Vec3(6.0, 6.0, 6.0)) self.spine04Ctrl.lockScale(True, True, True) # Spine03 self.spine03CtrlSpace = CtrlSpace('spine03', parent=self.spine04Ctrl) self.spine03Ctrl = Control('spine03', parent=self.spine03CtrlSpace, shape="circle") self.spine03Ctrl.scalePoints(Vec3(4.5, 4.5, 4.5)) self.spine03Ctrl.lockScale(True, True, True) self.spine03Ctrl.setColor("blue") # Pelvis self.pelvisCtrlSpace = CtrlSpace('pelvis', parent=self.spine01Ctrl) self.pelvisCtrl = Control('pelvis', parent=self.pelvisCtrlSpace, shape="cube") self.pelvisCtrl.alignOnYAxis(negative=True) self.pelvisCtrl.scalePoints(Vec3(4.0, 0.375, 3.75)) self.pelvisCtrl.translatePoints(Vec3(0.0, -0.5, -0.25)) self.pelvisCtrl.lockTranslation(True, True, True) self.pelvisCtrl.lockScale(True, True, True) self.pelvisCtrl.setColor("blueLightMuted") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) self.deformerJoints = [] self.spineOutputs = [] self.setNumDeformers(1) pelvisDef = Joint('pelvis', parent=self.defCmpGrp) pelvisDef.setComponent(self) # ===================== # Create Component I/O # ===================== # Setup component Xfo I/O's self.spineVertebraeOutput.setTarget(self.spineOutputs) # ============== # Constrain I/O # ============== # Constraint inputs self.spineSrtInputConstraint = PoseConstraint('_'.join([self.cogCtrlSpace.getName(), 'To', self.globalSRTInputTgt.getName()])) self.spineSrtInputConstraint.addConstrainer(self.globalSRTInputTgt) self.spineSrtInputConstraint.setMaintainOffset(True) self.cogCtrlSpace.addConstraint(self.spineSrtInputConstraint) # Constraint outputs self.spineCogOutputConstraint = PoseConstraint('_'.join([self.spineCogOutputTgt.getName(), 'To', self.cogCtrl.getName()])) self.spineCogOutputConstraint.addConstrainer(self.cogCtrl) self.spineCogOutputTgt.addConstraint(self.spineCogOutputConstraint) self.spineBaseOutputConstraint = PoseConstraint('_'.join([self.spineBaseOutputTgt.getName(), 'To', 'spineBase'])) self.spineBaseOutputConstraint.addConstrainer(self.spineOutputs[0]) self.spineBaseOutputTgt.addConstraint(self.spineBaseOutputConstraint) self.pelvisOutputConstraint = PoseConstraint('_'.join([self.pelvisOutputTgt.getName(), 'To', self.pelvisCtrl.getName()])) self.pelvisOutputConstraint.addConstrainer(self.pelvisCtrl) self.pelvisOutputTgt.addConstraint(self.pelvisOutputConstraint) self.spineEndOutputConstraint = PoseConstraint('_'.join([self.spineEndOutputTgt.getName(), 'To', 'spineEnd'])) self.spineEndOutputConstraint.addConstrainer(self.spineOutputs[0]) self.spineEndOutputTgt.addConstraint(self.spineEndOutputConstraint) # =============== # Add Splice Ops # =============== # Add Spine Splice Op self.bezierSpineKLOp = KLOperator('spineKLOp', 'BezierSpineSolver', 'Kraken') self.addOperator(self.bezierSpineKLOp) # Add Att Inputs self.bezierSpineKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierSpineKLOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierSpineKLOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierSpineKLOp.setInput('base', self.spine01Ctrl) self.bezierSpineKLOp.setInput('baseHandle', self.spine02Ctrl) self.bezierSpineKLOp.setInput('tipHandle', self.spine03Ctrl) self.bezierSpineKLOp.setInput('tip', self.spine04Ctrl) # Add Xfo Outputs self.bezierSpineKLOp.setOutput('outputs', self.spineOutputs) # Add Deformer Splice Op self.deformersToOutputsKLOp = KLOperator('spineDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.deformersToOutputsKLOp) # Add Att Inputs self.deformersToOutputsKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsKLOp.setInput('constrainers', self.spineOutputs) # Add Xfo Outputs self.deformersToOutputsKLOp.setOutput('constrainees', self.deformerJoints) # Add Pelvis Splice Op self.pelvisDefKLOp = KLOperator('pelvisDeformerKLOp', 'PoseConstraintSolver', 'Kraken') self.addOperator(self.pelvisDefKLOp) # Add Att Inputs self.pelvisDefKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.pelvisDefKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.pelvisDefKLOp.setInput('constrainer', self.pelvisOutputTgt) # Add Xfo Outputs self.pelvisDefKLOp.setOutput('constrainee', pelvisDef) Profiler.getInstance().pop() def setNumDeformers(self, numDeformers): # Add new deformers and outputs for i in xrange(len(self.spineOutputs), numDeformers): name = 'spine' + str(i + 1).zfill(2) spineOutput = ComponentOutput(name, parent=self.outputHrcGrp) self.spineOutputs.append(spineOutput) for i in xrange(len(self.deformerJoints), numDeformers): name = 'spine' + str(i + 1).zfill(2) spineDef = Joint(name, parent=self.defCmpGrp) spineDef.setComponent(self) self.deformerJoints.append(spineDef) 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(SpineComponentRig, self).loadData( data ) cogPosition = data['cogPosition'] spine01Position = data['spine01Position'] spine02Position = data['spine02Position'] spine03Position = data['spine03Position'] spine04Position = data['spine04Position'] numDeformers = data['numDeformers'] self.cogCtrlSpace.xfo.tr = cogPosition self.cogCtrl.xfo.tr = cogPosition self.pelvisCtrlSpace.xfo.tr = cogPosition self.pelvisCtrl.xfo.tr = cogPosition self.spine01CtrlSpace.xfo.tr = spine01Position self.spine01Ctrl.xfo.tr = spine01Position self.spine02CtrlSpace.xfo.tr = spine02Position self.spine02Ctrl.xfo.tr = spine02Position self.spine03CtrlSpace.xfo.tr = spine03Position self.spine03Ctrl.xfo.tr = spine03Position self.spine04CtrlSpace.xfo.tr = spine04Position self.spine04Ctrl.xfo.tr = spine04Position length = spine01Position.distanceTo(spine02Position) + spine02Position.distanceTo(spine03Position) + spine03Position.distanceTo(spine04Position) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) # Update number of deformers and outputs self.setNumDeformers(numDeformers) # Updating constraint to use the updated last output. self.spineEndOutputConstraint.setConstrainer(self.spineOutputs[-1], index=0) # ============ # Set IO Xfos # ============ # ==================== # Evaluate Splice Ops # ==================== # evaluate the spine op so that all the output transforms are updated. self.bezierSpineKLOp.evaluate() # evaluate the constraint op so that all the joint transforms are updated. self.deformersToOutputsKLOp.evaluate() self.pelvisDefKLOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.spineCogOutputConstraint.evaluate() self.spineBaseOutputConstraint.evaluate() self.pelvisOutputConstraint.evaluate() self.spineEndOutputConstraint.evaluate()
class HandComponentGuide(HandComponent): """Hand Component Guide""" def __init__(self, name='hand', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Hand Guide Component:" + name) super(HandComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= # Guide Controls self.guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.digitNamesAttr = StringAttribute('digitNames', value="thumb,index,middle,ring,pinky", parent=self.guideSettingsAttrGrp) self.digitNamesAttr.setValueChangeCallback(self.updateFingers) self.numJointsAttr = IntegerAttribute('numJoints', value=4, minValue=2, maxValue=20, parent=self.guideSettingsAttrGrp) self.numJointsAttr.setValueChangeCallback(self.resizeDigits) self.fingers = OrderedDict() self.handCtrl = Control('hand', parent=self.ctrlCmpGrp, shape="square") self.handCtrl.rotatePoints(0.0, 0.0, 90.0) self.handCtrl.scalePoints(Vec3(1.0, 0.75, 1.0)) self.handCtrl.setColor('yellow') self.handGuideSettingsAttrGrp = AttributeGroup("Settings", parent=self.handCtrl) self.ctrlShapeToggle = BoolAttribute('ctrlShape_vis', value=False, parent=self.handGuideSettingsAttrGrp) self.handDebugInputAttr = BoolAttribute('drawDebug', value=False, parent=self.handGuideSettingsAttrGrp) self.drawDebugInputAttr.connect(self.handDebugInputAttr) self.guideCtrlHrcGrp = HierarchyGroup('controlShapes', parent=self.ctrlCmpGrp) self.default_data = { "name": name, "location": "L", "handXfo": Xfo(Vec3(7.1886, 12.2819, 0.4906)), "digitNames": self.digitNamesAttr.getValue(), "numJoints": self.numJointsAttr.getValue(), "fingers": self.fingers } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(HandComponentGuide, self).saveData() data['handXfo'] = self.handCtrl.xfo data['digitNames'] = self.digitNamesAttr.getValue() data['numJoints'] = self.numJointsAttr.getValue() fingerXfos = {} fingerShapeCtrlData = {} for finger in self.fingers.keys(): fingerXfos[finger] = [x.xfo for x in self.fingers[finger]] fingerShapeCtrlData[finger] = [] for i, digit in enumerate(self.fingers[finger]): if i != len(self.fingers[finger]) - 1: fingerShapeCtrlData[finger].append(digit.shapeCtrl.getCurveData()) data['fingersGuideXfos'] = fingerXfos data['fingerShapeCtrlData'] = fingerShapeCtrlData return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(HandComponentGuide, self).loadData(data) self.handCtrl.xfo = data.get('handXfo') self.numJointsAttr.setValue(data.get('numJoints')) self.digitNamesAttr.setValue(data.get('digitNames')) fingersGuideXfos = data.get('fingersGuideXfos') fingerShapeCtrlData = data.get('fingerShapeCtrlData') if fingersGuideXfos is not None: for finger in self.fingers.keys(): for i in xrange(len(self.fingers[finger])): self.fingers[finger][i].xfo = fingersGuideXfos[finger][i] if hasattr(self.fingers[finger][i], 'shapeCtrl'): if fingerShapeCtrlData is not None: if finger in fingerShapeCtrlData: self.fingers[finger][i].shapeCtrl.setCurveData(fingerShapeCtrlData[finger][i]) for op in self.getOperators(): guideOpName = ''.join([op.getName().split('FingerGuideOp')[0], self.getLocation(), 'FingerGuideOp']) op.setName(guideOpName) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(HandComponentGuide, self).getRigBuildData() data['handXfo'] = self.handCtrl.xfo fingerData = {} for finger in self.fingers.keys(): fingerData[finger] = [] for i, joint in enumerate(self.fingers[finger]): if i == len(self.fingers[finger]) - 1: continue # Calculate Xfo boneVec = self.fingers[finger][i + 1].xfo.tr - self.fingers[finger][i].xfo.tr bone1Normal = self.fingers[finger][i].xfo.ori.getZaxis().cross(boneVec).unit() bone1ZAxis = boneVec.cross(bone1Normal).unit() jointXfo = Xfo() jointXfo.setFromVectors(boneVec.unit(), bone1Normal, bone1ZAxis, self.fingers[finger][i].xfo.tr) jointData = { 'curveData': self.fingers[finger][i].shapeCtrl.getCurveData(), 'length': self.fingers[finger][i].xfo.tr.distanceTo(self.fingers[finger][i + 1].xfo.tr), 'xfo': jointXfo } fingerData[finger].append(jointData) data['fingerData'] = fingerData return data # ========== # Callbacks # ========== def addFinger(self, name): digitSizeAttributes = [] fingerGuideCtrls = [] firstDigitCtrl = Control(name + "01", parent=self.handCtrl, shape='sphere') firstDigitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) firstDigitShapeCtrl = Control(name + "Shp01", parent=self.guideCtrlHrcGrp, shape='square') firstDigitShapeCtrl.setColor('yellow') firstDigitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) firstDigitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) fingerGuideCtrls.append(firstDigitShapeCtrl) firstDigitCtrl.shapeCtrl = firstDigitShapeCtrl firstDigitVisAttr = firstDigitShapeCtrl.getVisibilityAttr() firstDigitVisAttr.connect(self.ctrlShapeToggle) triangleCtrl = Control('tempCtrl', parent=None, shape='triangle') triangleCtrl.rotatePoints(90.0, 0.0, 0.0) triangleCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) triangleCtrl.translatePoints(Vec3(0.0, 0.0875, 0.0)) firstDigitCtrl.appendCurveData(triangleCtrl.getCurveData()) firstDigitCtrl.lockScale(True, True, True) digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=firstDigitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) # Set Finger self.fingers[name] = [] self.fingers[name].append(firstDigitCtrl) parent = firstDigitCtrl numJoints = self.numJointsAttr.getValue() if name == "thumb": numJoints = 3 for i in xrange(2, numJoints + 2): digitCtrl = Control(name + str(i).zfill(2), parent=parent, shape='sphere') if i != numJoints + 1: digitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) digitCtrl.appendCurveData(triangleCtrl.getCurveData()) digitShapeCtrl = Control(name + 'Shp' + str(i).zfill(2), parent=self.guideCtrlHrcGrp, shape='circle') digitShapeCtrl.setColor('yellow') digitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) digitShapeCtrl.getVisibilityAttr().connect(self.ctrlShapeToggle) digitCtrl.shapeCtrl = digitShapeCtrl if i == 2: digitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) else: digitShapeCtrl.rotatePoints(0.0, 0.0, 90.0) fingerGuideCtrls.append(digitShapeCtrl) # Add size attr to all but last guide control digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=digitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) else: digitCtrl.scalePoints(Vec3(0.0875, 0.0875, 0.0875)) digitCtrl.lockScale(True, True, True) self.fingers[name].append(digitCtrl) parent = digitCtrl # =========================== # Create Canvas Operators # =========================== # Add Finger Guide Canvas Op fingerGuideCanvasOp = CanvasOperator(name + 'FingerGuideOp', 'Kraken.Solvers.Biped.BipedFingerGuideSolver') self.addOperator(fingerGuideCanvasOp) # Add Att Inputs fingerGuideCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) fingerGuideCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs fingerGuideCanvasOp.setInput('controls', self.fingers[name]) fingerGuideCanvasOp.setInput('planeSizes', digitSizeAttributes) # Add Xfo Outputs fingerGuideCanvasOp.setOutput('result', fingerGuideCtrls) fingerGuideCanvasOp.setOutput('forceEval', firstDigitCtrl.getVisibilityAttr()) return firstDigitCtrl def removeFinger(self, name): self.handCtrl.removeChild(self.fingers[name][0]) del self.fingers[name] def placeFingers(self): spacing = 0.25 length = spacing * (len(self.fingers.keys()) - 1) mid = length / 2.0 startOffset = length - mid for i, finger in enumerate(self.fingers.keys()): parentCtrl = self.handCtrl numJoints = self.numJointsAttr.getValue() if finger == "thumb": numJoints = 3 for y in xrange(numJoints + 1): if y == 1: xOffset = 0.375 else: xOffset = 0.25 if y == 0: offsetVec = Vec3(xOffset, 0, startOffset - (i * spacing)) else: offsetVec = Vec3(xOffset, 0, 0) fingerPos = parentCtrl.xfo.transformVector(offsetVec) fingerXfo = Xfo(tr=fingerPos, ori=self.handCtrl.xfo.ori) self.fingers[finger][y].xfo = fingerXfo parentCtrl = self.fingers[finger][y] def updateFingers(self, fingers): if " " in fingers: self.digitNamesAttr.setValue(fingers.replace(" ", "")) return fingerNames = fingers.split(',') # Delete fingers that don't exist any more for finger in list(set(self.fingers.keys()) - set(fingerNames)): self.removeFinger(finger) # Add Fingers for finger in fingerNames: if finger in self.fingers.keys(): continue self.addFinger(finger) self.placeFingers() def resizeDigits(self, numJoints): initNumJoints = numJoints for finger in self.fingers.keys(): if finger == "thumb": numJoints = 3 else: numJoints = initNumJoints if numJoints + 1 == len(self.fingers[finger]): continue elif numJoints + 1 > len(self.fingers[finger]): for i in xrange(len(self.fingers[finger]), numJoints + 1): prevDigit = self.fingers[finger][i - 1] digitCtrl = Control(finger + str(i + 1).zfill(2), parent=prevDigit, shape='sphere') digitCtrl.setColor('orange') digitCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) digitCtrl.lockScale(True, True, True) self.fingers[finger].append(digitCtrl) elif numJoints + 1 < len(self.fingers[finger]): numExtraCtrls = len(self.fingers[finger]) - (numJoints + 1) for i in xrange(numExtraCtrls): removedJoint = self.fingers[finger].pop() removedJoint.getParent().removeChild(removedJoint) self.placeFingers() # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return HandComponentRig
class MainSrtComponentRig(MainSrtComponent): """MainSrt Component Rig""" def __init__(self, name="mainSrt", parent=None): Profiler.getInstance().push("Construct MainSrt Rig Component:" + name) super(MainSrtComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Add Controls self.mainSRTCtrlSpace = CtrlSpace("SRT", parent=self.ctrlCmpGrp) self.mainSRTCtrl = Control("SRT", shape="circle", parent=self.mainSRTCtrlSpace) self.mainSRTCtrl.lockScale(x=True, y=True, z=True) self.offsetCtrlSpace = CtrlSpace("Offset", parent=self.mainSRTCtrl) self.offsetCtrl = Control("Offset", shape="circle", parent=self.offsetCtrlSpace) self.offsetCtrl.setColor("orange") self.offsetCtrl.lockScale(x=True, y=True, z=True) # Add Component Params to IK control mainSrtSettingsAttrGrp = AttributeGroup("DisplayInfo_MainSrtSettings", parent=self.mainSRTCtrl) self.rigScaleAttr = ScalarAttribute( "rigScale", value=1.0, parent=mainSrtSettingsAttrGrp, minValue=0.1, maxValue=100.0 ) self.rigScaleOutputAttr.connect(self.rigScaleAttr) # ========== # Deformers # ========== # ============== # Constrain I/O # ============== # Constraint inputs # Constraint outputs srtConstraint = PoseConstraint("_".join([self.srtOutputTgt.getName(), "To", self.mainSRTCtrl.getName()])) srtConstraint.addConstrainer(self.mainSRTCtrl) self.srtOutputTgt.addConstraint(srtConstraint) offsetConstraint = PoseConstraint("_".join([self.offsetOutputTgt.getName(), "To", self.mainSRTCtrl.getName()])) offsetConstraint.addConstrainer(self.offsetCtrl) self.offsetOutputTgt.addConstraint(offsetConstraint) # =============== # Add Splice Ops # =============== # Add Rig Scale Splice Op self.rigScaleKLOp = KLOperator("rigScaleKLOp", "RigScaleSolver", "Kraken") self.addOperator(self.rigScaleKLOp) # Add Att Inputs self.rigScaleKLOp.setInput("drawDebug", self.drawDebugInputAttr) self.rigScaleKLOp.setInput("rigScale", self.rigScaleOutputAttr) # Add Xfo Inputs # Add Xfo Outputs self.rigScaleKLOp.setOutput("target", self.mainSRTCtrlSpace) Profiler.getInstance().pop() 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(MainSrtComponentRig, self).loadData(data) # ================ # Resize Controls # ================ self.mainSRTCtrl.scalePoints(Vec3(data["mainSrtSize"], 1.0, data["mainSrtSize"])) self.offsetCtrl.scalePoints(Vec3(data["mainSrtSize"] - 0.5, 1.0, data["mainSrtSize"] - 0.5)) # ======================= # Set Control Transforms # ======================= self.mainSRTCtrlSpace.xfo = data["mainSrtXfo"] self.mainSRTCtrl.xfo = data["mainSrtXfo"] self.offsetCtrlSpace.xfo = data["mainSrtXfo"] self.offsetCtrl.xfo = data["mainSrtXfo"] # ============ # Set IO Xfos # ============ self.srtOutputTgt = data["mainSrtXfo"] self.offsetOutputTgt = data["mainSrtXfo"]
class FabriceTailRig(FabriceTail): """Fabrice Tail Component""" def __init__(self, name="fabriceTail", parent=None): Profiler.getInstance().push("Construct Tail Rig Component:" + name) super(FabriceTailRig, self).__init__(name, parent) # ========= # Controls # ========= # Tail Base # self.tailBaseCtrlSpace = CtrlSpace('tailBase', parent=self.ctrlCmpGrp) # self.tailBaseCtrl = Control('tailBase', parent=self.tailBaseCtrlSpace, shape="circle") # self.tailBaseCtrl.rotatePoints(90, 0, 0) # self.tailBaseCtrl.scalePoints(Vec3(2.0, 2.0, 2.0)) # self.tailBaseCtrl.setColor("greenBlue") # Tail Base Handle self.tailBaseHandleCtrlSpace = CtrlSpace('tailBaseHandle', parent=self.ctrlCmpGrp) self.tailBaseHandleCtrl = Control('tailBaseHandle', parent=self.tailBaseHandleCtrlSpace, shape="pin") self.tailBaseHandleCtrl.lockScale(x=True, y=True, z=True) self.tailBaseHandleCtrl.setColor("turqoise") # Tail End Handle self.tailEndHandleCtrlSpace = CtrlSpace('tailEndHandle', parent=self.ctrlCmpGrp) self.tailEndHandleCtrl = Control('tailEndHandle', parent=self.tailEndHandleCtrlSpace, shape="pin") self.tailEndHandleCtrl.lockScale(x=True, y=True, z=True) self.tailEndHandleCtrl.setColor("turqoise") # Tail End self.tailEndCtrlSpace = CtrlSpace('tailEnd', parent=self.tailEndHandleCtrl) self.tailEndCtrl = Control('tailEnd', parent=self.tailEndCtrlSpace, shape="pin") self.tailEndCtrl.lockScale(x=True, y=True, z=True) self.tailEndCtrl.setColor("greenBlue") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.deformerJoints = [] self.tailOutputs = [] self.setNumDeformers(1) # ===================== # Create Component I/O # ===================== # Setup component Xfo I/O's self.tailVertebraeOutput.setTarget(self.tailOutputs) # ============== # Constrain I/O # ============== # Constraint inputs self.tailBaseHandleInputConstraint = PoseConstraint('_'.join([self.tailBaseHandleCtrlSpace.getName(), 'To', self.spineEndCtrlInputTgt.getName()])) self.tailBaseHandleInputConstraint.addConstrainer(self.spineEndCtrlInputTgt) self.tailBaseHandleInputConstraint.setMaintainOffset(True) self.tailBaseHandleCtrlSpace.addConstraint(self.tailBaseHandleInputConstraint) self.tailEndHandleInputConstraint = PoseConstraint('_'.join([self.tailEndHandleCtrlSpace.getName(), 'To', self.cogInputTgt.getName()])) self.tailEndHandleInputConstraint.addConstrainer(self.cogInputTgt) self.tailEndHandleInputConstraint.setMaintainOffset(True) self.tailEndHandleCtrlSpace.addConstraint(self.tailEndHandleInputConstraint) # Constraint outputs self.tailBaseOutputConstraint = PoseConstraint('_'.join([self.tailBaseOutputTgt.getName(), 'To', 'spineBase'])) self.tailBaseOutputConstraint.addConstrainer(self.tailOutputs[0]) self.tailBaseOutputTgt.addConstraint(self.tailBaseOutputConstraint) self.tailEndOutputConstraint = PoseConstraint('_'.join([self.tailEndOutputTgt.getName(), 'To', 'spineEnd'])) self.tailEndOutputConstraint.addConstrainer(self.tailOutputs[0]) self.tailEndOutputTgt.addConstraint(self.tailEndOutputConstraint) # =============== # Add Splice Ops # =============== # Add Tail Splice Op self.bezierTailKLOp = KLOperator('tailKLOp', 'BezierSpineSolver', 'Kraken') self.addOperator(self.bezierTailKLOp) # Add Att Inputs self.bezierTailKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierTailKLOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierTailKLOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierTailKLOp.setInput('base', self.spineEndInputTgt) self.bezierTailKLOp.setInput('baseHandle', self.tailBaseHandleCtrl) self.bezierTailKLOp.setInput('tipHandle', self.tailEndHandleCtrl) self.bezierTailKLOp.setInput('tip', self.tailEndCtrl) # Add Xfo Outputs self.bezierTailKLOp.setOutput('outputs', self.tailOutputs) # Add Deformer Splice Op self.deformersToOutputsKLOp = KLOperator('tailDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.deformersToOutputsKLOp) # Add Att Inputs self.deformersToOutputsKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsKLOp.setInput('constrainers', self.tailOutputs) # Add Xfo Outputs self.deformersToOutputsKLOp.setOutput('constrainees', self.deformerJoints) Profiler.getInstance().pop() def setNumDeformers(self, numDeformers): # Add new deformers and outputs for i in xrange(len(self.tailOutputs), numDeformers): name = 'tail' + str(i + 1).zfill(2) tailOutput = ComponentOutput(name, parent=self.outputHrcGrp) self.tailOutputs.append(tailOutput) for i in xrange(len(self.deformerJoints), numDeformers): name = 'tail' + str(i + 1).zfill(2) tailDef = Joint(name, parent=self.defCmpGrp) tailDef.setComponent(self) self.deformerJoints.append(tailDef) 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(FabriceTailRig, self).loadData( data ) tailBasePos = data['tailBasePos'] tailBaseHandlePos = data['tailBaseHandlePos'] tailBaseHandleCtrlCrvData = data['tailBaseHandleCtrlCrvData'] tailEndHandlePos = data['tailEndHandlePos'] tailEndHandleCtrlCrvData = data['tailEndHandleCtrlCrvData'] tailEndPos = data['tailEndPos'] tailEndCtrlCrvData = data['tailEndCtrlCrvData'] numDeformers = data['numDeformers'] # Set Xfos self.spineEndInputTgt.xfo.tr = tailBasePos self.spineEndCtrlInputTgt.xfo.tr = tailBasePos self.tailBaseHandleCtrlSpace.xfo.tr = tailBaseHandlePos self.tailBaseHandleCtrl.xfo.tr = tailBaseHandlePos self.tailBaseHandleCtrl.setCurveData(tailBaseHandleCtrlCrvData) self.tailEndHandleCtrlSpace.xfo.tr = tailEndHandlePos self.tailEndHandleCtrl.xfo.tr = tailEndHandlePos self.tailEndHandleCtrl.setCurveData(tailEndHandleCtrlCrvData) self.tailEndCtrlSpace.xfo.tr = tailEndPos self.tailEndCtrl.xfo.tr = tailEndPos self.tailEndCtrl.setCurveData(tailEndCtrlCrvData) length = tailBasePos.distanceTo(tailBaseHandlePos) + tailBaseHandlePos.distanceTo(tailEndHandlePos) + tailEndHandlePos.distanceTo(tailEndPos) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) # Update number of deformers and outputs self.setNumDeformers(numDeformers) # Updating constraint to use the updated last output. self.tailEndOutputConstraint.setConstrainer(self.tailOutputs[-1], index=0) # ============ # Set IO Xfos # ============ # ==================== # Evaluate Splice Ops # ==================== # evaluate the spine op so that all the output transforms are updated. self.bezierTailKLOp.evaluate() # evaluate the constraint op so that all the joint transforms are updated. self.deformersToOutputsKLOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.tailBaseHandleInputConstraint.evaluate() self.tailBaseOutputConstraint.evaluate() self.tailEndOutputConstraint.evaluate()
class FabriceTailRig(FabriceTail): """Fabrice Tail Component""" def __init__(self, name="fabriceTail", parent=None): Profiler.getInstance().push("Construct Tail Rig Component:" + name) super(FabriceTailRig, self).__init__(name, parent) # ========= # Controls # ========= # Tail Base # self.tailBaseCtrlSpace = CtrlSpace('tailBase', parent=self.ctrlCmpGrp) # self.tailBaseCtrl = Control('tailBase', parent=self.tailBaseCtrlSpace, shape="circle") # self.tailBaseCtrl.rotatePoints(90, 0, 0) # self.tailBaseCtrl.scalePoints(Vec3(2.0, 2.0, 2.0)) # self.tailBaseCtrl.setColor("greenBlue") # Tail Base Handle self.tailBaseHandleCtrlSpace = CtrlSpace('tailBaseHandle', parent=self.ctrlCmpGrp) self.tailBaseHandleCtrl = Control('tailBaseHandle', parent=self.tailBaseHandleCtrlSpace, shape="pin") self.tailBaseHandleCtrl.lockScale(x=True, y=True, z=True) self.tailBaseHandleCtrl.setColor("turqoise") # Tail End Handle self.tailEndHandleCtrlSpace = CtrlSpace('tailEndHandle', parent=self.ctrlCmpGrp) self.tailEndHandleCtrl = Control('tailEndHandle', parent=self.tailEndHandleCtrlSpace, shape="pin") self.tailEndHandleCtrl.lockScale(x=True, y=True, z=True) self.tailEndHandleCtrl.setColor("turqoise") # Tail End self.tailEndCtrlSpace = CtrlSpace('tailEnd', parent=self.tailEndHandleCtrl) self.tailEndCtrl = Control('tailEnd', parent=self.tailEndCtrlSpace, shape="pin") self.tailEndCtrl.lockScale(x=True, y=True, z=True) self.tailEndCtrl.setColor("greenBlue") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.deformerJoints = [] self.tailOutputs = [] self.setNumDeformers(1) # ===================== # Create Component I/O # ===================== # Setup component Xfo I/O's self.tailVertebraeOutput.setTarget(self.tailOutputs) # ============== # Constrain I/O # ============== # Constraint inputs self.tailBaseHandleInputConstraint = PoseConstraint('_'.join([self.tailBaseHandleCtrlSpace.getName(), 'To', self.spineEndCtrlInputTgt.getName()])) self.tailBaseHandleInputConstraint.addConstrainer(self.spineEndCtrlInputTgt) self.tailBaseHandleInputConstraint.setMaintainOffset(True) self.tailBaseHandleCtrlSpace.addConstraint(self.tailBaseHandleInputConstraint) self.tailEndHandleInputConstraint = PoseConstraint('_'.join([self.tailEndHandleCtrlSpace.getName(), 'To', self.cogInputTgt.getName()])) self.tailEndHandleInputConstraint.addConstrainer(self.cogInputTgt) self.tailEndHandleInputConstraint.setMaintainOffset(True) self.tailEndHandleCtrlSpace.addConstraint(self.tailEndHandleInputConstraint) # Constraint outputs self.tailBaseOutputConstraint = PoseConstraint('_'.join([self.tailBaseOutputTgt.getName(), 'To', 'spineBase'])) self.tailBaseOutputConstraint.addConstrainer(self.tailOutputs[0]) self.tailBaseOutputTgt.addConstraint(self.tailBaseOutputConstraint) self.tailEndOutputConstraint = PoseConstraint('_'.join([self.tailEndOutputTgt.getName(), 'To', 'spineEnd'])) self.tailEndOutputConstraint.addConstrainer(self.tailOutputs[0]) self.tailEndOutputTgt.addConstraint(self.tailEndOutputConstraint) # =============== # Add Splice Ops # =============== # Add Tail Splice Op self.bezierTailSpliceOp = SpliceOperator('tailSpliceOp', 'BezierSpineSolver', 'Kraken') self.addOperator(self.bezierTailSpliceOp) # Add Att Inputs self.bezierTailSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierTailSpliceOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierTailSpliceOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierTailSpliceOp.setInput('base', self.spineEndInputTgt) self.bezierTailSpliceOp.setInput('baseHandle', self.tailBaseHandleCtrl) self.bezierTailSpliceOp.setInput('tipHandle', self.tailEndHandleCtrl) self.bezierTailSpliceOp.setInput('tip', self.tailEndCtrl) # Add Xfo Outputs self.bezierTailSpliceOp.setOutput('outputs', self.tailOutputs) # Add Deformer Splice Op self.deformersToOutputsSpliceOp = SpliceOperator('tailDeformerSpliceOp', 'MultiPoseConstraintSolver', 'Kraken', alwaysEval=True) self.addOperator(self.deformersToOutputsSpliceOp) # Add Att Inputs self.deformersToOutputsSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsSpliceOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsSpliceOp.setInput('constrainers', self.tailOutputs) # Add Xfo Outputs self.deformersToOutputsSpliceOp.setOutput('constrainees', self.deformerJoints) Profiler.getInstance().pop() def setNumDeformers(self, numDeformers): # Add new deformers and outputs for i in xrange(len(self.tailOutputs), numDeformers): name = 'tail' + str(i + 1).zfill(2) tailOutput = ComponentOutput(name, parent=self.outputHrcGrp) self.tailOutputs.append(tailOutput) for i in xrange(len(self.deformerJoints), numDeformers): name = 'tail' + str(i + 1).zfill(2) tailDef = Joint(name, parent=self.defCmpGrp) tailDef.setComponent(self) self.deformerJoints.append(tailDef) 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(FabriceTailRig, self).loadData( data ) tailBasePos = data['tailBasePos'] tailBaseHandlePos = data['tailBaseHandlePos'] tailBaseHandleCtrlCrvData = data['tailBaseHandleCtrlCrvData'] tailEndHandlePos = data['tailEndHandlePos'] tailEndHandleCtrlCrvData = data['tailEndHandleCtrlCrvData'] tailEndPos = data['tailEndPos'] tailEndCtrlCrvData = data['tailEndCtrlCrvData'] numDeformers = data['numDeformers'] # Set Xfos self.spineEndInputTgt.xfo.tr = tailBasePos self.spineEndCtrlInputTgt.xfo.tr = tailBasePos self.tailBaseHandleCtrlSpace.xfo.tr = tailBaseHandlePos self.tailBaseHandleCtrl.xfo.tr = tailBaseHandlePos self.tailBaseHandleCtrl.setCurveData(tailBaseHandleCtrlCrvData) self.tailEndHandleCtrlSpace.xfo.tr = tailEndHandlePos self.tailEndHandleCtrl.xfo.tr = tailEndHandlePos self.tailEndHandleCtrl.setCurveData(tailEndHandleCtrlCrvData) self.tailEndCtrlSpace.xfo.tr = tailEndPos self.tailEndCtrl.xfo.tr = tailEndPos self.tailEndCtrl.setCurveData(tailEndCtrlCrvData) length = tailBasePos.distanceTo(tailBaseHandlePos) + tailBaseHandlePos.distanceTo(tailEndHandlePos) + tailEndHandlePos.distanceTo(tailEndPos) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) # Update number of deformers and outputs self.setNumDeformers(numDeformers) # Updating constraint to use the updated last output. self.tailEndOutputConstraint.setConstrainer(self.tailOutputs[-1], index=0) # ============ # Set IO Xfos # ============ # ==================== # Evaluate Splice Ops # ==================== # evaluate the spine op so that all the output transforms are updated. self.bezierTailSpliceOp.evaluate() # evaluate the constraint op so that all the joint transforms are updated. self.deformersToOutputsSpliceOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.tailBaseHandleInputConstraint.evaluate() self.tailBaseOutputConstraint.evaluate() self.tailEndOutputConstraint.evaluate()
class FabriceHeadGuide(FabriceHead): """Fabrice Head Component Guide""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Guide Component:" + name) super(FabriceHeadGuide, self).__init__(name, parent) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape="circle") self.headCtrl.rotatePoints(90.0, 0.0, 0.0) self.headCtrl.scalePoints(Vec3(3.5, 3.5, 3.5)) self.jawCtrl = Control('jaw', parent=self.ctrlCmpGrp, shape="cube") self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(2.0, 0.5, 2.0)) self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.setColor('orange') data = { "name": name, "location": "M", "headXfo": Xfo(Vec3(0.0, 1.67, 1.75)), "headCtrlCrvData": self.headCtrl.getCurveData(), "jawPosition": Vec3(0.0, 1.2787, 2.0078), "jawCtrlCrvData": self.jawCtrl.getCurveData(), } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(FabriceHeadGuide, self).saveData() data['headXfo'] = self.headCtrl.xfo data['headCtrlCrvData'] = self.headCtrl.getCurveData() data['jawPosition'] = self.jawCtrl.xfo.tr data['jawCtrlCrvData'] = self.jawCtrl.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(FabriceHeadGuide, self).loadData( data ) self.headCtrl.xfo = data['headXfo'] self.headCtrl.setCurveData(data['headCtrlCrvData']) self.jawCtrl.xfo.tr = data['jawPosition'] self.jawCtrl.setCurveData(data['jawCtrlCrvData']) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(FabriceHeadGuide, self).getRigBuildData() data['headXfo'] = self.headCtrl.xfo data['headCtrlCrvData'] = self.headCtrl.getCurveData() data['jawPosition'] = self.jawCtrl.xfo.tr data['jawCtrlCrvData'] = self.jawCtrl.getCurveData() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return FabriceHeadRig
class HeadComponentRig(HeadComponent): """Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(HeadComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Head self.headCtrlSpace = CtrlSpace('head', parent=self.ctrlCmpGrp) self.headCtrl = Control('head', parent=self.headCtrlSpace, shape="circle") self.headCtrl.rotatePoints(0, 0, 90) self.headCtrl.scalePoints(Vec3(3, 3, 3)) self.headCtrl.translatePoints(Vec3(0, 1, 0.25)) # Eye Left self.eyeLeftCtrlSpace = CtrlSpace('eyeLeft', parent=self.headCtrl) self.eyeLeftCtrl = Control('eyeLeft', parent=self.eyeLeftCtrlSpace, shape="sphere") self.eyeLeftCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeLeftCtrl.setColor("blueMedium") # Eye Right self.eyeRightCtrlSpace = CtrlSpace('eyeRight', parent=self.headCtrl) self.eyeRightCtrl = Control('eyeRight', parent=self.eyeRightCtrlSpace, shape="sphere") self.eyeRightCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeRightCtrl.setColor("blueMedium") # Jaw self.jawCtrlSpace = CtrlSpace('jawCtrlSpace', parent=self.headCtrl) self.jawCtrl = Control('jaw', parent=self.jawCtrlSpace, shape="cube") self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(1.45, 0.65, 1.25)) self.jawCtrl.translatePoints(Vec3(0, -0.25, 0)) self.jawCtrl.setColor("orange") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) headDef = Joint('head', parent=defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=defCmpGrp) jawDef.setComponent(self) eyeLeftDef = Joint('eyeLeft', parent=defCmpGrp) eyeLeftDef.setComponent(self) eyeRightDef = Joint('eyeRight', parent=defCmpGrp) eyeRightDef.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs headInputConstraint = PoseConstraint('_'.join([self.headCtrlSpace.getName(), 'To', self.headBaseInputTgt.getName()])) headInputConstraint.setMaintainOffset(True) headInputConstraint.addConstrainer(self.headBaseInputTgt) self.headCtrlSpace.addConstraint(headInputConstraint) # # Constraint outputs headOutputConstraint = PoseConstraint('_'.join([self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(headOutputConstraint) jawOutputConstraint = PoseConstraint('_'.join([self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(jawOutputConstraint) eyeLOutputConstraint = PoseConstraint('_'.join([self.eyeLOutputTgt.getName(), 'To', self.eyeLeftCtrl.getName()])) eyeLOutputConstraint.addConstrainer(self.eyeLeftCtrl) self.eyeLOutputTgt.addConstraint(eyeLOutputConstraint) eyeROutputConstraint = PoseConstraint('_'.join([self.eyeROutputTgt.getName(), 'To', self.eyeRightCtrl.getName()])) eyeROutputConstraint.addConstrainer(self.eyeRightCtrl) self.eyeROutputTgt.addConstraint(eyeROutputConstraint) # ================== # Add Component I/O # ================== # Add Xfo I/O's # self.addInput(self.headBaseInputTgt) # self.addOutput(self.headOutputTgt) # self.addOutput(self.jawOutputTgt) # self.addOutput(self.eyeLOutputTgt) # self.addOutput(self.eyeROutputTgt) # Add Attribute I/O's # self.addInput(self.drawDebugInputAttr) # =============== # Add Splice Ops # =============== # Add Deformer Splice Op # spliceOp = SpliceOperator('headDeformerSpliceOp', 'HeadConstraintSolver', 'KrakenHeadConstraintSolver') # self.addOperator(spliceOp) # # Add Att Inputs # spliceOp.setInput('drawDebug', self.drawDebugInputAttr) # spliceOp.setInput('rigScale', self.rigScaleInputAttr) # # Add Xfo Inputstrl) # spliceOp.setInput('headConstrainer', self.headOutputTgt) # spliceOp.setInput('jawConstrainer', self.jawOutputTgt) # spliceOp.setInput('eyeLeftConstrainer', self.eyeLOutputTgt) # spliceOp.setInput('eyeRightConstrainer', self.eyeROutputTgt) # # Add Xfo Outputs # spliceOp.setOutput('headDeformer', headDef) # spliceOp.setOutput('jawDeformer', jawDef) # spliceOp.setOutput('eyeLeftDeformer', eyeLeftDef) # spliceOp.setOutput('eyeRightDeformer', eyeRightDef) Profiler.getInstance().pop() 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(HeadComponentRig, self).loadData( data ) self.headCtrlSpace.xfo.tr = data['headPosition'] self.headCtrl.xfo.tr = data['headPosition'] self.eyeLeftCtrlSpace.xfo.tr = data['eyeLeftPosition'] self.eyeLeftCtrl.xfo.tr = data['eyeLeftPosition'] self.eyeRightCtrlSpace.xfo.tr = data['eyeRightPosition'] self.eyeRightCtrl.xfo.tr = data['eyeRightPosition'] self.jawCtrlSpace.xfo.tr = data['jawPosition'] self.jawCtrl.xfo.tr = data['jawPosition'] # ============ # Set IO Xfos # ============ self.headBaseInputTgt.xfo.tr = data['headPosition'] self.headOutputTgt.xfo.tr = data['headPosition'] self.jawOutputTgt.xfo.tr = data['jawPosition'] self.eyeLOutputTgt.xfo.tr = data['eyeLeftPosition'] self.eyeROutputTgt.xfo.tr = data['eyeRightPosition']
class HeadComponentRig(HeadComponent): """Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(HeadComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Head self.headCtrlSpace = CtrlSpace('head', parent=self.ctrlCmpGrp) self.headCtrl = Control('head', parent=self.headCtrlSpace, shape="circle") self.headCtrl.rotatePoints(0, 0, 90) self.headCtrl.scalePoints(Vec3(3, 3, 3)) self.headCtrl.translatePoints(Vec3(0, 1, 0.25)) # Eye Left self.eyeLeftCtrlSpace = CtrlSpace('eyeLeft', parent=self.headCtrl) self.eyeLeftCtrl = Control('eyeLeft', parent=self.eyeLeftCtrlSpace, shape="sphere") self.eyeLeftCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeLeftCtrl.setColor("blueMedium") # Eye Right self.eyeRightCtrlSpace = CtrlSpace('eyeRight', parent=self.headCtrl) self.eyeRightCtrl = Control('eyeRight', parent=self.eyeRightCtrlSpace, shape="sphere") self.eyeRightCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeRightCtrl.setColor("blueMedium") # Jaw self.jawCtrlSpace = CtrlSpace('jawCtrlSpace', parent=self.headCtrl) self.jawCtrl = Control('jaw', parent=self.jawCtrlSpace, shape="cube") self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(1.45, 0.65, 1.25)) self.jawCtrl.translatePoints(Vec3(0, -0.25, 0)) self.jawCtrl.setColor("orange") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) headDef = Joint('head', parent=defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=defCmpGrp) jawDef.setComponent(self) eyeLeftDef = Joint('eyeLeft', parent=defCmpGrp) eyeLeftDef.setComponent(self) eyeRightDef = Joint('eyeRight', parent=defCmpGrp) eyeRightDef.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs headInputConstraint = PoseConstraint('_'.join([ self.headCtrlSpace.getName(), 'To', self.headBaseInputTgt.getName() ])) headInputConstraint.setMaintainOffset(True) headInputConstraint.addConstrainer(self.headBaseInputTgt) self.headCtrlSpace.addConstraint(headInputConstraint) # # Constraint outputs headOutputConstraint = PoseConstraint('_'.join( [self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(headOutputConstraint) jawOutputConstraint = PoseConstraint('_'.join( [self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(jawOutputConstraint) eyeLOutputConstraint = PoseConstraint('_'.join( [self.eyeLOutputTgt.getName(), 'To', self.eyeLeftCtrl.getName()])) eyeLOutputConstraint.addConstrainer(self.eyeLeftCtrl) self.eyeLOutputTgt.addConstraint(eyeLOutputConstraint) eyeROutputConstraint = PoseConstraint('_'.join( [self.eyeROutputTgt.getName(), 'To', self.eyeRightCtrl.getName()])) eyeROutputConstraint.addConstrainer(self.eyeRightCtrl) self.eyeROutputTgt.addConstraint(eyeROutputConstraint) # ================== # Add Component I/O # ================== # Add Xfo I/O's # self.addInput(self.headBaseInputTgt) # self.addOutput(self.headOutputTgt) # self.addOutput(self.jawOutputTgt) # self.addOutput(self.eyeLOutputTgt) # self.addOutput(self.eyeROutputTgt) # Add Attribute I/O's # self.addInput(self.drawDebugInputAttr) # =============== # Add Splice Ops # =============== # Add Deformer Splice Op # spliceOp = SpliceOperator('headDeformerSpliceOp', 'HeadConstraintSolver', 'KrakenHeadConstraintSolver') # self.addOperator(spliceOp) # # Add Att Inputs # spliceOp.setInput('drawDebug', self.drawDebugInputAttr) # spliceOp.setInput('rigScale', self.rigScaleInputAttr) # # Add Xfo Inputstrl) # spliceOp.setInput('headConstrainer', self.headOutputTgt) # spliceOp.setInput('jawConstrainer', self.jawOutputTgt) # spliceOp.setInput('eyeLeftConstrainer', self.eyeLOutputTgt) # spliceOp.setInput('eyeRightConstrainer', self.eyeROutputTgt) # # Add Xfo Outputs # spliceOp.setOutput('headDeformer', headDef) # spliceOp.setOutput('jawDeformer', jawDef) # spliceOp.setOutput('eyeLeftDeformer', eyeLeftDef) # spliceOp.setOutput('eyeRightDeformer', eyeRightDef) Profiler.getInstance().pop() 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(HeadComponentRig, self).loadData(data) self.headCtrlSpace.xfo.tr = data['headPosition'] self.headCtrl.xfo.tr = data['headPosition'] self.eyeLeftCtrlSpace.xfo.tr = data['eyeLeftPosition'] self.eyeLeftCtrl.xfo.tr = data['eyeLeftPosition'] self.eyeRightCtrlSpace.xfo.tr = data['eyeRightPosition'] self.eyeRightCtrl.xfo.tr = data['eyeRightPosition'] self.jawCtrlSpace.xfo.tr = data['jawPosition'] self.jawCtrl.xfo.tr = data['jawPosition'] # ============ # Set IO Xfos # ============ self.headBaseInputTgt.xfo.tr = data['headPosition'] self.headOutputTgt.xfo.tr = data['headPosition'] self.jawOutputTgt.xfo.tr = data['jawPosition'] self.eyeLOutputTgt.xfo.tr = data['eyeLeftPosition'] self.eyeROutputTgt.xfo.tr = data['eyeRightPosition']
class HandComponentGuide(HandComponent): """Hand Component Guide""" def __init__(self, name='hand', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Hand Guide Component:" + name) super(HandComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= # Guide Controls self.guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.digitNamesAttr = StringAttribute('digitNames', value="thumb,index,middle,ring,pinky", parent=self.guideSettingsAttrGrp) self.digitNamesAttr.setValueChangeCallback(self.updateFingers) self.numJointsAttr = IntegerAttribute('numJoints', value=4, minValue=2, maxValue=20, parent=self.guideSettingsAttrGrp) self.numJointsAttr.setValueChangeCallback(self.resizeDigits) self.fingers = OrderedDict() self.handCtrl = Control('hand', parent=self.ctrlCmpGrp, shape="square") self.handCtrl.rotatePoints(0.0, 0.0, 90.0) self.handCtrl.scalePoints(Vec3(1.0, 0.75, 1.0)) self.handCtrl.setColor('yellow') self.handGuideSettingsAttrGrp = AttributeGroup("Settings", parent=self.handCtrl) self.ctrlShapeToggle = BoolAttribute('ctrlShape_vis', value=False, parent=self.handGuideSettingsAttrGrp) self.handDebugInputAttr = BoolAttribute('drawDebug', value=False, parent=self.handGuideSettingsAttrGrp) self.drawDebugInputAttr.connect(self.handDebugInputAttr) self.guideCtrlHrcGrp = HierarchyGroup('controlShapes', parent=self.ctrlCmpGrp) self.default_data = { "name": name, "location": "L", "handXfo": Xfo(Vec3(7.1886, 12.2819, 0.4906)), "digitNames": self.digitNamesAttr.getValue(), "numJoints": self.numJointsAttr.getValue(), "fingers": self.fingers } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(HandComponentGuide, self).saveData() data['handXfo'] = self.handCtrl.xfo data['digitNames'] = self.digitNamesAttr.getValue() data['numJoints'] = self.numJointsAttr.getValue() fingerXfos = {} fingerShapeCtrlData = {} for finger in self.fingers.keys(): fingerXfos[finger] = [x.xfo for x in self.fingers[finger]] fingerShapeCtrlData[finger] = [] for i, digit in enumerate(self.fingers[finger]): if i != len(self.fingers[finger]) - 1: fingerShapeCtrlData[finger].append(digit.shapeCtrl.getCurveData()) data['fingersGuideXfos'] = fingerXfos data['fingerShapeCtrlData'] = fingerShapeCtrlData return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(HandComponentGuide, self).loadData(data) self.handCtrl.xfo = data.get('handXfo') self.numJointsAttr.setValue(data.get('numJoints')) self.digitNamesAttr.setValue(data.get('digitNames')) fingersGuideXfos = data.get('fingersGuideXfos') fingerShapeCtrlData = data.get('fingerShapeCtrlData') if fingersGuideXfos is not None: for finger in self.fingers.keys(): for i in xrange(len(self.fingers[finger])): self.fingers[finger][i].xfo = fingersGuideXfos[finger][i] if hasattr(self.fingers[finger][i], 'shapeCtrl'): if fingerShapeCtrlData is not None: if finger in fingerShapeCtrlData: self.fingers[finger][i].shapeCtrl.setCurveData(fingerShapeCtrlData[finger][i]) for op in self.getOperators(): guideOpName = ''.join([op.getName().split('FingerGuideOp')[0], self.getLocation(), 'FingerGuideOp']) op.setName(guideOpName) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(HandComponentGuide, self).getRigBuildData() data['handXfo'] = self.handCtrl.xfo fingerData = {} for finger in self.fingers.keys(): fingerData[finger] = [] for i, joint in enumerate(self.fingers[finger]): if i == len(self.fingers[finger]) - 1: continue # Calculate Xfo boneVec = self.fingers[finger][i + 1].xfo.tr - self.fingers[finger][i].xfo.tr bone1Normal = self.fingers[finger][i].xfo.ori.getZaxis().cross(boneVec).unit() bone1ZAxis = boneVec.cross(bone1Normal).unit() jointXfo = Xfo() jointXfo.setFromVectors(boneVec.unit(), bone1Normal, bone1ZAxis, self.fingers[finger][i].xfo.tr) jointData = { 'curveData': self.fingers[finger][i].shapeCtrl.getCurveData(), 'length': self.fingers[finger][i].xfo.tr.distanceTo(self.fingers[finger][i + 1].xfo.tr), 'xfo': jointXfo } fingerData[finger].append(jointData) data['fingerData'] = fingerData return data # ========== # Callbacks # ========== def addFinger(self, name): digitSizeAttributes = [] fingerGuideCtrls = [] firstDigitCtrl = Control(name + "01", parent=self.handCtrl, shape='sphere') firstDigitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) firstDigitShapeCtrl = Control(name + "Shp01", parent=self.guideCtrlHrcGrp, shape='square') firstDigitShapeCtrl.setColor('yellow') firstDigitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) firstDigitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) fingerGuideCtrls.append(firstDigitShapeCtrl) firstDigitCtrl.shapeCtrl = firstDigitShapeCtrl firstDigitVisAttr = firstDigitShapeCtrl.getVisibilityAttr() firstDigitVisAttr.connect(self.ctrlShapeToggle) triangleCtrl = Control('tempCtrl', parent=None, shape='triangle') triangleCtrl.rotatePoints(90.0, 0.0, 0.0) triangleCtrl.scalePoints(Vec3(0.025, 0.025, 0.025)) triangleCtrl.translatePoints(Vec3(0.0, 0.0875, 0.0)) firstDigitCtrl.appendCurveData(triangleCtrl.getCurveData()) firstDigitCtrl.lockScale(True, True, True) digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=firstDigitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) # Set Finger self.fingers[name] = [] self.fingers[name].append(firstDigitCtrl) parent = firstDigitCtrl numJoints = self.numJointsAttr.getValue() if name == "thumb": numJoints = 3 for i in xrange(2, numJoints + 2): digitCtrl = Control(name + str(i).zfill(2), parent=parent, shape='sphere') if i != numJoints + 1: digitCtrl.scalePoints(Vec3(0.125, 0.125, 0.125)) digitCtrl.appendCurveData(triangleCtrl.getCurveData()) digitShapeCtrl = Control(name + 'Shp' + str(i).zfill(2), parent=self.guideCtrlHrcGrp, shape='circle') digitShapeCtrl.setColor('yellow') digitShapeCtrl.scalePoints(Vec3(0.175, 0.175, 0.175)) digitShapeCtrl.getVisibilityAttr().connect(self.ctrlShapeToggle) digitCtrl.shapeCtrl = digitShapeCtrl if i == 2: digitShapeCtrl.translatePoints(Vec3(0.0, 0.125, 0.0)) else: digitShapeCtrl.rotatePoints(0.0, 0.0, 90.0) fingerGuideCtrls.append(digitShapeCtrl) # Add size attr to all but last guide control digitSettingsAttrGrp = AttributeGroup("DigitSettings", parent=digitCtrl) digitSizeAttr = ScalarAttribute('size', value=0.25, parent=digitSettingsAttrGrp) digitSizeAttributes.append(digitSizeAttr) else: digitCtrl.scalePoints(Vec3(0.0875, 0.0875, 0.0875)) digitCtrl.lockScale(True, True, True) self.fingers[name].append(digitCtrl) parent = digitCtrl # =========================== # Create Canvas Operators # =========================== # Add Finger Guide Canvas Op fingerGuideCanvasOp = CanvasOperator(name + 'FingerGuide', 'Kraken.Solvers.Biped.BipedFingerGuideSolver') self.addOperator(fingerGuideCanvasOp) # Add Att Inputs fingerGuideCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) fingerGuideCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs fingerGuideCanvasOp.setInput('controls', self.fingers[name]) fingerGuideCanvasOp.setInput('planeSizes', digitSizeAttributes) # Add Xfo Outputs fingerGuideCanvasOp.setOutput('result', fingerGuideCtrls) fingerGuideCanvasOp.setOutput('forceEval', firstDigitCtrl.getVisibilityAttr()) return firstDigitCtrl def removeFinger(self, name): self.handCtrl.removeChild(self.fingers[name][0]) del self.fingers[name] def placeFingers(self): spacing = 0.25 length = spacing * (len(self.fingers.keys()) - 1) mid = length / 2.0 startOffset = length - mid for i, finger in enumerate(self.fingers.keys()): parentCtrl = self.handCtrl numJoints = self.numJointsAttr.getValue() if finger == "thumb": numJoints = 3 for y in xrange(numJoints + 1): if y == 1: xOffset = 0.375 else: xOffset = 0.25 if y == 0: offsetVec = Vec3(xOffset, 0, startOffset - (i * spacing)) else: offsetVec = Vec3(xOffset, 0, 0) fingerPos = parentCtrl.xfo.transformVector(offsetVec) fingerXfo = Xfo(tr=fingerPos, ori=self.handCtrl.xfo.ori) self.fingers[finger][y].xfo = fingerXfo parentCtrl = self.fingers[finger][y] def updateFingers(self, fingers): if " " in fingers: self.digitNamesAttr.setValue(fingers.replace(" ", "")) return fingerNames = fingers.split(',') # Delete fingers that don't exist any more for finger in list(set(self.fingers.keys()) - set(fingerNames)): self.removeFinger(finger) # Add Fingers for finger in fingerNames: if finger in self.fingers.keys(): continue self.addFinger(finger) self.placeFingers() def resizeDigits(self, numJoints): initNumJoints = numJoints for finger in self.fingers.keys(): if finger == "thumb": numJoints = 3 else: numJoints = initNumJoints if numJoints + 1 == len(self.fingers[finger]): continue elif numJoints + 1 > len(self.fingers[finger]): for i in xrange(len(self.fingers[finger]), numJoints + 1): prevDigit = self.fingers[finger][i - 1] digitCtrl = Control(finger + str(i + 1).zfill(2), parent=prevDigit, shape='sphere') digitCtrl.setColor('orange') digitCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) digitCtrl.lockScale(True, True, True) self.fingers[finger].append(digitCtrl) elif numJoints + 1 < len(self.fingers[finger]): numExtraCtrls = len(self.fingers[finger]) - (numJoints + 1) for i in xrange(numExtraCtrls): removedJoint = self.fingers[finger].pop() removedJoint.getParent().removeChild(removedJoint) self.placeFingers() # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return HandComponentRig
class FabriceTailGuide(FabriceTail): """Fabrice Tail Component Guide""" def __init__(self, name='tail', parent=None): Profiler.getInstance().push("Construct Fabrice Tail Guide Component:" + name) super(FabriceTailGuide, self).__init__(name, parent) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.numDeformersAttr = IntegerAttribute('numDeformers', value=1, minValue=0, maxValue=20, parent=guideSettingsAttrGrp) self.numDeformersAttr.setValueChangeCallback(self.updateNumDeformers) # Guide Controls self.tailBaseCtrl = Control('tailBase', parent=self.ctrlCmpGrp, shape='sphere') self.tailBaseCtrl.scalePoints(Vec3(1.2, 1.2, 1.2)) self.tailBaseCtrl.lockScale(x=True, y=True, z=True) self.tailBaseCtrl.setColor("turqoise") self.tailBaseHandleCtrl = Control('tailBaseHandle', parent=self.ctrlCmpGrp, shape='pin') self.tailBaseHandleCtrl.rotatePoints(90, 0, 0) self.tailBaseHandleCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailBaseHandleCtrl.lockScale(x=True, y=True, z=True) self.tailBaseHandleCtrl.setColor("turqoise") self.tailEndHandleCtrl = Control('tailEndHandle', parent=self.ctrlCmpGrp, shape='pin') self.tailEndHandleCtrl.rotatePoints(90, 0, 0) self.tailEndHandleCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailEndHandleCtrl.lockScale(x=True, y=True, z=True) self.tailEndHandleCtrl.setColor("turqoise") self.tailEndCtrl = Control('tailEnd', parent=self.ctrlCmpGrp, shape='pin') self.tailEndCtrl.rotatePoints(90, 0, 0) self.tailEndCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailEndCtrl.lockScale(x=True, y=True, z=True) self.tailEndCtrl.setColor("turqoise") # =============== # Add Splice Ops # =============== # Add Tail Splice Op self.bezierSpineSpliceOp = SpliceOperator('spineGuideSpliceOp', 'BezierSpineSolver', 'Kraken', alwaysEval=True) self.bezierSpineSpliceOp.setOutput('outputs', self.tailVertebraeOutput.getTarget()) self.addOperator(self.bezierSpineSpliceOp) # Add Att Inputs self.bezierSpineSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierSpineSpliceOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierSpineSpliceOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierSpineSpliceOp.setInput('base', self.tailBaseCtrl) self.bezierSpineSpliceOp.setInput('baseHandle', self.tailBaseHandleCtrl) self.bezierSpineSpliceOp.setInput('tipHandle', self.tailEndHandleCtrl) self.bezierSpineSpliceOp.setInput('tip', self.tailEndCtrl) self.loadData({ 'name': name, 'location': 'M', 'tailBasePos': Vec3(0.0, 0.65, -3.1), 'tailBaseHandlePos': Vec3(0.0, 0.157, -4.7), 'tailBaseHandleCtrlCrvData': self.tailBaseHandleCtrl.getCurveData(), 'tailEndHandlePos': Vec3(0.0, 0.0625, -6.165), 'tailEndHandleCtrlCrvData': self.tailEndHandleCtrl.getCurveData(), 'tailEndPos': Vec3(0.0, -0.22, -7.42), 'tailEndCtrlCrvData': self.tailEndCtrl.getCurveData(), 'numDeformers': 6 }) Profiler.getInstance().pop() # ========== # Callbacks # ========== def updateNumDeformers(self, count): """Generate the guide controls for the variable outputes array. Arguments: count -- object, The number of joints inthe chain. Return: True if successful. """ if count == 0: raise IndexError("'count' must be > 0") vertebraeOutputs = self.tailVertebraeOutput.getTarget() if count > len(vertebraeOutputs): for i in xrange(len(vertebraeOutputs), count): debugCtrl = Control('spine' + str(i+1).zfill(2), parent=self.outputHrcGrp, shape="vertebra") debugCtrl.rotatePoints(0, -90, 0) debugCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) debugCtrl.setColor('turqoise') vertebraeOutputs.append(debugCtrl) elif count < len(vertebraeOutputs): numExtraCtrls = len(vertebraeOutputs) - count for i in xrange(numExtraCtrls): extraCtrl = vertebraeOutputs.pop() self.outputHrcGrp.removeChild(extraCtrl) return True # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(FabriceTailGuide, self).saveData() data['tailBasePos'] = self.tailBaseCtrl.xfo.tr data['tailBaseHandlePos'] = self.tailBaseHandleCtrl.xfo.tr data['tailBaseHandleCtrlCrvData'] = self.tailBaseHandleCtrl.getCurveData() data['tailEndHandlePos'] = self.tailEndHandleCtrl.xfo.tr data['tailEndHandleCtrlCrvData'] = self.tailEndHandleCtrl.getCurveData() data['tailEndPos'] = self.tailEndCtrl.xfo.tr data['tailEndCtrlCrvData'] = self.tailEndCtrl.getCurveData() data['numDeformers'] = self.numDeformersAttr.getValue() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(FabriceTailGuide, self).loadData( data ) self.tailBaseCtrl.xfo.tr = data["tailBasePos"] self.tailBaseHandleCtrl.xfo.tr = data["tailBaseHandlePos"] self.tailBaseHandleCtrl.setCurveData(data['tailBaseHandleCtrlCrvData']) self.tailEndHandleCtrl.xfo.tr = data["tailEndHandlePos"] self.tailEndHandleCtrl.setCurveData(data['tailEndHandleCtrlCrvData']) self.tailEndCtrl.xfo.tr = data["tailEndPos"] self.tailEndCtrl.setCurveData(data['tailEndCtrlCrvData']) self.numDeformersAttr.setValue(data["numDeformers"]) length = data["tailBasePos"].distanceTo(data["tailBaseHandlePos"]) + data["tailBaseHandlePos"].distanceTo(data["tailEndHandlePos"]) + data["tailEndHandlePos"].distanceTo(data["tailEndPos"]) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) self.bezierSpineSpliceOp.evaluate() return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(FabriceTailGuide, self).getRigBuildData() data['tailBasePos'] = self.tailBaseCtrl.xfo.tr data['tailBaseHandlePos'] = self.tailBaseHandleCtrl.xfo.tr data['tailBaseHandleCtrlCrvData'] = self.tailBaseHandleCtrl.getCurveData() data['tailEndHandlePos'] = self.tailEndHandleCtrl.xfo.tr data['tailEndHandleCtrlCrvData'] = self.tailEndHandleCtrl.getCurveData() data['tailEndPos'] = self.tailEndCtrl.xfo.tr data['tailEndCtrlCrvData'] = self.tailEndCtrl.getCurveData() data['numDeformers'] = self.numDeformersAttr.getValue() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return FabriceTailRig
class HeadComponentGuide(HeadComponent): """Head Component Guide""" def __init__(self, name='head', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Head Guide Component:" + name) super(HeadComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) sphereCtrl = Control('sphere', shape='sphere') sphereCtrl.scalePoints(Vec3(0.375, 0.375, 0.375)) self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape='square') self.headCtrl.rotatePoints(90, 0, 0) self.headCtrl.translatePoints(Vec3(0.0, 0.5, 0.0)) self.headCtrl.scalePoints(Vec3(1.8, 2.0, 2.0)) self.eyeLeftCtrl = Control('eyeLeft', parent=self.headCtrl, shape='arrow_thin') self.eyeLeftCtrl.translatePoints(Vec3(0, 0, 0.5)) self.eyeLeftCtrl.rotatePoints(0, 90, 0) self.eyeLeftCtrl.appendCurveData(sphereCtrl.getCurveData()) self.eyeRightCtrl = Control('eyeRight', parent=self.headCtrl, shape='arrow_thin') self.eyeRightCtrl.translatePoints(Vec3(0, 0, 0.5)) self.eyeRightCtrl.rotatePoints(0, 90, 0) self.eyeRightCtrl.appendCurveData(sphereCtrl.getCurveData()) self.jawCtrl = Control('jaw', parent=self.headCtrl, shape='square') self.jawCtrl.rotatePoints(90, 0, 0) self.jawCtrl.rotatePoints(0, 90, 0) self.jawCtrl.translatePoints(Vec3(0.0, -0.5, 0.5)) self.jawCtrl.scalePoints(Vec3(1.0, 0.8, 1.5)) self.jawCtrl.setColor('orange') eyeXAlignOri = Quat() eyeXAlignOri.setFromAxisAndAngle(Vec3(0, 1, 0), Math_degToRad(-90)) self.default_data = { "name": name, "location": "M", "headXfo": Xfo(Vec3(0.0, 17.5, -0.5)), "headCrvData": self.headCtrl.getCurveData(), "eyeLeftXfo": Xfo(tr=Vec3(0.375, 18.5, 0.5), ori=eyeXAlignOri), "eyeLeftCrvData": self.eyeLeftCtrl.getCurveData(), "eyeRightXfo": Xfo(tr=Vec3(-0.375, 18.5, 0.5), ori=eyeXAlignOri), "eyeRightCrvData": self.eyeRightCtrl.getCurveData(), "jawXfo": Xfo(Vec3(0.0, 17.875, -0.275)), "jawCrvData": self.jawCtrl.getCurveData() } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(HeadComponentGuide, self).saveData() data['headXfo'] = self.headCtrl.xfo data['headCrvData'] = self.headCtrl.getCurveData() data['eyeLeftXfo'] = self.eyeLeftCtrl.xfo data['eyeLeftCrvData'] = self.eyeLeftCtrl.getCurveData() data['eyeRightXfo'] = self.eyeRightCtrl.xfo data['eyeRightCrvData'] = self.eyeRightCtrl.getCurveData() data['jawXfo'] = self.jawCtrl.xfo data['jawCrvData'] = self.jawCtrl.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(HeadComponentGuide, self).loadData(data) self.headCtrl.xfo = data.get('headXfo', self.default_data['headXfo']) self.headCtrl.setCurveData( data.get('headCrvData', self.default_data['headCrvData'])) self.eyeLeftCtrl.xfo = data.get('eyeLeftXfo', self.default_data['eyeLeftXfo']) self.eyeLeftCtrl.setCurveData( data.get('eyeLeftCrvData', self.default_data['eyeLeftCrvData'])) self.eyeRightCtrl.xfo = data.get('eyeRightXfo', self.default_data['eyeRightXfo']) self.eyeRightCtrl.setCurveData( data.get('eyeRightCrvData', self.default_data['eyeRightCrvData'])) self.jawCtrl.xfo = data.get('jawXfo', self.default_data['jawXfo']) self.jawCtrl.setCurveData( data.get('jawCrvData', self.default_data['jawCrvData'])) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(HeadComponentGuide, self).getRigBuildData() data['headXfo'] = self.headCtrl.xfo data['headCrvData'] = self.headCtrl.getCurveData() data['eyeLeftXfo'] = self.eyeLeftCtrl.xfo data['eyeLeftCrvData'] = self.eyeLeftCtrl.getCurveData() data['eyeRightXfo'] = self.eyeRightCtrl.xfo data['eyeRightCrvData'] = self.eyeRightCtrl.getCurveData() data['jawXfo'] = self.jawCtrl.xfo data['jawCrvData'] = self.jawCtrl.getCurveData() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return HeadComponentRig
class ArmComponentGuide(ArmComponent): """Arm Component Guide""" def __init__(self, name='arm', parent=None): Profiler.getInstance().push("Construct Arm Guide Component:" + name) super(ArmComponentGuide, self).__init__(name, parent) # =========== # Attributes # =========== # Add Component Params to IK control guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.bicepFKCtrlSizeInputAttr = ScalarAttribute( 'bicepFKCtrlSize', value=1.75, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp) self.forearmFKCtrlSizeInputAttr = ScalarAttribute( 'forearmFKCtrlSize', value=1.5, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp) # ========= # Controls # ========= # Guide Controls self.bicepCtrl = Control('bicepFK', parent=self.ctrlCmpGrp, shape="sphere") self.bicepCtrl.setColor('blue') self.forearmCtrl = Control('forearmFK', parent=self.ctrlCmpGrp, shape="sphere") self.forearmCtrl.setColor('blue') self.wristCtrl = Control('wristFK', parent=self.ctrlCmpGrp, shape="sphere") self.wristCtrl.setColor('blue') self.handCtrl = Control('hand', parent=self.ctrlCmpGrp, shape="cube") self.handCtrl.setColor('blue') data = { "name": name, "location": "L", "bicepXfo": Xfo(Vec3(2.27, 15.295, -0.753)), "forearmXfo": Xfo(Vec3(5.039, 13.56, -0.859)), "wristXfo": Xfo(Vec3(7.1886, 12.2819, 0.4906)), "handXfo": Xfo(tr=Vec3(7.1886, 12.2819, 0.4906), ori=Quat(Vec3(-0.0865, -0.2301, -0.2623), 0.9331)), "bicepFKCtrlSize": 1.75, "forearmFKCtrlSize": 1.5 } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ArmComponentGuide, self).saveData() data['bicepXfo'] = self.bicepCtrl.xfo data['forearmXfo'] = self.forearmCtrl.xfo data['wristXfo'] = self.wristCtrl.xfo data['handXfo'] = self.handCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ArmComponentGuide, self).loadData(data) self.bicepCtrl.xfo = data['bicepXfo'] self.forearmCtrl.xfo = data['forearmXfo'] self.wristCtrl.xfo = data['wristXfo'] self.handCtrl.xfo = data['handXfo'] return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ArmComponentGuide, self).getRigBuildData() # values bicepPosition = self.bicepCtrl.xfo.tr forearmPosition = self.forearmCtrl.xfo.tr wristPosition = self.wristCtrl.xfo.tr # Calculate Bicep Xfo rootToWrist = wristPosition.subtract(bicepPosition).unit() rootToElbow = forearmPosition.subtract(bicepPosition).unit() bone1Normal = rootToWrist.cross(rootToElbow).unit() bone1ZAxis = rootToElbow.cross(bone1Normal).unit() bicepXfo = Xfo() bicepXfo.setFromVectors(rootToElbow, bone1Normal, bone1ZAxis, bicepPosition) # Calculate Forearm Xfo elbowToWrist = wristPosition.subtract(forearmPosition).unit() elbowToRoot = bicepPosition.subtract(forearmPosition).unit() bone2Normal = elbowToRoot.cross(elbowToWrist).unit() bone2ZAxis = elbowToWrist.cross(bone2Normal).unit() forearmXfo = Xfo() forearmXfo.setFromVectors(elbowToWrist, bone2Normal, bone2ZAxis, forearmPosition) handXfo = Xfo() handXfo.tr = self.handCtrl.xfo.tr handXfo.ori = self.handCtrl.xfo.ori bicepLen = bicepPosition.subtract(forearmPosition).length() forearmLen = forearmPosition.subtract(wristPosition).length() armEndXfo = Xfo() armEndXfo.tr = wristPosition armEndXfo.ori = forearmXfo.ori upVXfo = xfoFromDirAndUpV(bicepPosition, wristPosition, forearmPosition) upVXfo.tr = forearmPosition upVXfo.tr = upVXfo.transformVector(Vec3(0, 0, 5)) data['bicepXfo'] = bicepXfo data['forearmXfo'] = forearmXfo data['handXfo'] = handXfo data['armEndXfo'] = armEndXfo data['upVXfo'] = upVXfo data['forearmLen'] = forearmLen data['bicepLen'] = bicepLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ArmComponentRig
class NeckComponentRig(NeckComponent): """Neck Component""" def __init__(self, name="neck", parent=None): Profiler.getInstance().push("Construct Neck Rig Component:" + name) super(NeckComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Neck self.neck01Ctrl = Control('neck01', parent=self.ctrlCmpGrp, shape="pin") self.neck01Ctrl.setColor("orange") self.neck01Ctrl.lockTranslation(True, True, True) self.neck01Ctrl.lockScale(True, True, True) self.neck01CtrlSpace = self.neck01Ctrl.insertCtrlSpace(name='neck01') self.neck02Ctrl = Control('neck02', parent=self.neck01Ctrl, shape="pin") self.neck02Ctrl.setColor("orange") self.neck02Ctrl.lockTranslation(True, True, True) self.neck02Ctrl.lockScale(True, True, True) self.neck02CtrlSpace = self.neck02Ctrl.insertCtrlSpace(name='neck02') # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) self.neck01Def = Joint('neck01', parent=self.defCmpGrp) self.neck01Def.setComponent(self) self.neck02Def = Joint('neck02', parent=self.defCmpGrp) self.neck02Def.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs neckInputConstraintName = '_'.join([self.neck01CtrlSpace.getName(), 'To', self.neckBaseInputTgt.getName()]) self.neckInputCnstr = self.neck01CtrlSpace.constrainTo( self.neckBaseInputTgt, 'Pose', maintainOffset=True, name=neckInputConstraintName) # Constraint outputs neck01OutCnstrName = '_'.join([self.neck01OutputTgt.getName(), 'To', self.neck01Ctrl.getName()]) self.neck01OutCnstr = self.neck01OutputTgt.constrainTo( self.neck01Ctrl, 'Pose', maintainOffset=False, name=neck01OutCnstrName) neck02OutCnstrName = '_'.join([self.neck02OutputTgt.getName(), 'To', self.neck02Ctrl.getName()]) self.neck02OutCnstr = self.neck02OutputTgt.constrainTo( self.neck02Ctrl, 'Pose', maintainOffset=False, name=neck02OutCnstrName) neckEndCnstrName = '_'.join([self.neckEndOutputTgt.getName(), 'To', self.neck02Ctrl.getName()]) self.neckEndCnstr = self.neckEndOutputTgt.constrainTo( self.neck02Ctrl, 'Pose', maintainOffset=True, name=neckEndCnstrName) # ============== # Add Operators # ============== # Add Deformer KL Op self.neckDeformerKLOp = KLOperator('neckDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.neckDeformerKLOp) # Add Att Inputs self.neckDeformerKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.neckDeformerKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputstrl) self.neckDeformerKLOp.setInput('constrainers', [self.neck01Ctrl, self.neck02Ctrl]) # Add Xfo Outputs self.neckDeformerKLOp.setOutput('constrainees', [self.neck01Def, self.neck02Def]) Profiler.getInstance().pop() 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(NeckComponentRig, self).loadData(data) neckXfo = data.get('neckXfo') neckCrvData = data.get('neckCrvData') neckMidXfo = data.get('neckMidXfo') neckMidCrvData = data.get('neckMidCrvData') neckEndXfo = data.get('neckEndXfo') self.neck01CtrlSpace.xfo = neckXfo self.neck01Ctrl.xfo = neckXfo self.neck01Ctrl.setCurveData(neckCrvData) self.neck02CtrlSpace.xfo = neckMidXfo self.neck02Ctrl.xfo = neckMidXfo self.neck02Ctrl.setCurveData(neckMidCrvData) # ============ # Set IO Xfos # ============ self.neckBaseInputTgt.xfo = neckXfo self.neck01OutputTgt.xfo = neckXfo self.neck02OutputTgt.xfo = neckMidXfo self.neckEndOutputTgt.xfo = neckEndXfo # Evaluate Constraints self.neckInputCnstr.evaluate() self.neck01OutCnstr.evaluate() self.neck02OutCnstr.evaluate() self.neckEndCnstr.evaluate()
class HeadComponentRig(HeadComponent): """Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(HeadComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Head self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape='circle') self.headCtrl.lockScale(x=True, y=True, z=True) self.headCtrl.lockTranslation(x=True, y=True, z=True) self.headCtrlSpace = self.headCtrl.insertCtrlSpace() self.headCtrl.rotatePoints(0, 0, 90) self.headCtrl.scalePoints(Vec3(3, 3, 3)) self.headCtrl.translatePoints(Vec3(0, 1, 0.25)) # Eye Left self.eyeLeftCtrl = Control('eyeLeft', parent=self.ctrlCmpGrp, shape='sphere') self.eyeLeftCtrl.lockScale(x=True, y=True, z=True) self.eyeLeftCtrl.lockTranslation(x=True, y=True, z=True) self.eyeLeftCtrlSpace = self.eyeLeftCtrl.insertCtrlSpace() self.eyeLeftCtrl.rotatePoints(0, 90, 0) self.eyeLeftCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeLeftCtrl.setColor('blueMedium') # Eye Right self.eyeRightCtrl = Control('eyeRight', parent=self.ctrlCmpGrp, shape='sphere') self.eyeRightCtrl.lockScale(x=True, y=True, z=True) self.eyeRightCtrl.lockTranslation(x=True, y=True, z=True) self.eyeRightCtrlSpace = self.eyeRightCtrl.insertCtrlSpace() self.eyeRightCtrl.rotatePoints(0, 90, 0) self.eyeRightCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeRightCtrl.setColor('blueMedium') # LookAt Control self.lookAtCtrl = Control('lookAt', parent=self.ctrlCmpGrp, shape='square') self.lookAtCtrl.lockScale(x=True, y=True, z=True) self.lookAtCtrl.rotatePoints(90, 0, 0) self.lookAtCtrlSpace = self.lookAtCtrl.insertCtrlSpace() self.eyeLeftBase = Transform('eyeLeftBase', parent=self.headCtrl) self.eyeRightBase = Transform('eyeRightBase', parent=self.headCtrl) self.eyeLeftUpV = Transform('eyeLeftUpV', parent=self.headCtrl) self.eyeRightUpV = Transform('eyeRightUpV', parent=self.headCtrl) self.eyeLeftAtV = Transform('eyeLeftAtV', parent=self.lookAtCtrl) self.eyeRightAtV = Transform('eyeRightAtV', parent=self.lookAtCtrl) # Jaw self.jawCtrl = Control('jaw', parent=self.headCtrl, shape='cube') self.jawCtrlSpace = self.jawCtrl.insertCtrlSpace() self.jawCtrl.lockScale(x=True, y=True, z=True) self.jawCtrl.lockTranslation(x=True, y=True, z=True) self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(1.45, 0.65, 1.25)) self.jawCtrl.translatePoints(Vec3(0, -0.25, 0)) self.jawCtrl.setColor('orange') # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) headDef = Joint('head', parent=self.defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=self.defCmpGrp) jawDef.setComponent(self) eyeLeftDef = Joint('eyeLeft', parent=self.defCmpGrp) eyeLeftDef.setComponent(self) eyeRightDef = Joint('eyeRight', parent=self.defCmpGrp) eyeRightDef.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs self.headInputConstraint = PoseConstraint('_'.join([ self.headCtrlSpace.getName(), 'To', self.neckRefInputTgt.getName() ])) self.headInputConstraint.setMaintainOffset(True) self.headInputConstraint.addConstrainer(self.neckRefInputTgt) self.headCtrlSpace.addConstraint(self.headInputConstraint) # Constraint outputs self.headOutputConstraint = PoseConstraint('_'.join( [self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) self.headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(self.headOutputConstraint) self.jawOutputConstraint = PoseConstraint('_'.join( [self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) self.jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(self.jawOutputConstraint) self.eyeLOutputConstraint = PoseConstraint('_'.join( [self.eyeLOutputTgt.getName(), 'To', self.eyeLeftCtrl.getName()])) self.eyeLOutputConstraint.addConstrainer(self.eyeLeftCtrl) self.eyeLOutputTgt.addConstraint(self.eyeLOutputConstraint) self.eyeROutputConstraint = PoseConstraint('_'.join( [self.eyeROutputTgt.getName(), 'To', self.eyeRightCtrl.getName()])) self.eyeROutputConstraint.addConstrainer(self.eyeRightCtrl) self.eyeROutputTgt.addConstraint(self.eyeROutputConstraint) # Add Eye Left Direction KL Op self.eyeLeftDirKLOp = KLOperator('eyeLeftDirKLOp', 'DirectionConstraintSolver', 'Kraken') self.addOperator(self.eyeLeftDirKLOp) # Add Att Inputs self.eyeLeftDirKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.eyeLeftDirKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.eyeLeftDirKLOp.setInput('position', self.eyeLeftBase) self.eyeLeftDirKLOp.setInput('upVector', self.eyeLeftUpV) self.eyeLeftDirKLOp.setInput('atVector', self.eyeLeftAtV) # Add Xfo Outputs self.eyeLeftDirKLOp.setOutput('constrainee', self.eyeLeftCtrlSpace) # Add Eye Right Direction KL Op self.eyeRightDirKLOp = KLOperator('eyeRightDirKLOp', 'DirectionConstraintSolver', 'Kraken') self.addOperator(self.eyeRightDirKLOp) # Add Att Inputs self.eyeRightDirKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.eyeRightDirKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.eyeRightDirKLOp.setInput('position', self.eyeRightBase) self.eyeRightDirKLOp.setInput('upVector', self.eyeRightUpV) self.eyeRightDirKLOp.setInput('atVector', self.eyeRightAtV) # Add Xfo Outputs self.eyeRightDirKLOp.setOutput('constrainee', self.eyeRightCtrlSpace) # Add Deformer Joints KL Op self.outputsToDeformersKLOp = KLOperator('headDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.outputsToDeformersKLOp) # Add Att Inputs self.outputsToDeformersKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.outputsToDeformersKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.outputsToDeformersKLOp.setInput('constrainers', [ self.headOutputTgt, self.jawOutputTgt, self.eyeROutputTgt, self.eyeLOutputTgt ]) # Add Xfo Outputs self.outputsToDeformersKLOp.setOutput( 'constrainees', [headDef, jawDef, eyeRightDef, eyeLeftDef]) Profiler.getInstance().pop() 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(HeadComponentRig, self).loadData(data) headXfo = data.get('headXfo') headCrvData = data.get('headCrvData') eyeLeftXfo = data.get('eyeLeftXfo') eyeLeftCrvData = data.get('eyeLeftCrvData') eyeRightXfo = data.get('eyeRightXfo') eyeRightCrvData = data.get('eyeRightCrvData') jawXfo = data.get('jawXfo') jawCrvData = data.get('jawCrvData') self.headCtrlSpace.xfo = headXfo self.headCtrl.xfo = headXfo self.headCtrl.setCurveData(headCrvData) # self.eyeLeftCtrlSpace.xfo = eyeLeftXfo # self.eyeLeftCtrl.xfo = eyeLeftXfo self.eyeLeftCtrl.setCurveData(eyeLeftCrvData) # self.eyeRightCtrlSpace.xfo = eyeRightXfo # self.eyeRightCtrl.xfo = eyeRightXfo self.eyeRightCtrl.setCurveData(eyeRightCrvData) # LookAt eyeLeftRelXfo = headXfo.inverse() * eyeLeftXfo eyeRightRelXfo = headXfo.inverse() * eyeRightXfo eyeMidRelPos = eyeLeftRelXfo.tr.linearInterpolate( eyeRightRelXfo.tr, 0.5) eyeMidRelPos = eyeMidRelPos + Vec3(0.0, 0.0, 8.0) eyeLen = eyeLeftRelXfo.tr.distanceTo(eyeRightRelXfo.tr) self.eyeLeftBase.xfo = eyeLeftXfo self.eyeRightBase.xfo = eyeRightXfo self.eyeLeftUpV.xfo = eyeLeftXfo * Xfo(Vec3(0, 1, 0)) self.eyeRightUpV.xfo = eyeRightXfo * Xfo(Vec3(0, 1, 0)) self.eyeLeftAtV.xfo.tr = eyeLeftXfo.transformVector(Vec3( 8.0, 0.0, 0.0)) self.eyeRightAtV.xfo.tr = eyeRightXfo.transformVector( Vec3(8.0, 0.0, 0.0)) lookAtXfo = headXfo.clone() lookAtXfo.tr = headXfo.transformVector(eyeMidRelPos) self.lookAtCtrl.scalePoints(Vec3(eyeLen * 1.6, eyeLen * 0.65, 1.0)) self.lookAtCtrl.xfo = lookAtXfo self.lookAtCtrlSpace.xfo = lookAtXfo self.jawCtrlSpace.xfo = jawXfo self.jawCtrl.xfo = jawXfo self.jawCtrl.setCurveData(jawCrvData) # ============ # Set IO Xfos # ============ self.neckRefInputTgt.xfo = headXfo self.worldRefInputTgt.xfo = headXfo self.headOutputTgt.xfo = headXfo self.jawOutputTgt.xfo = jawXfo self.eyeLOutputTgt.xfo = eyeLeftXfo self.eyeROutputTgt.xfo = eyeRightXfo # Eval Constraints self.headInputConstraint.evaluate() self.headOutputConstraint.evaluate() self.jawOutputConstraint.evaluate() self.eyeLOutputConstraint.evaluate() self.eyeROutputConstraint.evaluate() # Eval Operators self.eyeLeftDirKLOp.evaluate() self.eyeRightDirKLOp.evaluate() self.outputsToDeformersKLOp.evaluate() # Have to set the eye control xfos to match the evaluated xfos from self.eyeLeftCtrl.xfo = self.eyeLeftCtrlSpace.xfo self.eyeRightCtrl.xfo = self.eyeRightCtrlSpace.xfo
class ClavicleComponentGuide(ClavicleComponent): """Clavicle Component Guide""" def __init__(self, name='clavicle', parent=None, data=None): Profiler.getInstance().push("Construct Clavicle Guide Component:" + name) super(ClavicleComponentGuide, self).__init__(name, parent) # ========= # Controls # ========= # Guide Controls guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.clavicleCtrl = Control('clavicle', parent=self.ctrlCmpGrp, shape="sphere") self.clavicleUpVCtrl = Control('clavicleUpV', parent=self.ctrlCmpGrp, shape="triangle") self.clavicleUpVCtrl.setColor('red') self.clavicleEndCtrl = Control('clavicleEnd', parent=self.ctrlCmpGrp, shape="sphere") if data is None: data = { "name": name, "location": "L", "clavicleXfo": Xfo(Vec3(0.1322, 15.403, -0.5723)), "clavicleUpVXfo": Xfo(Vec3(0.0, 1.0, 0.0)), "clavicleEndXfo": Xfo(Vec3(2.27, 15.295, -0.753)) } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ClavicleComponentGuide, self).saveData() data['clavicleXfo'] = self.clavicleCtrl.xfo data['clavicleUpVXfo'] = self.clavicleUpVCtrl.xfo data['clavicleEndXfo'] = self.clavicleEndCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ClavicleComponentGuide, self).loadData(data) self.clavicleCtrl.xfo = data['clavicleXfo'] self.clavicleUpVCtrl.xfo = self.clavicleCtrl.xfo.multiply( data['clavicleUpVXfo']) self.clavicleEndCtrl.xfo = data['clavicleEndXfo'] return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ClavicleComponentGuide, self).getRigBuildData() # Values claviclePosition = self.clavicleCtrl.xfo.tr clavicleUpV = self.clavicleUpVCtrl.xfo.tr clavicleEndPosition = self.clavicleEndCtrl.xfo.tr # Calculate Clavicle Xfo rootToEnd = clavicleEndPosition.subtract(claviclePosition).unit() rootToUpV = clavicleUpV.subtract(claviclePosition).unit() bone1ZAxis = rootToUpV.cross(rootToEnd).unit() bone1Normal = bone1ZAxis.cross(rootToEnd).unit() clavicleXfo = Xfo() clavicleXfo.setFromVectors(rootToEnd, bone1Normal, bone1ZAxis, claviclePosition) clavicleLen = claviclePosition.subtract(clavicleEndPosition).length() data['clavicleXfo'] = clavicleXfo data['clavicleLen'] = clavicleLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ClavicleComponentRig
class mjEyelidComponentRig(mjEyelidComponent): """Eyelid Component Rig""" def __init__(self, name='mjEyelid', parent=None): Profiler.getInstance().push("Construct Eyelid Rig Component:" + name) super(mjEyelidComponentRig, self).__init__(name, parent) # ========= # Controls // Get the Guide Xfos data and create the final controllers, offset them if needed. # ========= # Inputs self.eyelidCtrlSpace = CtrlSpace('eyelid', parent=self.ctrlCmpGrp) self.eyeballLocator = Locator('eyeball', parent=self.ctrlCmpGrp) self.eyeballLocator.setShapeVisibility(False) self.eyelidUpVLocator = Locator('eyelid_Upv', parent=self.eyelidCtrlSpace) self.eyelidUpVLocator.setShapeVisibility(False) # Lid Sides self.lidMedialLocator = Locator('lid_Medial', parent=self.eyelidCtrlSpace) self.lidMedialLocator.setShapeVisibility(False) self.lidLateralLocator = Locator('lid_Lateral', parent=self.eyelidCtrlSpace) self.lidLateralLocator.setShapeVisibility(False) # Lid Upper self.lidUpCtrlSpace = CtrlSpace('lid_Up', parent=self.eyelidCtrlSpace) self.lidUpCtrl = Control('lid_Up', parent=self.lidUpCtrlSpace, shape="cube") self.lidUpCtrl.scalePoints(Vec3(0.05, 0.05, 0.05)) self.lidUpCtrl.lockTranslation(x=True, y=False, z=True) self.lidUpCtrl.setColor("yellow") self.lipUpMedialLocator = Locator('lid_Up_Medial', parent=self.eyelidCtrlSpace) self.lipUpMedialLocator.setShapeVisibility(False) self.lipUpLateralLocator = Locator('lid_Up_Lateral', parent=self.eyelidCtrlSpace) self.lipUpLateralLocator.setShapeVisibility(False) # Lid Lower self.lidLowCtrlSpace = CtrlSpace('lid_Low', parent=self.eyelidCtrlSpace) self.lidLowCtrl = Control('lid_Low', parent=self.lidLowCtrlSpace, shape="cube") self.lidLowCtrl.scalePoints(Vec3(0.05, 0.05, 0.05)) self.lidLowCtrl.lockTranslation(x=True, y=False, z=True) self.lidLowCtrl.setColor("yellow") self.lidLowMedialLocator = Locator('lid_Low_Medial', parent=self.eyelidCtrlSpace) self.lidLowMedialLocator.setShapeVisibility(False) self.lidLowLateralLocator = Locator('lid_Low_Lateral', parent=self.eyelidCtrlSpace) self.lidLowLateralLocator.setShapeVisibility(False) # Lid Attributes lidUp_AttrGrp = AttributeGroup("Eyelid_Settings", parent=self.lidUpCtrl) lidLow_AttrGrp = AttributeGroup("Eyelid_Settings", parent=self.lidLowCtrl) self.lidUp_OffsetInputAttr = BoolAttribute('Eyeball_Offset', value=True, parent=lidUp_AttrGrp) self.lidUp_FollowFactorInputAttr = ScalarAttribute( 'Eyeball_Follow_Factor', value=1.0, parent=lidUp_AttrGrp) self.lidUp_DebugInputAttr = BoolAttribute('DrawDebug', value=False, parent=lidUp_AttrGrp) self.lidUp_MedialBlinkInputAttr = ScalarAttribute( 'Medial_Blink_Factor', value=0.25, parent=lidUp_AttrGrp) self.lidUp_LateralBlinkInputAttr = ScalarAttribute( 'Lateral_Blink_Factor', value=0.65, parent=lidUp_AttrGrp) self.lidUp_DefCountInputAttr = IntegerAttribute('numDeformers', value=10, parent=lidUp_AttrGrp) self.lidLow_OffsetInputAttr = BoolAttribute('Eyeball_Offset', value=True, parent=lidLow_AttrGrp) self.lidLow_FollowFactorInputAttr = ScalarAttribute( 'Eyeball_Follow_Factor', value=0.8, parent=lidLow_AttrGrp) self.lidLow_DebugInputAttr = BoolAttribute('DrawDebug', value=False, parent=lidLow_AttrGrp) self.lidLow_MedialBlinkInputAttr = ScalarAttribute( 'Medial_Blink_Factor', value=0.25, parent=lidLow_AttrGrp) self.lidLow_LateralBlinkInputAttr = ScalarAttribute( 'Lateral_Blink_Factor', value=0.65, parent=lidLow_AttrGrp) self.lidLow_DefCountInputAttr = IntegerAttribute('numDeformers', value=10, parent=lidLow_AttrGrp) self.lidUp_DebugInputAttr.connect(self.drawDebugInputAttr) self.lidLow_DebugInputAttr.connect(self.drawDebugInputAttr) self.lidUp_DefCountInputAttr.connect(self.numUpDeformersInputAttr) self.lidLow_DefCountInputAttr.connect(self.numLowDeformersInputAttr) # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) # Lid Sides lidMedialDef = Joint('lid_Medial', parent=self.defCmpGrp) lidMedialDef.setComponent(self) lidLateralDef = Joint('lid_Lateral', parent=self.defCmpGrp) lidLateralDef.setComponent(self) # Lid Up self.eyelidUpDef = [] self.eyelidUpOutputs = [] self.setNumUpDeformers(1) # Lid Low self.eyelidLowDef = [] self.eyelidLowOutputs = [] self.setNumLowDeformers(1) # ===================== # Create Component I/O # ===================== # Setup component Xfo I/O's self.eyelidUpOutput.setTarget(self.eyelidUpOutputs) self.eyelidLowOutput.setTarget(self.eyelidLowOutputs) # ============== # Constrain I/O # ============== # Constraint inputs self.headInputConstraint = PoseConstraint('_'.join([ self.eyelidCtrlSpace.getName(), 'To', self.headInputTgt.getName() ])) self.headInputConstraint.addConstrainer(self.headInputTgt) self.eyelidCtrlSpace.addConstraint(self.headInputConstraint) self.eyeballInputConstraint = PoseConstraint('_'.join([ self.eyeballLocator.getName(), 'To', self.eyeballInputTgt.getName() ])) self.eyeballInputConstraint.setMaintainOffset(True) self.eyeballInputConstraint.addConstrainer(self.eyeballInputTgt) self.eyeballLocator.addConstraint(self.eyeballInputConstraint) # =============== # Add Splice Ops # =============== # Add MultiPoseConstraint Joints Splice Op self.outputsToDeformersKLOp = KLOperator('Canvas_Eyelid_Side_Op', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.outputsToDeformersKLOp) # Add Att Inputs self.outputsToDeformersKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.outputsToDeformersKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.outputsToDeformersKLOp.setInput('constrainers', [ self.lidMedialLocator, self.lidLateralLocator, ]) # Add Xfo Outputs self.outputsToDeformersKLOp.setOutput('constrainees', [ lidMedialDef, lidLateralDef, ]) # Add Lid Up Canvas Op self.lidUpCanvasOp = CanvasOperator( 'Canvas_Eyelid_Up_Op', 'MJCG.Solvers.mjEyelidConstraintSolver') self.addOperator(self.lidUpCanvasOp) # Add Attributes Inputs self.lidUpCanvasOp.setInput('drawDebug', self.lidUp_DebugInputAttr) self.lidUpCanvasOp.setInput('rigScale', self.rigScaleInputAttr) self.lidUpCanvasOp.setInput('Eyeball_Offset', self.lidUp_OffsetInputAttr) self.lidUpCanvasOp.setInput('Eyeball_Follow_Factor', self.lidUp_FollowFactorInputAttr) self.lidUpCanvasOp.setInput('Medial_Blink_Factor', self.lidUp_MedialBlinkInputAttr) self.lidUpCanvasOp.setInput('Lateral_Blink_Factor', self.lidUp_LateralBlinkInputAttr) self.lidUpCanvasOp.setInput('Deformer_Count', self.lidUp_DefCountInputAttr) # Add Xfo Inputs self.lidUpCanvasOp.setInput('Eye_Center', self.eyeballLocator) self.lidUpCanvasOp.setInput('Lid_Global', self.eyelidCtrlSpace) self.lidUpCanvasOp.setInput('Lid_UpV', self.eyelidUpVLocator) self.lidUpCanvasOp.setInput('Lid_Medial', self.lidMedialLocator) self.lidUpCanvasOp.setInput('Lid_MedialCen', self.lipUpMedialLocator) self.lidUpCanvasOp.setInput('Lid_Center_Ref', self.lidUpCtrlSpace) self.lidUpCanvasOp.setInput('Lid_Center_Ctrl', self.lidUpCtrl) self.lidUpCanvasOp.setInput('Lid_LateralCen', self.lipUpLateralLocator) self.lidUpCanvasOp.setInput('Lid_Lateral', self.lidLateralLocator) #Add Xfo Outputs self.lidUpCanvasOp.setOutput('result', self.eyelidUpDef) # Add Lid Low Canvas Op self.lidLowCanvasOp = CanvasOperator( 'Canvas_Eyelid_Low_Op', 'MJCG.Solvers.mjEyelidConstraintSolver') self.addOperator(self.lidLowCanvasOp) # Add Attributes Inputs self.lidLowCanvasOp.setInput('drawDebug', self.lidLow_DebugInputAttr) self.lidLowCanvasOp.setInput('rigScale', self.rigScaleInputAttr) self.lidLowCanvasOp.setInput('Eyeball_Offset', self.lidLow_OffsetInputAttr) self.lidLowCanvasOp.setInput('Eyeball_Follow_Factor', self.lidLow_FollowFactorInputAttr) self.lidLowCanvasOp.setInput('Medial_Blink_Factor', self.lidLow_MedialBlinkInputAttr) self.lidLowCanvasOp.setInput('Lateral_Blink_Factor', self.lidLow_LateralBlinkInputAttr) self.lidLowCanvasOp.setInput('Deformer_Count', self.lidLow_DefCountInputAttr) # Add Xfo Inputs self.lidLowCanvasOp.setInput('Eye_Center', self.eyeballLocator) self.lidLowCanvasOp.setInput('Lid_Global', self.eyelidCtrlSpace) self.lidLowCanvasOp.setInput('Lid_UpV', self.eyelidUpVLocator) self.lidLowCanvasOp.setInput('Lid_Medial', self.lidMedialLocator) self.lidLowCanvasOp.setInput('Lid_MedialCen', self.lidLowMedialLocator) self.lidLowCanvasOp.setInput('Lid_Center_Ref', self.lidLowCtrlSpace) self.lidLowCanvasOp.setInput('Lid_Center_Ctrl', self.lidLowCtrl) self.lidLowCanvasOp.setInput('Lid_LateralCen', self.lidLowLateralLocator) self.lidLowCanvasOp.setInput('Lid_Lateral', self.lidLateralLocator) #Add Xfo Outputs self.lidLowCanvasOp.setOutput('result', self.eyelidLowDef) Profiler.getInstance().pop() def setNumUpDeformers(self, numUpDeformers): # Add Up Deformers and Outputs for i in xrange(len(self.eyelidUpOutputs), numUpDeformers): name = 'Lid_Up_' + str(i + 1).zfill(2) lidUpOutputs = ComponentOutput(name, parent=self.outputHrcGrp) self.eyelidUpOutputs.append(lidUpOutputs) for i in xrange(len(self.eyelidUpDef), numUpDeformers): name = 'Lid_Up_' + str(i + 1).zfill(2) lidUpDef = Joint(name, parent=self.defCmpGrp) lidUpDef.setComponent(self) self.eyelidUpDef.append(lidUpDef) return True def setNumLowDeformers(self, numLowDeformers): # Add Low Deformers and Outputs for i in xrange(len(self.eyelidLowOutputs), numLowDeformers): name = 'Lid_Low_' + str(i + 1).zfill(2) lidLowOutputs = ComponentOutput(name, parent=self.outputHrcGrp) self.eyelidLowOutputs.append(lidLowOutputs) for i in xrange(len(self.eyelidLowDef), numLowDeformers): name = 'Lid_Low_' + str(i + 1).zfill(2) lidLowDef = Joint(name, parent=self.defCmpGrp) lidLowDef.setComponent(self) self.eyelidLowDef.append(lidLowDef) return True def loadData(self, data=None): super(mjEyelidComponentRig, self).loadData(data) # Set CtrlSpace Xfos self.eyelidCtrlSpace.xfo = data['eyeballXfo'] self.eyeballLocator.xfo = data['eyeballXfo'] self.eyelidUpVLocator.xfo = data['eyelidUpVXfo'] self.lidMedialLocator.xfo = data['lidMedialXfo'] self.lidLateralLocator.xfo = data['lidLateralXfo'] self.lidUpCtrlSpace.xfo = data['lidUpXfo'] self.lidUpCtrl.xfo = data['lidUpXfo'] self.lipUpMedialLocator.xfo = data['lidUpMedialXfo'] self.lipUpLateralLocator.xfo = data['lidUpLateralXfo'] self.lidLowCtrlSpace.xfo = data['lidLowXfo'] self.lidLowCtrl.xfo = data['lidLowXfo'] self.lidLowMedialLocator.xfo = data['lidLowMedialXfo'] self.lidLowLateralLocator.xfo = data['lidLowLateralXfo'] # Update number of deformers and outputs self.setNumUpDeformers(data['numUpDeformers']) self.setNumLowDeformers(data['numLowDeformers']) # Set Attributes self.upMedialFactorInputAttr.setValue(data['lidUpMedialBlink']) self.upLateralFactorInputAttr.setValue(data['lidUpLateralBlink']) self.numUpDeformersInputAttr.setValue(data['numUpDeformers']) self.lowMedialFactorInputAttr.setValue(data['lidLowMedialBlink']) self.lowLateralFactorInputAttr.setValue(data['lidLowLateralBlink']) self.numLowDeformersInputAttr.setValue(data['numLowDeformers']) self.lidUp_MedialBlinkInputAttr.setValue(data['lidUpMedialBlink']) self.lidUp_LateralBlinkInputAttr.setValue(data['lidUpLateralBlink']) self.lidLow_MedialBlinkInputAttr.setValue(data['lidLowMedialBlink']) self.lidLow_LateralBlinkInputAttr.setValue(data['lidLowLateralBlink']) # Set I/O Xfos self.headInputTgt.xfo = data['eyeballXfo'] self.eyeballInputTgt.xfo = data['eyeballXfo'] self.eyelidUpOutputTgt = self.eyelidUpDef self.eyelidLowOutputTgt = self.eyelidLowDef # Evaluate Constraints self.headInputConstraint.evaluate() self.eyeballInputConstraint.evaluate() # Evaluate Operators self.lidUpCanvasOp.evaluate() self.lidLowCanvasOp.evaluate() self.outputsToDeformersKLOp.evaluate()
class HeadComponentRig(HeadComponent): """Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(HeadComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Head self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape='circle') self.headCtrl.lockScale(x=True, y=True, z=True) self.headCtrl.lockTranslation(x=True, y=True, z=True) self.headCtrlSpace = self.headCtrl.insertCtrlSpace() self.headCtrl.rotatePoints(0, 0, 90) self.headCtrl.scalePoints(Vec3(3, 3, 3)) self.headCtrl.translatePoints(Vec3(0, 1, 0.25)) # Eye Left self.eyeLeftCtrl = Control('eyeLeft', parent=self.ctrlCmpGrp, shape='sphere') self.eyeLeftCtrl.lockScale(x=True, y=True, z=True) self.eyeLeftCtrl.lockTranslation(x=True, y=True, z=True) self.eyeLeftCtrlSpace = self.eyeLeftCtrl.insertCtrlSpace() self.eyeLeftCtrl.rotatePoints(0, 90, 0) self.eyeLeftCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeLeftCtrl.setColor('blueMedium') # Eye Right self.eyeRightCtrl = Control('eyeRight', parent=self.ctrlCmpGrp, shape='sphere') self.eyeRightCtrl.lockScale(x=True, y=True, z=True) self.eyeRightCtrl.lockTranslation(x=True, y=True, z=True) self.eyeRightCtrlSpace = self.eyeRightCtrl.insertCtrlSpace() self.eyeRightCtrl.rotatePoints(0, 90, 0) self.eyeRightCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.eyeRightCtrl.setColor('blueMedium') # LookAt Control self.lookAtCtrl = Control('lookAt', parent=self.ctrlCmpGrp, shape='square') self.lookAtCtrl.lockScale(x=True, y=True, z=True) self.lookAtCtrl.rotatePoints(90, 0, 0) self.lookAtCtrlSpace = self.lookAtCtrl.insertCtrlSpace() self.eyeLeftBase = Transform('eyeLeftBase', parent=self.headCtrl) self.eyeRightBase = Transform('eyeRightBase', parent=self.headCtrl) self.eyeLeftUpV = Transform('eyeLeftUpV', parent=self.headCtrl) self.eyeRightUpV = Transform('eyeRightUpV', parent=self.headCtrl) self.eyeLeftAtV = Transform('eyeLeftAtV', parent=self.lookAtCtrl) self.eyeRightAtV = Transform('eyeRightAtV', parent=self.lookAtCtrl) # Jaw self.jawCtrl = Control('jaw', parent=self.headCtrl, shape='cube') self.jawCtrlSpace = self.jawCtrl.insertCtrlSpace() self.jawCtrl.lockScale(x=True, y=True, z=True) self.jawCtrl.lockTranslation(x=True, y=True, z=True) self.jawCtrl.alignOnYAxis(negative=True) self.jawCtrl.alignOnZAxis() self.jawCtrl.scalePoints(Vec3(1.45, 0.65, 1.25)) self.jawCtrl.translatePoints(Vec3(0, -0.25, 0)) self.jawCtrl.setColor('orange') # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) headDef = Joint('head', parent=self.defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=self.defCmpGrp) jawDef.setComponent(self) eyeLeftDef = Joint('eyeLeft', parent=self.defCmpGrp) eyeLeftDef.setComponent(self) eyeRightDef = Joint('eyeRight', parent=self.defCmpGrp) eyeRightDef.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs self.headInputConstraint = PoseConstraint('_'.join([self.headCtrlSpace.getName(), 'To', self.neckRefInputTgt.getName()])) self.headInputConstraint.setMaintainOffset(True) self.headInputConstraint.addConstrainer(self.neckRefInputTgt) self.headCtrlSpace.addConstraint(self.headInputConstraint) # Constraint outputs self.headOutputConstraint = PoseConstraint('_'.join([self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) self.headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(self.headOutputConstraint) self.jawOutputConstraint = PoseConstraint('_'.join([self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) self.jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(self.jawOutputConstraint) self.eyeLOutputConstraint = PoseConstraint('_'.join([self.eyeLOutputTgt.getName(), 'To', self.eyeLeftCtrl.getName()])) self.eyeLOutputConstraint.addConstrainer(self.eyeLeftCtrl) self.eyeLOutputTgt.addConstraint(self.eyeLOutputConstraint) self.eyeROutputConstraint = PoseConstraint('_'.join([self.eyeROutputTgt.getName(), 'To', self.eyeRightCtrl.getName()])) self.eyeROutputConstraint.addConstrainer(self.eyeRightCtrl) self.eyeROutputTgt.addConstraint(self.eyeROutputConstraint) # Add Eye Left Direction KL Op self.eyeLeftDirKLOp = KLOperator('eyeLeftDirKLOp', 'DirectionConstraintSolver', 'Kraken') self.addOperator(self.eyeLeftDirKLOp) # Add Att Inputs self.eyeLeftDirKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.eyeLeftDirKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.eyeLeftDirKLOp.setInput('position', self.eyeLeftBase) self.eyeLeftDirKLOp.setInput('upVector', self.eyeLeftUpV) self.eyeLeftDirKLOp.setInput('atVector', self.eyeLeftAtV) # Add Xfo Outputs self.eyeLeftDirKLOp.setOutput('constrainee', self.eyeLeftCtrlSpace) # Add Eye Right Direction KL Op self.eyeRightDirKLOp = KLOperator('eyeRightDirKLOp', 'DirectionConstraintSolver', 'Kraken') self.addOperator(self.eyeRightDirKLOp) # Add Att Inputs self.eyeRightDirKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.eyeRightDirKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.eyeRightDirKLOp.setInput('position', self.eyeRightBase) self.eyeRightDirKLOp.setInput('upVector', self.eyeRightUpV) self.eyeRightDirKLOp.setInput('atVector', self.eyeRightAtV) # Add Xfo Outputs self.eyeRightDirKLOp.setOutput('constrainee', self.eyeRightCtrlSpace) # Add Deformer Joints KL Op self.outputsToDeformersKLOp = KLOperator('headDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.outputsToDeformersKLOp) # Add Att Inputs self.outputsToDeformersKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.outputsToDeformersKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.outputsToDeformersKLOp.setInput('constrainers', [self.headOutputTgt, self.jawOutputTgt, self.eyeROutputTgt, self.eyeLOutputTgt]) # Add Xfo Outputs self.outputsToDeformersKLOp.setOutput('constrainees', [headDef, jawDef, eyeRightDef, eyeLeftDef]) Profiler.getInstance().pop() 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(HeadComponentRig, self).loadData(data) headXfo = data.get('headXfo') headCrvData = data.get('headCrvData') eyeLeftXfo = data.get('eyeLeftXfo') eyeLeftCrvData = data.get('eyeLeftCrvData') eyeRightXfo = data.get('eyeRightXfo') eyeRightCrvData = data.get('eyeRightCrvData') jawXfo = data.get('jawXfo') jawCrvData = data.get('jawCrvData') self.headCtrlSpace.xfo = headXfo self.headCtrl.xfo = headXfo self.headCtrl.setCurveData(headCrvData) # self.eyeLeftCtrlSpace.xfo = eyeLeftXfo # self.eyeLeftCtrl.xfo = eyeLeftXfo self.eyeLeftCtrl.setCurveData(eyeLeftCrvData) # self.eyeRightCtrlSpace.xfo = eyeRightXfo # self.eyeRightCtrl.xfo = eyeRightXfo self.eyeRightCtrl.setCurveData(eyeRightCrvData) # LookAt eyeLeftRelXfo = headXfo.inverse() * eyeLeftXfo eyeRightRelXfo = headXfo.inverse() * eyeRightXfo eyeMidRelPos = eyeLeftRelXfo.tr.linearInterpolate(eyeRightRelXfo.tr, 0.5) eyeMidRelPos = eyeMidRelPos + Vec3(0.0, 0.0, 8.0) eyeLen = eyeLeftRelXfo.tr.distanceTo(eyeRightRelXfo.tr) self.eyeLeftBase.xfo = eyeLeftXfo self.eyeRightBase.xfo = eyeRightXfo self.eyeLeftUpV.xfo = eyeLeftXfo * Xfo(Vec3(0, 1, 0)) self.eyeRightUpV.xfo = eyeRightXfo * Xfo(Vec3(0, 1, 0)) self.eyeLeftAtV.xfo.tr = eyeLeftXfo.transformVector(Vec3(8.0, 0.0, 0.0)) self.eyeRightAtV.xfo.tr = eyeRightXfo.transformVector(Vec3(8.0, 0.0, 0.0)) lookAtXfo = headXfo.clone() lookAtXfo.tr = headXfo.transformVector(eyeMidRelPos) self.lookAtCtrl.scalePoints(Vec3(eyeLen * 1.6, eyeLen * 0.65, 1.0)) self.lookAtCtrl.xfo = lookAtXfo self.lookAtCtrlSpace.xfo = lookAtXfo self.jawCtrlSpace.xfo = jawXfo self.jawCtrl.xfo = jawXfo self.jawCtrl.setCurveData(jawCrvData) # ============ # Set IO Xfos # ============ self.neckRefInputTgt.xfo = headXfo self.worldRefInputTgt.xfo = headXfo self.headOutputTgt.xfo = headXfo self.jawOutputTgt.xfo = jawXfo self.eyeLOutputTgt.xfo = eyeLeftXfo self.eyeROutputTgt.xfo = eyeRightXfo # Eval Constraints self.headInputConstraint.evaluate() self.headOutputConstraint.evaluate() self.jawOutputConstraint.evaluate() self.eyeLOutputConstraint.evaluate() self.eyeROutputConstraint.evaluate() # Eval Operators self.eyeLeftDirKLOp.evaluate() self.eyeRightDirKLOp.evaluate() self.outputsToDeformersKLOp.evaluate() # Have to set the eye control xfos to match the evaluated xfos from self.eyeLeftCtrl.xfo = self.eyeLeftCtrlSpace.xfo self.eyeRightCtrl.xfo = self.eyeRightCtrlSpace.xfo
class NeckComponentRig(NeckComponent): """Neck Component""" def __init__(self, name="neck", parent=None): Profiler.getInstance().push("Construct Neck Rig Component:" + name) super(NeckComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Neck self.neck01Ctrl = Control('neck01', parent=self.ctrlCmpGrp, shape="pin") self.neck01Ctrl.setColor("orange") self.neck01Ctrl.lockTranslation(True, True, True) self.neck01Ctrl.lockScale(True, True, True) self.neck01CtrlSpace = self.neck01Ctrl.insertCtrlSpace(name='neck01') self.neck02Ctrl = Control('neck02', parent=self.neck01Ctrl, shape="pin") self.neck02Ctrl.setColor("orange") self.neck02Ctrl.lockTranslation(True, True, True) self.neck02Ctrl.lockScale(True, True, True) self.neck02CtrlSpace = self.neck02Ctrl.insertCtrlSpace(name='neck02') # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) self.neck01Def = Joint('neck01', parent=self.defCmpGrp) self.neck01Def.setComponent(self) self.neck02Def = Joint('neck02', parent=self.defCmpGrp) self.neck02Def.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs neckInputConstraintName = '_'.join([ self.neck01CtrlSpace.getName(), 'To', self.neckBaseInputTgt.getName() ]) self.neckInputCnstr = self.neck01CtrlSpace.constrainTo( self.neckBaseInputTgt, 'Pose', maintainOffset=True, name=neckInputConstraintName) # Constraint outputs neck01OutCnstrName = '_'.join( [self.neck01OutputTgt.getName(), 'To', self.neck01Ctrl.getName()]) self.neck01OutCnstr = self.neck01OutputTgt.constrainTo( self.neck01Ctrl, 'Pose', maintainOffset=False, name=neck01OutCnstrName) neck02OutCnstrName = '_'.join( [self.neck02OutputTgt.getName(), 'To', self.neck02Ctrl.getName()]) self.neck02OutCnstr = self.neck02OutputTgt.constrainTo( self.neck02Ctrl, 'Pose', maintainOffset=False, name=neck02OutCnstrName) neckEndCnstrName = '_'.join( [self.neckEndOutputTgt.getName(), 'To', self.neck02Ctrl.getName()]) self.neckEndCnstr = self.neckEndOutputTgt.constrainTo( self.neck02Ctrl, 'Pose', maintainOffset=True, name=neckEndCnstrName) # ============== # Add Operators # ============== # Add Deformer KL Op self.neckDeformerKLOp = KLOperator('neckDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.neckDeformerKLOp) # Add Att Inputs self.neckDeformerKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.neckDeformerKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputstrl) self.neckDeformerKLOp.setInput('constrainers', [self.neck01Ctrl, self.neck02Ctrl]) # Add Xfo Outputs self.neckDeformerKLOp.setOutput('constrainees', [self.neck01Def, self.neck02Def]) Profiler.getInstance().pop() 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(NeckComponentRig, self).loadData(data) neckXfo = data.get('neckXfo') neckCrvData = data.get('neckCrvData') neckMidXfo = data.get('neckMidXfo') neckMidCrvData = data.get('neckMidCrvData') neckEndXfo = data.get('neckEndXfo') self.neck01CtrlSpace.xfo = neckXfo self.neck01Ctrl.xfo = neckXfo self.neck01Ctrl.setCurveData(neckCrvData) self.neck02CtrlSpace.xfo = neckMidXfo self.neck02Ctrl.xfo = neckMidXfo self.neck02Ctrl.setCurveData(neckMidCrvData) # ============ # Set IO Xfos # ============ self.neckBaseInputTgt.xfo = neckXfo self.neck01OutputTgt.xfo = neckXfo self.neck02OutputTgt.xfo = neckMidXfo self.neckEndOutputTgt.xfo = neckEndXfo # Evaluate Constraints self.neckInputCnstr.evaluate() self.neck01OutCnstr.evaluate() self.neck02OutCnstr.evaluate() self.neckEndCnstr.evaluate()
class HeadComponentGuide(HeadComponent): """Head Component Guide""" def __init__(self, name='head', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Head Guide Component:" + name) super(HeadComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) sphereCtrl = Control('sphere', shape='sphere') sphereCtrl.scalePoints(Vec3(0.375, 0.375, 0.375)) self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape='square') self.headCtrl.rotatePoints(90, 0, 0) self.headCtrl.translatePoints(Vec3(0.0, 0.5, 0.0)) self.headCtrl.scalePoints(Vec3(1.8, 2.0, 2.0)) self.eyeLeftCtrl = Control('eyeLeft', parent=self.headCtrl, shape='arrow_thin') self.eyeLeftCtrl.translatePoints(Vec3(0, 0, 0.5)) self.eyeLeftCtrl.rotatePoints(0, 90, 0) self.eyeLeftCtrl.appendCurveData(sphereCtrl.getCurveData()) self.eyeRightCtrl = Control('eyeRight', parent=self.headCtrl, shape='arrow_thin') self.eyeRightCtrl.translatePoints(Vec3(0, 0, 0.5)) self.eyeRightCtrl.rotatePoints(0, 90, 0) self.eyeRightCtrl.appendCurveData(sphereCtrl.getCurveData()) self.jawCtrl = Control('jaw', parent=self.headCtrl, shape='square') self.jawCtrl.rotatePoints(90, 0, 0) self.jawCtrl.rotatePoints(0, 90, 0) self.jawCtrl.translatePoints(Vec3(0.0, -0.5, 0.5)) self.jawCtrl.scalePoints(Vec3(1.0, 0.8, 1.5)) self.jawCtrl.setColor('orange') eyeXAlignOri = Quat() eyeXAlignOri.setFromAxisAndAngle(Vec3(0, 1, 0), Math_degToRad(-90)) self.default_data = { "name": name, "location": "M", "headXfo": Xfo(Vec3(0.0, 17.5, -0.5)), "headCrvData": self.headCtrl.getCurveData(), "eyeLeftXfo": Xfo(tr=Vec3(0.375, 18.5, 0.5), ori=eyeXAlignOri), "eyeLeftCrvData": self.eyeLeftCtrl.getCurveData(), "eyeRightXfo": Xfo(tr=Vec3(-0.375, 18.5, 0.5), ori=eyeXAlignOri), "eyeRightCrvData": self.eyeRightCtrl.getCurveData(), "jawXfo": Xfo(Vec3(0.0, 17.875, -0.275)), "jawCrvData": self.jawCtrl.getCurveData() } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(HeadComponentGuide, self).saveData() data['headXfo'] = self.headCtrl.xfo data['headCrvData'] = self.headCtrl.getCurveData() data['eyeLeftXfo'] = self.eyeLeftCtrl.xfo data['eyeLeftCrvData'] = self.eyeLeftCtrl.getCurveData() data['eyeRightXfo'] = self.eyeRightCtrl.xfo data['eyeRightCrvData'] = self.eyeRightCtrl.getCurveData() data['jawXfo'] = self.jawCtrl.xfo data['jawCrvData'] = self.jawCtrl.getCurveData() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(HeadComponentGuide, self).loadData(data) self.headCtrl.xfo = data.get('headXfo', self.default_data['headXfo']) self.headCtrl.setCurveData(data.get('headCrvData', self.default_data['headCrvData'])) self.eyeLeftCtrl.xfo = data.get('eyeLeftXfo', self.default_data['eyeLeftXfo']) self.eyeLeftCtrl.setCurveData(data.get('eyeLeftCrvData', self.default_data['eyeLeftCrvData'])) self.eyeRightCtrl.xfo = data.get('eyeRightXfo', self.default_data['eyeRightXfo']) self.eyeRightCtrl.setCurveData(data.get('eyeRightCrvData', self.default_data['eyeRightCrvData'])) self.jawCtrl.xfo = data.get('jawXfo', self.default_data['jawXfo']) self.jawCtrl.setCurveData(data.get('jawCrvData', self.default_data['jawCrvData'])) return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(HeadComponentGuide, self).getRigBuildData() data['headXfo'] = self.headCtrl.xfo data['headCrvData'] = self.headCtrl.getCurveData() data['eyeLeftXfo'] = self.eyeLeftCtrl.xfo data['eyeLeftCrvData'] = self.eyeLeftCtrl.getCurveData() data['eyeRightXfo'] = self.eyeRightCtrl.xfo data['eyeRightCrvData'] = self.eyeRightCtrl.getCurveData() data['jawXfo'] = self.jawCtrl.xfo data['jawCrvData'] = self.jawCtrl.getCurveData() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return HeadComponentRig
class SpineComponentRig(SpineComponent): """Spine Component""" def __init__(self, name="spine", parent=None): Profiler.getInstance().push("Construct Spine Rig Component:" + name) super(SpineComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # COG self.cogCtrlSpace = CtrlSpace('cog', parent=self.ctrlCmpGrp) self.cogCtrl = Control('cog', parent=self.cogCtrlSpace, shape="circle") self.cogCtrl.scalePoints(Vec3(6.0, 6.0, 6.0)) self.cogCtrl.setColor("orange") # Spine01 self.spine01CtrlSpace = CtrlSpace('spine01', parent=self.cogCtrl) self.spine01Ctrl = Control('spine01', parent=self.spine01CtrlSpace, shape="circle") self.spine01Ctrl.scalePoints(Vec3(4.0, 4.0, 4.0)) # Spine02 self.spine02CtrlSpace = CtrlSpace('spine02', parent=self.spine01Ctrl) self.spine02Ctrl = Control('spine02', parent=self.spine02CtrlSpace, shape="circle") self.spine02Ctrl.scalePoints(Vec3(4.5, 4.5, 4.5)) # Spine03 self.spine03CtrlSpace = CtrlSpace('spine03', parent=self.spine02Ctrl) self.spine03Ctrl = Control('spine03', parent=self.spine03CtrlSpace, shape="circle") self.spine03Ctrl.scalePoints(Vec3(4.5, 4.5, 4.5)) self.spine03Ctrl.setColor("blue") # Spine04 self.spine04CtrlSpace = CtrlSpace('spine04', parent=self.cogCtrl) self.spine04Ctrl = Control('spine04', parent=self.spine04CtrlSpace, shape="circle") self.spine04Ctrl.scalePoints(Vec3(6.0, 6.0, 6.0)) # Pelvis self.pelvisCtrlSpace = CtrlSpace('pelvis', parent=self.cogCtrl) self.pelvisCtrl = Control('pelvis', parent=self.pelvisCtrlSpace, shape="cube") self.pelvisCtrl.alignOnYAxis(negative=True) self.pelvisCtrl.scalePoints(Vec3(2.0, 1.5, 1.5)) # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') self.defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.deformerJoints = [] self.spineOutputs = [] self.setNumDeformers(1) pelvisDef = Joint('pelvis', parent=self.defCmpGrp) pelvisDef.setComponent(self) # ===================== # Create Component I/O # ===================== # Setup component Xfo I/O's self.spineVertebraeOutput.setTarget(self.spineOutputs) # ============== # Constrain I/O # ============== # Constraint inputs self.spineSrtInputConstraint = PoseConstraint('_'.join([ self.cogCtrlSpace.getName(), 'To', self.spineMainSrtInputTgt.getName() ])) self.spineSrtInputConstraint.addConstrainer(self.spineMainSrtInputTgt) self.spineSrtInputConstraint.setMaintainOffset(True) self.cogCtrlSpace.addConstraint(self.spineSrtInputConstraint) # Constraint outputs self.spineCogOutputConstraint = PoseConstraint('_'.join( [self.spineCogOutputTgt.getName(), 'To', self.cogCtrl.getName()])) self.spineCogOutputConstraint.addConstrainer(self.cogCtrl) self.spineCogOutputTgt.addConstraint(self.spineCogOutputConstraint) self.spineBaseOutputConstraint = PoseConstraint('_'.join( [self.spineBaseOutputTgt.getName(), 'To', 'spineBase'])) self.spineBaseOutputConstraint.addConstrainer(self.spineOutputs[0]) self.spineBaseOutputTgt.addConstraint(self.spineBaseOutputConstraint) self.pelvisOutputConstraint = PoseConstraint('_'.join( [self.pelvisOutputTgt.getName(), 'To', self.pelvisCtrl.getName()])) self.pelvisOutputConstraint.addConstrainer(self.pelvisCtrl) self.pelvisOutputTgt.addConstraint(self.pelvisOutputConstraint) self.spineEndOutputConstraint = PoseConstraint('_'.join( [self.spineEndOutputTgt.getName(), 'To', 'spineEnd'])) self.spineEndOutputConstraint.addConstrainer(self.spineOutputs[0]) self.spineEndOutputTgt.addConstraint(self.spineEndOutputConstraint) # =============== # Add Splice Ops # =============== # Add Spine Splice Op self.bezierSpineSpliceOp = SpliceOperator('spineSpliceOp', 'BezierSpineSolver', 'Kraken') self.addOperator(self.bezierSpineSpliceOp) # Add Att Inputs self.bezierSpineSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierSpineSpliceOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierSpineSpliceOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierSpineSpliceOp.setInput('base', self.spine01Ctrl) self.bezierSpineSpliceOp.setInput('baseHandle', self.spine02Ctrl) self.bezierSpineSpliceOp.setInput('tipHandle', self.spine03Ctrl) self.bezierSpineSpliceOp.setInput('tip', self.spine04Ctrl) # Add Xfo Outputs self.bezierSpineSpliceOp.setOutput('outputs', self.spineOutputs) # Add Deformer Splice Op self.deformersToOutputsSpliceOp = SpliceOperator( 'spineDeformerSpliceOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.deformersToOutputsSpliceOp) # Add Att Inputs self.deformersToOutputsSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsSpliceOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsSpliceOp.setInput('constrainers', self.spineOutputs) # Add Xfo Outputs self.deformersToOutputsSpliceOp.setOutput('constrainees', self.deformerJoints) # Add Pelvis Splice Op self.pelvisDefSpliceOp = SpliceOperator('pelvisDeformerSpliceOp', 'PoseConstraintSolver', 'Kraken') self.addOperator(self.pelvisDefSpliceOp) # Add Att Inputs self.pelvisDefSpliceOp.setInput('drawDebug', self.drawDebugInputAttr) self.pelvisDefSpliceOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.pelvisDefSpliceOp.setInput('constrainer', self.pelvisOutputTgt) # Add Xfo Outputs self.pelvisDefSpliceOp.setOutput('constrainee', pelvisDef) Profiler.getInstance().pop() def setNumDeformers(self, numDeformers): # Add new deformers and outputs for i in xrange(len(self.spineOutputs), numDeformers): name = 'spine' + str(i + 1).zfill(2) spineOutput = ComponentOutput(name, parent=self.outputHrcGrp) self.spineOutputs.append(spineOutput) for i in xrange(len(self.deformerJoints), numDeformers): name = 'spine' + str(i + 1).zfill(2) spineDef = Joint(name, parent=self.defCmpGrp) spineDef.setComponent(self) self.deformerJoints.append(spineDef) 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(SpineComponentRig, self).loadData(data) cogPosition = data['cogPosition'] spine01Position = data['spine01Position'] spine02Position = data['spine02Position'] spine03Position = data['spine03Position'] spine04Position = data['spine04Position'] numDeformers = data['numDeformers'] self.cogCtrlSpace.xfo.tr = cogPosition self.cogCtrl.xfo.tr = cogPosition self.pelvisCtrlSpace.xfo.tr = cogPosition self.pelvisCtrl.xfo.tr = cogPosition self.spine01CtrlSpace.xfo.tr = spine01Position self.spine01Ctrl.xfo.tr = spine01Position self.spine02CtrlSpace.xfo.tr = spine02Position self.spine02Ctrl.xfo.tr = spine02Position self.spine03CtrlSpace.xfo.tr = spine03Position self.spine03Ctrl.xfo.tr = spine03Position self.spine04CtrlSpace.xfo.tr = spine04Position self.spine04Ctrl.xfo.tr = spine04Position length = spine01Position.distanceTo( spine02Position) + spine02Position.distanceTo( spine03Position) + spine03Position.distanceTo(spine04Position) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) # Update number of deformers and outputs self.setNumDeformers(numDeformers) # Updating constraint to use the updated last output. self.spineEndOutputConstraint.setConstrainer(self.spineOutputs[-1], index=0) # ============ # Set IO Xfos # ============ # ==================== # Evaluate Splice Ops # ==================== # evaluate the spine op so that all the output transforms are updated. self.bezierSpineSpliceOp.evaluate() # evaluate the constraint op so that all the joint transforms are updated. self.deformersToOutputsSpliceOp.evaluate() self.pelvisDefSpliceOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.spineCogOutputConstraint.evaluate() self.spineBaseOutputConstraint.evaluate() self.pelvisOutputConstraint.evaluate() self.spineEndOutputConstraint.evaluate()
class NeckComponentRig(NeckComponent): """Neck Component""" def __init__(self, name="neck", parent=None): Profiler.getInstance().push("Construct Neck Rig Component:" + name) super(NeckComponentRig, self).__init__(name, parent) # ========= # Controls # ========= # Neck self.neckCtrlSpace = CtrlSpace('neck', parent=self.ctrlCmpGrp) self.neckCtrl = Control('neck', parent=self.neckCtrlSpace, shape="pin") self.neckCtrl.scalePoints(Vec3(1.25, 1.25, 1.25)) self.neckCtrl.translatePoints(Vec3(0, 0, -0.5)) self.neckCtrl.rotatePoints(90, 0, 90) self.neckCtrl.setColor("orange") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) neckDef = Joint('neck', parent=defCmpGrp) neckDef.setComponent(self) # ============== # Constrain I/O # ============== # Constraint inputs clavicleInputConstraint = PoseConstraint('_'.join([self.neckCtrlSpace.getName(), 'To', self.neckBaseInputTgt.getName()])) clavicleInputConstraint.setMaintainOffset(True) clavicleInputConstraint.addConstrainer(self.neckBaseInputTgt) self.neckCtrlSpace.addConstraint(clavicleInputConstraint) # Constraint outputs neckOutputConstraint = PoseConstraint('_'.join([self.neckOutputTgt.getName(), 'To', self.neckCtrl.getName()])) neckOutputConstraint.addConstrainer(self.neckCtrl) self.neckOutputTgt.addConstraint(neckOutputConstraint) neckEndConstraint = PoseConstraint('_'.join([self.neckEndOutputTgt.getName(), 'To', self.neckCtrl.getName()])) neckEndConstraint.addConstrainer(self.neckCtrl) self.neckEndOutputTgt.addConstraint(neckEndConstraint) # =============== # Add Splice Ops # =============== #Add Deformer Splice Op spliceOp = KLOperator('neckDeformerKLOp', 'PoseConstraintSolver', 'Kraken') self.addOperator(spliceOp) # Add Att Inputs spliceOp.setInput('drawDebug', self.drawDebugInputAttr) spliceOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputstrl) spliceOp.setInput('constrainer', self.neckEndOutputTgt) # Add Xfo Outputs spliceOp.setOutput('constrainee', neckDef) Profiler.getInstance().pop() 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(NeckComponentRig, self).loadData( data ) self.neckCtrlSpace.xfo = data['neckXfo'] self.neckCtrl.xfo = data['neckXfo'] # ============ # Set IO Xfos # ============ self.neckBaseInputTgt.xfo = data['neckXfo'] self.neckEndOutputTgt.xfo = data['neckXfo'] self.neckOutputTgt.xfo = data['neckXfo']
class FabriceHeadRig(FabriceHead): """Fabrice Head Component Rig""" def __init__(self, name='head', parent=None): Profiler.getInstance().push("Construct Head Rig Component:" + name) super(FabriceHeadRig, self).__init__(name, parent) # ========= # Controls # ========= # Head Aim self.headAimCtrlSpace = CtrlSpace('headAim', parent=self.ctrlCmpGrp) self.headAimCtrl = Control('headAim', parent=self.headAimCtrlSpace, shape="sphere") self.headAimCtrl.scalePoints(Vec3(0.35, 0.35, 0.35)) self.headAimCtrl.lockScale(x=True, y=True, z=True) self.headAimUpV = Locator('headAimUpV', parent=self.headAimCtrl) self.headAimUpV.setShapeVisibility(False) # Head self.headAim = Locator('headAim', parent=self.ctrlCmpGrp) self.headAim.setShapeVisibility(False) self.headCtrlSpace = CtrlSpace('head', parent=self.ctrlCmpGrp) self.headCtrl = Control('head', parent=self.headCtrlSpace, shape="circle") self.headCtrl.lockTranslation(x=True, y=True, z=True) self.headCtrl.lockScale(x=True, y=True, z=True) # Jaw self.jawCtrlSpace = CtrlSpace('jawCtrlSpace', parent=self.headCtrl) self.jawCtrl = Control('jaw', parent=self.jawCtrlSpace, shape="cube") self.jawCtrl.lockTranslation(x=True, y=True, z=True) self.jawCtrl.lockScale(x=True, y=True, z=True) self.jawCtrl.setColor("orange") # ========== # Deformers # ========== deformersLayer = self.getOrCreateLayer('deformers') defCmpGrp = ComponentGroup(self.getName(), self, parent=deformersLayer) self.addItem('defCmpGrp', self.defCmpGrp) headDef = Joint('head', parent=defCmpGrp) headDef.setComponent(self) jawDef = Joint('jaw', parent=defCmpGrp) jawDef.setComponent(self) # ============== # Constrain I/O # ============== self.headToAimConstraint = PoseConstraint('_'.join( [self.headCtrlSpace.getName(), 'To', self.headAim.getName()])) self.headToAimConstraint.setMaintainOffset(True) self.headToAimConstraint.addConstrainer(self.headAim) self.headCtrlSpace.addConstraint(self.headToAimConstraint) # Constraint inputs self.headAimInputConstraint = PoseConstraint('_'.join([ self.headAimCtrlSpace.getName(), 'To', self.headBaseInputTgt.getName() ])) self.headAimInputConstraint.setMaintainOffset(True) self.headAimInputConstraint.addConstrainer(self.headBaseInputTgt) self.headAimCtrlSpace.addConstraint(self.headAimInputConstraint) # # Constraint outputs self.headOutputConstraint = PoseConstraint('_'.join( [self.headOutputTgt.getName(), 'To', self.headCtrl.getName()])) self.headOutputConstraint.addConstrainer(self.headCtrl) self.headOutputTgt.addConstraint(self.headOutputConstraint) self.jawOutputConstraint = PoseConstraint('_'.join( [self.jawOutputTgt.getName(), 'To', self.jawCtrl.getName()])) self.jawOutputConstraint.addConstrainer(self.jawCtrl) self.jawOutputTgt.addConstraint(self.jawOutputConstraint) # ============== # Add Operators # ============== # Add Aim Canvas Op # ================= self.headAimCanvasOp = CanvasOperator( 'headAimCanvasOp', 'Kraken.Solvers.DirectionConstraintSolver') self.addOperator(self.headAimCanvasOp) # Add Att Inputs self.headAimCanvasOp.setInput('drawDebug', self.drawDebugInputAttr) self.headAimCanvasOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Inputs self.headAimCanvasOp.setInput('position', self.headBaseInputTgt) self.headAimCanvasOp.setInput('upVector', self.headAimUpV) self.headAimCanvasOp.setInput('atVector', self.headAimCtrl) # Add Xfo Outputs self.headAimCanvasOp.setOutput('constrainee', self.headAim) # Add Deformer KL Op # ================== self.deformersToOutputsKLOp = KLOperator('headDeformerKLOp', 'MultiPoseConstraintSolver', 'Kraken') self.addOperator(self.deformersToOutputsKLOp) # Add Att Inputs self.deformersToOutputsKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.deformersToOutputsKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Xfo Outputs self.deformersToOutputsKLOp.setInput( 'constrainers', [self.headOutputTgt, self.jawOutputTgt]) # Add Xfo Outputs self.deformersToOutputsKLOp.setOutput('constrainees', [headDef, jawDef]) Profiler.getInstance().pop() 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(FabriceHeadRig, self).loadData(data) headXfo = data['headXfo'] headCtrlCrvData = data['headCtrlCrvData'] jawPosition = data['jawPosition'] jawCtrlCrvData = data['jawCtrlCrvData'] self.headAimCtrlSpace.xfo.ori = headXfo.ori self.headAimCtrlSpace.xfo.tr = headXfo.tr.add(Vec3(0, 0, 4)) self.headAimCtrl.xfo = self.headAimCtrlSpace.xfo self.headAimUpV.xfo.ori = self.headAimCtrl.xfo.ori self.headAimUpV.xfo.tr = self.headAimCtrl.xfo.tr.add(Vec3(0, 3, 0)) self.headAim.xfo = headXfo self.headCtrlSpace.xfo = headXfo self.headCtrl.xfo = headXfo self.headCtrl.setCurveData(headCtrlCrvData) self.jawCtrlSpace.xfo.tr = jawPosition self.jawCtrl.xfo.tr = jawPosition self.jawCtrl.setCurveData(jawCtrlCrvData) # ============ # Set IO Xfos # ============ self.headBaseInputTgt.xfo = headXfo self.headOutputTgt.xfo = headXfo self.jawOutputTgt.xfo.tr = jawPosition # ==================== # Evaluate Splice Ops # ==================== # evaluate the constraint op so that all the joint transforms are updated. self.headAimCanvasOp.evaluate() self.deformersToOutputsKLOp.evaluate() # evaluate the constraints to ensure the outputs are now in the correct location. self.headToAimConstraint.evaluate() self.headAimInputConstraint.evaluate() self.headOutputConstraint.evaluate() self.jawOutputConstraint.evaluate()
class ArmComponentGuide(ArmComponent): """Arm Component Guide""" def __init__(self, name="arm", parent=None): Profiler.getInstance().push("Construct Arm Guide Component:" + name) super(ArmComponentGuide, self).__init__(name, parent) # =========== # Attributes # =========== # Add Component Params to IK control guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.bicepFKCtrlSizeInputAttr = ScalarAttribute( "bicepFKCtrlSize", value=1.75, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp ) self.forearmFKCtrlSizeInputAttr = ScalarAttribute( "forearmFKCtrlSize", value=1.5, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp ) # ========= # Controls # ========= # Guide Controls self.bicepCtrl = Control("bicepFK", parent=self.ctrlCmpGrp, shape="sphere") self.bicepCtrl.setColor("blue") self.forearmCtrl = Control("forearmFK", parent=self.ctrlCmpGrp, shape="sphere") self.forearmCtrl.setColor("blue") self.wristCtrl = Control("wristFK", parent=self.ctrlCmpGrp, shape="sphere") self.wristCtrl.setColor("blue") self.handCtrl = Control("hand", parent=self.ctrlCmpGrp, shape="cube") self.handCtrl.setColor("blue") data = { "name": name, "location": "L", "bicepXfo": Xfo(Vec3(2.27, 15.295, -0.753)), "forearmXfo": Xfo(Vec3(5.039, 13.56, -0.859)), "wristXfo": Xfo(Vec3(7.1886, 12.2819, 0.4906)), "handXfo": Xfo(tr=Vec3(7.1886, 12.2819, 0.4906), ori=Quat(Vec3(-0.0865, -0.2301, -0.2623), 0.9331)), "bicepFKCtrlSize": 1.75, "forearmFKCtrlSize": 1.5, } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ArmComponentGuide, self).saveData() data["bicepXfo"] = self.bicepCtrl.xfo data["forearmXfo"] = self.forearmCtrl.xfo data["wristXfo"] = self.wristCtrl.xfo data["handXfo"] = self.handCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ArmComponentGuide, self).loadData(data) self.bicepCtrl.xfo = data["bicepXfo"] self.forearmCtrl.xfo = data["forearmXfo"] self.wristCtrl.xfo = data["wristXfo"] self.handCtrl.xfo = data["handXfo"] return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ArmComponentGuide, self).getRigBuildData() # values bicepPosition = self.bicepCtrl.xfo.tr forearmPosition = self.forearmCtrl.xfo.tr wristPosition = self.wristCtrl.xfo.tr # Calculate Bicep Xfo rootToWrist = wristPosition.subtract(bicepPosition).unit() rootToElbow = forearmPosition.subtract(bicepPosition).unit() bone1Normal = rootToWrist.cross(rootToElbow).unit() bone1ZAxis = rootToElbow.cross(bone1Normal).unit() bicepXfo = Xfo() bicepXfo.setFromVectors(rootToElbow, bone1Normal, bone1ZAxis, bicepPosition) # Calculate Forearm Xfo elbowToWrist = wristPosition.subtract(forearmPosition).unit() elbowToRoot = bicepPosition.subtract(forearmPosition).unit() bone2Normal = elbowToRoot.cross(elbowToWrist).unit() bone2ZAxis = elbowToWrist.cross(bone2Normal).unit() forearmXfo = Xfo() forearmXfo.setFromVectors(elbowToWrist, bone2Normal, bone2ZAxis, forearmPosition) handXfo = Xfo() handXfo.tr = self.handCtrl.xfo.tr handXfo.ori = self.handCtrl.xfo.ori bicepLen = bicepPosition.subtract(forearmPosition).length() forearmLen = forearmPosition.subtract(wristPosition).length() armEndXfo = Xfo() armEndXfo.tr = wristPosition armEndXfo.ori = forearmXfo.ori upVXfo = xfoFromDirAndUpV(bicepPosition, wristPosition, forearmPosition) upVXfo.tr = forearmPosition upVXfo.tr = upVXfo.transformVector(Vec3(0, 0, 5)) data["bicepXfo"] = bicepXfo data["forearmXfo"] = forearmXfo data["handXfo"] = handXfo data["armEndXfo"] = armEndXfo data["upVXfo"] = upVXfo data["forearmLen"] = forearmLen data["bicepLen"] = bicepLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return "Guide" @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ArmComponentRig
class ClavicleComponentGuide(ClavicleComponent): """Clavicle Component Guide""" def __init__(self, name='clavicle', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Clavicle Guide Component:" + name) super(ClavicleComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= # Guide Controls guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.clavicleCtrl = Control('clavicle', parent=self.ctrlCmpGrp, shape="circle") self.clavicleCtrl.scalePoints(Vec3(0.75, 0.75, 0.75)) self.clavicleCtrl.rotatePoints(0.0, 0.0, 90.0) self.clavicleGuideSettingsAttrGrp = AttributeGroup("Settings", parent=self.clavicleCtrl) self.handDebugInputAttr = BoolAttribute('drawDebug', value=False, parent=self.clavicleGuideSettingsAttrGrp) self.drawDebugInputAttr.connect(self.handDebugInputAttr) self.clavicleUpVCtrl = Control('clavicleUpV', parent=self.clavicleCtrl, shape="triangle") self.clavicleUpVCtrl.setColor('red') self.clavicleUpVCtrl.rotatePoints(-90.0, 0.0, 0.0) self.clavicleUpVCtrl.rotatePoints(0.0, 90.0, 0.0) self.clavicleUpVCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) self.clavicleEndCtrl = Control('clavicleEnd', parent=self.ctrlCmpGrp, shape="cube") self.clavicleEndCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) self.default_data = { "name": name, "location": "L", "clavicleXfo": Xfo(Vec3(0.15, 15.5, -0.5)), "clavicleUpVXfo": Xfo(Vec3(0.15, 16.5, -0.5)), "clavicleEndXfo": Xfo(Vec3(2.25, 15.5, -0.75)) } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ClavicleComponentGuide, self).saveData() data['clavicleXfo'] = self.clavicleCtrl.xfo data['clavicleUpVXfo'] = self.clavicleUpVCtrl.xfo data['clavicleEndXfo'] = self.clavicleEndCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ClavicleComponentGuide, self).loadData( data ) self.clavicleCtrl.xfo = data['clavicleXfo'] self.clavicleUpVCtrl.xfo = data['clavicleUpVXfo'] self.clavicleEndCtrl.xfo = data['clavicleEndXfo'] return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ClavicleComponentGuide, self).getRigBuildData() # Values claviclePosition = self.clavicleCtrl.xfo.tr clavicleUpV = self.clavicleUpVCtrl.xfo.tr clavicleEndPosition = self.clavicleEndCtrl.xfo.tr # Calculate Clavicle Xfo clavicleXfo = Xfo() clavicleOri = Quat() clavicleOri.setFromDirectionAndUpvector((clavicleEndPosition - claviclePosition).unit(), (clavicleUpV - claviclePosition).unit()) xAlignOffset = Quat() xAlignOffset.setFromAxisAndAngle(Vec3(0, 1, 0), Math_degToRad(-90)) clavicleXfo.ori = clavicleOri * xAlignOffset clavicleXfo.tr = claviclePosition clavicleLen = claviclePosition.subtract(clavicleEndPosition).length() data['clavicleXfo'] = clavicleXfo data['clavicleLen'] = clavicleLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ClavicleComponentRig
class ArmComponentGuide(ArmComponent): """Arm Component Guide""" def __init__(self, name='arm', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Arm Guide Component:" + name) super(ArmComponentGuide, self).__init__(name, parent, *args, **kwargs) # =========== # Attributes # =========== # Add Component Params to IK control guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.bicepFKCtrlSizeInputAttr = ScalarAttribute( 'bicepFKCtrlSize', value=1.75, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp) self.forearmFKCtrlSizeInputAttr = ScalarAttribute( 'forearmFKCtrlSize', value=1.5, minValue=0.0, maxValue=10.0, parent=guideSettingsAttrGrp) # ========= # Controls # ========= # Guide Controls self.bicepCtrl = Control('bicep', parent=self.ctrlCmpGrp, shape="sphere") self.bicepCtrl.setColor('blue') self.forearmCtrl = Control('forearm', parent=self.ctrlCmpGrp, shape="sphere") self.forearmCtrl.setColor('blue') self.wristCtrl = Control('wrist', parent=self.ctrlCmpGrp, shape="sphere") self.wristCtrl.setColor('blue') armGuideSettingsAttrGrp = AttributeGroup("DisplayInfo_ArmSettings", parent=self.bicepCtrl) self.armGuideDebugAttr = BoolAttribute('drawDebug', value=True, parent=armGuideSettingsAttrGrp) self.guideOpHost = Transform('guideOpHost', self.ctrlCmpGrp) # Guide Operator self.armGuideKLOp = KLOperator('guide', 'TwoBoneIKGuideSolver', 'Kraken') self.addOperator(self.armGuideKLOp) # Add Att Inputs self.armGuideKLOp.setInput('drawDebug', self.armGuideDebugAttr) self.armGuideKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Source Inputs self.armGuideKLOp.setInput('root', self.bicepCtrl) self.armGuideKLOp.setInput('mid', self.forearmCtrl) self.armGuideKLOp.setInput('end', self.wristCtrl) # Add Target Outputs self.armGuideKLOp.setOutput('guideOpHost', self.guideOpHost) self.default_data = { "name": name, "location": "L", "bicepXfo": Xfo(Vec3(2.275, 15.3, -0.75)), "forearmXfo": Xfo(Vec3(5.0, 13.5, -0.75)), "wristXfo": Xfo(Vec3(7.2, 12.25, 0.5)), "bicepFKCtrlSize": self.bicepFKCtrlSizeInputAttr.getValue(), "forearmFKCtrlSize": self.forearmFKCtrlSizeInputAttr.getValue() } self.loadData(self.default_data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ArmComponentGuide, self).saveData() data['bicepXfo'] = self.bicepCtrl.xfo data['forearmXfo'] = self.forearmCtrl.xfo data['wristXfo'] = self.wristCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ArmComponentGuide, self).loadData(data) self.bicepCtrl.xfo = data['bicepXfo'] self.forearmCtrl.xfo = data['forearmXfo'] self.wristCtrl.xfo = data['wristXfo'] guideOpName = ''.join([ self.getName().split('GuideKLOp')[0], self.getLocation(), 'GuideKLOp' ]) self.armGuideKLOp.setName(guideOpName) self.armGuideKLOp.evaluate() return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ArmComponentGuide, self).getRigBuildData() # values bicepPosition = self.bicepCtrl.xfo.tr forearmPosition = self.forearmCtrl.xfo.tr wristPosition = self.wristCtrl.xfo.tr # Calculate Bicep Xfo rootToWrist = wristPosition.subtract(bicepPosition).unit() rootToElbow = forearmPosition.subtract(bicepPosition).unit() bone1Normal = rootToWrist.cross(rootToElbow).unit() bone1ZAxis = rootToElbow.cross(bone1Normal).unit() bicepXfo = Xfo() bicepXfo.setFromVectors(rootToElbow, bone1Normal, bone1ZAxis, bicepPosition) # Calculate Forearm Xfo elbowToWrist = wristPosition.subtract(forearmPosition).unit() elbowToRoot = bicepPosition.subtract(forearmPosition).unit() bone2Normal = elbowToRoot.cross(elbowToWrist).unit() bone2ZAxis = elbowToWrist.cross(bone2Normal).unit() forearmXfo = Xfo() forearmXfo.setFromVectors(elbowToWrist, bone2Normal, bone2ZAxis, forearmPosition) # Calculate Wrist Xfo wristXfo = Xfo() wristXfo.tr = self.wristCtrl.xfo.tr wristXfo.ori = forearmXfo.ori upVXfo = xfoFromDirAndUpV(bicepPosition, wristPosition, forearmPosition) upVXfo.tr = forearmPosition upVXfo.tr = upVXfo.transformVector(Vec3(0, 0, 5)) # Lengths bicepLen = bicepPosition.subtract(forearmPosition).length() forearmLen = forearmPosition.subtract(wristPosition).length() data['bicepXfo'] = bicepXfo data['forearmXfo'] = forearmXfo data['wristXfo'] = wristXfo data['upVXfo'] = upVXfo data['bicepLen'] = bicepLen data['forearmLen'] = forearmLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ArmComponentRig
class FabriceTailGuide(FabriceTail): """Fabrice Tail Component Guide""" def __init__(self, name='tail', parent=None): Profiler.getInstance().push("Construct Fabrice Tail Guide Component:" + name) super(FabriceTailGuide, self).__init__(name, parent) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.numDeformersAttr = IntegerAttribute('numDeformers', value=1, minValue=0, maxValue=20, parent=guideSettingsAttrGrp) self.numDeformersAttr.setValueChangeCallback(self.updateNumDeformers) # Guide Controls self.tailBaseCtrl = Control('tailBase', parent=self.ctrlCmpGrp, shape='sphere') self.tailBaseCtrl.scalePoints(Vec3(1.2, 1.2, 1.2)) self.tailBaseCtrl.lockScale(x=True, y=True, z=True) self.tailBaseCtrl.setColor("turqoise") self.tailBaseHandleCtrl = Control('tailBaseHandle', parent=self.ctrlCmpGrp, shape='pin') self.tailBaseHandleCtrl.rotatePoints(90, 0, 0) self.tailBaseHandleCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailBaseHandleCtrl.lockScale(x=True, y=True, z=True) self.tailBaseHandleCtrl.setColor("turqoise") self.tailEndHandleCtrl = Control('tailEndHandle', parent=self.ctrlCmpGrp, shape='pin') self.tailEndHandleCtrl.rotatePoints(90, 0, 0) self.tailEndHandleCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailEndHandleCtrl.lockScale(x=True, y=True, z=True) self.tailEndHandleCtrl.setColor("turqoise") self.tailEndCtrl = Control('tailEnd', parent=self.ctrlCmpGrp, shape='pin') self.tailEndCtrl.rotatePoints(90, 0, 0) self.tailEndCtrl.translatePoints(Vec3(0, 1.0, 0)) self.tailEndCtrl.lockScale(x=True, y=True, z=True) self.tailEndCtrl.setColor("turqoise") # =============== # Add Splice Ops # =============== # Add Tail Splice Op self.bezierSpineKLOp = KLOperator('spineGuideKLOp', 'BezierSpineSolver', 'Kraken') self.bezierSpineKLOp.setOutput('outputs', self.tailVertebraeOutput.getTarget()) self.addOperator(self.bezierSpineKLOp) # Add Att Inputs self.bezierSpineKLOp.setInput('drawDebug', self.drawDebugInputAttr) self.bezierSpineKLOp.setInput('rigScale', self.rigScaleInputAttr) self.bezierSpineKLOp.setInput('length', self.lengthInputAttr) # Add Xfo Inputs self.bezierSpineKLOp.setInput('base', self.tailBaseCtrl) self.bezierSpineKLOp.setInput('baseHandle', self.tailBaseHandleCtrl) self.bezierSpineKLOp.setInput('tipHandle', self.tailEndHandleCtrl) self.bezierSpineKLOp.setInput('tip', self.tailEndCtrl) self.loadData({ 'name': name, 'location': 'M', 'tailBasePos': Vec3(0.0, 0.65, -3.1), 'tailBaseHandlePos': Vec3(0.0, 0.157, -4.7), 'tailBaseHandleCtrlCrvData': self.tailBaseHandleCtrl.getCurveData(), 'tailEndHandlePos': Vec3(0.0, 0.0625, -6.165), 'tailEndHandleCtrlCrvData': self.tailEndHandleCtrl.getCurveData(), 'tailEndPos': Vec3(0.0, -0.22, -7.42), 'tailEndCtrlCrvData': self.tailEndCtrl.getCurveData(), 'numDeformers': 6 }) Profiler.getInstance().pop() # ========== # Callbacks # ========== def updateNumDeformers(self, count): """Generate the guide controls for the variable outputes array. Arguments: count -- object, The number of joints inthe chain. Return: True if successful. """ if count == 0: raise IndexError("'count' must be > 0") vertebraeOutputs = self.tailVertebraeOutput.getTarget() if count > len(vertebraeOutputs): for i in xrange(len(vertebraeOutputs), count): debugCtrl = Control('spine' + str(i+1).zfill(2), parent=self.outputHrcGrp, shape="vertebra") debugCtrl.rotatePoints(0, -90, 0) debugCtrl.scalePoints(Vec3(0.5, 0.5, 0.5)) debugCtrl.setColor('turqoise') vertebraeOutputs.append(debugCtrl) elif count < len(vertebraeOutputs): numExtraCtrls = len(vertebraeOutputs) - count for i in xrange(numExtraCtrls): extraCtrl = vertebraeOutputs.pop() self.outputHrcGrp.removeChild(extraCtrl) return True # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(FabriceTailGuide, self).saveData() data['tailBasePos'] = self.tailBaseCtrl.xfo.tr data['tailBaseHandlePos'] = self.tailBaseHandleCtrl.xfo.tr data['tailBaseHandleCtrlCrvData'] = self.tailBaseHandleCtrl.getCurveData() data['tailEndHandlePos'] = self.tailEndHandleCtrl.xfo.tr data['tailEndHandleCtrlCrvData'] = self.tailEndHandleCtrl.getCurveData() data['tailEndPos'] = self.tailEndCtrl.xfo.tr data['tailEndCtrlCrvData'] = self.tailEndCtrl.getCurveData() data['numDeformers'] = self.numDeformersAttr.getValue() return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(FabriceTailGuide, self).loadData( data ) self.tailBaseCtrl.xfo.tr = data["tailBasePos"] self.tailBaseHandleCtrl.xfo.tr = data["tailBaseHandlePos"] self.tailBaseHandleCtrl.setCurveData(data['tailBaseHandleCtrlCrvData']) self.tailEndHandleCtrl.xfo.tr = data["tailEndHandlePos"] self.tailEndHandleCtrl.setCurveData(data['tailEndHandleCtrlCrvData']) self.tailEndCtrl.xfo.tr = data["tailEndPos"] self.tailEndCtrl.setCurveData(data['tailEndCtrlCrvData']) self.numDeformersAttr.setValue(data["numDeformers"]) length = data["tailBasePos"].distanceTo(data["tailBaseHandlePos"]) + data["tailBaseHandlePos"].distanceTo(data["tailEndHandlePos"]) + data["tailEndHandlePos"].distanceTo(data["tailEndPos"]) self.lengthInputAttr.setMax(length * 3.0) self.lengthInputAttr.setValue(length) self.bezierSpineKLOp.evaluate() return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig. Return: The JSON rig data object. """ data = super(FabriceTailGuide, self).getRigBuildData() data['tailBasePos'] = self.tailBaseCtrl.xfo.tr data['tailBaseHandlePos'] = self.tailBaseHandleCtrl.xfo.tr data['tailBaseHandleCtrlCrvData'] = self.tailBaseHandleCtrl.getCurveData() data['tailEndHandlePos'] = self.tailEndHandleCtrl.xfo.tr data['tailEndHandleCtrlCrvData'] = self.tailEndHandleCtrl.getCurveData() data['tailEndPos'] = self.tailEndCtrl.xfo.tr data['tailEndCtrlCrvData'] = self.tailEndCtrl.getCurveData() data['numDeformers'] = self.numDeformersAttr.getValue() return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return FabriceTailRig
class ClavicleComponentGuide(ClavicleComponent): """Clavicle Component Guide""" def __init__(self, name='clavicle', parent=None, data=None): Profiler.getInstance().push("Construct Clavicle Guide Component:" + name) super(ClavicleComponentGuide, self).__init__(name, parent) # ========= # Controls # ========= # Guide Controls guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.clavicleCtrl = Control('clavicle', parent=self.ctrlCmpGrp, shape="sphere") self.clavicleUpVCtrl = Control('clavicleUpV', parent=self.ctrlCmpGrp, shape="triangle") self.clavicleUpVCtrl.setColor('red') self.clavicleEndCtrl = Control('clavicleEnd', parent=self.ctrlCmpGrp, shape="sphere") if data is None: data = { "name": name, "location": "L", "clavicleXfo": Xfo(Vec3(0.1322, 15.403, -0.5723)), "clavicleUpVXfo": Xfo(Vec3(0.0, 1.0, 0.0)), "clavicleEndXfo": Xfo(Vec3(2.27, 15.295, -0.753)) } self.loadData(data) Profiler.getInstance().pop() # ============= # Data Methods # ============= def saveData(self): """Save the data for the component to be persisted. Return: The JSON data object """ data = super(ClavicleComponentGuide, self).saveData() data['clavicleXfo'] = self.clavicleCtrl.xfo data['clavicleUpVXfo'] = self.clavicleUpVCtrl.xfo data['clavicleEndXfo'] = self.clavicleEndCtrl.xfo return data def loadData(self, data): """Load a saved guide representation from persisted data. Arguments: data -- object, The JSON data object. Return: True if successful. """ super(ClavicleComponentGuide, self).loadData( data ) self.clavicleCtrl.xfo = data['clavicleXfo'] self.clavicleUpVCtrl.xfo = self.clavicleCtrl.xfo.multiply(data['clavicleUpVXfo']) self.clavicleEndCtrl.xfo = data['clavicleEndXfo'] return True def getRigBuildData(self): """Returns the Guide data used by the Rig Component to define the layout of the final rig.. Return: The JSON rig data object. """ data = super(ClavicleComponentGuide, self).getRigBuildData() # Values claviclePosition = self.clavicleCtrl.xfo.tr clavicleUpV = self.clavicleUpVCtrl.xfo.tr clavicleEndPosition = self.clavicleEndCtrl.xfo.tr # Calculate Clavicle Xfo rootToEnd = clavicleEndPosition.subtract(claviclePosition).unit() rootToUpV = clavicleUpV.subtract(claviclePosition).unit() bone1ZAxis = rootToUpV.cross(rootToEnd).unit() bone1Normal = bone1ZAxis.cross(rootToEnd).unit() clavicleXfo = Xfo() clavicleXfo.setFromVectors(rootToEnd, bone1Normal, bone1ZAxis, claviclePosition) clavicleLen = claviclePosition.subtract(clavicleEndPosition).length() data['clavicleXfo'] = clavicleXfo data['clavicleLen'] = clavicleLen return data # ============== # Class Methods # ============== @classmethod def getComponentType(cls): """Enables introspection of the class prior to construction to determine if it is a guide component. Return: The true if this component is a guide component. """ return 'Guide' @classmethod def getRigComponentClass(cls): """Returns the corresponding rig component class for this guide component class Return: The rig component class. """ return ClavicleComponentRig