def split_joint (joint, splits): #check if joint have child joint if not joint.getChildren(type='joint'): return prefix = joint.name() # Determine Amount of Spacing endJoint = joint.getChildren(type='joint')[0] spacing = endJoint.tx.get() / (splits + 1) # Split Joints split_joints = [] radius = joint.radius.get() for x in range (1, splits + 1) : newJoint = pm.PyNode(pm.insertJoint(joint)) newJoint.radius.set(radius) newJoint.rename("%s_split_%d" %(prefix, x)) newJoint.tx.set(spacing) split_joints.append(newJoint) joint = newJoint endJoint.tx.set(spacing) return split_joints
def placeJointChain(startLoc, endLoc, numJoints=3, parent=None, name='jointChain'): joints = [] startJoint = placeJoint( getWsLocation(startLoc), name = '%s%02d' % (name, 1), parent = parent) endJoint = placeJoint( getWsLocation(endLoc), name = '%s%02d' % (name, numJoints), parent = startJoint) dist = endJoint.getTranslation() dist = dist / float(numJoints-1) joints.append(startJoint) for i in range(2,numJoints): insideJoint = pm.insertJoint(joints[-1]) insideJoint = toPmNodes(insideJoint)[0] insideJoint = pm.rename(insideJoint, '%s%02d' % (name, i)) insideJoint.translateBy(dist) endJoint.translateBy(-dist) joints.append(insideJoint) joints.append(endJoint) return joints
def addManyJoint(firstJoint, secondJoint, num=1): jointRadius = firstJoint.getRadius() firstPoint = firstJoint.getTranslation(space='world') secondPoint = secondJoint.getTranslation(space='world') for n in range(0,num): newJoint = pm.insertJoint(firstJoint) #追加したジョイントの位置を計算する px = secondPoint[0] + (((firstPoint[0]-secondPoint[0])/(num+1))*(n+1)) py = secondPoint[1] + (((firstPoint[1]-secondPoint[1])/(num+1))*(n+1)) pz = secondPoint[2] + (((firstPoint[2]-secondPoint[2])/(num+1))*(n+1)) #newJointはunicode型なのでpyMelの機能が使えない。ここではcmdsを使用する cmds.joint(newJoint, e=True, component=True, position=[px, py, pz], radius=jointRadius)
def split_joints(n=5): selection = ls(selection=True) if JointSplitter.validate_for_split_joint(selection): first_joint = ls(selection=True)[0] fj = pm.joint(pm.general.ls(selection=True)[0], query=True, position=True) lj = pm.joint(pm.general.ls(selection=True)[1], query=True, position=True) fj_vector = dt.Vector(fj[0], fj[1], fj[2]) lj_vector = dt.Vector(lj[0], lj[1], lj[2]) new_joint = 0 pm.select(deselect=True) for i in range(0, n - 1): split_point = fj_vector.__mul__((n - i - 1.0) / n).__add__(lj_vector.__mul__(i + 1.0) / n) new_joint = pm.insertJoint(new_joint if i > 0 else first_joint) pm.joint(new_joint, edit=True, component=True, position=split_point)
def split_joints(first_joint, second_joint, n=5): if not (first_joint or second_joint): return -1 JointSplitter.flatten_joints(first_joint, second_joint) fj = pm.joint(first_joint, query=True, position=True) lj = pm.joint(second_joint, query=True, position=True) fj_vector = dt.Vector(fj[0], fj[1], fj[2]) lj_vector = dt.Vector(lj[0], lj[1], lj[2]) new_joint = None pm.select(deselect=True) for i in range(0, n - 1): split_point = fj_vector.__mul__( (n - i - 1.0) / n).__add__(lj_vector.__mul__(i + 1.0) / n) new_joint = pm.insertJoint(new_joint if i > 0 else first_joint) pm.joint(new_joint, edit=True, component=True, position=split_point) pm.select(d=True)
def makeJointHair(self, sel, hairSystem): simDuped = pm.duplicate(sel, n='sim_%s' % sel.nodeName())[0] mixDuped = pm.duplicate(sel, n='mix_%s' % sel.nodeName())[0] wgtDuped = pm.duplicate(sel, n='weight_%s' % sel.nodeName())[0] selJointList = self.getJointChainList(sel) simJointList = self.getJointChainList(simDuped) mixJointList = self.getJointChainList(mixDuped) wgtJointList = self.getJointChainList(wgtDuped) if not (selJointList and simJointList and mixJointList): return False num = len(selJointList) pos = sel.getTranslation(space='world') ctrlGrp = pm.group(n='%s_ctrls#' % sel.nodeName(), em=1) axis, circle = self.makeXformController( '%s_top_ctrl#' % sel.nodeName(), '%s_top_ctrl_axis#' % sel.nodeName(), selJointList[0]) circle.addAttr('space', at='enum', en='World:Local', k=1, dv=self.dnspRBGval - 1) circle.addAttr('ctrl_size', at='double', k=1, dv=1.0) circle.attr('ctrl_size') >> circle.attr('scaleX') circle.attr('ctrl_size') >> circle.attr('scaleY') circle.attr('ctrl_size') >> circle.attr('scaleZ') pntMatrix = [] skclList = list(set(sel.outputs(type='skinCluster'))) for i in xrange(num): if i != 0: pm.rename(simJointList[i], 'sim_%s' % simJointList[i].nodeName()) pm.rename(mixJointList[i], 'mix_%s' % mixJointList[i].nodeName()) pos = selJointList[i].getTranslation(space='world') ofstJoint = pm.rename( pm.insertJoint(mixJointList[i]), mixJointList[i].nodeName().replace('mix', 'offset')) pntMatrix.append(pos) attrList = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz'] for attr in attrList: simJointList[i].attr(attr) >> mixJointList[i].attr(attr) pm.parentConstraint(ofstJoint, selJointList[i], mo=True) mixJointList[i].attr('radius').set(0.0) ofstJoint.attr('radius').set(0.0) if not (i == num - 1 and not self.pctlCBXval): ''' # If on, no controllers will be created to the joints which does't have any skinCluster for skcl in skclList: if selJointList[i] in skcl.getInfluence(): break else: continue ''' if self.ctshRBGval == 1: ctrl = self.makeCircleController( '%s_ctrl' % selJointList[i].nodeName()) elif self.ctshRBGval == 2: ctrl = self.makePinController('%s_ctrl' % selJointList[i].nodeName()) elif self.ctshRBGval == 3: ctrl = self.makeOctaController('%s_ctrl' % selJointList[i].nodeName()) ctrl.attr('overrideEnabled').set(1) ctrl.attr('overrideColor').set((self.colrPLTval)) ctrlAxis = pm.group(ctrl, n='%s_ctrl_axis' % selJointList[i].nodeName()) ctrlAxis.attr('rotatePivot').set([0, 0, 0]) ctrlAxis.attr('scalePivot').set([0, 0, 0]) circle.attr('ctrl_size') >> ctrl.attr('scaleX') circle.attr('ctrl_size') >> ctrl.attr('scaleY') circle.attr('ctrl_size') >> ctrl.attr('scaleZ') pm.parentConstraint(mixJointList[i], ctrlAxis) pm.parentConstraint(ctrl, ofstJoint) pm.parent(ctrlAxis, ctrlGrp) # Pour weights to simJointList temporarily for skcl in skclList: if selJointList[i] in skcl.getInfluence(): skcl.addInfluence(wgtJointList[i], wt=0) inflList = skcl.getInfluence() isMaintainMax = skcl.attr('maintainMaxInfluences').get() maxInfl = skcl.attr('maxInfluences').get() isFullInfl = False if isMaintainMax and maxInfl == len(inflList): isFullInfl = True skcl.attr('maintainMaxInfluences').set(False) for infl in inflList: if infl == selJointList[i] or infl == wgtJointList[i]: infl.attr('lockInfluenceWeights').set(False) else: infl.attr('lockInfluenceWeights').set(True) for geo in skcl.getGeometry(): pm.skinPercent(skcl, geo.verts, nrm=True, tv=[selJointList[i], 0]) skcl.removeInfluence(selJointList[i]) if isFullInfl: skcl.attr('maintainMaxInfluences').set(True) crv1d = pm.curve(d=1, p=pntMatrix) crv = pm.fitBspline(crv1d, ch=1, tol=0.001) follicle, hcrv, hairSystem = self.assignHair(crv, hairSystem) follicleGrp = follicle.getParent() curveGrp = hcrv.getParent() ikhandle = pm.ikHandle(sj=simJointList[0], ee=simJointList[num - 1], c=hcrv, createCurve=0, solver='ikSplineSolver')[0] # Pour back for i in xrange(num): for skcl in skclList: if wgtJointList[i] in skcl.getInfluence(): skcl.addInfluence(selJointList[i], wt=0) inflList = skcl.getInfluence() isMaintainMax = skcl.attr('maintainMaxInfluences').get() maxInfl = skcl.attr('maxInfluences').get() isFullInfl = False if isMaintainMax and maxInfl == len(inflList): isFullInfl = True skcl.attr('maintainMaxInfluences').set(False) for infl in inflList: if infl == selJointList[i] or infl == wgtJointList[i]: infl.attr('lockInfluenceWeights').set(False) else: infl.attr('lockInfluenceWeights').set(True) for geo in skcl.getGeometry(): pm.skinPercent(skcl, geo.verts, nrm=True, tv=[wgtJointList[i], 0]) for infl in inflList: infl.attr('lockInfluenceWeights').set(False) attrList = [ wgtJointList[i].attr('message'), wgtJointList[i].attr('bindPose') ] for attr in attrList: for dst in pm.connectionInfo(attr, dfs=True): dst = pm.Attribute(dst) if dst.node().type() == 'dagPose': attr // dst if isFullInfl: skcl.attr('maintainMaxInfluences').set(True) pm.delete(wgtJointList) simGrp = pm.group(simJointList[0], follicle, n='sim_joints#') xformer = pm.group(simGrp, mixJointList[0], selJointList[0], n='%s_transformer#' % sel.nodeName()) hcrv.attr('scalePivot').set( selJointList[0].getTranslation(space='world')) hcrv.attr('rotatePivot').set( selJointList[0].getTranslation(space='world')) ctrlGrp.attr('scalePivot').set( selJointList[0].getTranslation(space='world')) ctrlGrp.attr('rotatePivot').set( selJointList[0].getTranslation(space='world')) simGrp.attr('scalePivot').set( selJointList[0].getTranslation(space='world')) simGrp.attr('rotatePivot').set( selJointList[0].getTranslation(space='world')) mixJointList[0].attr('template').set(1) hcrv.attr('template').set(1) hairSystem.attr('iterations').set(20) xformer.attr('scalePivot').set(axis.getTranslation()) xformer.attr('rotatePivot').set(axis.getTranslation()) wcnst = pm.parentConstraint(circle, hcrv, mo=True) lcnst = pm.parentConstraint(circle, xformer, mo=True) rev = pm.shadingNode('reverse', asUtility=True) circle.attr('space') >> wcnst.attr('%sW0' % wcnst.getTargetList()[0]) circle.attr('space') >> rev.attr('inputX') rev.attr('outputX') >> lcnst.attr('%sW0' % lcnst.getTargetList()[0]) pm.delete(follicleGrp, curveGrp, crv1d) pm.hide(simGrp) crvGrp = self.makeGroupIfNotExist('hairSystemOutputCurves', 0) ikGrp = self.makeGroupIfNotExist('hairSystemIKHandles', 1) nodesGrp = self.makeGroupIfNotExist('hairSystemNodes', 1) pm.parent(hcrv, crvGrp) pm.parent(ikhandle, ikGrp) if hairSystem.getParent() != nodesGrp: pm.parent(hairSystem, nodesGrp) if not pm.objExists(self.topName): topGrp = pm.group(n=self.topName, em=1) pm.parent(nodesGrp, ikGrp, crvGrp, xformer, axis, ctrlGrp, topGrp) else: pm.parent(xformer, axis, ctrlGrp, self.topName) topNode = pm.PyNode(self.topName) self.lockXformAttrs(topNode, False) self.lockXformAttrs(ctrlGrp, False) self.lockXformAttrs(crvGrp, False) self.lockXformAttrs(ikGrp, False) self.lockXformAttrs(nodesGrp, False) pm.select(topNode, r=1) self.selList.pop(0) windowName = 'hairSystem_Window' if pm.window(windowName, ex=1): pm.deleteUI(windowName) if self.selList: self.dialog(self.selList[0]) pm.displayInfo('"Make Joint Hair" has been successfully done.') return True
def createIKspline(IK_chain = None, ikSpineGrp = None): """ maj: x-- add pelvis control -- add follow on mid ctrl debug: -- orient ik mid ctrl in the same orientation then other controllers """ # insert joints # global IKjointList, dwCtrl,upCtrl IKjointList = [] jointIt = 3 for jnt in IK_chain: IKjointList.append(jnt) child = jnt.getChildren() if len(child)>0: num = jointIt rad = pm.joint(jnt, query = True , radius = True)[0] dist = pm.joint(child[0], query = True , relative = True, position = True)[0] gap = dist/(num) for i in range((num-1),0,-1): newJnt = pm.insertJoint(jnt) pm.joint( newJnt, edit = True,component = True, relative = True, radius = rad, position = ((gap*i),0,0)) IKjointList.append(newJnt) # create ikhandle IKspine = pm.ikHandle(solver = "ikSplineSolver", name = "IKspine", simplifyCurve = True, startJoint = IK_chain[0], endEffector = IK_chain[(len(IK_chain)-1)], createCurve = True, numSpans = 4) IKhandle = IKspine[0] IKcurve = IKspine[2] IKhandle.setParent(ikSpineGrp) curveJointList = pm.ikHandle(IKhandle, query = True, jointList = True) # create clusters on point cvsList = (IKcurve.getShape()).getCVs() clusterGrp = pm.group(name = "cluster_grp", empty = True) clusterGrp.setParent(ikSpineGrp) ctrlGrp = pm.group(name = "IK_ctrls_grp", empty = True) ctrlGrp.setParent(ikSpineGrp) # parent cluster to sphere ctrlList = [] clusterList = [] for i,cv in enumerate(cvsList): cluster = pm.cluster("curve1.cv[%s]" % i) cluster[0].setAttr("relative", 1) tmpCluster = cluster[1] tmpCluster.setParent(clusterGrp) clusterList.append(tmpCluster) oneCtrl = helpers.createNurbsSphere(rad = 0.5) ctrlList.append(oneCtrl) # oneCtrl.setParent(ctrlGrp) tmpPoint = pm.pointConstraint(tmpCluster, oneCtrl) pm.delete(tmpPoint) pm.pointConstraint(oneCtrl, tmpCluster) for c in ctrlList: c.setParent(ctrlGrp) ctrlListGrp = helpers.insertGroups(ctrlList) # create main ctrls # orient up and down ctrls as joint selection upCtrlGrp, upCtrl = helpers.createOneCircle([1,0,0], sel = sel[0], rad = 4, suf= "_IK_ctrl") dwCtrlGrp, dwCtrl = helpers.createOneCircle([1,0,0], sel = sel[len(sel)-1], rad = 4, suf= "_IK_ctrl") idMid = int((pm.datatypes.round(float(len(ctrlListGrp))/2)) - 1) midCtrlGrp, midCtrl = helpers.createOneCircle([0,1,0], sel = ctrlList[idMid], rad = 4, suf= "_IK_ctrl") upCtrlGrp.setParent(ctrlGrp) dwCtrlGrp.setParent(ctrlGrp) midCtrlGrp.setParent(ctrlGrp) upLoc = helpers.createOneLoc(parentToWorld = False, s = upCtrl) dwLoc = helpers.createOneLoc(parentToWorld = False, s = dwCtrl) upLoc.setAttr("tz", 2) dwLoc.setAttr("tz", 2) # parent sphere ctrls to main ctrls ctrlListGrp[0].setParent(upCtrl) ctrlListGrp[1].setParent(upCtrl) ctrlListGrp[idMid - 1].setParent(midCtrl) ctrlListGrp[idMid].setParent(midCtrl) ctrlListGrp[idMid + 1].setParent(midCtrl) ctrlListGrp[(len(ctrlListGrp)-2)].setParent(dwCtrl) ctrlListGrp[(len(ctrlListGrp)-1)].setParent(dwCtrl) # add twist IKhandle.setAttr("dTwistControlEnable", 1) IKhandle.setAttr("dWorldUpType", 2) IKhandle.setAttr("dWorldUpAxis", 3) pm.connectAttr(upLoc.worldMatrix, IKhandle.dWorldUpMatrix, force = True) pm.connectAttr(dwLoc.worldMatrix, IKhandle.dWorldUpMatrixEnd, force = True) #### add stretch # add parameters on upper control pm.addAttr(dwCtrl, longName = "________", attributeType = "enum", enumName = "CTRLS:") pm.setAttr(dwCtrl.________, keyable = True, lock = True) # make stretch editable pm.addAttr(dwCtrl, longName = "stretch", attributeType = "double", min = 0, max = 1, dv = 0) # pm.addAttr(dwCtrl, longName = "squash", attributeType = "double", min = 0, max = 1, dv = 0) pm.addAttr(dwCtrl, longName = "followJoint", attributeType = "double", min = 0, max = 1, dv = 1) pm.addAttr(dwCtrl, longName = "followCtrl", attributeType = "double", min = 0, max = 1, dv = 0) pm.setAttr(dwCtrl.stretch, keyable = True) # pm.setAttr(dwCtrl.squash, keyable = True) pm.setAttr(dwCtrl.followJoint, keyable = True) pm.setAttr(dwCtrl.followCtrl, keyable = True) subFollowNode = pm.createNode('plusMinusAverage', name = "follow_mode_compense") subFollowNode.setAttr("input1D[0]", 1) subFollowNode.setAttr('operation', 2) pm.connectAttr(dwCtrl.followJoint, subFollowNode.input1D[1], f = True) pm.connectAttr(subFollowNode.output1D, dwCtrl.followCtrl, f = True) newJointsNum = (len(IKjointList)) # add arclenght on curve arcLenNode = pm.arclen(IKcurve, ch = True) defaultSize = arcLenNode.getAttr("arcLength") # multiply/divide default size by current size mdNode = pm.createNode("multiplyDivide") mdNode.setAttr("operation", 2 ) mdNode.setAttr("input2X", arcLenNode.getAttr("arcLength") ) pm.connectAttr(arcLenNode.arcLength, mdNode.input1X) # average to calculate stretch addition : stretch - 1 addStretchNode = pm.createNode("plusMinusAverage", name = "add_stretch") addStretchNode.setAttr("operation", 2) pm.connectAttr(mdNode.outputX, addStretchNode.input1D[0]) addStretchNode.setAttr("input1D[1]", 1) # multiplydivide to mutiply stretch addition by strecth parameter stretchMultiplyNode = pm.createNode("multiplyDivide", name = "multiply_stretch") pm.connectAttr(addStretchNode.output1D, stretchMultiplyNode.input1X) pm.connectAttr(dwCtrl.stretch, stretchMultiplyNode.input2X) # average to addition 1 + stretch addition addStretchFinalNode = pm.createNode("plusMinusAverage", name = "add_stretch") addStretchFinalNode.setAttr("operation", 1) pm.connectAttr(stretchMultiplyNode.outputX, addStretchFinalNode.input1D[0]) addStretchFinalNode.setAttr("input1D[1]", 1) for jnt in IKjointList: jntNode = (pm.PyNode(jnt)) try: pm.connectAttr(addStretchFinalNode.output1D, jntNode.scaleX) except: print(Exception) ## add parametrable squash ## follow control on neck lastJoint = IKjointList[-1] IKfollowJnt = pm.duplicate(lastJoint, name = (lastJoint.nodeName() + "_follow"))[0] IKfollowJnt.setAttr("scaleX", 1) IKfollowJnt.setParent(ikSpineGrp) """ tmp = IKfollowJnt.getParent() if tmp: tmp.setAttr("scaleX", 1) IKfollowJnt.setParent(world = True) pm.delete(tmp) """ constrain = pm.parentConstraint(dwCtrl, IK_chain[len(IK_chain)-1], IKfollowJnt) for attr in pm.listAttr(constrain, visible = True, keyable= True): if 'IKW' in attr: # print(attr) pm.connectAttr(dwCtrl.followJoint, '%s.%s' % (constrain,attr)) ikFound = True elif 'ctrl' in attr: # print(attr) pm.connectAttr(dwCtrl.followCtrl, '%s.%s' % (constrain,attr)) ##### ik pelvis # follow control on pelvis # duplicate first joint as follow_pelvis_joint pelvisIKjoint = pm.duplicate(IKjointList[0], parentOnly = True, name = (IKjointList[0].nodeName() + "_pelvis_follow_joint"))[0] pelvisIKjoint.jointOrient.set([0,0,0]) # duplicate down ctrl as pelvis ctrl pelvisIKctrlList = pm.duplicate(upCtrl, name = (upCtrl.nodeName() + "_pelvis")) pelvisIKctrl = pelvisIKctrlList[0] toDel = pm.listRelatives(pelvisIKctrl, children = True, type = "transform") pm.delete(toDel) manageCtrl.scaleShape(sel = pelvisIKctrl, scalX = True, scalY = True, scalZ = True, scale = 0.9) # parent pelvis ctrl under down ctrl pm.parent(pelvisIKctrl, upCtrl) helpers.createOneHelper(sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "insert") # add loc on IKjointList[0] IKpelvisJointLocGrp, IKpelvisJointLoc = helpers.createOneHelper(type = "loc", sel = IKjointList[0], freezeGrp = False, hierarchyParent = "child") # add loc on pelvis ctrl IKpelvisCtrlLocGrp, IKpelvisCtrlLoc = helpers.createOneHelper(type = "loc", sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "child") # parent constraint follow_pelvis_joint to locs IKpelvisConstraint = pm.parentConstraint(IKpelvisJointLoc, IKpelvisCtrlLoc, pelvisIKjoint) # add attributes on base controller pm.addAttr(upCtrl, ln = "_______" , attributeType = "enum", enumName = "CTRLS:") pm.addAttr(upCtrl, ln = "followJoint" , at = 'double', min = 0, max = 1, dv = 0) pm.addAttr(upCtrl, ln = "followCtrl" , at = 'double', min = 0, max = 1) pm.setAttr(upCtrl._______ , keyable = True, lock = True) pm.setAttr(upCtrl.followJoint, keyable = True) pm.setAttr(upCtrl.followCtrl, keyable = True) pelvisSubFollowNode = pm.createNode('plusMinusAverage', name = "pelvis_follow_mode_compense") pelvisSubFollowNode.setAttr("input1D[0]", 1) pelvisSubFollowNode.setAttr('operation', 2) pm.connectAttr(upCtrl.followJoint, pelvisSubFollowNode.input1D[1], f = True) pm.connectAttr(pelvisSubFollowNode.output1D, upCtrl.followCtrl, f = True) # connect attributes to constraint parent contraintList = pm.parentConstraint(IKpelvisConstraint, query = True, targetList = True ) # pprint(contraintList) weightAliasList = pm.parentConstraint(IKpelvisConstraint, query = True, weightAliasList = True ) # pprint(weightAliasList) # pprint(IKpelvisJointLoc) for i,c in enumerate(contraintList): if c == IKpelvisJointLoc: pm.connectAttr(upCtrl.followJoint, weightAliasList[i] ) elif c == IKpelvisCtrlLoc: pm.connectAttr(upCtrl.followCtrl, weightAliasList[i] ) ## constraint deformation system to follow ik # return good array of ik joint to parent on return IKfollowJnt, pelvisIKjoint
def bendyLimb( self , *args ): print 'ehm_leg........................bendyLimb' #============================================================================ # duplicate main leg joints and rename bendy joints self.segMainJnts = pm.duplicate (self.upLegJnt ) # delete not joint nodes under the hierarchy if any extraShapes = pm.listRelatives (self.segMainJnts[0], ad=True ) for extraShape in extraShapes : if not pm.objectType(extraShape) == "joint": pm.delete(extraShape) self.segMainJnt = pm.ls (self.segMainJnts[0] )[0] self.segMainJnts = pm.listRelatives (self.segMainJnts[0], ad=True ) self.segMainJnts.append(self.segMainJnt) self.segMainJnts.reverse() #============================================================================ # create locators for positioning and orienting "curvy_midCtrl" # upLeg_rev_loc upLeg_rev_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( upLeg_rev_loc , self.upLegJnt ) pm.rename ( upLeg_rev_loc , self.side + "_upLeg_rev_loc" ) upLeg_rev_loc.translate.translateX.set ( self.dist + self.dist/20 ) upLeg_rev_loc.translate.translateY.set ( 0 ) upLeg_rev_loc.translate.translateZ.set ( (self.dist/200) ) upLeg_rev_loc.rotate.set (0,0,0) #============================================================================ # find the position of self.kneeJnt to create empty group for this loc # we can compensate the length of leg parts by scaling this group upLeg_rev_loc_grp = pm.group ( n = upLeg_rev_loc.name() + "_grp" ) pm.xform ( upLeg_rev_loc_grp , ws=True , piv = self.kneePos) # we need to make this locator scalable. if not, we won't be able to scale upLeg or knee seperately upLeg_rev_loc_mdn = pm.createNode ("multiplyDivide" , n = upLeg_rev_loc.name() + "_mdn" ) upLeg_rev_loc_mdn.operation.set ( 2 ) upLeg_rev_loc_mdn.input1X.set ( 1 ) self.upLegJnt.scaleX >> upLeg_rev_loc_mdn.input2X upLeg_rev_loc_mdn.outputX >> upLeg_rev_loc_grp.scaleX #============================================================================ # knee_rev_loc knee_rev_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( knee_rev_loc , self.kneeJnt ) pm.rename ( knee_rev_loc , self.side + "_knee_rev_loc" ) knee_rev_loc.translate.translateX.set (self.dist/-20) knee_rev_loc.translate.translateY.set ( 0 ) knee_rev_loc.translate.translateZ.set (self.dist/200) knee_rev_loc.rotate.set (0,0,0) pm.select(knee_rev_loc) knee_rev_loc_grp = pm.group ( n = knee_rev_loc.name() + "_grp" ) pm.xform ( knee_rev_loc_grp , ws=True , piv = self.kneePos ) # we need to make this locator scalable. if not, we won't be able to scale upLeg or knee seperately knee_rev_loc_mdn = pm.createNode ("multiplyDivide" , n = knee_rev_loc.name() + "_mdn") knee_rev_loc_mdn.operation.set ( 2 ) knee_rev_loc_mdn.input1X.set ( 1 ) self.kneeJnt.scaleX >> knee_rev_loc_mdn.input2X knee_rev_loc_mdn.outputX >> knee_rev_loc_grp.scaleX # L_knee_aim_loc #================ knee_aim_loc = pm.spaceLocator ( p = (0,0,0) ) pm.parent ( knee_aim_loc , self.kneeJnt ) pm.rename ( knee_aim_loc , self.side + "_knee_aim_loc" ) pm.pointConstraint( upLeg_rev_loc , knee_rev_loc , knee_aim_loc ) # creating the curvy_midCtrl_Parent for mid_joint position ( main purpose of this part ) self.midCtrlParent = pm.group ( em = True ) pm.pointConstraint( self.kneeJnt , self.midCtrlParent ) pm.aimConstraint ( knee_aim_loc, self.midCtrlParent , aimVector = (0,0,-1) , upVector = (-1,0,0) , worldUpType = "object" , worldUpObject = self.upLegJnt ) pm.rename ( self.midCtrlParent , self.side + "_curvy_midCtrl_Parent") #============================================================================ # finding the position for segMainJnts and creating them self.midJntPosition = 0.0 midJnt = self.segMainJnts[0] # create upLeg seg joints for i in ( range (self.legNumOfJnts-1) ) : midJntPosition = (self.kneeJnt.translate.translateX.get() / self.legNumOfJnts ) midJnt = pm.insertJoint ( midJnt ) pm.joint ( midJnt , e = True , relative = True , component = True , position = ( midJntPosition , 0 , 0 ) ) #============= # create knee seg joints # create an extra joint on knee in segmenty so that we could create two ikSplines for the whole leg midJnt = self.segMainJnts[1] midJntParent = midJnt.duplicate() pm.delete ( pm.listRelatives ( midJntParent , allDescendents = True) ) pm.parent ( midJnt , midJntParent) for i in ( range (self.legNumOfJnts-1) ) : midJntPosition = (self.ankleJnt.translate.translateX.get() / self.legNumOfJnts ) midJnt = pm.insertJoint ( midJnt ) pm.joint ( midJnt , e = True , relative = True , component = True , position = ( midJntPosition , 0 , 0 ) ) segJnts = pm.listRelatives ( self.segMainJnts[0] , allDescendents = True) segJnts.append ( self.segMainJnts[0] ) segJnts.reverse() pm.select (segJnts) segJnts = Renamer ( objs=segJnts, name=self.side+"_leg_seg_###_jnt" , hierarchyMode=False).newJnts # select skin joint tempSkinJnts = pm.ls ( segJnts [ 0 : self.legNumOfJnts ] , segJnts [ self.legNumOfJnts+1 : self.legNumOfJnts*2+1 ] ) # add skin jnt to skinJnts list for jnt in tempSkinJnts : self.skinJnts.append ( jnt ) # rename them pm.select ( tempSkinJnts ) SearchReplaceNames ( "_jnt", "_skinJnt", tempSkinJnts ) #============================================================================ # creating ik splines for segmenty joints pm.select ( segJnts[0] ) pm.select ( segJnts[self.legNumOfJnts] , add = True ) self.upLeg_seg_ik_stuff = pm.ikHandle ( sol = "ikSplineSolver" , parentCurve = False , ns = 2 ) self.upLeg_seg_ikh = pm.rename ( self.upLeg_seg_ik_stuff[0] , self.side + "_upLeg_seg_ikh" ) upLeg_seg_eff = pm.rename ( self.upLeg_seg_ik_stuff[1] , self.side + "_upLeg_seg_eff" ) upLeg_seg_crv = pm.rename ( self.upLeg_seg_ik_stuff[2] , self.side + "_upLeg_seg_crv" ) pm.select ( segJnts[self.legNumOfJnts+1] ) pm.select ( segJnts[self.legNumOfJnts*2+1] , add = True ) self.knee_seg_ik_stuff = pm.ikHandle ( sol = "ikSplineSolver" , parentCurve = False , ns = 2 ) knee_seg_ikh = pm.rename ( self.knee_seg_ik_stuff[0] , self.side + "_knee_seg_ikh" ) knee_seg_eff = pm.rename ( self.knee_seg_ik_stuff[1] , self.side + "_knee_seg_eff" ) knee_seg_crv = pm.rename ( self.knee_seg_ik_stuff[2] , self.side + "_knee_seg_crv" ) #============================================================================ # creating curvy_midCtrl_jnt curvy_midCtrl_jnt = pm.joint ( p = ( self.kneePos[0] , self.kneePos[1] ,self.kneePos[2] ) , name = ( self.side + "_curvy_midCtrl_jnt" ) ) # creating ctrl curve for curvy_midCtrl_jnt self.midCtrl = Circle8Crv ( self.legSize*1.2 , self.side+"_leg_toon_ctrl") pm.parent (self.midCtrl , self.midCtrlParent ) self.midCtrl.rotate.set (0,0,0) self.midCtrl.translate.set (0,0,0) pm.parent (curvy_midCtrl_jnt , self.midCtrl ) curvy_midCtrl_jnt.jointOrient.set (0,0,0) LockHideAttr ( objs=curvy_midCtrl_jnt , attrs="vv") LockHideAttr ( objs=self.midCtrl , attrs="sy") LockHideAttr ( objs=self.midCtrl , attrs="sz") LockHideAttr ( objs=self.midCtrl , attrs="v") #============================================================================ # skinning the seg_crvs #========== # before skinning we should make sure that leg is completely staright. # we temporarly parent segmenty ikCurve to joint pm.parent ( knee_seg_crv , self.kneeJnt ) if self.FKIKMode != "IK" : # tempKneeOri = pm.getAttr ( self.kneeJnt.jointOrient ) tempKneeOri = self.kneeJnt.jointOrient.get() self.kneeJnt.jointOrient.set(0,0,0) else : # find position for putting the ik so that leg gets straight tempAnkleIKLoc = pm.spaceLocator ( p = (0,0,0) ) pm.parent (tempAnkleIKLoc , self.upLegJnt ) tempAnkleIKLoc.rotate.set(0,0,0) legLen = ( self.kneeJnt.translate.translateX.get() + self.ankleJnt.translate.translateX.get() ) tempAnkleIKLoc.translate.set( legLen ,0,0) tempAnkleIKPos = pm.xform ( tempAnkleIKLoc , q=True , ws=True , translation = True ) pm.parent (self.IKlegDistLocs[1], w=True) # straighten the leg for skinning self.IKlegDistLocs[1].translate.set( tempAnkleIKPos ) #========== upLeg_seg_crv_skinCluster = ( pm.skinCluster( upLeg_seg_crv , self.upLegJnt , curvy_midCtrl_jnt , toSelectedBones = True ) ) knee_seg_crv_skinCluster = ( pm.skinCluster( knee_seg_crv , curvy_midCtrl_jnt , self.kneeJnt , toSelectedBones = True ) ) #========== pm.setAttr ( upLeg_seg_crv.tx , lock=False ) pm.setAttr ( upLeg_seg_crv.ty , lock=False ) pm.setAttr ( upLeg_seg_crv.tz , lock=False ) pm.setAttr ( upLeg_seg_crv.rx , lock=False ) pm.setAttr ( upLeg_seg_crv.ry , lock=False ) pm.setAttr ( upLeg_seg_crv.rz , lock=False ) pm.setAttr ( knee_seg_crv.tx , lock=False ) pm.setAttr ( knee_seg_crv.ty , lock=False ) pm.setAttr ( knee_seg_crv.tz , lock=False ) pm.setAttr ( knee_seg_crv.rx , lock=False ) pm.setAttr ( knee_seg_crv.ry , lock=False ) pm.setAttr ( knee_seg_crv.rz , lock=False ) pm.parent ( knee_seg_crv , w =True ) pm.setAttr ( upLeg_seg_crv.tx , lock=True ) pm.setAttr ( upLeg_seg_crv.ty , lock=True ) pm.setAttr ( upLeg_seg_crv.tz , lock=True ) pm.setAttr ( upLeg_seg_crv.rx , lock=True ) pm.setAttr ( upLeg_seg_crv.ry , lock=True ) pm.setAttr ( upLeg_seg_crv.rz , lock=True ) pm.setAttr ( knee_seg_crv.tx , lock=True ) pm.setAttr ( knee_seg_crv.ty , lock=True ) pm.setAttr ( knee_seg_crv.tz , lock=True ) pm.setAttr ( knee_seg_crv.rx , lock=True ) pm.setAttr ( knee_seg_crv.ry , lock=True ) pm.setAttr ( knee_seg_crv.rz , lock=True ) if self.FKIKMode != "IK" : self.kneeJnt.jointOrient.set ( tempKneeOri ) else: # now that we have skinned segmenty curves, we can put the leg to it's default pose pm.parent ( self.IKlegDistLocs[1] , self.ankleIKCtrl ) self.IKlegDistLocs[1].translate.set( 0,0,0 ) # setting the weights pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[3:4]") , transformValue = ( curvy_midCtrl_jnt, 1) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[0:1]") , transformValue = ( curvy_midCtrl_jnt, 1) ) pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[2]") , transformValue = ( curvy_midCtrl_jnt, 0.5) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[2]") , transformValue = ( curvy_midCtrl_jnt, 0.5) ) pm.skinPercent ( upLeg_seg_crv_skinCluster , (upLeg_seg_crv + ".cv[1]") , transformValue = ( curvy_midCtrl_jnt, 0.1) ) pm.skinPercent ( knee_seg_crv_skinCluster , (knee_seg_crv + ".cv[3]") , transformValue = ( curvy_midCtrl_jnt, 0.1) ) #============================================================================ # making the joints stratchable MakeSplineStretchy ( ikCrv=upLeg_seg_crv , stretchSwitch=True , volume=False , thicknessPlace="end") upLeg_seg_crv.inheritsTransform.set ( 0 ) MakeSplineStretchy ( ikCrv=knee_seg_crv , stretchSwitch=True , volume=False ,thicknessPlace="start") knee_seg_crv.inheritsTransform.set ( 0 ) #============================================================================ # setting the twist parameters for the segmenty joints self.upLeg_seg_ikh.dTwistControlEnable.set ( 1 ) self.upLeg_seg_ikh.dWorldUpType.set ( 4 ) self.upLeg_seg_ikh.dWorldUpVectorX.set ( 1 ) self.upLeg_seg_ikh.dWorldUpVectorY.set ( 0 ) pm.connectAttr ( self.kneeJnt + ".worldMatrix[0]" , self.upLeg_seg_ikh + ".dWorldUpMatrixEnd" , f = True ) knee_seg_ikh.dTwistControlEnable.set ( 1 ) knee_seg_ikh.dWorldUpType.set ( 4 ) pm.connectAttr ( self.kneeJnt + ".worldMatrix[0]" , knee_seg_ikh + ".dWorldUpMatrix" , f = True ) pm.connectAttr ( self.ankleJnt + ".worldMatrix[0]" , knee_seg_ikh + ".dWorldUpMatrixEnd" , f = True )
def splitJnt(numSegments, joints=None, name='C_split##_skinJnt'): ''' Args: numSegments: number of segments joints: the two joints in an array ['start_jnt', 'end_jnt'] name: the name, ## will be replaced with 01, 02 ... Returns: the list of new joints ['C_split01_jnt', ...] ''' if numSegments < 2: pm.error("The number of segments has to be greater than 1.. ") # for all selected joints joint = None splitJnts = [] if joints == None: joints = pm.ls(sl=1, type='joint') for joint in joints: prevJoint = joint child = pm.listRelatives(joint, children=1, type='joint') if child == []: print("Joint: " + str(joint) + " has no children joints.\n") continue else: print("Joint: " + str(joint) + " has children joints.\n") child = child[0] # axis radius = pm.getAttr("%s.radius" % joint) axis = getJointAxis(child) # make sure the rotation order on $joint is correct. rotOrderIndex = int(pm.getAttr("%s.rotateOrder" % joint)) # calculate spacing attr = ("t" + axis) childT = pm.getAttr("%s.%s" % (child, attr)) print 'childT is %s' % childT space = childT / numSegments # create a series of locators along the joint based on the number of segments. locators = [] for x in range(0, (numSegments - 1)): # align locator to joint locator = pm.spaceLocator() locators.append(locator) pm.parent(locator, joint) pm.setAttr("%s.t" % locator, (0, 0, 0)) # offset pm.setAttr("%s.%s" % (locator, attr), (space * (x + 1))) # insert a joint newJoint = pm.PyNode(pm.insertJoint(prevJoint)) splitJnts.append(newJoint) # get the position of the locator position = pm.xform(locator, q=1, rp=1, ws=1) # move the joint there pm.move(position, ws=1, pcp=1) pm.setAttr("%s.radius" % newJoint, radius) pm.setAttr("%s.rotateOrder" % newJoint, rotOrderIndex) prevJoint = newJoint pm.delete(locator) pm.select(joint) # mo_stringUtils.renameHierarchy() return splitJnts