def build(self): ''' ''' super(Neck, self).build() jointList = eval(self.jointList) self.spline = spline.SplineBase(jointList=jointList + [self._skullBind], splineName=self._splineName) self.spline.create() grp = mc.rename(self.name, "{}_grp".format(self.name)) # Neck neckNul, neckOrt, neckCtrl = control.create(name="neck", controlType="cube", color=common.BLUE, hierarchy=['nul', "ort"]) matrix = mc.xform(jointList[0], q=True, ws=True, matrix=True) mc.xform(neckNul, ws=True, matrix=matrix) # Parent the entire ik group to the neck mc.parent(self.spline.getGroup(), neckCtrl) # head headNul, headCtrl = control.create(name="head", controlType="cube", color=common.BLUE, hierarchy=['nul']) # head gimabl control # head headGimbalNul, headGimbalCtrl = control.create(name="head_gimbal", controlType="cube", color=common.BLUE, hierarchy=['nul'], parent=headCtrl) clusters = self.spline._clusters con = mc.pointConstraint(jointList[0], self._skullBind, headNul) mc.delete(con) mc.parent(headNul, neckCtrl) mc.parent(clusters[2:], headGimbalCtrl) mc.orientConstraint(headGimbalCtrl, self.spline._endTwistNul, mo=1) skullOffset = mc.duplicate(self._skullBind, po=True, rr=True, name="{}_offset".format(self._skullBind))[0] mc.parent(skullOffset, headGimbalCtrl) mc.orientConstraint(skullOffset, self.spline._ikJointList[-1], mo=1) #mc.connectAttr(headCtrl+'.s', self._skullBind+'.s') anchor = self.getAttributeByName('anchor').getValue() if mc.objExists(anchor): mc.parentConstraint(anchor, neckNul, mo=1) else: mc.warning('Anchor object [ {} ] does not exist.'.format(anchor)) mc.parent(neckNul, grp) mc.hide(self.spline._group, clusters)
def build(self): ''' ''' super(Tongue, self).build() jointList = eval(self.jointList) self.spline = spline.SplineBase(jointList=jointList, splineName=self._splineName) self.spline.create() # Tongue Base tonugeBaseNul, tonugeBaseCtrl = control.create(name="tonuge_base", controlType=None, color=common.RED, hierarchy=['nul']) matrix = mc.xform(jointList[0], q=True, ws=True, matrix=True) mc.xform(tonugeBaseNul, ws=True, matrix=matrix) # Parent the entire ik group to the neck mc.parent(self.spline.getGroup(), tonugeBaseCtrl) # tongue Mid tonugeMidNul, tonugeMidCtrl = control.create(name="tonuge_mid", controlType=None, color=common.RED, hierarchy=['nul']) # move the middle control between the last the middle joints mc.delete(mc.parentConstraint(jointList[-2], jointList[1], tonugeMidNul)) mc.parent(tonugeMidNul, tonugeBaseCtrl) # tongue Tip tonugeTipNul, tonugeTipCtrl = control.create(name="tonuge_tip", controlType=None, color=common.RED, hierarchy=['nul']) # make the tongue tip matches the last joint in the chain matrix=mc.xform(jointList[-1], q=True, ws=True, matrix=True) mc.xform(tonugeTipNul, ws=True, matrix=matrix) clusters = self.spline._clusters mc.parent(tonugeTipNul, tonugeMidCtrl) mc.parent(clusters[2:], tonugeTipCtrl) mc.orientConstraint(tonugeTipCtrl, self.spline._endTwistNul, mo=1) #mc.parentConstraint(tonugeTipCtrl, self._skullBind, mo=1) #mc.connectAttr(headCtrl+'.s', self._skullBind+'.s') anchor = self.getAttributeByName('anchor').getValue() if mc.objExists(anchor): mc.parentConstraint(anchor, tonugeBaseNul, mo=1) else: mc.warning('Anchor object [ {} ] does not exist.'.format(anchor)) mc.parent(tonugeBaseNul, self.name) mc.hide(self.spline._group, clusters)
def build(self): ''' ''' super(Spine, self).build() # store the joint list jointList = eval(self.jointList) # initialize the spline class scaleFactor = self.getAttributeByName('scaleFactor').getValue() self.spline = spline.SplineBase(jointList=jointList + [self._chestBind], splineName=self._splineName, scaleFactor=scaleFactor) # create the spline self.spline.create() # get the name of the curveInfo node. This is hard coded to be this way in the # spline code. If that changes, this will not work. We can change the code below # to use the API to get the length of the curve instead of this node, but for now, this # is quicker because it's available already. spineCurveInfo = self._splineName + "_curveInfo" # get the attributes from the user geometry = self.getAttributeByName("geometry").getValue() bendyCurve = self.getAttributeByName("bendyCurve").getValue() createBendySpline = self.getAttributeByName( "createBendySpline").getValue() hipSwivelPivotValue = self.getAttributeByName( "hipSwivelPivot").getValue() chestPivotValue = self.getAttributeByName("chestPivot").getValue() # Hips hipMatrix = mc.xform(self._hipsBind, q=True, ws=True, matrix=True) hipsPivotNul, hipsPivotCtrl = control.create( name="hipsPivot", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul'], color=rigrepo.libs.common.RED) # create the grp that we will use to move the pivot of the hips movablePivotGrp = mc.createNode("transform", name="{}_grp".format(hipsPivotCtrl)) mc.xform(hipsPivotNul, ws=True, matrix=hipMatrix) mc.xform(movablePivotGrp, ws=True, matrix=hipMatrix) mc.parent(movablePivotGrp, hipsPivotNul) # connect the movable pivot control to the grp mc.connectAttr("{}.t".format(hipsPivotCtrl), "{}.rotatePivot".format(movablePivotGrp), f=True) mc.connectAttr("{}.r".format(hipsPivotCtrl), "{}.r".format(movablePivotGrp), f=True) hipsCtrlHierarchy = control.create(name="hips", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) hipsCtrl = hipsCtrlHierarchy[-1] hipsNul = hipsCtrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipsCtrl, ["sx", "sy", "sz", "v"]) mc.xform(hipsNul, ws=True, matrix=hipMatrix) hipsGimbalCtrlHierarchy = control.create( name="hips_gimbal", controlType="cube", hierarchy=['nul'], hideAttrs=["sx", "sy", "sz", "v"], parent=hipsCtrl) hipsGimbalCtrl = hipsGimbalCtrlHierarchy[-1] hipsGimbalNul = hipsGimbalCtrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipsGimbalCtrl, ["sx", "sy", "sz", "v"]) mc.xform(hipsGimbalNul, ws=True, matrix=hipMatrix) # hip swivel ctrlHierarchy = control.create(name="hip_swivel", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) hipSwivelCtrl = ctrlHierarchy[-1] hipSwivelNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipSwivelCtrl, ["sx", "sy", "sz", "v"]) mc.xform(hipSwivelNul, ws=True, matrix=hipMatrix) averagePos = rigrepo.libs.transform.getAveragePosition([jointList[0]]) mc.xform(hipSwivelNul, ws=True, t=mc.xform(jointList[0], q=True, ws=True, t=True)) mc.parent(hipSwivelNul, hipsGimbalCtrl) clusters = self.spline._clusters # create a group that is driven by the ctrl hipSwivelGrp = mc.createNode("transform", n="hips_swivel_grp") # move the group into the same matrix as the control mc.xform(hipSwivelGrp, ws=True, matrix=mc.xform(hipSwivelCtrl, q=True, ws=True, matrix=True)) # parent the group into the same space as the control mc.parent(hipSwivelGrp, hipSwivelCtrl) mc.parent(clusters[0:2], hipSwivelGrp) mc.orientConstraint(hipSwivelGrp, self.spline._startTwistNul, mo=1) # Parent the entire ik group to the hips mc.parent(self.spline.getGroup(), hipsGimbalCtrl) # torso ctrlHierarchy = control.create(name="torso", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) torsoCtrl = ctrlHierarchy[-1] torsoNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(torsoCtrl, ["sx", "sy", "sz", "v"]) rotation = mc.xform(hipsCtrl, q=True, ws=True, rotation=True) averagePos = rigrepo.libs.transform.getAveragePosition(jointList[:2]) mc.xform(torsoNul, ws=True, rotation=rotation) mc.xform(torsoNul, ws=True, t=averagePos) mc.parent(torsoNul, hipsGimbalCtrl) # chest ctrlHierarchy = control.create(name="chest", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestCtrl = ctrlHierarchy[-1] chestNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestCtrl, ["sx", "sy", "sz", "v"]) matrix = mc.xform(self._chestBind, q=True, ws=True, matrix=True) mc.xform(chestNul, ws=True, matrix=matrix) mc.parent(chestNul, torsoCtrl) # chest IK ctrlHierarchy = control.create(name="chest_ik", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestIkCtrl = ctrlHierarchy[-1] chestIkNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestIkCtrl, ["sx", "sy", "sz", "v"]) mc.xform(chestIkNul, ws=True, matrix=matrix) mc.parent(chestIkNul, chestCtrl) # connect the rotate pivots so the pivots for these two controls are in the same location. mc.connectAttr("{}.rp".format(chestCtrl), "{}.rp".format(chestIkCtrl), f=True) # chest top ctrlHierarchy = control.create(name="chest_top", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestTopCtrl = ctrlHierarchy[-1] chestTopNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestTopCtrl, ["sx", "sy", "sz", "v"]) mc.xform(chestTopNul, ws=True, matrix=matrix) mc.parent(chestTopNul, chestIkCtrl) mc.parent(clusters[2:], chestIkCtrl) chestTopGrp = mc.createNode("transform", name="chest_top_grp") mc.xform(chestTopGrp, ws=True, matrix=matrix) mc.parent(chestTopGrp, chestTopCtrl) mc.orientConstraint(chestTopGrp, self.spline._endTwistNul, mo=1) # ========================================================================================== # chest pivot # create pivot attributes to use for moving the pivot and tangent heights. mc.addAttr(chestCtrl, ln="pivotHeight", at="double", dv=0, min=0, max=10, keyable=True) mc.setAttr("{}.pivotHeight".format(chestCtrl), chestPivotValue) # create the remap node to use to remap the pivot height to the lenght of the curve chestRemapNode = mc.createNode("remapValue", n="chest_pivot_remap") # map the 0-10 to the length of the curve on the spine curveLength = mc.getAttr("{}.arcLength".format(spineCurveInfo)) # set the max output value for the remap to be the length of the curve mc.setAttr("{}.outputMax".format(chestRemapNode), curveLength) # set the input max mc.setAttr("{}.inputMax".format(chestRemapNode), 10) # connect the slider for pivot to the input max mc.connectAttr("{}.pivotHeight".format(chestCtrl), "{}.inputValue".format(chestRemapNode), f=True) # get the aim axis chestPivotNulGrp = mc.createNode("transform", name="chestPivot_aim_nul") chestPivotAimGrp = mc.createNode("transform", name="chestPivot_aim_grp") chestPivotDriver = mc.createNode("transform", name="chestPivot_aim_drv") mc.parent(chestPivotAimGrp, chestPivotNulGrp) mc.parent(chestPivotNulGrp, chestCtrl) mc.parent(chestPivotDriver, chestPivotAimGrp) mc.xform(chestPivotNulGrp, ws=True, matrix=matrix) mc.xform(chestPivotDriver, ws=True, matrix=hipMatrix) aimAxis, aimVector = self._getDistanceVector( mc.getAttr('{}.t'.format(chestPivotDriver))[0]) mc.parent(chestPivotNulGrp, chestNul) # move the transform back to the skull mc.xform(chestPivotDriver, ws=True, matrix=matrix) mc.xform(chestPivotNulGrp, ws=True, t=mc.xform(chestNul, q=True, ws=True, t=True)) mc.orientConstraint(chestNul, chestPivotNulGrp) mc.parent(chestPivotDriver, chestNul) mc.pointConstraint(chestPivotAimGrp, chestPivotDriver) mc.orientConstraint(chestPivotAimGrp, chestPivotDriver) if '-' in aimAxis: chestCtrlPivotMdl = mc.createNode('multDoubleLinear', n='chest_pivot_mdl') mc.connectAttr('{}.outValue'.format(chestRemapNode), '{}.input1'.format(chestCtrlPivotMdl), f=True) mc.setAttr('{}.input2'.format(chestCtrlPivotMdl), -1) mc.connectAttr('{}.output'.format(chestCtrlPivotMdl), '{}.t{}'.format(chestPivotAimGrp, aimAxis.strip('-')), f=True) mc.connectAttr('{}.t'.format(chestPivotDriver), '{}.rotatePivot'.format(chestCtrl), f=True) else: mc.connectAttr('{}.outValue'.format(chestRemapNode), '{}.t{}'.format(chestPivotAimGrp, aimAxis), f=True) mc.connectAttr('{}.t'.format(chestPivotDriver), '{}.rotatePivot'.format(chestCtrl), f=True) # ========================================================================================== # hip swivel pivot # create pivot attributes to use for moving the pivot and tangent heights. mc.addAttr(hipSwivelCtrl, ln="pivotHeight", at="double", dv=0, min=0, max=10, keyable=False) mc.setAttr("{}.pivotHeight".format(hipSwivelCtrl), hipSwivelPivotValue) # create the remap node to use to remap the pivot height to the lenght of the curve hipSwivelRemapNode = mc.createNode("remapValue", n="hipSwivel_pivot_remap") # set the max output value for the remap to be the length of the curve mc.setAttr("{}.outputMax".format(hipSwivelRemapNode), curveLength) # set the input max mc.setAttr("{}.inputMax".format(hipSwivelRemapNode), 10) # connect the slider for pivot to the input max mc.connectAttr("{}.pivotHeight".format(hipSwivelCtrl), "{}.inputValue".format(hipSwivelRemapNode), f=True) # get the aim axis tempNode = mc.createNode("transform", name="temp") mc.parent(tempNode, hipSwivelGrp) mc.xform(tempNode, ws=True, matrix=matrix) aimAxis, aimVector = self._getDistanceVector( mc.getAttr('{}.t'.format(tempNode))[0]) mc.delete(tempNode) if '-' in aimAxis: hipSwivelPivotMdl = mc.createNode('multDoubleLinear', n='hipSwivel_pivot_pma') mc.connectAttr("{}.outValue".format(hipSwivelRemapNode), '{}.input1'.format(hipSwivelPivotMdl), f=True) mc.setAttr('{}.input2'.format(hipSwivelPivotMdl), -1) mc.connectAttr('{}.output'.format(hipSwivelPivotMdl), '{}.rotatePivot{}'.format( hipSwivelCtrl, aimAxis.strip('-').capitalize()), f=True) else: mc.connectAttr("{}.outValue".format(hipSwivelRemapNode), '{}.rotatePivot{}'.format(hipSwivelCtrl, aimAxis.capitalize()), f=True) self._hipsCtrl = hipsCtrl self._hipSwivelCtrl = hipSwivelCtrl self._torsoCtrl = torsoCtrl self._chestCtrl = chestCtrl self._chestTopCtrl = chestTopCtrl self._chestIkCtrl = chestIkCtrl # Remove existing constraint on chestBind orientConstraint = mc.orientConstraint(self._chestBind, q=1) pointConstraint = mc.pointConstraint(self._chestBind, q=1) if orientConstraint: mc.delete(orientConstraint) if pointConstraint: mc.delete(pointConstraint) mc.pointConstraint(chestTopGrp, self._chestBind, mo=1) mc.orientConstraint(chestTopGrp, self._chestBind, mo=1) #mc.connectAttr(chestTopCtrl+'.s', self._chestBind+'.s') mc.parentConstraint(hipSwivelGrp, self._hipsBind, mo=1) mc.connectAttr(hipSwivelGrp + '.s', self._hipsBind + '.s') mc.parent(hipsPivotNul, self.name) mc.parent(hipsNul, movablePivotGrp) mc.hide(self.spline._group, clusters) if createBendySpline and mc.objExists(bendyCurve): bindmeshGeometry, follicleList, controlHieracrchyList, bendJointList = self.__buildCurveRig( bendyCurve, name='{}_bend'.format(self.getName()), parent=self.name) if mc.objExists(geometry): #deform the lid bindmesh with the lid curve using a wire deformer. wireDeformer = mc.wire(geometry, gw=False, en=1.00, ce=0.00, li=0.00, w=bendyCurve, name="{}_wire".format(bendyCurve))[0] baseCurveJointList = list() i = 0 for jnt, controlList in zip(bendJointList, controlHieracrchyList): # create the joint that we will use later to deform the base wire. baseCurveJoint = mc.joint( name=jnt.replace("_jnt", "_baseCurve_jnt")) baseCurveJointList.append(baseCurveJoint) # hide the base curve joint. Then parent it under the null node mc.setAttr("{}.v".format(baseCurveJoint), 0) mc.parent(baseCurveJoint, controlList[1]) mc.setAttr("{}.t".format(baseCurveJoint), 0, 0, 0) baseCurve = "{}BaseWire".format(bendyCurve) mc.parent([bendyCurve, baseCurve], self.name) baseCurveSkin = mc.skinCluster( *[baseCurveJointList] + mc.ls(baseCurve), n="{}_skinCluster".format(baseCurve), tsb=True)[0] # set the default values for the wire deformer mc.setAttr("{}.rotation".format(wireDeformer), 0) mc.setAttr("{}.dropoffDistance[0]".format(wireDeformer), 100) bindMeshSkin = mc.skinCluster( *jointList + [self._hipsBind, self._chestBind] + mc.ls(bindmeshGeometry), n="{}_skinCluster".format(bindmeshGeometry), tsb=True)[0] mc.skinPercent(bindMeshSkin, '{}.vtx[0:3]'.format(bindmeshGeometry), transformValue=[(self._hipsBind, 1.0), (jointList[0], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[4:7]'.format(bindmeshGeometry), transformValue=[(jointList[0], 0.0), (jointList[1], 1.0), (jointList[2], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[8:11]'.format(bindmeshGeometry), transformValue=[(jointList[3], 1.0), (jointList[1], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[12:15]'.format(bindmeshGeometry), transformValue=[(jointList[2], 0.0), (jointList[4], 0.0), (self._chestBind, 1.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[16:19]'.format(bindmeshGeometry), transformValue=[(self._chestBind, 1.0), (jointList[1], 0.0), (jointList[2], 0.0)]) # ------------------------------------------------------------------------------------ # Length Preservation # ------------------------------------------------------------------------------------ spline.preserveLength(name='spineIk_length', curve='spineIk_curve', primary_control='chest', rotate_controls=['torso', 'chest', 'chest_ik'], no_rotate_cvs=[2, 3], parent='spine', position_output_child='chest_top_nul')
def build(self): ''' ''' super(Neck, self).build() jointList = eval(self.jointList) headPivotValue = self.getAttributeByName("headPivot").getValue() scaleFactor = self.getAttributeByName('scaleFactor').getValue() self.spline = spline.SplineBase(jointList=jointList + [self._skullBind], splineName=self._splineName, scaleFactor=scaleFactor) self.spline.create() # get the name of the curveInfo node. This is hard coded to be this way in the # spline code. If that changes, this will not work. We can change the code below # to use the API to get the length of the curve instead of this node, but for now, this # is quicker because it's available already. spineCurveInfo = self._splineName + "_curveInfo" grp = mc.rename(self.name, "{}_grp".format(self.name)) # Neck neckNul, neckOrt, neckCtrl = control.create(name="neck", controlType="cube", color=common.BLUE, hierarchy=['nul', "ort"]) matrix = mc.xform(jointList[0], q=True, ws=True, matrix=True) mc.xform(neckNul, ws=True, matrix=matrix) # Parent the entire ik group to the neck mc.parent(self.spline.getGroup(), neckCtrl) # head headNul, headCtrl = control.create(name="head", controlType="cube", color=common.BLUE, hierarchy=['nul']) # head gimabl control # head headGimbalNul, headGimbalCtrl = control.create(name="head_gimbal", controlType="cube", color=common.BLUE, hierarchy=['nul'], parent=headCtrl) clusters = self.spline._clusters headGimbalGrp = mc.createNode("transform", n="head_gimbal_grp") # move the group into the same matrix as the control mc.xform(headGimbalGrp, ws=True, matrix=mc.xform(headGimbalCtrl, q=True, ws=True, matrix=True)) # parent the group into the same space as the control mc.parent(headGimbalGrp, headGimbalCtrl) # constrain the gimbal group to the gimbal control mc.connectAttr("{}.rp".format(headCtrl), "{}.rp".format(headGimbalCtrl), f=True) #mc.connectAttr("{}.rp".format(headGimbalCtrl), "{}.rp".format(headGimbalGrp), f=True) #mc.pointConstraint(headGimbalCtrl, headGimbalGrp) #mc.orientConstraint(headGimbalCtrl, headGimbalGrp) #mc.scaleConstraint(headGimbalCtrl, headGimbalGrp) # make sure the nul is where the joint is mc.xform(headNul, ws=True, t=mc.xform(self._skullBind, q=True, ws=True, t=True)) # tangent will be figured out later. #mc.addAttr(hipSwivelCtrl, ln="tangentHeight", at="double", dv=0, min=0, max=4, keyable=False) # make sure the nul is where the joint is mc.xform(headNul, ws=True, t=mc.xform(self._skullBind, q=True, ws=True, t=True)) # create pivot attributes to use for moving the pivot and tangent heights. mc.addAttr(headCtrl, ln="pivotHeight", at="double", dv=0, min=0, max=10, keyable=False) mc.setAttr("{}.pivotHeight".format(headCtrl), headPivotValue) # create the remap node to use to remap the pivot height to the lenght of the curve headRemapNode = mc.createNode("remapValue", n="head_pivot_remap") # map the 0-10 to the length of the curve on the spine curveLength = mc.getAttr("{}.arcLength".format(spineCurveInfo)) # set the max output value for the remap to be the length of the curve mc.setAttr("{}.outputMax".format(headRemapNode), curveLength) # set the input max mc.setAttr("{}.inputMax".format(headRemapNode), 10) # connect the slider for pivot to the input max mc.connectAttr("{}.pivotHeight".format(headCtrl), "{}.inputValue".format(headRemapNode), f=True) # get the aim axis headPivotNulGrp = mc.createNode("transform", name="headPivot_aim_nul") headPivotAimGrp = mc.createNode("transform", name="headPivot_aim_grp") headPivotDriver = mc.createNode("transform", name="headPivot_aim_drv") mc.parent(headPivotAimGrp, headPivotNulGrp) mc.parent(headPivotNulGrp, headGimbalGrp) mc.parent(headPivotDriver, headPivotAimGrp) mc.xform(headPivotNulGrp, ws=True, matrix=matrix) # get the aim axis aimAxis = rigrepo.libs.transform.getAimAxis(headGimbalGrp) mc.parent(headPivotNulGrp, headNul) vector = om.MVector(*mc.getAttr("{}.t".format(headPivotNulGrp))) vector.normalize() distanceValue = max(vector, key=abs) index = (vector.x, vector.y, vector.z).index(distanceValue) aimVector = list() for i in range(len(vector)): if i == index: aimVector.append(1) else: aimVector.append(0) # move the transform back to the skull mc.xform(headPivotNulGrp, ws=True, matrix=mc.xform(headCtrl, q=True, ws=True, matrix=True)) mc.parent(headPivotDriver, headNul) mc.pointConstraint(headPivotAimGrp, headPivotDriver, mo=False) mc.orientConstraint(headPivotAimGrp, headPivotDriver, mo=False) mc.aimConstraint(neckCtrl, headPivotAimGrp, w=1, upVector=(0, 0, 0), aimVector=aimVector, wut="none") if '-' in aimAxis: headCtrlPivotMdl = mc.createNode('multDoubleLinear', n='head_pivot_mdl') mc.connectAttr('{}.outValue'.format(headRemapNode), '{}.input1'.format(headCtrlPivotMdl), f=True) mc.setAttr('{}.input2'.format(headCtrlPivotMdl), -1) mc.connectAttr('{}.output'.format(headCtrlPivotMdl), '{}.t{}'.format(headPivotAimGrp, aimAxis.strip('-')), f=True) mc.connectAttr('{}.t'.format(headPivotDriver), '{}.rotatePivot'.format(headCtrl), f=True) else: mc.connectAttr('{}.outValue'.format(headRemapNode), '{}.t{}'.format(headPivotAimGrp, aimAxis), f=True) mc.connectAttr('{}.t'.format(headPivotDriver), '{}.rotatePivot'.format(headCtrl), f=True) mc.parent(headNul, neckCtrl) mc.parent(clusters[2:], headGimbalGrp) mc.orientConstraint(headGimbalGrp, self.spline._endTwistNul, mo=1) # make the offset joint for the skull skullOffset = mc.duplicate(self._skullBind, po=True, rr=True, name="{}_offset".format(self._skullBind))[0] mc.setAttr(skullOffset + '.v', 0) mc.parent(skullOffset, headGimbalGrp) mc.orientConstraint(skullOffset, self.spline._ikJointList[-1], mo=1) # connect the scale of the gimbal group to the scale of skull bind headScaleMdn = mc.createNode("multiplyDivide", n="head_scale_mdn") mc.connectAttr("{}.s".format(headCtrl), "{}.input1".format(headScaleMdn), f=True) mc.connectAttr("{}.s".format(headGimbalCtrl), "{}.input2".format(headScaleMdn), f=True) mc.connectAttr("{}.output".format(headScaleMdn), "{}.s".format(self._skullBind), f=True) anchor = self.getAttributeByName('anchor').getValue() if mc.objExists(anchor): mc.parentConstraint(anchor, neckNul, mo=1) else: mc.warning('Anchor object [ {} ] does not exist.'.format(anchor)) mc.parent(neckNul, grp) mc.hide(self.spline._group, clusters) # Head psd driver driver_nul = mc.duplicate(headNul, po=1, n='head_driver_nul')[0] driver = mc.createNode('transform', n='head_driver', p=driver_nul) mc.orientConstraint(headCtrl, driver)
def build(self): ''' ''' super(Spine, self).build() jointList = eval(self.jointList) self.spline = spline.SplineBase(jointList=jointList + [self._chestBind], splineName=self._splineName) self.spline.create() # get the attributes from the user geometry = self.getAttributeByName("geometry").getValue() bendyCurve = self.getAttributeByName("bendyCurve").getValue() createBendySpline = self.getAttributeByName( "createBendySpline").getValue() # Hips hipsCtrlHierarchy = control.create(name="hips", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) hipsCtrl = hipsCtrlHierarchy[-1] hipsNul = hipsCtrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipsCtrl, ["sx", "sy", "sz", "v"]) matrix = mc.xform(self._hipsBind, q=True, ws=True, matrix=True) mc.xform(hipsNul, ws=True, matrix=matrix) hipsGimbalCtrlHierarchy = control.create( name="hips_gimbal", controlType="cube", hierarchy=['nul'], hideAttrs=["sx", "sy", "sz", "v"], parent=hipsCtrl) hipsGimbalCtrl = hipsGimbalCtrlHierarchy[-1] hipsGimbalNul = hipsGimbalCtrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipsGimbalCtrl, ["sx", "sy", "sz", "v"]) mc.xform(hipsGimbalNul, ws=True, matrix=matrix) # hip swivel ctrlHierarchy = control.create(name="hip_swivel", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) hipSwivelCtrl = ctrlHierarchy[-1] hipSwivelNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(hipSwivelCtrl, ["sx", "sy", "sz", "v"]) mc.xform(hipSwivelNul, ws=True, matrix=matrix) averagePos = rigrepo.libs.transform.getAveragePosition(jointList[0:3]) mc.xform(hipSwivelNul, ws=True, t=averagePos) mc.parent(hipSwivelNul, hipsGimbalCtrl) clusters = self.spline._clusters mc.parent(clusters[0:2], hipSwivelCtrl) mc.orientConstraint(hipSwivelCtrl, self.spline._startTwistNul, mo=1) # Parent the entire ik group to the hips mc.parent(self.spline.getGroup(), hipsGimbalCtrl) # torso ctrlHierarchy = control.create(name="torso", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) torsoCtrl = ctrlHierarchy[-1] torsoNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(torsoCtrl, ["sx", "sy", "sz", "v"]) rotation = mc.xform(hipsCtrl, q=True, ws=True, rotation=True) averagePos = rigrepo.libs.transform.getAveragePosition(jointList[:2]) mc.xform(torsoNul, ws=True, rotation=rotation) mc.xform(torsoNul, ws=True, t=averagePos) mc.parent(torsoNul, hipsGimbalCtrl) # chest ctrlHierarchy = control.create(name="chest", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestCtrl = ctrlHierarchy[-1] chestNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestCtrl, ["sx", "sy", "sz", "v"]) matrix = mc.xform(jointList[-3], q=True, ws=True, matrix=True) averagePos = rigrepo.libs.transform.getAveragePosition( jointList[-3:-1]) mc.xform(chestNul, ws=True, matrix=matrix) mc.xform(chestNul, ws=True, t=averagePos) mc.parent(chestNul, torsoCtrl) # chest IK ctrlHierarchy = control.create(name="chest_ik", controlType="cube", color=common.GREEN, hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestIkCtrl = ctrlHierarchy[-1] chestIkNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestIkCtrl, ["sx", "sy", "sz", "v"]) mc.xform(chestIkNul, ws=True, matrix=matrix) mc.xform(chestIkNul, ws=True, t=averagePos) mc.parent(chestIkNul, chestCtrl) # chest top ctrlHierarchy = control.create(name="chest_top", controlType="cube", hideAttrs=["sx", "sy", "sz", "v"], hierarchy=['nul']) chestTopCtrl = ctrlHierarchy[-1] chestTopNul = ctrlHierarchy[0] rigrepo.libs.attribute.lockAndHide(chestTopCtrl, ["sx", "sy", "sz", "v"]) matrix = mc.xform(self._chestBind, q=True, ws=True, matrix=True) mc.xform(chestTopNul, ws=True, matrix=matrix) mc.parent(chestTopNul, chestIkCtrl) mc.parent(clusters[2:], chestIkCtrl) mc.orientConstraint(chestTopCtrl, self.spline._endTwistNul, mo=1) self._hipsCtrl = hipsCtrl self._hipSwivelCtrl = hipSwivelCtrl self._torsoCtrl = torsoCtrl self._chestCtrl = chestCtrl self._chestTopCtrl = chestTopCtrl self._chestIkCtrl = chestIkCtrl # Remove existing constraint on chestBind orientConstraint = mc.orientConstraint(self._chestBind, q=1) pointConstraint = mc.pointConstraint(self._chestBind, q=1) if orientConstraint: mc.delete(orientConstraint) if pointConstraint: mc.delete(pointConstraint) mc.pointConstraint(chestTopCtrl, self._chestBind, mo=1) mc.orientConstraint(chestTopCtrl, self._chestBind, mo=1) #mc.connectAttr(chestTopCtrl+'.s', self._chestBind+'.s') mc.parentConstraint(hipSwivelCtrl, self._hipsBind, mo=1) mc.connectAttr(hipSwivelCtrl + '.s', self._hipsBind + '.s') mc.parent(hipsNul, self.name) mc.hide(self.spline._group, clusters) if createBendySpline and mc.objExists(bendyCurve): bindmeshGeometry, follicleList, controlHieracrchyList, bendJointList = self.__buildCurveRig( bendyCurve, name='{}_bend'.format(self.getName()), parent=self.name) if mc.objExists(geometry): #deform the lid bindmesh with the lid curve using a wire deformer. wireDeformer = mc.wire(geometry, gw=False, en=1.00, ce=0.00, li=0.00, w=bendyCurve, name="{}_wire".format(bendyCurve))[0] baseCurveJointList = list() i = 0 for jnt, controlList in zip(bendJointList, controlHieracrchyList): # create the joint that we will use later to deform the base wire. baseCurveJoint = mc.joint( name=jnt.replace("_jnt", "_baseCurve_jnt")) baseCurveJointList.append(baseCurveJoint) # hide the base curve joint. Then parent it under the null node mc.setAttr("{}.v".format(baseCurveJoint), 0) mc.parent(baseCurveJoint, controlList[1]) mc.setAttr("{}.t".format(baseCurveJoint), 0, 0, 0) baseCurve = "{}BaseWire".format(bendyCurve) mc.parent([bendyCurve, baseCurve], self.name) baseCurveSkin = mc.skinCluster( *[baseCurveJointList] + mc.ls(baseCurve), n="{}_skinCluster".format(baseCurve), tsb=True)[0] # set the default values for the wire deformer mc.setAttr("{}.rotation".format(wireDeformer), 0) mc.setAttr("{}.dropoffDistance[0]".format(wireDeformer), 100) bindMeshSkin = mc.skinCluster( *jointList + [self._hipsBind, self._chestBind] + mc.ls(bindmeshGeometry), n="{}_skinCluster".format(bindmeshGeometry), tsb=True)[0] mc.skinPercent(bindMeshSkin, '{}.vtx[0:3]'.format(bindmeshGeometry), transformValue=[(self._hipsBind, 1.0), (jointList[0], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[4:7]'.format(bindmeshGeometry), transformValue=[(jointList[0], 0.0), (jointList[1], 0.5), (jointList[2], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[8:11]'.format(bindmeshGeometry), transformValue=[(jointList[3], 1.0), (jointList[1], 0.0)]) mc.skinPercent(bindMeshSkin, '{}.vtx[12:15]'.format(bindmeshGeometry), transformValue=[(jointList[2], 0.0), (jointList[4], 0.5), (self._chestBind, .5)]) mc.skinPercent(bindMeshSkin, '{}.vtx[16:19]'.format(bindmeshGeometry), transformValue=[(self._chestBind, 1.0), (jointList[1], 0.0), (jointList[2], 0.0)])