def __init__(self, name='neck', parent=None, data=None): Profiler.getInstance().push("Construct Neck Component:" + name) super(NeckComponentGuide, self).__init__(name, parent) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) # Guide Controls self.neckCtrl = Control('neck', parent=self.ctrlCmpGrp, shape="sphere") self.neckEndCtrl = Control('neckEnd', parent=self.ctrlCmpGrp, shape="sphere") if data is None: data = { "name": name, "location": "M", "neckPosition": Vec3(0.0, 16.5572, -0.6915), "neckEndPosition": Vec3(0.0, 17.4756, -0.421) } self.loadData(data) 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 __init__(self, name='head', parent=None, data=None): Profiler.getInstance().push("Construct Head Guide Component:" + name) super(HeadComponentGuide, self).__init__(name, parent) # ========= # Controls # ========= guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.headCtrl = Control('head', parent=self.ctrlCmpGrp, shape="cube") self.headEndCtrl = Control('headEnd', parent=self.ctrlCmpGrp, shape="sphere") self.eyeLeftCtrl = Control('eyeLeft', parent=self.ctrlCmpGrp, shape="sphere") self.eyeRightCtrl = Control('eyeRight', parent=self.ctrlCmpGrp, shape="sphere") self.jawCtrl = Control('jaw', parent=self.ctrlCmpGrp, shape="cube") if data is None: data = { "name": name, "location": "M", "headPosition": Vec3(0.0, 17.4756, -0.421), "headEndPosition": Vec3(0.0, 19.5, -0.421), "eyeLeftPosition": Vec3(0.3497, 18.0878, 0.6088), "eyeRightPosition": Vec3(-0.3497, 18.0878, 0.6088), "jawPosition": Vec3(0.0, 17.613, -0.2731) } self.loadData(data) 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(ClavicleComponentRig, self).loadData(data) self.clavicleCtrlSpace.xfo = data['clavicleXfo'] self.clavicleCtrl.xfo = data['clavicleXfo'] self.clavicleCtrl.scalePoints(Vec3(data['clavicleLen'], 0.75, 0.75)) if data['location'] == "R": self.clavicleCtrl.translatePoints(Vec3(0.0, 0.0, -1.0)) else: self.clavicleCtrl.translatePoints(Vec3(0.0, 0.0, 1.0)) # ============ # Set IO Xfos # ============ self.spineEndInputTgt.xfo = data['clavicleXfo'] self.clavicleEndOutputTgt.xfo = data['clavicleXfo'] self.clavicleOutputTgt.xfo = data['clavicleXfo']
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()
def __init__(self, name='limb', parent=None, *args, **kwargs): Profiler.getInstance().push("Construct StretchyLimb Guide Component:" + name) super(StretchyLimbComponentGuide, self).__init__(name, parent, *args, **kwargs) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) # Guide Controls self.upperCtl = Control('upper', parent=self.ctrlCmpGrp, shape="sphere") self.lowerCtl = Control('lower', parent=self.ctrlCmpGrp, shape="sphere") self.endCtl = Control('end', parent=self.ctrlCmpGrp, shape="sphere") self.default_data = { "name": name, "location": "L", "upperXfo": Xfo(Vec3(0.9811, 9.769, -0.4572)), "lowerXfo": Xfo(Vec3(1.4488, 5.4418, -0.5348)), "endXfo": Xfo(Vec3(1.841, 1.1516, -1.237)) } self.loadData(self.default_data) Profiler.getInstance().pop()
def __init__(self, name='leg', parent=None, data=None): Profiler.getInstance().push("Construct Leg Guide Component:" + name) super(LegComponentGuide, self).__init__(name, parent) # ========= # 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") self.toeCtrl = Control('toe', parent=self.ctrlCmpGrp, shape="sphere") self.toeTipCtrl = Control('toeTip', parent=self.ctrlCmpGrp, shape="sphere") if data is None: data = { "name": name, "location": "L", "femurXfo": Xfo(Vec3(0.9811, 9.769, -0.4572)), "kneeXfo": Xfo(Vec3(1.4488, 5.4418, -0.5348)), "ankleXfo": Xfo(Vec3(1.841, 1.1516, -1.237)), "toeXfo": Xfo(Vec3(1.85, 0.4, 0.25)), "toeTipXfo": Xfo(Vec3(1.85, 0.4, 1.5)) } self.loadData(data) Profiler.getInstance().pop()
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 __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()
def __init__(self, name='clavicle', parent=None): Profiler.getInstance().push("Construct Clavicle Guide Component:" + name) super(FabriceClavicleGuide, self).__init__(name, parent) # ========= # Controls # ========= # Guide Controls guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.clavicleCtrl = Control('clavicle', parent=self.ctrlCmpGrp, shape="cube") self.clavicleCtrl.alignOnXAxis() self.clavicleCtrl.scalePoints(Vec3(1.0, 0.25, 0.25)) data = { "name": name, "location": "L", "clavicleXfo": Xfo(Vec3(0.1322, 15.403, -0.5723)), 'clavicleCtrlCrvData': self.clavicleCtrl.getCurveData() } self.loadData(data) 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(TentacleComponentRig, self).loadData(data) boneXfos = data['boneXfos'] boneLengths = data['boneLengths'] numJoints = data['numJoints'] endXfo = data['endXfo'] # Add extra controls and outputs self.setNumControls(numJoints) self.setNumDeformers(numJoints) # Scale controls based on bone lengths for i, each in enumerate(self.fkCtrlSpaces): self.fkCtrlSpaces[i].xfo = boneXfos[i] self.fkCtrls[i].xfo = boneXfos[i] self.fkCtrls[i].scalePoints( Vec3( Vec3(boneLengths[i], boneLengths[i] * 0.45, boneLengths[i] * 0.45))) self.chainBase.xfo = boneXfos[0] self.tentacleIKCtrlSpace.xfo = endXfo self.tentacleIKCtrl.xfo = endXfo # ============ # Set IO Xfos # ============ self.rootInputTgt.xfo = boneXfos[0] for i in xrange(len(boneLengths)): self.boneOutputsTgt[i].xfo = boneXfos[i] self.tentacleEndXfoOutputTgt.xfo = endXfo # ============= # Set IO Attrs # ============= tipBoneLen = boneLengths[len(boneLengths) - 1] self.tipBoneLenInputAttr.setMax(tipBoneLen * 2.0) self.tipBoneLenInputAttr.setValue(tipBoneLen) # ==================== # Evaluate Splice Ops # ==================== # evaluate the nbone op so that all the output transforms are updated. self.tentacleSolverKLOp.evaluate() self.outputsToDeformersKLOp.evaluate()
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('guide', '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()
def buildArm(mode='guide'): Profiler.getInstance().push("arm_build") guideContainer = Container('armGuide') armGuide = ArmComponentGuide("arm", parent=guideContainer) armGuide.loadData({ "name": "Arm", "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 }) if mode == 'guide': builder = plugins.getBuilder() builder.build(guideContainer) elif mode == 'rig': synchronizer = plugins.getSynchronizer() synchronizer.setTarget(guideContainer) synchronizer.sync() armGuideData = armGuide.getRigBuildData() rigContainer = Container('armRig') arm = ArmComponent(parent=rigContainer) arm.loadData(armGuideData) builder = plugins.getBuilder() builder.build(rigContainer) else: LogMessage('Invalid mode set') Profiler.getInstance().pop() if __name__ == "__main__": print Profiler.getInstance().generateReport() else: if mode == 'guide': logHierarchy(armGuide) elif mode == 'rig': logHierarchy(arm)
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()
def __init__(self, name='twist', parent=None): Profiler.getInstance().push('Construct Spine Guide Component:' + name) super(TwistComponentGuide, self).__init__(name, parent) # ========= # Controls # ======== guideSettingsAttrGrp = AttributeGroup('GuideSettings', parent=self) self.numDeformersAttr = IntegerAttribute('numDeformers', value=1, minValue=0, maxValue=20, parent=guideSettingsAttrGrp) self.blendBiasAttr = ScalarAttribute('blendBias', value=0.0, minValue=0, maxValue=1.0, parent=guideSettingsAttrGrp) # Guide Controls triangleCtrl = Control('triangle', shape='triangle') triangleCtrl.rotatePoints(90, 0, 0) triangleCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) triangleCtrl.scalePoints(Vec3(1.0, 0.5, 1.0)) triangleCtrl.translatePoints(Vec3(0.0, 1.25, 0.0)) triangleCtrl.rotatePoints(0, 90, 0) self.originCtrl = Control('origin', parent=self.ctrlCmpGrp, shape='circle') self.originCtrl.rotatePoints(90, 0, 0) self.originCtrl.rotatePoints(0, 90, 0) self.originCtrl.appendCurveData(triangleCtrl.getCurveData()) self.insertCtrl = Control('insert', parent=self.ctrlCmpGrp, shape='circle') self.insertCtrl.rotatePoints(90, 0, 0) self.insertCtrl.rotatePoints(0, 90, 0) self.insertCtrl.appendCurveData(triangleCtrl.getCurveData()) self.default_data = { 'name': name, 'location': 'M', 'blendBias': 0.5, 'originXfo': Xfo(Vec3(0.0, 0.0, 0.0)), 'insertXfo': Xfo(Vec3(5.0, 0.0, 0.0)), 'numDeformers': 5 } self.loadData(self.default_data) 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()
def syncXfo(self, kObject): """Syncs the xfo from the DCC object to the Kraken object. Args: kObject (object): Object to sync the xfo for. Returns: Boolean: True if successful. """ if kObject.isOfAnyType(('Rig', 'Container', 'Layer', 'HierarchyGroup', 'ComponentInput', 'ComponentOutput')): logger.debug("SyncXfo: Skipping '" + kObject.getName() + "'!") return False hrcMap = self.getHierarchyMap() if kObject not in hrcMap.keys(): logger.warning("SyncXfo: 3D Object '" + kObject.getName() + "' was not found in the mapping!") return False dccItem = hrcMap[kObject]['dccItem'] if dccItem is None: logger.warning("SyncXfo: No DCC Item for :" + kObject.getPath()) return False dccPos = dccItem.GetWorldPosition() dccQuat = dccItem.GetWorldRotation() dccScl = dccItem.GetWorldScale() pos = Vec3(x=dccPos.X, y=dccPos.Y, z=dccPos.Z) quat = Quat(v=Vec3(dccQuat.X, dccQuat.Y, dccQuat.Z), w=dccQuat.W) # If flag is set, pass the DCC Scale values. if kObject.testFlag('SYNC_SCALE') is True: scl = Vec3(x=dccScl.X, y=dccScl.Y, z=dccScl.Z) else: scl = Vec3(1.0, 1.0, 1.0) newXfo = Xfo(tr=pos, ori=quat, sc=scl) rotateUpXfo = Xfo() rotateUpXfo.ori = Quat().setFromAxisAndAngle(Vec3(1, 0, 0), Math_degToRad(-90)) newXfo = rotateUpXfo * newXfo kObject.xfo = newXfo 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 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
def __init__(self, name='mainSrt', parent=None): Profiler.getInstance().push("Construct MainSrt Guide Component:" + name) super(MainSrtComponentGuide, self).__init__(name, parent) # ========= # Attributes # ========= # Add Component Params to IK control guideSettingsAttrGrp = AttributeGroup("GuideSettings", parent=self) self.mainSrtSizeInputAttr = ScalarAttribute('mainSrtSize', value=5.0, minValue=1.0, maxValue=50.0, parent=guideSettingsAttrGrp) # ========= # Controls # ========= # Guide Controls self.mainSrtCtrl = Control('mainSrt', parent=self.ctrlCmpGrp, shape="circle") data = { "location": 'M', "mainSrtSize": self.mainSrtSizeInputAttr.getValue(), "mainSrtXfo": Xfo(tr=Vec3(0.0, 0.0, 0.0)) } self.loadData(data) Profiler.getInstance().pop()
def calculateUpVXfo(self, boneXfos, endXfo): """Calculates the transform for the UpV control. Args: boneXfos (list): Bone transforms. endXfo (Xfo): Transform for the end of the chain. Returns: Xfo: Up Vector transform. """ # Calculate FW toFirst = boneXfos[1].tr.subtract(boneXfos[0].tr).unit() toTip = endXfo.tr.subtract(boneXfos[0].tr).unit() fw = toTip.cross(toFirst).unit() chainNormal = fw.cross(toTip).unit() chainZAxis = toTip.cross(chainNormal).unit() chainXfo = Xfo() chainXfo.setFromVectors(toTip.unit(), chainNormal, chainZAxis, boneXfos[0].tr) rootToTip = endXfo.tr.subtract(boneXfos[0].tr).length() upVXfo = Xfo() upVXfo.tr = chainXfo.transformVector( Vec3(rootToTip / 2.0, rootToTip / 2.0, 0.0)) return upVXfo
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() # values neckEndPosition = self.neckCtrl.xfo.tr neckPosition = self.neckEndCtrl.xfo.tr neckUpV = Vec3(0.0, 0.0, -1.0) # Calculate Neck Xfo rootToEnd = neckEndPosition.subtract(neckPosition).unit() rootToUpV = neckUpV.subtract(neckPosition).unit() bone1ZAxis = rootToUpV.cross(rootToEnd).unit() bone1Normal = bone1ZAxis.cross(rootToEnd).unit() neckXfo = Xfo() neckXfo.setFromVectors(rootToEnd, bone1Normal, bone1ZAxis, neckPosition) data['neckXfo'] = neckXfo return data
def rotatePoints(self, xRot, yRot, zRot): """Rotates the points by the input values. Arguments: xRot -- Float, euler x rotate value. yRot -- Float, euler y rotate value. zRot -- Float, euler z rotate value. Return: True if successful. """ curveData = list(self.getCurveData()) quatRot = Quat() quatRot.setFromEuler( Euler(Math_degToRad(xRot), Math_degToRad(yRot), Math_degToRad(zRot))) newPoints = [] for eachSubCurve in curveData: for eachPoint in eachSubCurve["points"]: pointVec = Vec3(eachPoint[0], eachPoint[1], eachPoint[2]) rotVec = quatRot.rotateVector(pointVec) eachPoint[0] = rotVec.x eachPoint[1] = rotVec.y eachPoint[2] = rotVec.z self.setCurveData(curveData) return True
def generateGuidePositions(self, numJoints): """Generates the positions for the guide controls based on the number of joints. Args: numJoints (int): Number of joints to generate a transform for. Returns: list: Guide control positions. """ halfPi = math.pi / 2.0 step = halfPi / numJoints xValues = [] yValues = [] for i in xrange(numJoints + 1): xValues.append(math.cos((i * step) + halfPi) * -10) yValues.append(math.sin((i * step) + halfPi) * 10) guidePositions = [] for i in xrange(numJoints + 1): guidePositions.append(Vec3(xValues[i], yValues[i], 0.0)) return guidePositions
def scalePointsOnAxis(self, scale, scaleAxis="POSX"): """Scales the point positions from it's center along the given axis only. Args: scale: scale value to apply to the points. scaleAxis: which axes to scale and by what direction Returns: bool: True if successful. """ # would be great if vec3 was iterable axis = AXIS_NAME_TO_TUPLE_MAP.get(scaleAxis) if axis is None: raise KeyError("'" + scaleAxis + "' is not a valid axis. Valid axes are: " + ','.join(AXIS_NAME_TO_TUPLE_MAP.keys())) scaleList = [1.0, 1.0, 1.0] for i, x in enumerate(axis): if x != 0: scaleList[i] = scale * axis[i] return self.scalePoints(Vec3(scaleList[0], scaleList[1], scaleList[2]))
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(FKChainComponentGuide, self).getRigBuildData() numJoints = self.numJoints.getValue() # Calculate Xfos fw = Vec3(0, 0, 1) boneXfos = [] boneLengths = [] for i in xrange(numJoints): boneVec = self.jointCtrls[i + 1].xfo.tr.subtract( self.jointCtrls[i].xfo.tr) boneLengths.append(boneVec.length()) bone1Normal = fw.cross(boneVec).unit() bone1ZAxis = boneVec.cross(bone1Normal).unit() xfo = Xfo() xfo.setFromVectors(boneVec.unit(), bone1Normal, bone1ZAxis, self.jointCtrls[i].xfo.tr) boneXfos.append(xfo) data['boneXfos'] = boneXfos data['endXfo'] = self.jointCtrls[-1].xfo data['boneLengths'] = boneLengths return data
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(StretchyLimbComponentGuide, self).getRigBuildData() # Values startPos = self.upperCtl.xfo.tr midPos = self.lowerCtl.xfo.tr endPos = self.endCtl.xfo.tr # Calculate Upper Xfo startToEnd = endPos.subtract(startPos).unit() startToMid = midPos.subtract(startPos).unit() bone1Normal = startToEnd.cross(startToMid).unit() bone1ZAxis = startToMid.cross(bone1Normal).unit() upperXfo = Xfo() upperXfo.setFromVectors(startToMid, bone1Normal, bone1ZAxis, startPos) # Calculate Lower Xfo midToEnd = endPos.subtract(midPos).unit() midToStart = startPos.subtract(midPos).unit() bone2Normal = midToStart.cross(midToEnd).unit() bone2ZAxis = midToEnd.cross(bone2Normal).unit() lowerXfo = Xfo() lowerXfo.setFromVectors(midToEnd, bone2Normal, bone2ZAxis, midPos) upperLen = startPos.subtract(midPos).length() lowerLen = endPos.subtract(midPos).length() handleXfo = Xfo() handleXfo.tr = endPos endXfo = Xfo() endXfo.tr = endPos # endXfo.ori = lowerXfo.ori upVXfo = xfoFromDirAndUpV(startPos, endPos, midPos) upVXfo.tr = midPos upVXfo.tr = upVXfo.transformVector(Vec3(0, 0, 5)) data['upperXfo'] = upperXfo data['lowerXfo'] = lowerXfo data['endXfo'] = endXfo data['handleXfo'] = handleXfo data['upVXfo'] = upVXfo data['upperLen'] = upperLen data['lowerLen'] = lowerLen return data
def syncXfo(self, kObject): """Syncs the xfo from the DCC object to the Kraken object. Args: kObject (object): Object to sync the xfo for. Returns: Boolean: True if successful. """ hrcMap = self.getHierarchyMap() if kObject not in hrcMap.keys(): ogger.warning("SyncXfo: 3D Object '" + kObject.getName() + "' was not found in the mapping!") return False dccItem = hrcMap[kObject]['dccItem'] if dccItem is None: logger.warning("SyncXfo: Syncing. No DCC Item for :" + kObject.getPath()) return False dccPos = dccItem.getTranslation(space='world') dccQuat = dccItem.getRotation(space='world', quaternion=True).get() dccScl = dccItem.getScale() pos = Vec3(x=dccPos[0], y=dccPos[1], z=dccPos[2]) quat = Quat(v=Vec3(dccQuat[0], dccQuat[1], dccQuat[2]), w=dccQuat[3]) # If flag is set, pass the DCC Scale values. if kObject.testFlag('SYNC_SCALE') is True: scl = Vec3(x=dccScl[0], y=dccScl[1], z=dccScl[2]) else: scl = Vec3(1.0, 1.0, 1.0) newXfo = Xfo(tr=pos, ori=quat, sc=scl) kObject.xfo = newXfo return True
def updateNumJointControls(self, numJoints): """Load a saved guide representation from persisted data. Arguments: numJoints -- object, The number of joints inthe chain. Return: True if successful. """ if numJoints == 0: raise IndexError("'numJoints' must be > 0") if numJoints + 1 > len(self.jointCtrls): for i in xrange(len(self.jointCtrls), numJoints + 1): if i == 0: ctrlParent = self.ctrlCmpGrp else: ctrlParent = self.jointCtrls[i - 1] newCtrl = Control('chain' + str(i + 1).zfill(2), parent=ctrlParent, shape="sphere") newCtrl.scalePoints(Vec3(0.25, 0.25, 0.25)) # Generate thew new ctrl off the end of the existing one. newCtrl.xfo = self.jointCtrls[i - 1].xfo.multiply( Xfo(Vec3(10.0, 0.0, 0.0))) self.jointCtrls.append(newCtrl) elif numJoints + 1 < len(self.jointCtrls): numExtraCtrls = len(self.jointCtrls) - (numJoints + 1) for i in xrange(numExtraCtrls): extraCtrl = self.jointCtrls.pop() extraCtrl.getParent().removeChild(extraCtrl) # Reset the control positions based on new number of joints jointPositions = self.generateGuidePositions(numJoints) for i in xrange(len(self.jointCtrls)): self.jointCtrls[i].xfo.tr = jointPositions[i] return True