class LegComponentGuide(LegComponent): """Leg Component Guide""" def __init__(self, name='leg', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct Leg Guide Component:" + name) super(LegComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) # Guide Controls self.femurCtrl = Control('femur', parent=self.ctrlCmpGrp, shape="sphere") self.kneeCtrl = Control('knee', parent=self.ctrlCmpGrp, shape="sphere") self.ankleCtrl = Control('ankle', parent=self.ctrlCmpGrp, shape="sphere") armGuideSettingsAttrGrp = AttributeGroup("DisplayInfo_ArmSettings", parent=self.femurCtrl) self.armGuideDebugAttr = BoolAttribute('drawDebug', value=True, parent=armGuideSettingsAttrGrp) self.guideOpHost = Transform('guideOpHost', self.ctrlCmpGrp) # Guide Operator self.legGuideKLOp = KLOperator(name + 'GuideKLOp', 'TwoBoneIKGuideSolver', 'Kraken') self.addOperator(self.legGuideKLOp) # Add Att Inputs self.legGuideKLOp.setInput('drawDebug', self.armGuideDebugAttr) self.legGuideKLOp.setInput('rigScale', self.rigScaleInputAttr) # Add Source Inputs self.legGuideKLOp.setInput('root', self.femurCtrl) self.legGuideKLOp.setInput('mid', self.kneeCtrl) self.legGuideKLOp.setInput('end', self.ankleCtrl) # Add Target Outputs self.legGuideKLOp.setOutput('guideOpHost', self.guideOpHost) self.default_data = { "name": name, "location": "L", "createIKHandle": False, "femurXfo": Xfo(Vec3(1.0, 9.75, -0.5)), "kneeXfo": Xfo(Vec3(1.5, 5.5, -0.5)), "ankleXfo": Xfo(Vec3(1.75, 1.15, -1.25)) } 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(LegComponentGuide, self).saveData() data['femurXfo'] = self.femurCtrl.xfo data['kneeXfo'] = self.kneeCtrl.xfo data['ankleXfo'] = self.ankleCtrl.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(LegComponentGuide, self).loadData( data ) self.femurCtrl.xfo = data.get('femurXfo') self.kneeCtrl.xfo = data.get('kneeXfo') self.ankleCtrl.xfo = data.get('ankleXfo') guideOpName = ''.join([self.getName().split('GuideKLOp')[0], self.getLocation(), 'GuideKLOp']) self.legGuideKLOp.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(LegComponentGuide, self).getRigBuildData() # Values femurPosition = self.femurCtrl.xfo.tr kneePosition = self.kneeCtrl.xfo.tr anklePosition = self.ankleCtrl.xfo.tr # Calculate Bicep Xfo rootToWrist = anklePosition.subtract(femurPosition).unit() rootToKnee = kneePosition.subtract(femurPosition).unit() bone1Normal = rootToWrist.cross(rootToKnee).unit() bone1ZAxis = rootToKnee.cross(bone1Normal).unit() femurXfo = Xfo() femurXfo.setFromVectors(rootToKnee, bone1Normal, bone1ZAxis, femurPosition) # Calculate Forearm Xfo elbowToWrist = anklePosition.subtract(kneePosition).unit() elbowToRoot = femurPosition.subtract(kneePosition).unit() bone2Normal = elbowToRoot.cross(elbowToWrist).unit() bone2ZAxis = elbowToWrist.cross(bone2Normal).unit() kneeXfo = Xfo() kneeXfo.setFromVectors(elbowToWrist, bone2Normal, bone2ZAxis, kneePosition) femurLen = femurPosition.subtract(kneePosition).length() shinLen = kneePosition.subtract(anklePosition).length() handleXfo = Xfo() handleXfo.tr = anklePosition upVXfo = xfoFromDirAndUpV(femurPosition, anklePosition, kneePosition) upVXfo.tr = kneePosition upVXfo.tr = upVXfo.transformVector(Vec3(0, 0, 5)) data['femurXfo'] = femurXfo data['kneeXfo'] = kneeXfo data['handleXfo'] = handleXfo data['upVXfo'] = upVXfo data['femurLen'] = femurLen data['shinLen'] = shinLen 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 LegComponentRig
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