def __get_curve_info(self): """ Get the curve info """ crv_info = cmds.arclen(self.transform, constructionHistory=True) self.info = cmds.rename( crv_info, self._side + '_' + self._mod + self._name[0].upper() + self._name[1:] + 'Info_CRV') self.arclen = cmds.arclen(self.transform)
def setup_scaling(self): measureCrv = cmds.duplicate(self.splCrv, name="{0}_measure_CRV".format( self.name))[0] splPoc = cmds.arclen(self.splCrv, ch=True) msrPoc = cmds.arclen(measureCrv, ch=True) ratioMult = cmds.shadingNode("multiplyDivide", asUtility=True, name="{0}_ratio_mult".format(self.name)) cmds.setAttr("{0}.operation".format(ratioMult), 2) cmds.connectAttr("{0}.arcLength".format(splPoc), "{0}.input1.input1X".format(ratioMult)) cmds.connectAttr("{0}.arcLength".format(msrPoc), "{0}.input2.input2X".format(ratioMult)) scaleDefaultMult = cmds.shadingNode("multiplyDivide", asUtility=True, name="{0}_envelope_mult".format( self.name)) cmds.setAttr("{0}.input1X".format(scaleDefaultMult), 1.0) envelopeBlend = cmds.shadingNode("blendColors", asUtility=True, name="{0}_scaleBlClr".format( self.name)) cmds.connectAttr("{0}.auto_stretch".format(self.ctrlJntCtrls[2][0]), "{0}.blender".format(envelopeBlend)) cmds.connectAttr("{0}.outputX".format(ratioMult), "{0}.color1.color1R".format(envelopeBlend)) cmds.connectAttr("{0}.outputX".format(scaleDefaultMult), "{0}.color2.color2R".format(envelopeBlend)) for jnt in self.jntList[:-1]: cmds.connectAttr("{0}.output.outputR".format(envelopeBlend), "{0}.sx".format(jnt)) return (measureCrv)
def __get_curve_info(self, character = None, mod = None, side = None, name = None): #--- this method gets the curve info crv_info = cmds.arclen(self.transform, constructionHistory = True) self.info = cmds.rename(crv_info, side + '_' + mod + name[0].upper() + name[1:] + 'Info_CRV') self.arclen = cmds.arclen(self.transform)
def addStretch(self, jntArray, crvSpline, jntSize, name, ctrlRootTrans, *args): curveInfo = mc.arclen(crvSpline, ch=True) splineInfo = "{0}Info".format(name) curveInfo = mc.rename(curveInfo, splineInfo) curveLen = mc.getAttr("{0}.arcLength".format(curveInfo)) splineStretchNameDiv = "{0}_stretchPercent_DIV".format(name) mc.shadingNode("multiplyDivide", n=splineStretchNameDiv, au=True) mc.setAttr("{0}.i2x".format(splineStretchNameDiv), curveLen) mc.setAttr("{0}.operation".format(splineStretchNameDiv), 2) mc.connectAttr("{0}.arcLength".format(curveInfo), "{0}.i1x".format(splineStretchNameDiv)) # get the scales to the spline # to allow for the squash/stretch # get square root of output splineStretchNamePow = "{0}_sqrtStretch_POW".format(name) mc.shadingNode("multiplyDivide", n=splineStretchNamePow, au=True) mc.setAttr("{0}.operation".format(splineStretchNamePow), 3) mc.setAttr("{0}.i2x".format(splineStretchNamePow), 0.5) mc.connectAttr("{0}.ox".format(splineStretchNameDiv), "{0}.i1x".format(splineStretchNamePow)) # divide by the square root splineStretchNameInv = "{0}_stretchInvert_DIV".format(name) mc.shadingNode("multiplyDivide", n=splineStretchNameInv, au=True) mc.setAttr("{0}.operation".format(splineStretchNameInv), 2) mc.setAttr("{0}.i1x".format(splineStretchNameInv), 1) mc.connectAttr("{0}.ox".format(splineStretchNamePow), "{0}.i2x".format(splineStretchNameInv)) for i in range(jntSize - 1): # connects the spline's joints to the joint scale to allow for squash and stretch mc.connectAttr("{0}.ox".format(splineStretchNameDiv), "{0}.scaleX".format(jntArray[i])) mc.connectAttr("{0}.ox".format(splineStretchNameInv), "{0}.scaleY".format(jntArray[i])) mc.connectAttr("{0}.ox".format(splineStretchNameInv), "{0}.scaleZ".format(jntArray[i])) globalScaleNormalizeDiv = "globalScale_{0}Normalize_DIV".format(name) mc.shadingNode("multiplyDivide", n=globalScaleNormalizeDiv, au=True) mc.setAttr("{0}.operation".format(globalScaleNormalizeDiv), 2) mc.connectAttr("{0}.arcLength".format(splineInfo), "{0}.i1x".format(globalScaleNormalizeDiv)) mc.connectAttr("{0}.sy".format(ctrlRootTrans), "{0}.i2x".format(globalScaleNormalizeDiv)) # we want to overwrite the old version mc.connectAttr("{0}.ox".format(globalScaleNormalizeDiv), "{0}.i1x".format(splineStretchNameDiv), f=True) return splineInfo, splineStretchNameDiv, globalScaleNormalizeDiv
def _makeIKStretchy(self): ''' add squash and stretch to the ikSpline ''' info = cmds.arclen(self._ik_curve, ch=True) info = cmds.rename(info, "spine_info") val = cmds.getAttr("%s.arcLength" %info) mdv_node = cmds.createNode("multiplyDivide", n="spine_stretch_multiplier") cmds.setAttr("%s.operation" %mdv_node, 2) cmds.connectAttr("%s.arcLength" %info, "%s.i1x" %mdv_node) cmds.setAttr("%s.i2x" %mdv_node, val) # adding an extra multiplier for the scaling of the rig # to divide the scaling factor by mdv_scale = cmds.createNode("multiplyDivide", n="spine_scale_multiplier") cmds.setAttr("%s.i2x" %mdv_scale, 1) cmds.setAttr("%s.operation" %mdv_scale, 2) cmds.connectAttr("%s.ox" %mdv_node, "%s.i1x" %mdv_scale) self._mdv_scale = mdv_scale for joint in self._ikJnts: # make each joint stretchy using a scaling multiplier on tx mdl_name = joint.replace('jnt', 'mdl') mdl_node = cmds.createNode("multDoubleLinear", n=mdl_name) cmds.connectAttr("%s.ox" %mdv_scale, "%s.i1" %mdl_node) tx = cmds.getAttr("%s.tx" %joint) cmds.setAttr("%s.i2" %mdl_node, tx) cmds.connectAttr("%s.o" %mdl_node, "%s.tx" %joint) '''
def setupStretch(self): # Создаем ноду для вычисления длины управляющей кривой self.arclenNode = cmds.arclen(self.ikSystemObjs[2], constructionHistory=True) self.arclenNode = cmds.rename( self.arclenNode, NamingAgreementHandler(base=NAMING["spineJointName"], suffix=NAMING["curveInfoSuffix"]).nodeName) # Сохраняем исходную длину кривой для дальнейших вычислений curveLength = cmds.getAttr("{}.arcLength".format(self.arclenNode)) # Создаем ноду, где вычисляем во сколько раз изменилась длина кривой по сравнению с исходным значением self.baseStretch = cmds.createNode( "multiplyDivide", name=NamingAgreementHandler( base=NAMING["spineJointName"], suffix=NAMING["stretchSuffix"]).nodeName) # Соединяем нужные атрибуты, выставляем еужную операции cmds.setAttr("{}.operation".format(self.baseStretch), 2) cmds.setAttr("{}.input2X".format(self.baseStretch), curveLength) cmds.connectAttr("{}.arcLength".format(self.arclenNode), "{}.input1X".format(self.baseStretch)) # Возвращаем маштаб каждому джоинту спины вдоль оси Х for x in range(len(self.joints) - 1): cmds.connectAttr("{}.outputX".format(self.baseStretch), "{}.scaleX".format(self.joints[x]))
def accept(self, *args): numAnts = int(cmds.intFieldGrp("numAnts",query=True,value=True)[0]) startFrame = int(cmds.intFieldGrp("startFrame",query=True,value=True)[0]) endFrame = int(cmds.intFieldGrp("endFrame",query=True,value=True)[0]) curves = cmds.textScrollList("curves",q=True,ai=True) if curves == None: curves = ["curve1"] isFlat = cmds.checkBox("isFlat", query = True, value = True) vel = cmds.floatSliderGrp("Velocity", query=True, value=True) load = cmds.floatSliderGrp("load", query=True, value=True) ground = cmds.textFieldButtonGrp("groundObj",q=True,text=True) if ground == None: ground = "nurbsPlane1" numCurves = len(curves) if (numAnts > 1) and (numAnts != numCurves): cmds.warning("the number of ants and curves must be the same") return 0 else: if (numAnts > 1): self.duplicateAnts(numAnts-1) for ind in range(numAnts): arcLen = cmds.arclen(curves[ind]) # rebuiltCurve = cmds.rebuildCurve(curves[ind], kr=1)[0] ct.walking(ind+1, startFrame, endFrame, curves[ind], ground, vel, load, isFlat)
def len_(self, safe=True): """Get the length of this curve. The OpenMaya method returns the unscaled lenght, which can be unsafe. Using cmds.arclen is slower but more reliable. Args: safe (bool): use cmds.arclen (slow) Returns: (float): curve length """ if safe: return cmds.arclen(self.shp) # Check for scale issues _scale = self.get_m().scale() if round(_scale.x - _scale.y, 4) or round(_scale.x - _scale.z, 4): raise RuntimeError( "The curve %s has non-uniform scale %s - the length cannot " "be calculated accurately using the length function. You " "can freeze transforms, or use the slower safe mode." % ((self.T, _scale))) return self.length() * _scale.x
def chordLength(surface, param=0.0, direction='u'): """ Return the length of a surface isoparm given a parameter and a direction @param surface: Surface to query closest point from @type surface: str @param param: The parameter on the surface to query length of @type param: float @param direction: Direction along the surface to measure length of @type direction: str """ # Check surface if not isSurface(surface): raise Exception('Object ' + surface + ' is not a valid surface!') # Duplicate surface curve curve = cmds.duplicateCurve(surface + '.' + direction + '[' + str(param) + ']', ch=0, rn=0, local=0) # Measure curve length length = cmds.arclen(curve[0]) # Cleanup cmds.delete(curve) # Return result return length
def curveToArray(curve): """Convert the curve into an array This function caches the array in the subfolder: *cache/*, and uses the cache if the file has a same name as the curve. Make sure the cache is deleted if the curve is replaced, revised or removed. """ fileName = projDir+"/cache/"+str(curve).translate(None, ">")+".txt" if os.path.exists(fileName): return np.loadtxt(fileName) else: pCurve = 0 minP = cmds.getAttr( curve+'.minValue' ) maxP = cmds.getAttr( curve+'.maxValue' ) curveLen = cmds.arclen( curve ) # The arc length between two points is 0.1 unit length dp = (maxP - minP)/(curveLen/0.1) resArray = [] while pCurve < maxP: pos = getPosCurvePoint(curve, pCurve) tan = getTanCurvePoint(curve, pCurve) cvt = getCurvatureCurvePoint(curve, pCurve) pointInfo = np.hstack((pos, tan, [cvt])) pCurve = pCurve + dp resArray.append(pointInfo) np.savetxt(fileName, resArray, fmt="%1.5f") return np.array(resArray)
def setupStrechy (): # >>> get IK from selection, get start/end joints & IK curve, determine strechy joints _IK = cmds.ls (selection = True)[0] _IKcurve = cmds.listConnections (_IK + '.inCurve', destination = True)[0] _startJoint = cmds.listConnections (_IK + '.startJoint', destination = True)[0] _endEffector = cmds.listConnections (_IK + '.endEffector', destination = True)[0] _endJoint = cmds.listConnections (_endEffector + '.translateX', destination = True)[0] cmds.select (_endJoint, hierarchy = True) _jointsTrash = cmds.ls (selection = True) cmds.select (_startJoint, hierarchy = True) _strachyJoints_ = cmds.ls (selection = True) _strachyJoints_ = _strachyJoints_[:len (_strachyJoints_) - len (_jointsTrash)-1] # >>> setup utility nodes _curveInfo = cmds.arclen (_IKcurve, constructionHistory = True) _condtition = cmds.createNode ('condition') _startLength = cmds.getAttr (_curveInfo + '.arcLength') _currentLength = cmds.createNode ('multiplyDivide') cmds.setAttr (_currentLength + '.operation', 2) cmds.setAttr (_currentLength + '.input2X', _startLength) cmds.setAttr (_condtition + '.firstTerm', _startLength) cmds.setAttr (_condtition + '.operation', 4) cmds.connectAttr (_curveInfo + '.arcLength', _currentLength + '.input1X', force = True) cmds.connectAttr (_curveInfo + '.arcLength', _condtition + '.secondTerm', force = True) cmds.connectAttr (_currentLength + '.outputX', _condtition + '.colorIfTrueR', force = True) # >>> connect calculated scale to joints for _j in _strachyJoints_: cmds.connectAttr (_condtition + '.outColorR', _j + '.scaleX', force = True)
def Main(node, node2, transformNode, pointsAmount, pointCheck, *pArgs): #run function that creates mash network createMashNetwork(node, node2, transformNode) #using inputs fromm UI valueCheck = [None, True, False] #returns a value showing which button is checked pointCheckValue = cmds.radioButtonGrp(pointCheck, query=True, select=True) if valueCheck[pointCheckValue] == False or valueCheck[ pointCheckValue] == None: #add points to mash for autofill curve option addpoints(node, node2) #runs the addpoints function everytime arclen is changed to update number of points curveInfoNode = cmds.arclen( node2, ch=True) #creates node that tracks arclen of curve cmds.scriptJob( attributeChange=["curveInfo1.arcLength", "addpoints(node,node2)"]) cmds.scriptJob(attributeChange=[ transformNode[0] + ".scaleX", "addpoints(node,node2)" ]) else: #add points to mash for manual option points = cmds.intField(pointsAmount, value=True, query=True) cmds.setAttr('MASH_Distribute.pointCount', points)
def getValue(selList, selFrontAxis): """ Calculates the number of objects and step accepts arguments: @selList[list] - list of objects @selFrontAxis[str] - selected front axis return arguments: @objNumber[int] - number of objects @iterValue[float] - step """ #length curve cvLen = mc.arclen(selList[0]) #length of the object along the selected axis objLen = getLengthObj(obj=selList[2], vector=selFrontAxis) #number of objects to create objNumber = int(cvLen // objLen) #step between objects iterValue = round(((objLen * 100) / cvLen) / 100, 4) return objNumber, iterValue
def creatSphere(*args): tip = u'请选择要创建拖尾粒子的控制器或曲线!!!' try: circleSel = mc.ls(sl=1)[0] #radiusCircle = mc.circle(circleSel, q=1, r=1) radiusSpere = ((mc.arclen( circleSel )/(2*3.1415))/2)*.75 #radiusSpere = radiusCircle*.75 particleSphere = mc.polySphere(n='%s_Sphere'%circleSel, r=radiusSpere, sx=float(radiusSpere), sy=float(radiusSpere), ax=[0, 1, 0])[0] mc.parentConstraint(circleSel, particleSphere, mo=0, w=1) #mc.parent(particleSphere, circleSel) mc.setAttr('%s.tx'%particleSphere, 0) mc.setAttr('%s.ty'%particleSphere, 0) mc.setAttr('%s.tz'%particleSphere, 0) mc.setAttr('%s.rx'%particleSphere, 0) mc.setAttr('%s.ry'%particleSphere, 0) mc.setAttr('%s.rz'%particleSphere, 0) mc.setAttr('%s.v'%particleSphere, 0) mc.select(particleSphere, r=1) mc.emitter(type='surface', r=4, dx=1, dy=0, dz=0, n='%s_emitter'%circleSel ) mc.particle( n='%s_Particles'%circleSel ) mc.connectDynamic( '%s_Particles'%circleSel, em='%s_emitter'%circleSel ) particlesShape = mc.listRelatives('%s_Particles'%circleSel, s=1)[0] mc.setAttr('%s.lifespanMode'%particlesShape, 1) mc.setAttr('%s.lifespan'%particlesShape, 0.4) mc.setAttr('%s.startFrame'%particlesShape, 1001) mc.connectControl( 'numText', '%s.rate'%('%s_emitter'%circleSel) ) mc.shadingNode('blinn', n='%s_blinn'%circleSel, asShader=1) mc.sets( n='%s_blinnSG'%circleSel, renderable=True, noSurfaceShader=True, empty=1) mc.connectAttr('%s.outColor'%('%s_blinn'%circleSel), '%s.surfaceShader'%('%s_blinnSG'%circleSel)) mc.connectControl( 'myColorIndex', '%s.color'%('%s_blinn'%circleSel) ) mc.connectControl( 'lifeText', '%s.lifespan'%particlesShape ) mc.sets('%s_Particles'%circleSel, e=1, forceElement='%s'%('%s_blinnSG'%circleSel)) except: mm.eval('print "%s";'%tip)
def addStretch(self, crvSpine, jntSize, *args): curveInfo = mc.arclen(crvSpine, ch=True) curveInfo = mc.rename(curveInfo, "spineInfo") curveLen = mc.getAttr("{0}.arcLength".format(curveInfo)) mc.shadingNode("multiplyDivide", n="spine_md", au=True) mc.setAttr("spine_md.i2x".format(curveInfo), curveLen) mc.setAttr("spine_md.operation".format(curveInfo), 2) mc.connectAttr("{0}.arcLength".format(curveInfo), "spine_md.i1x") # get the scales to the spines # to allow for the squash/stretch # get square root of output mc.shadingNode("multiplyDivide", n="spineSquashPow_md", au=True) mc.setAttr("spineSquashPow_md.operation".format(curveInfo), 3) mc.setAttr("spineSquashPow_md.i2x".format(curveInfo), 0.5) mc.connectAttr("spine_md.ox", "spineSquashPow_md.i1x") # divide by the square root mc.shadingNode("multiplyDivide", n="spineSquashDiv_md", au=True) mc.setAttr("spineSquashDiv_md.operation".format(curveInfo), 2) mc.setAttr("spineSquashDiv_md.i1x".format(curveInfo), 1) mc.connectAttr("spineSquashPow_md.ox", "spineSquashDiv_md.i2x") for i in range(jntSize - 1): # connects the spine joints to the joint scale to allow for squash and stretch mc.connectAttr("spine_md.ox", "{0}.scaleX".format(self.jointArray[i])) mc.connectAttr("spineSquashDiv_md.ox", "{0}.scaleY".format(self.jointArray[i])) mc.connectAttr("spineSquashDiv_md.ox", "{0}.scaleZ".format(self.jointArray[i]))
def getLenToP(curve): """Compute the parameter range per unit arc length of the curve """ minP = cmds.getAttr( curve+'.minValue' ) maxP = cmds.getAttr( curve+'.maxValue' ) curveLen = cmds.arclen( curve ) return (maxP-minP)/curveLen
def cut_curve(): """ 先选所有曲线,最后选mesh :return: """ sels = mc.ls(sl=True) mesh = sels[-1] for sel in sels[:-1]: try: cur = mc.polyProjectCurve(sel,mesh, ch=0,pointsOnEdges=1,curveSamples=50,automatic=1)[0] cur_chr = mc.listRelatives(cur,c=True)[0] mc.arclen(cur_chr,ch=True) mc.select([sel,cur]) mm.eval('cutCurvePreset(1,1,0.01,6,0,1,0,2,2)') mc.delete(cur) except: pass
def orient_to_axis(self): """ Aligns the ribbon to the primary axis """ mc.setAttr("{}.translateX".format(self.ribbon), mc.arclen(self.lenCurves[0]) * .5) mc.setAttr("{}.translate{}".format( self.lenCurves[0], self.primaryAxis), mc.arclen(self.lenCurves[0]) * .5) if self.primaryAxis == "Z": mc.setAttr("{}.rotateY".format(self.ribbon), -90) mc.setAttr("{}.rotateY".format(self.lenCurves[0]), -90) if self.primaryAxis == "Y": mc.setAttr("{}.rotateZ".format(self.ribbon), 90) mc.setAttr("{}.rotateX".format(self.ribbon), 90) mc.setAttr("{}.rotateZ".format(self.lenCurves[0]), 90)
def arclen(*args, **kwargs): res = cmds.arclen(*args, **kwargs) wraps = _factories.simpleCommandWraps['arclen'] for func, wrapCondition in wraps: if wrapCondition.eval(kwargs): res = func(res) break return res
def Global_scale(self , ALLfollic , tail_end_ctrl , keepLengthAtt , tail_basePlane , base_jnt_num , gobal_ctrl , cv , JntFirst): mc.arclen(cv,ch = 1)#显示去想长度节点 #查询全名 jnts = mc.listRelatives(JntFirst,ad = True,type = 'joint',f= True) #查询短名称 #jnts01 = mc.listRelatives(JntFirst,ad = True,type = 'joint') cv_shape = mc.listRelatives(cv,ad=True)[0]#获取曲线的shape节点 cv_Info_inputcv = mc.listConnections( cv_shape + '.worldSpace[0]',p=True)[0]#获取Info节点的inputcurve属性 cv_Info_length = cv_Info_inputcv.replace('.inputCurve','.arcLength')#曲线长度属性 cv_length = mc.getAttr(cv_Info_length)#attain cv length MD01_Node = mc.createNode('multiplyDivide')#creat multiplyDivide Node mc.setAttr(MD01_Node + '.operation',2)#modify ,Node, for Divide mc.connectAttr(cv_Info_length,MD01_Node + '.input1.input1X') # Global_mdNode = mc.createNode('multiplyDivide',name = gobal_ctrl + '_Global_multiplyDivide') mc.setAttr(Global_mdNode + '.input2X',cv_length) mc.connectAttr(gobal_ctrl + '.scaleY',Global_mdNode + '.input1.input1X') mc.connectAttr(Global_mdNode + '.outputX',MD01_Node + '.input2X') # #MD02_Node = mc.createNode('multiplyDivide')#creat multiplyDivide Node #mc.connectAttr(MD01_Node + '.outputX',MD02_Node + '.input1.input1X') for i in range(base_jnt_num - 1): jnt = jnts[i] tail_jnt_multiplyDivideName = jnt.split('|')[-1] + '_multiplyDivide' jnt_tX_number = mc.getAttr(jnt + '.translateX')#get jnt tX number tail_jnt_multiplyDivide = mc.createNode('multiplyDivide',name = tail_jnt_multiplyDivideName)#creat multiplyDivide Node mc.setAttr(tail_jnt_multiplyDivide + '.input2X',jnt_tX_number) mc.connectAttr(MD01_Node + '.outputX',tail_jnt_multiplyDivide + '.input1.input1X') blendNode = mc.shadingNode('blendColors', asShader=True,name = jnt.split('|')[-1] + 'blendColors')#blendColors Node mc.connectAttr(keepLengthAtt,blendNode + '.blender') mc.connectAttr(tail_jnt_multiplyDivide + '.outputX',blendNode + '.color1.color1R') mc.setAttr(blendNode + '.color2.color2R',jnt_tX_number) # baseCondition = mc.shadingNode( 'condition',asUtility = True,name = tail_basePlane + '_condition0' + str(i + 2)) mc.setAttr(baseCondition + '.secondTerm',jnt_tX_number) mc.setAttr(baseCondition + '.operation',2) mc.connectAttr(blendNode + '.color1.color1R',baseCondition + '.firstTerm') mc.connectAttr(blendNode + '.output.outputR',baseCondition + '.colorIfTrueR') mc.connectAttr(blendNode + '.color1.color1R',baseCondition + '.colorIfFalseR') #mc.setAttr(baseCondition + '.colorIfFalseR',jnt_tX_number) mc.connectAttr(baseCondition + '.outColorR',jnt + '.translateX') # #mc.connectAttr(blendNode + '.output.outputR',jnt + '.translateX') for follic in ALLfollic: mc.scaleConstraint(gobal_ctrl,follic,weight = 1)
def calculatePts(crv, *args): """ uses the window to get the number of pts that should be in the curve """ cLen = cmds.arclen(crv, ch=False) perUnit = cmds.intFieldGrp(widgets["recoIFBG"], q=True, v1=True) total = cLen * perUnit return total
def addpoints(node, node2): curvelen = (cmds.arclen(node2)) #need bbbox #use that to drive number of points in curve node according to arclen bbox = cmds.exactWorldBoundingBox(node) objlen = (bbox[3] - bbox[0]) numpoints = int(curvelen // objlen) cmds.setAttr('MASH_Distribute.pointCount', numpoints)
def straightCrvToOrigin(crv): arcLength = cmds.arclen(crv) numCvs = getNumCvs(crv) interval = arcLength / (numCvs - 1) startYPos = 0 for i in xrange(numCvs): cmds.xform('%s.cv[%d]' % (crv, i), ws=True, t=(0, startYPos, 0)) startYPos += interval return arcLength
def curveDisNode(self): disNode = cmds.arclen(self.obj1,ch=1) disNode = cmds.rename(disNode,(self.obj1+'_crvInfo')) disVal = cmds.getAttr(disNode+'.arcLength') cmds.connectAttr((self.mdnG+'.outputX'),(self.mdn+'.input1X'),f=1) self.mdnConnector((disNode+'.arcLength'), disVal) print self.gCtrl if(self.gCtrl): self.globalScaleConnector(self.gCtrl) return self.con
def create_spine(start_joint, end_joint, lower_control, upper_control, name='spine'): spline_chain, original_chain = shortcuts.duplicate_chain(start_joint, end_joint, prefix='ikSpine_') # Create the spline ik ikh, effector, curve = cmds.ikHandle( name='{0}_ikh'.format(name), solver='ikSplineSolver', startJoint=spline_chain[0], endEffector=spline_chain[-1], parentCurve=False, simplifyCurve=False) effector = cmds.rename(effector, '{0}_eff'.format(name)) curve = cmds.rename(curve, '{0}_crv'.format(name)) # Create the joints to skin the curve curve_start_joint = cmds.duplicate(start_joint, parentOnly=True, name='{0}CurveStart_jnt'.format(name)) cmds.parent(curve_start_joint, lower_control) curve_end_joint = cmds.duplicate(end_joint, parentOnly=True, name='{0}CurveEnd_jnt'.format(name)) cmds.parent(curve_end_joint, upper_control) # Skin curve cmds.skinCluster(curve_start_joint, curve_end_joint, curve, name='{0}_scl'.format(name), tsb=True) # Create stretch network curve_info = cmds.arclen(curve, constructionHistory=True) mdn = cmds.createNode('multiplyDivide', name='{0}Stretch_mdn'.format(name)) cmds.connectAttr('{0}.arcLength'.format(curve_info), '{0}.input1X'.format(mdn)) cmds.setAttr('{0}.input2X'.format(mdn), cmds.getAttr('{0}.arcLength'.format(curve_info))) cmds.setAttr('{0}.operation'.format(mdn), 2) # Divide # Connect to joints for joint in spline_chain[1:]: tx = cmds.getAttr('{0}.translateX'.format(joint)) mdl = cmds.createNode('multDoubleLinear', name='{0}Stretch_mdl'.format(joint)) cmds.setAttr('{0}.input1'.format(mdl), tx) cmds.connectAttr('{0}.outputX'.format(mdn), '{0}.input2'.format(mdl)) cmds.connectAttr('{0}.output'.format(mdl), '{0}.translateX'.format(joint)) # Setup advanced twist cmds.setAttr('{0}.dTwistControlEnable'.format(ikh), True) cmds.setAttr('{0}.dWorldUpType'.format(ikh), 4) # Object up cmds.setAttr('{0}.dWorldUpAxis'.format(ikh), 0) # Positive Y Up cmds.setAttr('{0}.dWorldUpVectorX'.format(ikh), 0) cmds.setAttr('{0}.dWorldUpVectorY'.format(ikh), 1) cmds.setAttr('{0}.dWorldUpVectorZ'.format(ikh), 0) cmds.setAttr('{0}.dWorldUpVectorEndX'.format(ikh), 0) cmds.setAttr('{0}.dWorldUpVectorEndY'.format(ikh), 1) cmds.setAttr('{0}.dWorldUpVectorEndZ'.format(ikh), 0) cmds.connectAttr('{0}.worldMatrix[0]'.format(lower_control), '{0}.dWorldUpMatrix'.format(ikh)) cmds.connectAttr('{0}.worldMatrix[0]'.format(upper_control), '{0}.dWorldUpMatrixEnd'.format(ikh)) # Constrain original chain back to spline chain for ik_joint, joint in zip(spline_chain, original_chain): if joint == end_joint: cmds.pointConstraint(ik_joint, joint, mo=True) cmds.orientConstraint(upper_control, joint, mo=True) else: cmds.parentConstraint(ik_joint, joint)
def mk_driver_joints(self): """ Create the joints that will drive your ribbon """ for i in range(self.driverJointNum): # Define rotation order based on riibbon's primary axis if self.primaryAxis == "X": ro = "xyz" elif self.primaryAxis == "Y": ro = "yzx" else: ro = "zxy" if i == 0: jnt = mc.joint(n="{}_base_driver_jnt".format( self.name), rad=3, roo=ro) elif i == self.driverJointNum - 1: jnt = mc.joint(n="{}_tip_driver_jnt".format( self.name), rad=3, roo=ro) mc.setAttr("{}.translate{}".format( jnt, self.primaryAxis), mc.arclen(self.proxieCrv) / (self.driverJointNum - 1)) elif i == 1 and self.driverJointNum == 3: jnt = mc.joint(n="{}_mid_driver_jnt".format( self.name), rad=3, roo=ro) mc.setAttr("{}.translate{}".format( jnt, self.primaryAxis), mc.arclen(self.proxieCrv) / (self.driverJointNum - 1)) else: jnt = mc.joint( n="{}_mid{}_driver_jnt".format(self.name, str(i).zfill(2)), rad=3, roo=ro) mc.setAttr("{}.translate{}".format(jnt, self.primaryAxis), mc.arclen( self.proxieCrv) / (self.driverJointNum - 1)) self.driverJoints.append(jnt) # Group your driver joints and parent it to your rig group driverGrp = mc.createNode( "transform", n="{}_driver_jnt_grp".format(self.name)) mc.parent(self.driverJoints[0], driverGrp) mc.parent(driverGrp, "{}{}".format(self.name, RIG)) mc.reorder(driverGrp, r=-1) return self.driverJoints
def mv_ribbon(self): """ Move the Rig group into position with the bottom driver """ btDriver = self.driverJoints[0] pos = mc.getAttr("{}.translate".format(btDriver))[0] rot = mc.getAttr("{}.rotate".format(btDriver))[0] for i, v in enumerate(VECTORS): mc.setAttr("{}_rig.translate{}".format(self.name, v), pos[i]) mc.setAttr("{}_rig.rotate{}".format(self.name, v), rot[i]) mc.setAttr("{}.translateX".format(self.ribbon), mc.arclen(self.lenCurves[0]) * .5)
def make_ikspline_stretchy(*args): '''main function to make joints stretching''' try: #get data of IKfandle and joint selected_ikHandle = cmds.ls(sl=True)[0] ikJoints = cmds.ikHandle(selected_ikHandle, q=True, jl=True) numberOfBones = len(ikJoints) ikCurve = cmds.ikHandle(selected_ikHandle, q=True, c=True) cmds.rebuildCurve(ikCurve, rt=0, kr=0, d=4, s=1) curveInfo = cmds.arclen(ikCurve, ch=True) #create Node of length multiDivArclen = cmds.shadingNode('multiplyDivide', asUtility=True) cmds.setAttr(multiDivArclen + '.operation', 2) cmds.addAttr(multiDivArclen, ln="stretchy", at='double', dv=0, k=True) #connect curve length cmds.connectAttr(curveInfo + '.arcLength', multiDivArclen + '.input1X', f=True) cmds.connectAttr(multiDivArclen + '.outputX', multiDivArclen + '.stretchy', f=True) input2X = cmds.getAttr(multiDivArclen + '.input1X') cmds.setAttr(multiDivArclen + '.input2X', input2X) #multDivArclen.OutputX == 1 #create Node of thickness multiDivThickness = cmds.shadingNode('multiplyDivide', asUtility=True) cmds.setAttr(multiDivThickness + '.operation', 3) cmds.connectAttr(multiDivArclen + '.stretchy', multiDivThickness + '.input1X', f=True) cmds.setAttr(multiDivThickness + '.input2X', -0.5) #cmds.addAttr( multiDivArclen, ln="stretchy", at='double', dv=0, k=True) cmds.cluster(ikCurve + '.cv[3]', n="cluster_end") cmds.cluster(ikCurve + '.cv[0]', ikCurve + '.cv[1]', ikCurve + '.cv[2]', n="cluster_root") for i in range(numberOfBones): cmds.connectAttr(multiDivArclen + '.stretchy', ikJoints[i] + '.scaleX', f=True) if i > 0 and i < numberOfBones: cmds.connectAttr(multiDivThickness + '.outputX', ikJoints[i] + '.scaleY', f=True) cmds.connectAttr(multiDivThickness + '.outputX', ikJoints[i] + '.scaleZ', f=True) #cmds.connectAttr( outMultDiv+'.outputX', item+'.scaleX', f=True) except: print "no curve selected"
def chain(cu,num,name='joint'): """ build a simple chain of joints equal to a defined length """ cmds.select(cl=True) length=cmds.arclen(cu,ch=0) jts=[];jts.append(cmds.joint(n='%s\#' %name,rad=1)) for j in range(num): rd = 1 - linstep(0., num+1, j+1) jtmp=cmds.joint(p=(length/num*(j+1),0, 0),rad=rd, n='%s\#' %name ) jts.append(jtmp) return jts
def generate(self, *a): jl = cmds.floatField('ff_ac2sJL', q=1, value=1) jax = cmds.radioCollection('rdc_ac2sJA', q=1, select=1) wu = cmds.radioCollection('rdc_ac2sWU', q=1, select=1) st = cmds.textField('tf_ac2sST', q=1, text=1) gik = cmds.createNode('transform', name='grp_spineIk', skipSelect=1) axAttr = '.translateX' dir = 1 fax = 0 uax = 0 if jax in ['rd_ac2sY', 'rd_ac2sy']: axAttr = '.translateY' if jax in ['rd_ac2sZ', 'rd_ac2sz']: axAttr = '.translateZ' if jax in ['rd_ac2sx', 'rd_ac2sy', 'rd_ac2sz']: dir = -1 if jax == 'rd_ac2sY': fax = 2 uax = 6 if jax == 'rd_ac2sZ': fax = 4 uax = 0 if jax == 'rd_ac2sx': fax = 1 uax = 1 if jax == 'rd_ac2sy': fax = 3 uax = 7 if jax == 'rd_ac2sz': fax = 5 uax = 1 for x in cmds.ls(selection=1): len = cmds.arclen(x, constructionHistory=0) jn = (len / jl) + 1 joList = [] for i in range(int(jn)): jo = cmds.createNode('joint') if i > 0: cmds.parent(jo, joList[-1]) cmds.setAttr(jo + axAttr, jl * dir) joList.append(jo) ik = cmds.ikHandle(startJoint=joList[0], endEffector=joList[-1], sol='ikSplineSolver', createCurve=0, curve=x, parentCurve=0) if wu != 'rd_ac2sWU': cmds.setAttr(ik[0] + '.dTwistControlEnable', 1) cmds.setAttr(ik[0] + '.dWorldUpType', 3) cmds.setAttr(ik[0] + '.dForwardAxis', fax) cmds.setAttr(ik[0] + '.dWorldUpAxis', uax) if wu == 'rd_ac2sWUT': cmds.connectAttr(st + '.xformMatrix', ik[0] + '.dWorldUpMatrix') cmds.parent(ik[0], gik)
def createStretchDeformer(self): # Get the length of the wire deformer curve to see if the rig is being stretched or squashed. arcLength = cmds.arclen(self.wireDeformerCurve, constructionHistory=True) length = cmds.getAttr("%s.arcLength" % arcLength) # Add attributes on the master control to enable squashing and stretching. cmds.addAttr(self.masterControlCurve, longName="enable", attributeType='bool', keyable=True, hidden=False) cmds.addAttr(self.masterControlCurve, longName="volume", attributeType='float', defaultValue=1.0, keyable=True, hidden=False) # If the rig is being pulled or pushed, calculate the percentage. stretchDivideNode = cmds.createNode("multiplyDivide", name="%s_STRETCH_DIV" % self.name) cmds.setAttr("%s.operation" % str(stretchDivideNode), 2) cmds.setAttr("%s.input2X" % str(stretchDivideNode), length) cmds.connectAttr("%s.arcLength" % arcLength, "%s.input1X" % str(stretchDivideNode)) volumeDivideNode = cmds.createNode("multiplyDivide", name="%s_VOL_DIV" % self.name) cmds.setAttr("%s.operation" % str(volumeDivideNode), 2) cmds.setAttr("%s.input1X" % str(volumeDivideNode), 1) cmds.connectAttr("%s.outputX" % str(stretchDivideNode), "%s.input2X" % str(volumeDivideNode)) # Check to ensure that scaling is on. stretchConditionNode = cmds.createNode("condition", name="%s_STRETCH_COND" % self.name) cmds.connectAttr("%s.enable" % str(self.masterControlCurve), "%s.firstTerm" % str(stretchConditionNode)) cmds.connectAttr( "%s.outputX" % str(volumeDivideNode), "%s.colorIfTrue.colorIfTrueR" % str(stretchConditionNode)) cmds.setAttr("%s.secondTerm" % str(stretchConditionNode), 1) # If so, scale the joints in Y and Z. for joint in self.bindJoints: cmds.connectAttr("%s.outColorR" % str(stretchConditionNode), "%s.scaleY" % joint) cmds.connectAttr("%s.outColorR" % str(stretchConditionNode), "%s.scaleZ" % joint)
def connectJointBtnCmd(self, *args): """Function to execute when Create button is pressed""" print('属性链接') #创建乘除节点 multiply_divide = cmds.createNode('multiplyDivide') cmds.setAttr(multiply_divide + '.operation', 2) #cmds.setAttr(multiply_divide+'.input2X',self.curveinfo+'.arcLength')#出错 cmds.setAttr(multiply_divide + '.input2X', cmds.arclen(self.ik_names[2])) #连接 cmds.connectAttr(self.curveinfo + '.arcLength', multiply_divide + '.input1X') for i in range(7): cmds.connectAttr(multiply_divide + '.outputX', self.jnts[i] + '.scaleY')
def execute(self,*a): jb = cmds.radioCollection('rdc_acac1',q=1,select=1) fl = cmds.intField('if_acacFL',q=1,value=1) fs = cmds.intField('if_acacFS',q=1,value=1) jl = cmds.floatField('ff_acacSL',q=1,value=1) sel = cmds.ls(selection=1) lenList = [] for x in sel : if cmds.nodeType(x) != 'nurbsCurve' : for y in cmds.listRelatives(x) : if cmds.nodeType(y) == 'nurbsCurve' : x = y lenList.append(cmds.arclen(x)) ll = max(lenList) / fl sl = min(lenList) / fs for x in sel : cvn = cmds.getAttr(x+'.spans') + cmds.getAttr(x+'.degree') fcvn = int(round(cmds.arclen(x)/jl)) if jb == 'if_acacFL' : fcvn = int(round(cmds.arclen(x)/ll)) if jb == 'if_acacFS' : fcvn = int(round(cmds.arclen(x)/sl)) if fcvn < 4 : fcvn = 4 if cvn != fcvn : cmds.rebuildCurve(x,constructionHistory=0,replaceOriginal=1,rebuildType=0,keepRange=0,spans=fcvn-3,degree=3)
def calculatePts(crv, *args): """ uses the window to get the number of pts that should be in the curve """ mode = cmds.radioButtonGrp(widgets["methodRBG"], q=True, sl=True) if mode == 1: cLen = cmds.arclen(crv, ch=False) perUnit = cmds.intFieldGrp(widgets["recoIFBG"], q=True, v1=True) total = cLen * perUnit if mode == 2: total = cmds.intFieldGrp(widgets["totalIFBG"], q=True, v1=True) # print "curve = {0}, total = {1}".format(crv, total) return total
def createSpiralCurves( crvs, loops, hrsSys ): """create spiral curves for curve guides""" i = 0 maxVal = mc.arclen( crvs[0] ) for c in crvs: if mc.arclen( c ) > maxVal: maxVal = mc.arclen( c ) prevLoc = '' spiralCrvs = [] fols = [] locs = [] count = 0 baseName = 'spiral' for a in drange( 0.0, maxVal, ( 1.0 / len( crvs ) / loops ) ): if i == ( len( crvs ) ): i = 0 c = crvs[i] i += 1 offset = a * ( maxVal ) / mc.arclen( c ) offset = offset + random.uniform(-0.01,0.01) if c.shape.a.maxValue.v < offset: break pointOnCur = pntcrv.PointOnCurve( c ) nod = pointOnCur.nodeAt( offset ) loc = mn.Node( mc.spaceLocator( )[0] ) nod.a.position >> loc.a.translate if prevLoc: prevLoc.name = 'spiderWeb_' + str( count ) + '_LOC' curv, folPar = createCurveaBasedOnLocator( prevLoc, loc, baseName, hrsSys ) fols.append( folPar ) curv.shape.a.aiRenderCurve.v = 1 spiralCrvs.append( curv ) count += 1 locs.append( loc ) prevLoc = loc return spiralCrvs, fols, locs
def makeHairCurves(hullCurves, d, twist = 0.0): ''' Populate a hull with hair curves based on arclen of the biggest curve ''' largestArclen = 0 for curve in hullCurves: arclen = mc.arclen(curve) if arclen > largestArclen: largestArclen = arclen numCurves = largestArclen / (d * 1.0) allCurves = [] for i in range(int(numCurves)): allCurves.append(makeHairCurve(hullCurves, i/numCurves, twist)) return allCurves
def makeHairCurves(hullCurves, d, twist=0.0): ''' Populate a hull with hair curves based on arclen of the biggest curve ''' largestArclen = 0 for curve in hullCurves: arclen = mc.arclen(curve) if arclen > largestArclen: largestArclen = arclen numCurves = largestArclen / (d * 1.0) allCurves = [] for i in range(int(numCurves)): allCurves.append(makeHairCurve(hullCurves, i / numCurves, twist)) return allCurves
def addStretch(self, jntArray, crvSpine, jntArrayLen, *args): curveInfo = mc.arclen(crvSpine, ch=True) spineInfo = "spineInfo" curveInfo = mc.rename(curveInfo, "spineInfo") curveLen = mc.getAttr("{0}.arcLength".format(curveInfo)) spineStretchNameDiv = "spine_stretchPercent_DIV" mc.shadingNode("multiplyDivide", n=spineStretchNameDiv, au=True) mc.setAttr("{0}.i2x".format(spineStretchNameDiv), curveLen) mc.setAttr("{0}.operation".format(spineStretchNameDiv), 2) mc.connectAttr("{0}.arcLength".format(curveInfo), "{0}.i1x".format(spineStretchNameDiv)) # get the scales to the spines # to allow for the squash/stretch # get square root of output spineStretchNamePow = "spine_sqrtStretch_POW" mc.shadingNode("multiplyDivide", n=spineStretchNamePow, au=True) mc.setAttr("{0}.operation".format(spineStretchNamePow), 3) mc.setAttr("{0}.i2x".format(spineStretchNamePow), 0.5) mc.connectAttr("{0}.ox".format(spineStretchNameDiv), "{0}.i1x".format(spineStretchNamePow)) # divide by the square root spineStretchNameInv = "spine_stretchInvert_DIV" mc.shadingNode("multiplyDivide", n=spineStretchNameInv, au=True) mc.setAttr("{0}.operation".format(spineStretchNameInv), 2) mc.setAttr("{0}.i1x".format(spineStretchNameInv), 1) mc.connectAttr("{0}.ox".format(spineStretchNamePow), "{0}.i2x".format(spineStretchNameInv)) for i in range(jntArrayLen - 1): # connects the spine joints to the joint scale to allow for squash and stretch mc.connectAttr("{0}.ox".format(spineStretchNameDiv), "{0}.scaleX".format(jntArray[i])) mc.connectAttr("{0}.ox".format(spineStretchNameInv), "{0}.scaleY".format(jntArray[i])) mc.connectAttr("{0}.ox".format(spineStretchNameInv), "{0}.scaleZ".format(jntArray[i])) return spineInfo, spineStretchNameDiv
def StretchNodes(blndSuffix, curve, jnts): # create math nodes # math crvInfo = cmds.arclen(curve, ch=True, n=(curve + '_arcLength')) crvLength = cmds.getAttr(crvInfo + '.arcLength') dvd = cmds.shadingNode('multiplyDivide', au=True, n=(curve + '_scale')) # set math nodes # set operation: 2 = divide, 1 = multiply cmds.setAttr((dvd + '.operation'), 2) # connect math nodes cmds.connectAttr((crvInfo + '.arcLength'), (dvd + '.input1Z')) # To Scale spline - figure out which groups scale will control dvdNodes value ##cmds.connectAttr(('?scaleGroup?' + '.scaleZ'), (dvd + '.input2Z')) # create and connect blends # assumes 'aimValue' point down chain blnd = [] jj = 1 for i in range(1, len(jnts), 1): # measure length, get translate(aimValue) value aimValue = cmds.getAttr(jnts[i] + '.translateX') # create stretch node ## mltpl = cmds.shadingNode('multiplyDivide', au=True, n=(curve + str(jj) + '_stretch')) cmds.setAttr((mltpl + '.operation'), 1) # multiplier = length of joint/default crv length cmds.setAttr((mltpl + '.input2Z'), (aimValue / crvLength)) cmds.connectAttr((dvd + '.outputZ'), (mltpl + '.input1Z')) ## # create blend MidB = cmds.shadingNode('blendColors', name=(blndSuffix + str(jj) + '_Stretch'), asUtility=True) # set blend 'blender attr to 1' cmds.setAttr(MidB + '.blender', 1) # set color2B to 'aimValue' cmds.setAttr(MidB + '.color2B', aimValue) # connect mltpl output to blend color1B cmds.connectAttr((mltpl + '.outputZ'), (MidB + '.color1B')) # connect blend outputB to joint translateZ cmds.connectAttr((MidB + '.outputB'), (jnts[i] + '.translateX')) # store blend for return blnd.append(MidB) jj = jj + 1 return blnd
def snap_root_CV_to_mesh(*args): ''' Snap root CV of curve to closest point on mesh for selected mesh and curves which are currently selected. ''' initialSelection = cmds.ls(sl=True) scalpMesh = cmds.ls(sl=True, dag=True, type='mesh')[0] curveSet = cmds.listRelatives(cmds.ls(sl=True, dag=True, type='nurbsCurve'), parent=True) CPOM_A = cmds.createNode('closestPointOnMesh') CPOM_B = cmds.createNode('closestPointOnMesh') cmds.connectAttr(scalpMesh+'.outMesh', CPOM_A+'.inMesh') cmds.connectAttr(scalpMesh+'.outMesh', CPOM_B+'.inMesh') for CRV in curveSet: #CRV = curveSet[0] curveLen = int(cmds.arclen(CRV)/3+4) rebuildCRV = cmds.rebuildCurve(CRV, d=3, spans=curveLen) #print CRV CRVroot = cmds.pointPosition(CRV+'.cv[0]', world=True) CRVvec = cmds.pointPosition(CRV+'.cv[2]', world=True) abc = ['X', 'Y', 'Z'] for x in abc: cmds.setAttr(CPOM_A+'.inPosition'+x, CRVroot[abc.index(x)]) cmds.setAttr(CPOM_B+'.inPosition'+x, CRVvec[abc.index(x)]) CPOM_rootPOS = cmds.getAttr(CPOM_A+'.position')[0] CPOM_vecPOS = cmds.getAttr(CPOM_B+'.position')[0] #print CRV, CRVroot, CPOM_POS cmds.reverseCurve(CRV) CRVcvs = cmds.getAttr(CRV+'.spans') #print CRV, curveLen, CRVcvs, rebuildCRV cmds.delete(CRV, constructionHistory=True) CRVshape = cmds.listRelatives(CRV, children=True) cmds.curve(CRVshape, a=True, ws=True, p=[CPOM_vecPOS, CPOM_rootPOS])#[(0,0,0) for x in range(CRVcvs/5)]) cmds.reverseCurve(CRV) cmds.rebuildCurve(CRV, degree=3, spans=CRVcvs+2) cmds.smoothCurve(CRV+'.cv[*]', smoothness=10) #break cmds.select(initialSelection)
def chordLength(surface,param=0.0,direction='u'): ''' Return the length of a surface isoparm given a parameter and a direction @param surface: Surface to query closest point from @type surface: str @param param: The parameter on the surface to query length of @type param: float @param direction: Direction along the surface to measure length of @type direction: str ''' # Check surface if not isSurface(surface): raise UserInputError('Object '+surface+' is not a valid surface!') # Duplicate surface curve curve = mc.duplicateCurve(surface+'.'+direction+'['+str(param)+']',ch=0,rn=0,local=0) # Measure curve length length = mc.arclen(curve[0]) # Cleanup mc.delete(curve) # Return result return length
def stretchSpline(self, getbones): childBones=cmds.listRelatives(getbones, ad=1, typ="joint") alljoints=childBones alljoints.append(getbones)#make full list of bones getIKEffector=cmds.listRelatives(getbones, ad=1, typ="ikEffector")#find effector getIKHandle=cmds.listConnections(getIKEffector[0], d=1, t="ikHandle")#now i can find ikhandle getCurve=cmds.listConnections(getIKHandle[0], d=1, t="nurbsCurve")#now i can find curve getShape=cmds.listRelatives(getCurve[0], ad=1, typ="nurbsCurve")#now i can find shape curvInf=cmds.arclen(getShape[0], ch=1)#get shape length getDistance=cmds.getAttr(curvInf+".arcLength") MultDivNode=cmds.shadingNode( "multiplyDivide", au=1, n=getbones+'_md') ConditionNode=cmds.shadingNode( "condition", au=1, n=getbones+"_cond") cmds.setAttr(str(MultDivNode)+".operation", 2)#change to divide cmds.setAttr(str(ConditionNode)+".operation", 2)#change to greater than cmds.connectAttr(curvInf+".arcLength", MultDivNode+".input1.input1"+scaleAxis, f=1)#set default length on input of divide cmds.connectAttr(curvInf+".arcLength", ConditionNode+".firstTerm", f=1)#set default on first term when greater than cmds.connectAttr(MultDivNode+".output.output"+scaleAxis, ConditionNode+".colorIfTrue.colorIfTrueR", f=1)#divide outputscaleX to color is greater than cmds.setAttr(ConditionNode+".secondTerm", getDistance)#set default length on second term of greaterThan cmds.setAttr(MultDivNode+".input2"+scaleAxis, getDistance)#set default length on second input of divide for each in alljoints[1:]: cmds.connectAttr(ConditionNode+".outColor.outColorR",each+".scale.scale"+scaleAxis, f=1)#set divide on scale X of each bone except for last bone
def j_MakeStretchy(mainContrl="Main"): u'做拉伸,主控制器,先选骨骼链,最后选ik曲线' #ready jnt = mc.ls(sl =True)[:-1] cuv = mc.ls(sl =True)[-1] arcNode = mc.arclen(cuv,ch =True,) num = len(jnt) #operater length = mc.getAttr((arcNode + ".arcLength")) # mainScale = mc.getAttr((mainContrl+".scaleX")) md1 = mc.createNode('multiplyDivide') md2 = mc.createNode('multiplyDivide') #md3 = mc.createNode('multiplyDivide') mc.connectAttr((mainContrl+".scaleX"),(md1 +".input1X")) mc.setAttr((md1 +".input2X"),length) mc.connectAttr((arcNode+".arcLength"),(md2+".input1X")) mc.connectAttr((md1+".outputX"),(md2 +".input2X")) mc.setAttr((md2+".operation"),2) axiss = ("X","Y","Z") nodeNumA = (num*1.0)/3 # num%3 # #nodeNumB = math.ceil(nodeNumB) nodeCount = int(math.ceil(nodeNumA)) attr = 0 for n in range(nodeCount): mdnode = mc.createNode('multiplyDivide') for i in axiss: print attr if attr>=(num): break tranX = mc.getAttr(jnt[attr] + ".tx") mc.setAttr((mdnode + ".input2" + i),tranX) #设置为骨骼的初始位移值 mc.connectAttr((md2+".outputX"),(mdnode + ".input1"+i)) mc.connectAttr((mdnode+".output"+i),(jnt[attr]+'.tx')) attr +=1 #compelte
def rebuild_old(surface,spansU=0,spansV=0,fullRebuildU=False,fullRebuildV=False,replaceOrig=False): ''' Do brute force surface rebuild for even parameterization @param surface: Nurbs surface to rebuild @type surface: str @param spansU: Number of spans along U. If 0, keep original value. @type spansU: int @param spansV: Number of spans along V. If 0, keep original value. @type spansV: int @param replaceOrig: Replace original surface, or create new rebuilt surface. @type replaceOrig: bool ''' # Check surface if not isSurface(surface): raise Exception('Object "'+surface+'" is not a valid surface!') # Check spans if not spansU: spansU = mc.getAttr(surface+'.spansU') if not spansV: spansV = mc.getAttr(surface+'.spansV') # ------------- # - Rebuild V - # Get V range minu = mc.getAttr(surface+'.minValueU') maxu = mc.getAttr(surface+'.maxValueU') u = minu + (maxu - minu) * 0.5 # Extract isoparm curve iso_crv = mc.duplicateCurve(surface+'.u['+str(u)+']',ch=0,rn=0,local=0)[0] iso_len = mc.arclen(iso_crv) iso_inc = iso_len / spansV curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [surface+'.v['+str(curveFn.findParamFromLength(iso_inc*i))+']' for i in range(spansV+1)] mc.delete(iso_crv) # Check full rebuild if fullRebuildU: # Extract isoparm curves iso_crv_list = [mc.duplicateCurve(iso,ch=False,rn=False,local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: mc.rebuildCurve(iso_crv,ch=False,rpo=True,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=0,d=3,tol=0) # Loft final surface int_surface = mc.loft(iso_crv_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # Delete intermediate curves mc.delete(iso_crv_list) else: # Loft intermediate surface int_surface = mc.loft(iso_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # ------------- # - Rebuild U - # Get V range (intermediate surface) minv = mc.getAttr(int_surface+'.minValueV') maxv = mc.getAttr(int_surface+'.maxValueV') v = minv + (maxv - minv) * 0.5 # Extract isoparm curve (intermediate surface) iso_crv = mc.duplicateCurve(int_surface+'.v['+str(v)+']',ch=0,rn=0,local=0)[0] iso_len = mc.arclen(iso_crv) iso_inc = iso_len / spansU curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [int_surface+'.u['+str(curveFn.findParamFromLength(iso_inc*i))+']' for i in range(spansU+1)] mc.delete(iso_crv) # Check full rebuild if fullRebuildV: # Extract isoparm curves iso_crv_list = [mc.duplicateCurve(iso,ch=False,rn=False,local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: mc.rebuildCurve(iso_crv,ch=False,rpo=True,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=0,d=3,tol=0) # Loft final surface rebuild_surface = mc.loft(iso_crv_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # Delete intermediate curves mc.delete(iso_crv_list) else: # Loft final surface rebuild_surface = mc.loft(iso_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] rebuild_surface = mc.rename(rebuild_surface,surface+'_rebuild') rebuild_surfaceShape = mc.listRelatives(surface,s=True,ni=True)[0] mc.delete(int_surface) # Initialize return value outputShape = rebuild_surfaceShape # -------------------- # - Replace Original - if replaceOrig: """ # Get original shape shapes = glTools.utils.shape.getShapes(surface,nonIntermediates=True,intermediates=False) if not shapes: # Find Intermediate Shapes shapes = glTools.utils.shape.listIntermediates(surface) # Check shapes if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') # Check connections if mc.listConnections(shapes[0]+'.create',s=True,d=False): # Find Intermediate Shapes shapes = glTools.utils.shape.findInputShape(shapes[0]) """ # Check history shapes = mc.listRelatives(surface,s=True,ni=True) if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') shape = shapes[0] shapeHist = mc.listHistory(shape) if shapeHist.count(shape): shapeHist.remove(shape) if shapeHist: print('Surface "" contains construction history, creating new shape!') # Override shape info and delete intermediate mc.connectAttr(rebuild_surfaceShape+'.local',shape+'.create',f=True) outputShape = shape # Return result return outputShape
def rebuild(surface, spansU=0, spansV=0, fullRebuildU=False, fullRebuildV=False, rebuildUfirst=True, replaceOrig=False): """ Do brute force surface rebuild for even parameterization @param surface: Nurbs surface to rebuild @type surface: str @param spansU: Number of spans along U. If 0, keep original value. @type spansU: int @param spansV: Number of spans along V. If 0, keep original value. @type spansV: int @param replaceOrig: Replace original surface, or create new rebuilt surface. @type replaceOrig: bool """ # ========== # - Checks - # ========== # Check surface if not isSurface(surface): raise Exception('Object "' + surface + '" is not a valid surface!') # Check spans if not spansU: spansU = cmds.getAttr(surface + '.spansU') if not spansV: spansV = cmds.getAttr(surface + '.spansV') # ============= # - Rebuild U - # ============= # Get V range if rebuildUfirst: dir = 'u' opp = 'v' spans = spansU min = cmds.getAttr(surface + '.minValueV') max = cmds.getAttr(surface + '.maxValueV') else: dir = 'v' opp = 'u' spans = spansV min = cmds.getAttr(surface + '.minValueU') max = cmds.getAttr(surface + '.maxValueU') val = min + (max - min) * 0.5 # Caluculate surface length iso_crv = cmds.duplicateCurve(surface + '.' + opp + '[' + str(val) + ']', ch=0, rn=0, local=0)[0] iso_len = cmds.arclen(iso_crv) iso_inc = iso_len / spans # Get spaced isoparm list curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [surface + '.' + dir + '[' + str(curveFn.findParamFromLength(iso_inc * i)) + ']' for i in range(spans + 1)] cmds.delete(iso_crv) # Check full rebuild if fullRebuildV: # Extract isoparm curves iso_crv_list = [cmds.duplicateCurve(iso, ch=False, rn=False, local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: cmds.rebuildCurve(iso_crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=0, d=3, tol=0) # Loft final surface int_surface = cmds.loft(iso_crv_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Delete intermediate curves cmds.delete(iso_crv_list) else: # Loft intermediate surface int_surface = cmds.loft(iso_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # ============= # - Rebuild V - # ============= # Get V range (intermediate surface) if rebuildUfirst: dir = 'u' opp = 'v' spans = spansV min = cmds.getAttr(int_surface + '.minValueU') max = cmds.getAttr(int_surface + '.maxValueU') else: dir = 'v' opp = 'u' spans = spansU min = cmds.getAttr(int_surface + '.minValueV') max = cmds.getAttr(int_surface + '.maxValueV') val = min + (max - min) * 0.5 # Caluculate surface length (intermediate surface) iso_crv = cmds.duplicateCurve(int_surface + '.' + opp + '[' + str(val) + ']', ch=0, rn=0, local=0)[0] iso_len = cmds.arclen(iso_crv) iso_inc = iso_len / spans # Get spaced isoparm list curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [int_surface + '.' + dir + '[' + str(curveFn.findParamFromLength(iso_inc * i)) + ']' for i in range(spans + 1)] cmds.delete(iso_crv) # Check full rebuild if fullRebuildU: # Extract isoparm curves iso_crv_list = [cmds.duplicateCurve(iso, ch=False, rn=False, local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: cmds.rebuildCurve(iso_crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=0, d=3, tol=0) # Loft final surface rebuild_surface = cmds.loft(iso_crv_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Delete intermediate curves cmds.delete(iso_crv_list) else: # Loft final surface rebuild_surface = cmds.loft(iso_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Rename rebuilt surface rebuild_surface = cmds.rename(rebuild_surface, surface + '_rebuild') rebuild_surfaceShape = cmds.listRelatives(surface, s=True, ni=True, pa=True)[0] cmds.delete(int_surface) # Re-parameterize 0-1 cmds.rebuildSurface(rebuild_surface, ch=False, rpo=True, dir=2, rt=0, end=1, kr=0, kcp=1, kc=1, tol=0, fr=0) # Initialize return value outputShape = rebuild_surfaceShape # ==================== # - Replace Original - # ==================== if replaceOrig: """ # Get original shape shapes = glTools.utils.shape.getShapes(surface,nonIntermediates=True,intermediates=False) if not shapes: # Find Intermediate Shapes shapes = glTools.utils.shape.listIntermediates(surface) # Check shapes if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') # Check connections if cmds.listConnections(shapes[0]+'.create',s=True,d=False): # Find Intermediate Shapes shapes = glTools.utils.shape.findInputShape(shapes[0]) """ # Check history shapes = cmds.listRelatives(surface, s=True, ni=True, pa=True) if not shapes: raise Exception('Unable to determine shape for surface "' + surface + '"!') shape = shapes[0] shapeHist = cmds.listHistory(shape) if shapeHist.count(shape): shapeHist.remove(shape) if shapeHist: print('Surface "" contains construction history, creating new shape!') # Override shape info and delete intermediate cmds.connectAttr(rebuild_surfaceShape + '.local', shape + '.create', f=True) outputShape = shape # ================= # - Return Result - # ================= return outputShape
#coding:utf-8 """ Author: Jiangjishi E-mail: [email protected] Created: 2016/5/20 18:39:28 Description: Instruction: auto create joints stretchy on translateX """ import maya.cmds as mc jnts = mc.ls(sl =True) cuv = mc.ls(sl =True)[0] mainCtl = mc.ls(sl=True)[0] + '.ScaleX' arcNode = mc.arclen(cuv,ch =True,) jntCount = len(jnts) axis = ("X","Y","Z") i = 0 # get the right scale value md1 = mc.createNode("multiplyDivide",n = 'md_scaleValue1') md2 = mc.createNode("multiplyDivide",n = 'md_scaleValue2') dftLength = mc.getAttr((arcNode + ".arcLength")) dftScale = mc.getAttr((mainCtl + ".ScaleX")) mc.setAttr((md1 + ".input1X"),dftLength ) mc.connectAttr((mainCtl + ".ScaleX") , (md1 + ".input1X")) for jnt in jnts:
def createLimb(self, controlSize): getGuide=cmds.ls("*_guide") spine=(cmds.ls("spine*_guide")) spineTwist=(cmds.ls("spine*_guide")) spineSection=len(spine)/3 sudoSpine=spine[:1]+[spine[spineSection]]+spine[-spineSection-1::spineSection+1]+spine[-1:] cmds.select(cl=1) lastSpineJoint=spine[-1:] for each in spine: jointSuffix='_jnt' getClass.rigJoints(each, jointSuffix) cmds.select(cl=1) for each in spine: jointSuffix='FK_jnt' getClass.rigJoints(each, jointSuffix) cmds.select(cl=1) for each in spine: jointSuffix='IK_jnt' getClass.rigJoints(each, jointSuffix) cmds.select(cl=1) #for each in spine[::2]: for each in spine: jointSuffix='_Clst_jnt' getClass.rigJoints(each, jointSuffix) resetOrient=[ "spine01_jnt", "spine01FK_jnt", "spine01IK_jnt", ] for each in resetOrient: cmds.joint( each, e=1, children=1, zso=1, oj='xyz', sao='yup', spa=1) cmds.select(cl=1) ################################## ################################## ################################## ################################## ######################CONTROLLERS translations=[".tx", ".ty", ".tz"] rotation=[".rx", ".ry", ".rz"] FKSpineJoints=[(each) for each in cmds.listRelatives("spine01FK_jnt", ad=1, typ="joint")] FKSpineJoints.append("spine01FK_jnt") fkSpine=sorted(FKSpineJoints) bindSpine=[(each) for each in cmds.listRelatives("spine01_jnt", ad=1, typ="joint") if "spine" in each] bindSpine.append("spine01_jnt") lastSpineJoint=bindSpine[-1:] lastSpine=lastSpineJoint[0].split("_") colour1=18 colour2=colour1 colour3=colour1 transformWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, ro=True) getClass.guideBuild(each, transformWorldMatrix, rotateWorldMatrix, colour1, colour2, colour3 ) getsel=cmds.ls(sl=1) cmds.setAttr(getsel[0]+".overrideColor", colour1) cmds.rename(getsel[0], "spineArmParent_nod") getsel=cmds.ls(sl=1) getClass.buildGrp(getsel[0]) clusterSpline=cmds.ls("spine*Clst_jnt") CLSspine=cmds.listRelatives(clusterSpline[0], ad=1, typ="joint") spineFK_Ctrls=[] spineIK_CLSTR=[] spine=cmds.ls("spine*_guide") if spine[ len(spine) / 2 - 1] < spine[ len(spine) / 2 ]: clstrSplineCtrl=spine[ len(spine) / 2 - 1] else: clstrSplineCtrl=spine[ len(spine) / 2 ] # clstrSplineCnt= spine[::2] # #clstrSplineCnt= spine # clstrSplineCtrl=clstrSplineCnt[1:-1] clstrCtrl=[] #create the hips transformWorldMatrix = cmds.xform(spine[:1], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[:1], q=True, wd=1, ro=True) name="Hips_Ctrl" grpname="Hips_grp" size=controlSize[0] colour=13 nrx=0 nry=1 nrz=0 getClass.buildCtrl(spine[:1], name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) spineFK_Ctrls.append("Hips_Ctrl") #spineFK_Ctrls.append(clstrCtrl)4 #create clusters for IK chain lognm=clstrSplineCtrl.replace("guide", "clst") name="Torso_IK_Ctrl" grpname="Torso_IK_grp" size=controlSize[1] colour=13 nrx=0 nry=1 nrz=0 transformWorldMatrix = cmds.xform(clstrSplineCtrl, q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(clstrSplineCtrl, q=True, wd=1, ro=True) getClass.buildCtrl(clstrSplineCtrl, name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) getClass.buildGrp(name) clstrCtrl.append(name) cmds.setAttr(name+".sx" , keyable=0, lock=1) cmds.setAttr(name+".sy" , keyable=0, lock=1) cmds.setAttr(name+".sz", keyable=0, lock=1) FKCtrl=[] spineguides=cmds.ls("spine*_guide") for each in spineguides[::2]: FKTorsoJoint=each.split("_guide")[0]+"FK_jnt" name=each.split("_guide")[0]+"_FK_ctrl" grpname=each.split("_guide")[0]+"_FK_grp" size=controlSize[1] colour=6 nrx=0 nry=1 nrz=0 transformWorldMatrix = cmds.xform(each, q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(each, q=True, wd=1, ro=True) getClass.buildCtrl(each, name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) spineFK_Ctrls.append(name) FKCtrl.append(name) cmds.parentConstraint(name, FKTorsoJoint , mo=1) name="LowerBody_Ctrl" grpname="LowerBody_grp" size=controlSize[0] colour=22 nrx=0 nry=1 nrz=0 transformWorldMatrix = cmds.xform(spine[1:2], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[1:2], q=True, wd=1, ro=True) getClass.buildCtrl(spine[:1], name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) name="WaistFollow_Ctrl" grpname="WaistFollow_grp" size=35 colour=22 nrx=0 nry=1 nrz=0 transformWorldMatrix = cmds.xform(spine[:1], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[:1], q=True, wd=1, ro=True) getClass.buildCtrl(spine[:1], name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) name="WaistFollow_offset_Ctrl" grpname="WaistFollow_offset_grp" size=controlSize[0] colour=23 nrx=0 nry=1 nrz=0 getClass.buildCtrl(spine[:1], name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) cmds.group( em=True, name='IK_grp' ) #create the main controller cmds.circle(n="Master_Ctrl", r=30, nrx=0, nry=1, nrz=0) cmds.setAttr("Master_CtrlShape.overrideEnabled", 1) cmds.setAttr("Master_CtrlShape.overrideColor", 13) getClass.buildGrp("Master_Ctrl") cmds.circle(n="Main_Ctrl", r=25, nrx=0, nry=1, nrz=0) cmds.setAttr("Main_CtrlShape.overrideEnabled", 1) cmds.setAttr("Main_CtrlShape.overrideColor", 17) getClass.buildGrp("Main_Ctrl") cmds.circle(n="Main_offset_Ctrl", r=27, nrx=0, nry=1, nrz=0) cmds.setAttr("Main_offset_CtrlShape.overrideEnabled", 1) cmds.setAttr("Main_offset_CtrlShape.overrideColor", 23) getClass.buildGrp("Main_offset_Ctrl") #create the IK controller name="Chest_IK_Ctrl" grpname="ChestIK_grp" num=controlSize[1] colour=13 nrx=0 nry=1 nrz=0 transformWorldMatrix = cmds.xform(spine[-2:-1], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[-2:-1], q=True, wd=1, ro=True) # transformWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, t=True) # rotateWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, ro=True) getClass.buildCtrl(each, name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) #getClass.squareI(name, grpname, num, transformWorldMatrix, rotateWorldMatrix, colour) cmds.makeIdentity("Chest_IK_Ctrl", a=True, t=1, s=1, r=1, n=0) OrigName="Chest_FK" num=controlSize[1] colour=6 nrx=0 nry=1 nrz=0 eachPiece=OrigName+"_jnt" name=OrigName+"_Ctrl" grpname=OrigName+"_grp" transformWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, t=True) rotateWorldMatrix = cmds.xform(spine[-1:], q=True, wd=1, ro=True) getClass.buildCtrl(each, name, grpname,transformWorldMatrix, rotateWorldMatrix, size, colour, nrx, nry, nrz) cmds.makeIdentity("Chest_FK_Ctrl", a=True, t=1, s=1, r=1, n=0) spineFK_Ctrls.append("Chest_FK_Ctrl") #IK #'''-------------------------------------- # SPINE #--------------------------------------''' spineJoints=(cmds.ls("spine*_jnt")) lastJoint=spineJoints[-1:] spineTwistJnt=(cmds.ls("spine*IK_jnt")) spineLow=(cmds.ls("spine*FK_jnt")) spineCtrl=(cmds.ls("spine*_Ctrl")) #spineCtrlGrp=cmds.pickWalk(spineCtrl, d="up") '''-------------------------------------- # set axis for scale --------------------------------------''' scaleAxis='X' lastSpineJoint=spineTwistJnt[-1:] allButLastspineJoints=spineJoints[:-1] '''-------------------------------------- # create spline IK --------------------------------------''' cmds.ikHandle(n="spineIK", sj="spine01IK_jnt", ee=str(lastSpineJoint[0]), sol="ikSplineSolver", scv=0, ns=4, rtm=1) '''-------------------------------------- # find the spline of the IK --------------------------------------''' list=cmds.listConnections('spineIK', t="shape") cmds.rename(list, "spineIK_crv") '''-------------------------------------- # get length of spline --------------------------------------''' curvInf=cmds.arclen("spineIK_crv", ch=1) '''-------------------------------------- # connect the length to a multiplyDivide --------------------------------------''' MDshader=cmds.shadingNode( "multiplyDivide", au=1) '''-------------------------------------- # set multiplyDivide to Divide --------------------------------------''' cmds.setAttr(str(MDshader)+".operation", 2) '''-------------------------------------- # connect length of spline to MD node --------------------------------------''' cmds.connectAttr(curvInf+".arcLength", MDshader+".input1"+scaleAxis, f=1) '''-------------------------------------- # input the length into the second input --------------------------------------''' spineCrvLength=cmds.getAttr(MDshader+".input1"+scaleAxis) cmds.setAttr(MDshader+".input2"+scaleAxis,spineCrvLength) '''-------------------------------------- # skinbind lowres spine to the spline --------------------------------------''' for each in CLSspine: cmds.bindSkin(each,"spineIK_crv") #cmds.bindSkin(clusterSpline[0],"spineIK_crv") cmds.addAttr("Hips_Ctrl", ln="spineFK_IK", min=0, max=1, at="double",en="FK:IK:", k=1, nn="spineFK_IK") cmds.setAttr("Hips_Ctrl.spineFK_IK", 1) Controller="Hips_Ctrl.spineFK_IK" baseSpine=[(each.split("_")[0])for each in bindSpine] #IK setup for each in baseSpine: getClass.blendColors(each, Controller) getSortedclusterSpline=cmds.ls("spine*_Clst_jnt") if getSortedclusterSpline[ len(getSortedclusterSpline) / 2 - 1] < getSortedclusterSpline[ len(getSortedclusterSpline) / 2 ]: clstrSplineCtrl=getSortedclusterSpline[ len(getSortedclusterSpline) / 2 - 1] else: clstrSplineCtrl=getSortedclusterSpline[ len(getSortedclusterSpline) / 2 ] cmds.pointConstraint(clstrCtrl, clstrSplineCtrl, mo=1) num0, num1, num2, num3 = 1, .5, .7, .9 colour=13 for each in getSortedclusterSpline[1:-1]: name=each+"_Ctrl" grpname=each+"_grp" cmds.parent(each, w=1) getTranslation, getRotation=getClass.locationXForm(each) getClass.CCCircle(name, grpname, num0, num1, num2, num3,getTranslation, getRotation, colour) cmds.parentConstraint(name, each) fkSpine=sorted(FKSpineJoints) ChildActivatedValue=1 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Controller="Hips_Ctrl.spineFK_IK" defaultSet=1 for each in clstrCtrl: Child=each+".visibility" getClass.controlSecondValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) #constrain FK spin to controls #cmds.parent(spineFK_Ctrls[0], "Hips_Ctrl") cmds.pointConstraint("Hips_Ctrl", "spine01_jnt", mo=1) cmds.orientConstraint("Chest_FK_Ctrl", fkSpine[-1], mo=1) ChildActivatedValue=1 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Child="Chest_IK_Ctrl.visibility" Controller="Hips_Ctrl.spineFK_IK" defaultSet=1 getClass.controlSecondValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) ChildActivatedValue=1 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Child="Chest_FK_Ctrl.visibility" Controller="Hips_Ctrl.spineFK_IK" defaultSet=1 getClass.controlFirstValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) #stretch getIKClass.stretchSpline("spine01IK_jnt") cmds.addAttr("Hips_Ctrl", ln="StretchSpine", at="enum",en="on:off:", k=1, nn="StretchSpine") ChildActivatedValue=2 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Child="spine01IK_jnt_cond.operation" Controller="Hips_Ctrl.StretchSpine" defaultSet=0 getClass.controlFirstValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) ChildActivatedValue=1 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Controller="Hips_Ctrl.spineFK_IK" defaultSet=1 for each in FKCtrl: Child=each+".visibility" getClass.controlFirstValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) cmds.setAttr("Hips_Ctrl.spineFK_IK", 1) cmds.parent("Main_Ctrl_grp", "Main_offset_Ctrl") cmds.parent("Main_offset_Ctrl_grp", "Master_Ctrl") lastClstr=cmds.listRelatives(clstrCtrl, ap=1) firstClstr=cmds.listRelatives(clstrCtrl, ap=1) # else: lastFK=cmds.listRelatives(FKCtrl, ap=1) firstFK=cmds.listRelatives(FKCtrl, ap=1) lastFKCtrl=FKCtrl firstFKCtrl=FKCtrl bindSpine=[(each) for each in cmds.listRelatives("spine01_jnt", ad=1, typ="joint") if "spine" in each] cmds.parent(firstFK, "Hips_Ctrl") cmds.parent("Hips_grp","LowerBody_Ctrl") cmds.parent("ChestIK_grp","LowerBody_Ctrl") cmds.parent("LowerBody_grp","Main_Ctrl") cmds.parent("spine01_jnt","Hips_Ctrl") cmds.parent("spine01FK_jnt","Hips_Ctrl") cmds.parent("spine01IK_jnt","Hips_Ctrl") cmds.connectAttr("Chest_IK_Ctrl.rotate.rotateY", "spineIK.twist") cmds.parent("Main_offset_Ctrl_grp", "WaistFollow_Ctrl") cmds.parent("WaistFollow_grp", "WaistFollow_offset_Ctrl") cmds.parent("WaistFollow_offset_grp", "Master_Ctrl") cmds.setAttr("WaistFollow_CtrlShape.visibility" , 0) cmds.setAttr("WaistFollow_offset_CtrlShape.visibility" , 0) spineChildBones=[(each) for each in cmds.listRelatives('spine01_jnt', ad=1, typ="joint") if "spine" in each] cmds.parent("spineIK","Chest_IK_Ctrl") cmds.parent("spineArmParent_nod_grp", spineChildBones[0]) seq=cmds.ls("spine*Clst_jnt") size=3 getClusterChunk=[] getMiddleClusters=[] splitsize = 1.0/size*len(seq) for i in range(size): getClusterChunk.append(seq[int(round(i*splitsize)):int(round((i+1)*splitsize))]) # getClusterChunk=[seq[i:i+size] for i in range(0, len(seq), size)] for each in getClusterChunk[0]: cmds.parent(each, "Hips_Ctrl") if len(getClusterChunk[0])>1: cmds.parent(getClusterChunk[0][-1:],"Torso_IK_Ctrl") else: pass for each in getClusterChunk[1]: cmds.parent(each,"Torso_IK_Ctrl") for each in getClusterChunk[2]: cmds.parent(each, "Chest_IK_Ctrl") if len(getClusterChunk[2])>1: cmds.parent(getClusterChunk[2][0],"Torso_IK_Ctrl") else: pass poleAxis=("X", "Y", "Z") for each in poleAxis: cmds.connectAttr("Chest_IK_Ctrl.rotate.rotate"+each, "spineIK.poleVector.poleVector"+each) getMidClstr=cmds.ls("spine*_Clst_jnt_grp") num = float(len(getMidClstr))/size getMiddleClusters = [ getMidClstr [i:i + int(num)] for i in range(0, (size-1)*int(num), int(num))] getMiddleClusters.append(getMidClstr[(size-1)*int(num):]) if len(getMiddleClusters[0])>1: cmds.parentConstraint("Hips_Ctrl", getMiddleClusters[0][0], mo=1, w=.8) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[0][0], mo=1, w=.2) cmds.parentConstraint("Hips_Ctrl", getMiddleClusters[0][1], mo=1, w=.4) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[0][1], mo=1, w=.6) else: cmds.parentConstraint("Hips_Ctrl", getMiddleClusters[0], mo=1, w=1.0) if len(getMiddleClusters[1])>1: cmds.parentConstraint("Hips_Ctrl", getMiddleClusters[1][0], mo=1, w=.3) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[1][0], mo=1, w=.7) cmds.parentConstraint("Chest_IK_Ctrl", getMiddleClusters[1][1], mo=1, w=.3) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[1][1], mo=1, w=.7) else: cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[1], mo=1, w=1.0) if len(getMiddleClusters[2])>1: cmds.parentConstraint("Chest_IK_Ctrl", getMiddleClusters[2][0], mo=1, w=.4) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[2][0], mo=1, w=.6) cmds.parentConstraint("Chest_IK_Ctrl", getMiddleClusters[2][1], mo=1, w=.8) cmds.parentConstraint("Torso_IK_Ctrl", getMiddleClusters[2][1], mo=1, w=.2) else: cmds.parentConstraint("Chest_IK_Ctrl", getMiddleClusters[2], mo=1, w=1.0) cmds.parentConstraint( "Hips_Ctrl", "Torso_IK_grp",mo=1, w=.50) cmds.parentConstraint( "Chest_IK_Ctrl", "Torso_IK_grp",mo=1, w=.50) #lock off head cmds.parentConstraint("spineIK","spineArmParent_nod_grp", mo=1) ChildActivatedValue=1 ChildDeactivatedValue=0 ControllerSecondValue=1 ControllerFirstValue=0 Child="spineArmParent_nod_grp_parentConstraint1.spineIKW0" Controller="Hips_Ctrl.spineFK_IK" defaultSet=1 getClass.controlSecondValueChildOn(Controller, Child, defaultSet, ChildActivatedValue, ChildDeactivatedValue, ControllerSecondValue, ControllerFirstValue) #create control on the ends of the IK spline #cmds.disconnectAttr("spine01IK_jnt_cond.outColorR", "spine06IK_jnt.scale.scaleX") cmds.disconnectAttr("spine01IK_jnt_cond.outColorR", "spine07IK_jnt.scale.scaleX") cmds.disconnectAttr("spine01IK_jnt_cond.outColorR", "spine01IK_jnt.scale.scaleX") #lock off IK spline Vector="X" YUpswitch=0 cmds.setAttr("spineIK.dTwistControlEnable", 0) cmds.setAttr("spineIK.dWorldUpType", 4) cmds.setAttr("spineIK.dWorldUpAxis", 1) cmds.connectAttr("Hips_Ctrl.xformMatrix", "spineIK.dWorldUpMatrix", f=1) cmds.connectAttr("Chest_IK_Ctrl.xformMatrix", "spineIK.dWorldUpMatrixEnd", f=1) cmds.setAttr("spineIK.dWorldUpVector"+Vector, 1) cmds.setAttr("spineIK.dWorldUpVectorEnd"+Vector, 1) if YUpswitch==0: cmds.setAttr("spineIK.dWorldUpVectorY", YUpswitch) cmds.setAttr("spineIK.dWorldUpVectorEndY", YUpswitch) else: pass cmds.setAttr("spineIK.ikFkManipulation", 1) if len(FKCtrl)>1: lastFK=cmds.listRelatives(FKCtrl[-1:], ap=1) firstFK=cmds.listRelatives(FKCtrl[:1], ap=1) lastFKCtrl=FKCtrl[-1:] firstFKCtrl=FKCtrl[:1] for eachctrl in xrange(len(FKCtrl) - 1): current_item, next_item = FKCtrl[eachctrl], FKCtrl[eachctrl + 1] getParentgrp=cmds.listRelatives(next_item, ap=1) cmds.parent(getParentgrp[0], current_item) cmds.parent("Chest_FK_grp", FKCtrl[-1:]) else: cmds.parent("Chest_FK_grp", FKCtrl[0])
def install(self, *args): # Collect layout info print "Install" sel = cmds.ls(sl=True) userDefinedName = sel[0].partition('PartRoot_')[0] lytObs = part_utils.collectLayoutInfo(sel) # Find the side we are on #side = part_utils.getSide(self.lyt_info['layoutRoot']) # Create an rig joint chain self.jnt_info['rigJnts'] = part_utils.createJoints('rigj_', lytObs) # Create an ik joint chain self.jnt_info['iksJnts'] = part_utils.createJoints('ikSj_', lytObs) self.jnt_info['ikrJnts'] = part_utils.createJoints('ikRj_', lytObs) #self.jnt_info['ikJnts'] = part_utils.createJoints('ikj_', lytObs) spl = len(self.jnt_info['iksJnts']) -1 # Create a new joint at the root and the top of the iksJoint chain. rootJointList = (['ikBRoot_'+userDefinedName, cmds.xform(self.jnt_info['iksJnts'][0], q=True, ws=True, t=True)], ['ikTRoot_'+userDefinedName, cmds.xform(self.jnt_info['iksJnts'][spl], q=True, ws=True, t=True)]) rootJoints = [] for i in rootJointList: cmds.select(d=True) rootJoints.append(cmds.joint(n=i[0], p=i[1])) cmds.select(d=True) self.jnt_info['rootJnts'] = rootJoints # Define names for components involved in ik setup #ikHandleName = "ikHandle_%s_leg" % (side) ikHandleName = userDefinedName + 'ikh' #ctrlName = "ctrl_%s_leg" % (side) ctrlName = userDefinedName + 'ctrl' # Draw a splineIK from the root to the last iksJnt. ikSol = cmds.ikHandle(n='iks_spine_Ik', solver='ikSplineSolver', sj=self.jnt_info['iksJnts'][0], ee=self.jnt_info['iksJnts'][spl], ccv=True) cmds.select(d=True) # Bind the splineIK curve to those 2 new joints. cmds.select('curve1', rootJoints) cmds.skinCluster(tsb=True) #Rename the curve cmds.rename('curve1', userDefinedName+'_aSpine_curve') # Draw an iKhandle between each self.jnt_info['ikrJnts'] ikHandles = [] for j in range(spl): if j < spl: ikh = cmds.ikHandle( n='ikH_'+ self.jnt_info['ikrJnts'][j], sol='ikRPsolver', sj=self.jnt_info['ikrJnts'][j], ee=self.jnt_info['ikrJnts'][j+1] ) cmds.parent(ikh, self.jnt_info['iksJnts'][j]) ikHandles.append(ikh) # Point constrain 1st iks to 1st ikb for j in range(spl+1): cmds.pointConstraint(self.jnt_info['iksJnts'][j], self.jnt_info['ikrJnts'][j], mo=True) cmds.pointConstraint(self.jnt_info['ikrJnts'][j], self.jnt_info['rigJnts'][j], mo=True) # Create a locator for each ikh locator_groups = [] for i in range(spl+1): bPos = cmds.xform(self.jnt_info['iksJnts'][i], q=True, ws=True, t=True) nPos = [bPos[0], bPos[1], bPos[2]+1.0] lctr = cmds.spaceLocator(name='lctr_'+self.jnt_info['iksJnts'][i], a=True) cmds.xform(lctr, ws=True, t=nPos) grp = cmds.group(name='grp_lctr_'+self.jnt_info['iksJnts'][i], em=True) cmds.xform(grp, ws=True, t=bPos) cmds.parent(lctr, grp) # Create pole vector constraints if i < spl: cmds.poleVectorConstraint(lctr, ikHandles[i][0]) cmds.parent(grp, self.jnt_info['iksJnts'][i]) cmds.makeIdentity( grp, apply=True ) locator_groups.append(grp) self.jnt_info['locator_groups'] = locator_groups # Create PMA nodes to control the twist # NOTE: This is tricky if we want to allow for more joints. For now I am coding for 5 but need a solution for more. pma_nodes = [] for i in range(spl+1): if spl > 5: print " I currently only support 5 joints" return else: pmaNode_Name = self.jnt_info['iksJnts'][i].replace('ikSj', 'pmaTwist_') pma = cmds.shadingNode("plusMinusAverage", asUtility=True, n=pmaNode_Name) cmds.setAttr(pma+'.operation', 3) #average pma_nodes.append(pma) # Now connect the Pma self.jnt_info['twistPma'] = pma_nodes cmds.connectAttr(self.jnt_info['rootJnts'][0] + '.ry', self.jnt_info['twistPma'][2]+'.input1D[0]') cmds.connectAttr(self.jnt_info['rootJnts'][1] + '.ry', self.jnt_info['twistPma'][2]+'.input1D[1]') cmds.connectAttr(self.jnt_info['twistPma'][2]+'.output1D', self.jnt_info['locator_groups'][2] +'.rx') cmds.connectAttr(self.jnt_info['twistPma'][0]+'.output1D', self.jnt_info['twistPma'][1]+'.input1D[0]') cmds.connectAttr(self.jnt_info['rootJnts'][0] + '.ry', self.jnt_info['twistPma'][1]+'.input1D[1]') cmds.connectAttr(self.jnt_info['twistPma'][1]+'.output1D', self.jnt_info['locator_groups'][1] +'.rx') cmds.connectAttr(self.jnt_info['rootJnts'][0] + '.ry', self.jnt_info['twistPma'][0]+'.input1D[0]') cmds.connectAttr(self.jnt_info['twistPma'][0]+'.output1D', self.jnt_info['locator_groups'][0] +'.rx') cmds.connectAttr(self.jnt_info['rootJnts'][0] + '.ry', self.jnt_info['twistPma'][3]+'.input1D[0]') cmds.connectAttr(self.jnt_info['twistPma'][2]+'.output1D', self.jnt_info['twistPma'][3]+'.input1D[1]') cmds.connectAttr(self.jnt_info['twistPma'][3]+'.output1D', self.jnt_info['locator_groups'][3] +'.rx') cmds.connectAttr(self.jnt_info['rootJnts'][1] + '.ry', self.jnt_info['twistPma'][4]+'.input1D[0]') cmds.connectAttr(self.jnt_info['twistPma'][4]+'.output1D', self.jnt_info['locator_groups'][4] +'.ry') # Make the spine stretch. # NOTE: Try the expression method # NOTE: Add stretch ammount attribute. #cmds.expression( s= 'surface1.sx = %s.arcLength' % curveInfoNode ) curveInfoNode = cmds.arclen(userDefinedName+'_aSpine_curve', ch=True) mdsNode_Name = self.jnt_info['iksJnts'][0].replace('ikSj', 'mdStretch') mds = cmds.shadingNode("multiplyDivide", asUtility=True, n=mdsNode_Name) cmds.setAttr(mds+'.operation', 2) #divide cmds.connectAttr(curveInfoNode+'.arcLength', mds+'.input1X') #cmds.connectAttr(curveInfoNode+'.arcLength', mda+'.input2X') crvLen = cmds.getAttr(curveInfoNode+'.arcLength') print crvLen cmds.setAttr(mds+'.input2X', crvLen) # Connect stretch to joints for i in range(len(self.jnt_info['iksJnts'])-1): cmds.connectAttr(mds+'.outputX', self.jnt_info['iksJnts'][i]+'.sx') cmds.rename(curveInfoNode, userDefinedName+'_curveInfo') # Setup controls suffix = userDefinedName ctrlAttrs = [] for i in range(len(self.jnt_info['rootJnts'])): ctrlName = userDefinedName + 'ctrl_' + str(i) ctrlPos = cmds.xform(self.jnt_info['rootJnts'][i], q=True, ws=True, t=True) # NOTE: Dynamically generate the control objects spineControl = part_utils.setupControlObject("SpineControl.ma", ctrlName, ctrlAttrs, ctrlPos, os.environ['Parts_Maya_Controls']) cmds.parentConstraint(spineControl, self.jnt_info['rootJnts'][i])
def __init__( self , ikJnts = [] , ikUpJnts = [] , ikPosJnts = [] , ikCtrlJnts = [] , ikCrv = '' , ikUpCrv = '' , ax = 'y' , aimVec = (0,1,0) , upVec = (1,0,0 ) , name = '' , side = '' ) : # Info self.ik_crv = pc.Dag( ikCrv ) self.ikUp_crv = pc.Dag( ikUpCrv ) self.ikJnts = ikJnts self.ikUpJnts = ikUpJnts self.ikPosJnts = [] self.ikOrig_crv = pc.Dag( mc.duplicate( self.ik_crv , rr=True )[0] ) self.ikUpOrig_crv = pc.Dag( mc.duplicate( self.ikUp_crv , rr=True )[0] ) self.ikOrig_crv.name = '%sOrig%s_crv' % ( name , side ) self.ikUpOrig_crv.name = '%sUpOrig%s_crv' % ( name , side ) # Pos joints if not ikPosJnts : # In case of pos joints have not been prepared for ix in range( len( self.ikJnts ) ) : jnt = rigTools.jointAt( self.ikJnts[ix] ) jnt.name = '%sPos%s%s_jnt' % ( name , (ix+1) , side ) self.ikPosJnts.append( jnt ) if ix > 0 : self.ikPosJnts[ ix ].parent( self.ikPosJnts[ ix - 1 ] ) else : self.ikPosJnts = ikPosJnts print self.ikPosJnts # Main group self.rig_grp = pc.group( em=True , n='%sRig%s_grp' % ( name , side ) ) self.jnt_grp = pc.group( em=True , n='%sJnt%s_grp' % ( name , side ) ) self.still_grp = pc.group( em=True , n='%sStill%s_grp' % ( name , side ) ) self.ikh_grp = pc.group( em=True , n='%sIkh%s_grp' % ( name , side ) ) self.worOri_grp = pc.group( em=True , n='%sWorOri%s_grp' % ( name , side ) ) mc.parent( self.ikPosJnts[0] , self.jnt_grp ) mc.parent( self.ikUpJnts[0] , self.jnt_grp ) mc.parent( self.ikJnts[0] , self.jnt_grp ) mc.parent( self.worOri_grp , self.still_grp ) # IK controller self.ikCtrl_grp = pc.group( em=True , n='%sIkCtrl%s_grp' % ( name , side ) ) self.ctrls = [] self.gmblCtrls = [] self.ctrlZros = [] for ix in range( len( ikCtrlJnts ) ) : currCtrl = rigTools.jointControl( 'cube' ) currGmbl = pc.addGimbal( currCtrl ) currZro = rigTools.zeroGroup( currCtrl ) currCtrl.color = 'blue' currCtrl.name = '%sIk%s%s_ctrl' % ( name , (ix+1) , side ) currGmbl.name = '%sIk%sGmbl%s_ctrl' % ( name , (ix+1) , side ) currZro.name = '%sIkCtrl%sZro%s_grp' % ( name , (ix+1) , side ) currZro.snap( ikCtrlJnts[ix] ) currCtrl.lockHideAttrs( 'sx' , 'sy' , 'sz' , 'v' ) mc.parentConstraint( currCtrl , ikCtrlJnts[ix] ) mc.parent( ikCtrlJnts[ix] , self.jnt_grp ) self.ctrls.append( currCtrl ) self.gmblCtrls.append( currGmbl ) self.ctrlZros.append( currZro ) if not ix == 0 : mc.parent( currZro , self.gmblCtrls[0] ) locGrp,worGrp,worParCon,zroParCon,locWorRev = rigTools.parentLocalWorldCtrl( currCtrl , self.gmblCtrls[0] , self.worOri_grp , currZro ) locGrp.name = '%sIk%sCtrlLocOri%s_grp' % ( name , (ix+1) , side ) worGrp.name = '%sIk%sCtrlWorOri%s_grp' % ( name , (ix+1) , side ) worParCon.name = '%sIk%sCtrlWorOriGrp%s_parCons' % ( name , (ix+1) , side ) locWorRev.name = '%sIk%sCtrlLocWorOri%s_rev' % ( name , (ix+1) , side ) mc.parent( self.ctrlZros[0] , self.ikCtrl_grp ) mc.parent( self.ikCtrl_grp , self.rig_grp ) # IK handle self.ik_ikh = pc.Ik( mc.ikHandle( sol='ikSplineSolver' , createCurve=False , parentCurve=False , curve=self.ik_crv , startJoint=self.ikPosJnts[0], endEffector=self.ikPosJnts[-1] )[0] ) self.ikUp_ikh = pc.Ik( mc.ikHandle( sol='ikSplineSolver' , createCurve=False , parentCurve=False , curve=self.ikUp_crv , startJoint=self.ikUpJnts[0], endEffector=self.ikUpJnts[-1] )[0] ) self.ik_ikh.name = '%sPos%s_ikh' % ( name , side ) self.ikUp_ikh.name = '%sUp%s_ikh' % ( name , side ) self.ik_ikh.parent( self.ikh_grp ) self.ikUp_ikh.parent( self.ikh_grp ) self.ik_crv.parent( self.still_grp ) self.ikUp_crv.parent( self.still_grp ) upCrvShp = pc.Dag( self.ikUp_crv ) # upCrvShp.attr( 'overrideEnabled' ).v = 1 # upCrvShp.attr( 'overrideDisplayType' ).v = 2 # Ori joints self.ikOriJnts = [] for ix in range( len( self.ikPosJnts ) ) : jnt = rigTools.jointAt( self.ikPosJnts[ix] ) # jnt = rigTools.jointAt( self.ikJnts[ix] ) jnt.name = '%sOri%s%s_jnt' % ( name , (ix+1) , side ) jnt.parent( self.ikPosJnts[ix] ) self.ikOriJnts.append( jnt ) # Aim constraints for ix in range( len( self.ikOriJnts ) ) : if ix < ( len( self.ikOriJnts ) - 1 ) : pc.aimConstraint( self.ikOriJnts[ ix+1 ] , self.ikOriJnts[ ix ] , aim = aimVec , u = upVec , wut = 'object' , wuo = self.ikUpJnts[ ix ] , wu = upVec ) # Detail controller self.dtlCtrl_grp = pc.group( em=True ) self.dtlCtrl_grp.name = '%sDtlCtrl%s_grp' % ( name , side ) self.dtlCtrl_grp.parent( self.rig_grp ) self.dtlCtrls = [] self.dtlCtrlOriGrps = [] self.dtlCtrlZroGrps = [] for ix in range( len( self.ikOriJnts ) ) : ctrl = pc.Control( 'circle' ) ctrlOriGrp = pc.group( ctrl ) ctrlZroGrp = pc.group( ctrlOriGrp ) ctrl.color = 'softBlue' ctrl.name = '%sDtl%s%s_ctrl' % ( name , (ix+1) , side ) ctrlOriGrp.name = '%sDtl%sCtrlOri%s_grp' % ( name , (ix+1) , side ) ctrlZroGrp.name = '%sDtl%sCtrlZro%s_grp' % ( name , (ix+1) , side ) mc.parentConstraint( self.ikOriJnts[ix] , ctrlZroGrp ) ctrlOriGrp.snap( self.ikJnts[ix] ) mc.parentConstraint( ctrl , self.ikJnts[ix] ) mc.scaleConstraint( ctrl , self.ikJnts[ix] ) ctrlZroGrp.parent( self.dtlCtrl_grp ) self.dtlCtrls.append( ctrl ) self.dtlCtrlOriGrps.append( ctrlOriGrp ) self.dtlCtrlZroGrps.append( ctrlZroGrp ) ikCtrlShp = pc.Dag( self.ctrls[0].shape ) ikCtrlShp.add( ln='detailVis' , k=True , min=0 , max=1 ) ikCtrlShp.attr( 'detailVis' ) >> self.dtlCtrl_grp.attr('v') # Auto-Stretch self.ctrls[0].add( ln='autoStretch' , min=0 , max=1 , k=True ) self.ikOrig_crv.parent( self.rig_grp ) self.ikUpOrig_crv.parent( self.rig_grp ) self.ikOrig_crv.attr('v').v = 0 self.ikUpOrig_crv.attr('v').v = 0 self.ikCrvLen_cif = pc.Dag( mc.arclen( self.ik_crv , ch=True ) ) self.ikUpCrvLen_cif = pc.Dag( mc.arclen( self.ikUp_crv , ch=True ) ) self.ikOrigCrvLen_cif = pc.Dag( mc.arclen( self.ikOrig_crv , ch=True ) ) self.ikUpOrigCrvLen_cif = pc.Dag( mc.arclen( self.ikUpOrig_crv , ch=True ) ) self.ikCrvLen_cif.name = '%sCrvLen%s_cif' % ( name , side ) self.ikUpCrvLen_cif.name = '%sUpCrvLen%s_cif' % ( name , side ) self.ikOrigCrvLen_cif.name = '%sOrigCrvLen%s_cif' % ( name , side ) self.ikUpOrigCrvLen_cif.name = '%sUpOrigCrvLen%s_cif' % ( name , side ) self.ikStretch_mdv = pc.MultiplyDivide() self.ikUpStretch_mdv = pc.MultiplyDivide() self.ikStretch_mdv.name = '%sStretch%s_mdv' % ( name , side ) self.ikUpStretch_mdv.name = '%sUpStretch%s_mdv' % ( name , side ) self.ikStretch_mdv.attr( 'operation' ).v = 2 self.ikUpStretch_mdv.attr( 'operation' ).v = 2 self.ikCrvLen_cif.attr( 'arcLength' ) >> self.ikStretch_mdv.attr( 'i1x' ) self.ikUpCrvLen_cif.attr( 'arcLength' ) >> self.ikUpStretch_mdv.attr( 'i1x' ) self.ikStretch_bc = pc.BlendColors() self.ikUpStretch_bc = pc.BlendColors() self.ikStretch_bc.name = '%sStretch%s_bc' % ( name , side ) self.ikUpStretch_bc.name = '%sUpStretch%s_bc' % ( name , side ) self.ctrls[0].attr( 'autoStretch' ) >> self.ikStretch_bc.attr( 'blender' ) self.ctrls[0].attr( 'autoStretch' ) >> self.ikUpStretch_bc.attr( 'blender' ) self.ikCrvLen_cif.attr( 'arcLength' ) >> self.ikStretch_bc.attr( 'color2R' ) self.ikUpCrvLen_cif.attr( 'arcLength' ) >> self.ikUpStretch_bc.attr( 'color2R' ) self.ikOrigCrvLen_cif.attr( 'arcLength' ) >> self.ikStretch_bc.attr( 'color1R' ) self.ikUpOrigCrvLen_cif.attr( 'arcLength' ) >> self.ikUpStretch_bc.attr( 'color1R' ) self.ikStretch_bc.attr( 'outputR' ) >> self.ikStretch_mdv.attr( 'i2x' ) self.ikUpStretch_bc.attr( 'outputR' ) >> self.ikUpStretch_mdv.attr( 'i2x' ) self.ikPosMdvs = [] self.ikUpMdvs = [] for ix in range( 1 , len( self.ikPosJnts ) ) : posJnt = pc.Dag( self.ikPosJnts[ ix ] ) upJnt = pc.Dag( self.ikUpJnts[ ix ] ) posMdv = pc.MultiplyDivide() posMdv.name = '%sStretch%s%s_mdv' % ( name , (ix+1) , side ) upMdv = pc.MultiplyDivide() upMdv.name = '%sUpStretch%s%s_mdv' % ( name , (ix+1) , side ) origLen = posJnt.attr( 't%s'%ax ).v origUpLen = upJnt.attr( 't%s'%ax ).v posMdv.attr( 'i2x' ).v = origLen upMdv.attr( 'i2x' ).v = origUpLen self.ikStretch_mdv.attr( 'ox' ) >> posMdv.attr( 'i1x' ) self.ikUpStretch_mdv.attr( 'ox' ) >> upMdv.attr( 'i1x' ) posMdv.attr( 'ox' ) >> posJnt.attr( 't%s'%ax ) upMdv.attr( 'ox' ) >> upJnt.attr( 't%s'%ax ) self.ikPosMdvs.append( posMdv ) self.ikUpMdvs.append( upMdv )
def locatorEpCurve(curve,locatorScale=0.05,prefix=''): ''' Creates locators for each edit point for the specified curve. Edit points are constrained to the locator world positions. @param curve: Curve to operate on @type curve: str @param locatorScale: Control the relative scale of the locators to the length of curve @type locatorScale: float @param prefix: Name prefix for newly created nodes @type prefix: str @return: A list containing the names of the locators driving the curve @returnType: list ''' # Check curve if not isCurve(curve): raise Exception('Object '+curve+ ' is not a valid curve!') # Check curve shape curveShape='' if mc.objectType(curve) == 'transform': curveShape = mc.listRelatives(curve,s=1,ni=1)[0] else: curveShape = curve curve = mc.listRelatives(curve,p=1)[0] # Check prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(curve) # Get curve information spans = mc.getAttr(curve+'.spans') openCrv = not mc.getAttr(curve+'.form') numPt = spans + openCrv # Set locator scale locatorScale *= mc.arclen(curve) # Initialize return list locatorList=[] # Iterate over edit points for i in range(numPt): # Create point on curve deformer curveCon = mc.pointCurveConstraint(curveShape+'.ep['+str(i)+']',ch=1,rpo=1,w=1) locatorList.append(curveCon[0]) # Create standin locatorList entries for tangency points if openCrv: if not i: # Get start tangency point position pos = mc.pointPosition(curveShape+'.cv[1]') coord = closestPoint(curve,pos) # Create point on curve deformer curveCon = mc.pointCurveConstraint(curveShape+'.u['+str(coord)+']',ch=1,rpo=1,w=1) locatorList.append(curveCon[0]) if i == (numPt-2): # Get end tangency point position pos = mc.pointPosition(curveShape+'.cv['+str(numPt)+']') coord = closestPoint(curve,pos) # Create point on curve deformer curveCon = mc.pointCurveConstraint(curveShape+'.u['+str(coord)+']',ch=1,rpo=1,w=1) locatorList.append(curveCon[0]) for i in range(len(locatorList)): # Scale and Center Locator Pivots localOffset = mc.getAttr(locatorList[i]+'.localPosition')[0] mc.setAttr(locatorList[i]+'.translate',localOffset[0],localOffset[1],localOffset[2]) mc.setAttr(locatorList[i]+'.localPosition',0,0,0) mc.setAttr(locatorList[i]+'.localScale',locatorScale,locatorScale,locatorScale) # Rename Locator ind = str(i+1) if i<9: ind = '0' + ind locatorList[i] = mc.rename(locatorList[i],prefix+'ep'+ind+'_locator') # Return locator list return locatorList
def create(surface, spansU=0, spansV=0, prefix=None): """ """ # Load Plugins loadPlugin() # ========== # - Checks - # ========== # Check Surface if not glTools.utils.surface.isSurface(surface): raise Exception('Object "' + surface + '" is not a valid nurbs surface!') # Check Prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(surface) # Get Surface Details if not spansU: spansU = cmds.getAttr(surface + ".spansU") if not spansV: spansV = cmds.getAttr(surface + ".spansV") minU = cmds.getAttr(surface + ".minValueU") maxU = cmds.getAttr(surface + ".maxValueU") minV = cmds.getAttr(surface + ".minValueV") maxV = cmds.getAttr(surface + ".maxValueV") incU = (maxU - minU) / spansU incV = (maxV - minV) / spansV # ============= # - Rebuild U - # ============= crvU = [] for i in range(spansU + 1): # Duplicate Surface Curve dupCurve = cmds.duplicateCurve(surface + ".u[" + str(incU * i) + "]", ch=True, rn=False, local=False) dupCurveNode = cmds.rename(dupCurve[1], prefix + "_spanU" + str(i) + "_duplicateCurve") dupCurve = cmds.rename(dupCurve[0], prefix + "_spanU" + str(i) + "_crv") crvU.append(dupCurve) # Set Curve Length arcLen = cmds.arclen(dupCurve) setLen = cmds.createNode("setCurveLength", n=prefix + "_spanU" + str(i) + "_setCurveLength") crvInfo = cmds.createNode("curveInfo", n=prefix + "_spanU" + str(i) + "_curveInfo") blendLen = cmds.createNode("blendTwoAttr", n=prefix + "_spanU" + str(i) + "length_blendTwoAttr") cmds.addAttr(dupCurve, ln="targetLength", dv=arcLen, k=True) cmds.connectAttr(dupCurveNode + ".outputCurve", crvInfo + ".inputCurve", f=True) cmds.connectAttr(dupCurveNode + ".outputCurve", setLen + ".inputCurve", f=True) cmds.connectAttr(crvInfo + ".arcLength", blendLen + ".input[0]", f=True) cmds.connectAttr(dupCurve + ".targetLength", blendLen + ".input[1]", f=True) cmds.connectAttr(blendLen + ".output", setLen + ".length", f=True) cmds.connectAttr(setLen + ".outputCurve", dupCurve + ".create", f=True) # Add Control Attributes cmds.addAttr(dupCurve, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(dupCurve, ln="lengthBias", min=0, max=1, dv=0, k=True) cmds.connectAttr(dupCurve + ".lockLength", blendLen + ".attributesBlender", f=True) cmds.connectAttr(dupCurve + ".lengthBias", setLen + ".bias", f=True) # Loft New Surface srfU = cmds.loft(crvU, ch=True, uniform=True, close=False, autoReverse=False, degree=3) srfUloft = cmds.rename(srfU[1], prefix + "_rebuildU_loft") srfU = cmds.rename(srfU[0], prefix + "_rebuildU_srf") # Rebuild 0-1 rebuildSrf = cmds.rebuildSurface(srfU, ch=True, rpo=True, rt=0, end=1, kr=0, kcp=1, su=0, du=3, sv=0, dv=3, tol=0) rebuildSrfNode = cmds.rename(rebuildSrf[1], prefix + "_rebuildU_rebuildSurface") # Add Control Attributes cmds.addAttr(srfU, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(srfU, ln="lengthBias", min=0, max=1, dv=0, k=True) for crv in crvU: cmds.connectAttr(srfU + ".lockLength", crv + ".lockLength", f=True) cmds.connectAttr(srfU + ".lengthBias", crv + ".lengthBias", f=True) # ============= # - Rebuild V - # ============= crvV = [] for i in range(spansV + 1): # Duplicate Surface Curve dupCurve = cmds.duplicateCurve(srfU + ".v[" + str(incV * i) + "]", ch=True, rn=False, local=False) dupCurveNode = cmds.rename(dupCurve[1], prefix + "_spanV" + str(i) + "_duplicateCurve") dupCurve = cmds.rename(dupCurve[0], prefix + "_spanV" + str(i) + "_crv") crvV.append(dupCurve) # Set Curve Length arcLen = cmds.arclen(dupCurve) setLen = cmds.createNode("setCurveLength", n=prefix + "_spanV" + str(i) + "_setCurveLength") crvInfo = cmds.createNode("curveInfo", n=prefix + "_spanV" + str(i) + "_curveInfo") blendLen = cmds.createNode("blendTwoAttr", n=prefix + "_spanV" + str(i) + "length_blendTwoAttr") cmds.addAttr(dupCurve, ln="targetLength", dv=arcLen, k=True) cmds.connectAttr(dupCurveNode + ".outputCurve", crvInfo + ".inputCurve", f=True) cmds.connectAttr(dupCurveNode + ".outputCurve", setLen + ".inputCurve", f=True) cmds.connectAttr(crvInfo + ".arcLength", blendLen + ".input[0]", f=True) cmds.connectAttr(dupCurve + ".targetLength", blendLen + ".input[1]", f=True) cmds.connectAttr(blendLen + ".output", setLen + ".length", f=True) cmds.connectAttr(setLen + ".outputCurve", dupCurve + ".create", f=True) # Add Control Attribute cmds.addAttr(dupCurve, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(dupCurve, ln="lengthBias", min=0, max=1, dv=0, k=True) cmds.connectAttr(dupCurve + ".lockLength", blendLen + ".attributesBlender", f=True) cmds.connectAttr(dupCurve + ".lengthBias", setLen + ".bias", f=True) # Loft New Surface srfV = cmds.loft(crvV, ch=True, uniform=True, close=False, autoReverse=False, degree=3) srfVloft = cmds.rename(srfV[1], prefix + "_rebuildV_loft") srfV = cmds.rename(srfV[0], prefix + "_rebuildV_srf") # Rebuild 0-1 rebuildSrf = cmds.rebuildSurface(srfV, ch=True, rpo=True, rt=0, end=1, kr=0, kcp=1, su=0, du=3, sv=0, dv=3, tol=0) rebuildSrfNode = cmds.rename(rebuildSrf[1], prefix + "_rebuildV_rebuildSurface") # Add Control Attribute cmds.addAttr(srfV, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(srfV, ln="lengthBias", min=0, max=1, dv=0, k=True) for crv in crvV: cmds.connectAttr(srfV + ".lockLength", crv + ".lockLength", f=True) cmds.connectAttr(srfV + ".lengthBias", crv + ".lengthBias", f=True) # =================== # - Build Hierarchy - # =================== rebuildUGrp = cmds.group(em=True, n=prefix + "_rebuildU_grp") cmds.parent(crvU, rebuildUGrp) cmds.parent(srfU, rebuildUGrp) rebuildVGrp = cmds.group(em=True, n=prefix + "_rebuildV_grp") cmds.parent(crvV, rebuildVGrp) cmds.parent(srfV, rebuildVGrp) rebuildGrp = cmds.group(em=True, n=prefix + "_lockLength_grp") cmds.parent(rebuildUGrp, rebuildGrp) cmds.parent(rebuildVGrp, rebuildGrp) # ================= # - Return Result - # ================= return rebuildGrp
#print sorted(allParticleDictionary[curveParticleId].keys()) #print curveParticleId pointList = [] sortedKeyFrameList = sorted(allParticleDictionary[curveParticleId].keys()) if len(sortedKeyFrameList) > 1: for keyFrame in sortedKeyFrameList: pointList.append(allParticleDictionary[curveParticleId][keyFrame]) curveName = "partiCurve" + str(curveParticleId) curveObj = mc.curve(name=curveName, p=pointList) #For every locator we create, make a bubble and attach that to the locator in worldspace and parent in underneath getCurvLen = mc.arclen(curveObj) makeCvrLenInt = math.ceil(getCurvLen*.5)#reduces the amount of spans the curve has, this is useful on very long extrusions makeCircle = mc.circle(n="newCircle",d=1, s=12) aCircle = mc.planarSrf(makeCircle[0], n="extruTube", ch=1, d=1, ko=0, rn=0, po=1, nds=3) getTesInfo = mc.listConnections(aCircle[1], t="nurbsTessellate") mc.setAttr(getTesInfo[0] + ".polygonCount", 1) mc.setAttr(getTesInfo[0] + ".polygonType", 1) mc.setAttr(getTesInfo[0] + ".format", 0) getCurveCVPos = mc.xform(curveObj + ".cv[0]", ws=True, q=True, translation=True) mc.xform(makeCircle[0], ws=True, t=(getCurveCVPos[0], getCurveCVPos[1], getCurveCVPos[2]),ro=(90, 0, 0))#use "ro" to orient the circle to the curve if your extrusion is black tubes = mc.polyExtrudeFacet(aCircle[0] + ".f[0]", inc=curveObj, d=makeCvrLenInt)
def stretchyIkSpline_arcLength(ikHandle, scaleAxis='x', scaleAttr='', blendControl='', blendAttr='stretchScale', prefix=''): """ Build stretchy IK spline setup using the arc length of the input curve. @param ikHandle: IK Handle to create stretchy setup for @type ikHandle: str @param scaleAxis: Axis along which the ik joints will be scaled @type scaleAxis: str @param scaleAttr: World scale attribute @type scaleAttr: str @param blendControl: Control object that will contain the attribute to control the stretchy IK blending. If left at default (""), blending will not be enabled. @type blendControl: str @param blendAttr: The name of the attribute on blendControl that will control the stretchy IK blending. @type blendAttr: str @param prefix: Name prefix for builder created nodes @type prefix: str """ # Check prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(ikHandle) # Check objects if not cmds.objExists(ikHandle): raise UserInputError('IK handle ' + ikHandle + ' does not exist!') # Check blendControl blend = cmds.objExists(blendControl) if blend and not cmds.objExists(blendControl + '.' + blendAttr): cmds.addAttr(blendControl, ln=blendAttr, at='double', min=0, max=1, dv=1, k=True) blendAttr = blendControl + '.' + blendAttr # Get IK spline information ik_joints = glTools.utils.ik.getAffectedJoints(ikHandle) ik_curve = cmds.listConnections(ikHandle + '.inCurve', s=1, d=0, sh=1)[0] ik_length = cmds.arclen(ik_curve) # Setup multily node multDbl = cmds.createNode('multDoubleLinear', n=prefix + '_multDoubleLinear') cmds.setAttr(multDbl + '.input2', 1.0 / ik_length) # Setup blend blendNode = '' if blend: blendNode = cmds.createNode('blendTwoAttr', n=prefix + '_blendTwoAttr') cmds.addAttr(blendNode, ln=self.defaultScaleAttr, at='double', min=1, max=1, dv=1) cmds.connectAttr(blendAttr, blendNode + '.attributesBlender', f=True) cmds.connectAttr(blendNode + '.' + self.defaultScaleAttr, blendNode + '.input[0]', f=True) # Create curveInfo crvInfo = cmds.createNode('curveInfo', n=prefix + '_curveInfo') cmds.connectAttr(ik_curve + '.worldSpace[0]', crvInfo + '.inputCurve', f=True) # Connect multilyDivide cmds.connectAttr(crvInfo + '.arcLength', multDbl + '.input1', f=True) # Attach stretchy IK network to joint scale if blend: cmds.connectAttr(multDbl + '.output', blendNode + '.input[1]', f=True) # Attach output of blendNode to joint scale for i in range(len(ik_joints) - 1): cmds.connectAttr(blendNode + '.output', ik_joints[i] + '.s' + scaleAxis, f=True) else: for i in range(len(ik_joints) - 1): cmds.connectAttr(multDbl + '.output', ik_joints[i] + '.s' + scaleAxis, f=True) # Return result return [crvInfo, multDbl, blendNode]
def setup(self): #create a 2 joint chain so that we have them pointing correctly #duplicate start joint startJoint = cmds.duplicate( self.startJointDupe, po=True, n='startJoint' )[0] startJointPosition = cmds.xform( startJoint, q=True, ws=True, t=True ) endJoint = cmds.duplicate( self.endJointDupe, po=True, n='endJoint' )[0] endJointPosition = cmds.xform( endJoint, q=True, ws=True, t=True ) cmds.parent(endJoint, startJoint) #create joint chain for i in range( 0, self.jointAmmount ): jointNum = i+1 self.jointList.append( cmds.duplicate( startJoint, n= '{0}_{1}{2}'.format( self.name, nameSpace.SPLINE, str(jointNum) ), po=True )[0] ) #place them accordingly #get tx attr totalDist = cmds.getAttr( '{0}.tx'.format( endJoint )) iteration = totalDist/ (self.jointAmmount-1) cmds.setAttr('{0}.radius'.format(self.jointList[i]), 2.25) if i>0: cmds.parent( self.jointList[i], self.jointList[i-1] ) cmds.setAttr( '{0}.tx'.format(self.jointList[i]), iteration) cmds.setAttr( '{0}.ty'.format(self.jointList[i]), 0) cmds.setAttr( '{0}.tz'.format(self.jointList[i]), 0) #determine joint chain down axis will always be x #create curve loc = cmds.spaceLocator(n='inbetweenSpaceLoc')[0] cmds.parentConstraint( startJoint, endJoint, loc ) halfway = cmds.getAttr('{0}.translate'.format(loc)) points = [ startJointPosition, cmds.xform( loc, q=1, ws=1, t=1), endJointPosition ] print 'Start of curve created at: {0}'.format( str(startJointPosition) ) print 'End of curve created at: {0}'.format( str(endJointPosition) ) cmds.curve(ep=points, d=3, n=self.curve ) #delete the start and end joints, we don't need them anymore cmds.delete( startJoint, endJoint ) #delete the loc cmds.delete(loc) #Create the spline IKH self.ik = cmds.ikHandle( sol="ikSplineSolver", sj=self.jointList[0], ee=self.jointList[-1], ccv = False, c = self.curve, n ="{0}_splineIk".format(self.name) )[0] cmds.setAttr('{0}.dTwistControlEnable'.format(self.ik), 1 ) cmds.setAttr('{0}.dWorldUpType'.format(self.ik), 4 ) cmds.setAttr('{0}.v'.format(self.ik), 0 ) #add stretch to joints #create curveInfo node cmds.select( self.curve ) arc = cmds.arclen( ch=True ) arclen = '{0}_arcLength'.format(self.name) cmds.rename( arc, arclen ) #create mdn mdn = cmds.createNode( 'multiplyDivide', n='{0}_mdn'.format(self.name) ) #set mdn to divide cmds.setAttr('{0}.operation'.format(mdn), 2) #connect curveInfo.arcLength to mdn.input1X and mdn.input2X cmds.connectAttr( '{0}.arcLength'.format(arclen), '{0}.input1X'.format(mdn) ) #query distance dist = cmds.getAttr( '{0}.arcLength'.format(arclen) ) #set distance to input2 cmds.setAttr( '{0}.input2X'.format(mdn), dist ) #connect to all joints for jnt in self.jointList: cmds.connectAttr( '{0}.outputX'.format(mdn), '{0}.sx'.format(jnt) ) self.mdn = mdn
def createRibbon(axis=(0, 0, 1), name='xxxx', horizontal=False, numJoints=3, guias=None, v=True, s=0, firstLimb=True, upCtrl=None, ctrlRadius=1, worldRef="worldRef"): retDict = {} #define variables top_Loc = [] mid_Loc = [] bttm_Loc = [] rb_Jnt = [] drv_Jnt =[] fols = [] aux_Jnt = [] ribbon = '' extraCtrlList = [] #define attributes limbManualVVAttr = "limbManualVolume" limbVVAttr = "limbVolumeVariation" limbMinVVAttr = "limbMinVolume" #create a nurbsPlane based in the choose orientation option if horizontal: ribbon =cmds.nurbsPlane(ax=axis, w=numJoints, lr=(1/float(numJoints)), d=3, u=numJoints, v=1, ch=0, name=name+'_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, sv=1, du=3, dv=1, tol=0.01, fr=0, dir=1) else: ribbon =cmds.nurbsPlane(ax=axis, w=1, lr=numJoints, d=3, u=1, v=numJoints, ch=0, name=name+'_Plane')[0] cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, dv=3, tol=0.01, fr=0, dir=0) # make this ribbonNurbsPlane as not skinable from dpAR_UI: cmds.addAttr(ribbon, longName="doNotSkinIt", attributeType="bool", keyable=True) cmds.setAttr(ribbon+".doNotSkinIt", 1) #call the function to create follicles and joint in the nurbsPlane results = createFollicles(rib=ribbon, num=numJoints, name=name, horizontal=horizontal) rb_Jnt = results[0] fols = results[1] #create locator controls for the middle of the ribbon mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Pos_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Aim_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Off_Loc')[0]) mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Up_Loc')[0]) #parent correctly the middle locators cmds.parent(mid_Loc[2], mid_Loc[1], relative=True) cmds.parent(mid_Loc[1], mid_Loc[0], relative=True) cmds.parent(mid_Loc[3], mid_Loc[0], relative=True) #create the locators controls for the top of the ribbon top_Loc.append(cmds.spaceLocator(name=name+'_Top_Pos_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name+'_Top_Aim_Loc')[0]) top_Loc.append(cmds.spaceLocator(name=name+'_Top_Up_Loc')[0]) #parent correctly the top locators cmds.parent(top_Loc[1], top_Loc[0], relative=True) cmds.parent(top_Loc[2], top_Loc[0], relative=True) #create the locators for the end of the ribbon bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Pos_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Aim_Loc')[0]) bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Up_Loc')[0]) #parent correctly the bottom locators cmds.parent(bttm_Loc[1], bttm_Loc[0], relative=True) cmds.parent(bttm_Loc[2], bttm_Loc[0], relative=True) #put the top locators in the same place of the top joint cmds.parent(top_Loc[0], fols[len(fols)-1], relative=True) cmds.parent(top_Loc[0], w=True) #put the bottom locators in the same place of the bottom joint cmds.parent(bttm_Loc[0], fols[0], relative=True) cmds.parent(bttm_Loc[0], w=True) cmds.select(clear=True) #create the joints that will be used to control the ribbon drv_Jnt = cmds.duplicate([rb_Jnt[0], rb_Jnt[(len(rb_Jnt)-1)/2], rb_Jnt[len(rb_Jnt)-1]]) dup = cmds.duplicate([drv_Jnt[0], drv_Jnt[2]]) drv_Jnt.append(dup[0]) drv_Jnt.append(dup[1]) #cmds.parent(drv_Jnt, w=True) for jnt in drv_Jnt: cmds.joint(jnt, e=True, oj='none', ch=True, zso=True); cmds.setAttr(jnt+'.radius', cmds.getAttr(jnt+'.radius')+0.5) #rename created joints drv_Jnt[0] = cmds.rename(drv_Jnt[0], name+'_Drv_Bttm_Jxt') drv_Jnt[1] = cmds.rename(drv_Jnt[1], name+'_Drv_Mid_Jxt') drv_Jnt[2] = cmds.rename(drv_Jnt[2], name+'_Drv_Top_Jxt') drv_Jnt[3] = cmds.rename(drv_Jnt[3], name+'_Drv_Bttm_End') drv_Jnt[4] = cmds.rename(drv_Jnt[4], name+'_Drv_Top_End') #place joints correctly accordaly with the user options choose if (horizontal and axis==(1, 0, 0)) or (horizontal and axis==(0, 0, 1)): cmds.setAttr(bttm_Loc[2]+'.translateY', 2) cmds.setAttr(top_Loc[2]+'.translateY', 2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) elif (horizontal and axis==(0, 1, 0)) or (not horizontal and axis==(1, 0, 0)): cmds.setAttr(bttm_Loc[2]+'.translateZ', 2) cmds.setAttr(top_Loc[2]+'.translateZ', 2) cmds.setAttr(mid_Loc[3]+'.translateZ', 2) elif not horizontal and axis==(0, 1, 0) or (not horizontal and axis==(0, 0, 1)): cmds.setAttr(bttm_Loc[2]+'.translateX', 2) cmds.setAttr(top_Loc[2]+'.translateX', 2) cmds.setAttr(mid_Loc[3]+'.translateX', 2) elif horizontal and axis==(0, 0, -1): if firstLimb: cmds.setAttr(bttm_Loc[2]+'.translateY', 2) cmds.setAttr(top_Loc[2]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) else: if s == 0: cmds.setAttr(bttm_Loc[2]+'.translateX', -2) cmds.setAttr(top_Loc[2]+'.translateY', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) else: cmds.setAttr(bttm_Loc[2]+'.translateX', -2) cmds.setAttr(top_Loc[2]+'.translateY', -2) cmds.setAttr(mid_Loc[3]+'.translateX', -2) cmds.setAttr(mid_Loc[3]+'.translateY', 2) #create auxiliary joints that will be used to control the ribbon aux_Jnt.append(cmds.duplicate(drv_Jnt[1], name=name+'_Jxt_Rot')[0]) cmds.setAttr(aux_Jnt[0]+'.jointOrient', 0, 0, 0) aux_Jnt.append(cmds.duplicate(aux_Jnt[0], name=name+'_Jxt_Rot_End')[0]) cmds.parent(aux_Jnt[1], mid_Loc[3]) cmds.setAttr(aux_Jnt[1]+'.translate', 0, 0, 0) cmds.parent(aux_Jnt[1], aux_Jnt[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #calculate the adjust for the new chain position dist = float(numJoints)/2.0 end_dist = (1/float(numJoints)) cmds.parent(drv_Jnt[3], drv_Jnt[0]) cmds.parent(drv_Jnt[4], drv_Jnt[2]) #adjust the joints orientation and position based in the options choose from user if horizontal and axis==(1, 0, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0]+'.tz', -dist) cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tz', dist) cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist) elif horizontal and axis==(0, 1, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif horizontal and axis==(0, 0, 1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif horizontal and axis==(0, 0, -1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0) cmds.setAttr(drv_Jnt[0]+'.tx', -dist) cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tx', dist) cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist) elif not horizontal and axis==(1, 0, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0]+'.ty', -dist) cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.ty', dist) cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist) elif not horizontal and axis==(0, 1, 0): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0) cmds.setAttr(drv_Jnt[0]+'.tz', -dist) cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.tz', dist) cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist) elif not horizontal and axis==(0, 0, 1): cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90) cmds.setAttr(drv_Jnt[0]+'.ty', -dist) cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist) cmds.setAttr(drv_Jnt[2]+'.ty', dist) cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist) #fix the control locators position and orientation cmds.parent(top_Loc[0], drv_Jnt[2]) cmds.setAttr(top_Loc[0]+'.translate', 0, 0, 0) cmds.parent(top_Loc[0], w=True) cmds.setAttr(top_Loc[0]+'.rotate', 0, 0, 0) cmds.parent(bttm_Loc[0], drv_Jnt[0]) cmds.setAttr(bttm_Loc[0]+'.translate', 0, 0, 0) cmds.parent(bttm_Loc[0], w=True) cmds.setAttr(bttm_Loc[0]+'.rotate', 0, 0, 0) cmds.parent(drv_Jnt[2], top_Loc[1]) cmds.parent(drv_Jnt[1], mid_Loc[2]) cmds.parent(drv_Jnt[0], bttm_Loc[1]) cmds.parent(aux_Jnt[0], mid_Loc[0]) #create a nurbs control in order to be used in the ribbon offset mid_Ctrl = cmds.circle (c=(0, 0, 0), nr=(1, 0, 0), ch=0, name=name+'_MidCtrl')[0] ctrls.renameShape([mid_Ctrl]) midCtrl = mid_Ctrl mid_Ctrl = cmds.group(n=mid_Ctrl+'_Grp', em=True) cmds.delete(cmds.parentConstraint(midCtrl, mid_Ctrl, mo=0)) cmds.parent(midCtrl, mid_Ctrl) #adjust the realtionship between the locators cmds.parent(mid_Ctrl, mid_Loc[2], r=True) cmds.parent(drv_Jnt[1], midCtrl) cmds.parent([top_Loc[2], mid_Loc[3], bttm_Loc[2]], w=True) cmds.makeIdentity(top_Loc[0], apply=True) cmds.makeIdentity(mid_Loc[0], apply=True) cmds.makeIdentity(bttm_Loc[0], apply=True) cmds.parent(top_Loc[2], top_Loc[0]) cmds.parent(bttm_Loc[2], bttm_Loc[0]) cmds.parent(mid_Loc[3], aux_Jnt[1]) #create needed constraints in the locators in order to set the top always follow, to the base always aim the middle, to the middle always aim the top if firstLimb: cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint") else: # bug fix to plane twist cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint") cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint") cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint") #create a point and orient constraint for the middel control cmds.pointConstraint(top_Loc[0], bttm_Loc[0], mid_Loc[0], offset=(0, 0, 0), weight=1, name=mid_Loc[0]+"_PointConstraint") ori = cmds.orientConstraint(top_Loc[0], bttm_Loc[0], aux_Jnt[0], offset=(0, 0, 0), weight=1, name=aux_Jnt[0]+"_OrientConstraint") #ribbon scale (volume variation) if numJoints == 3: proportionList = [0.5, 1, 0.5] elif numJoints == 5: proportionList = [0.4, 0.8, 1, 0.8, 0.4] elif numJoints == 7: proportionList = [0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25] curveInfoNode = cmds.arclen(ribbon+".v[0.5]", constructionHistory=True) curveInfoNode = cmds.rename(curveInfoNode, ribbon+"_CurveInfo") rbScaleMD = cmds.createNode("multiplyDivide", name=ribbon+"_ScaleCompensate_MD") rbNormalizeMD = cmds.createNode("multiplyDivide", name=ribbon+"_Normalize_MD") cmds.setAttr(rbNormalizeMD+".operation", 2) cmds.connectAttr(curveInfoNode+".arcLength", rbNormalizeMD+".input2X", force=True) cmds.connectAttr(rbScaleMD+".outputX", rbNormalizeMD+".input1X", force=True) if cmds.objExists(worldRef): if not cmds.objExists(worldRef+"."+limbManualVVAttr): cmds.addAttr(worldRef, longName=limbVVAttr, attributeType="float", minValue=0, maxValue=1, defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbManualVVAttr, attributeType="float", defaultValue=1, keyable=True) cmds.addAttr(worldRef, longName=limbMinVVAttr, attributeType="float", defaultValue=0.01, keyable=True) cmds.connectAttr(worldRef+".scaleX", rbScaleMD+".input1X", force=True) #fix group hierarchy extraCtrlGrp = cmds.group(empty=True, name=name+"_ExtraBendyCtrl_Grp") i = 0 for jnt in rb_Jnt: cmds.makeIdentity(jnt, a=True) # create extra control extraCtrlName = jnt.replace("_Jnt", "_Ctrl") extraCtrl = ctrls.cvSquare(ctrlName=extraCtrlName, r=ctrlRadius) extraCtrlList.append(extraCtrl) cmds.rotate(0, 0, 90, extraCtrl) cmds.makeIdentity(extraCtrl, a=True) extraCtrlZero = utils.zeroOut([extraCtrl])[0] cmds.parent(extraCtrlZero, extraCtrlGrp) cmds.parentConstraint(fols[i], extraCtrlZero, w=1, name=extraCtrlZero+"_ParentConstraint") cmds.parentConstraint(extraCtrl, jnt, w=1, name=jnt+"_ParentConstraint") cmds.scaleConstraint(extraCtrl, jnt, w=1, name=jnt+"_ScaleConstraint") # work with volume variation rbProportionMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Proportion_MD")) rbIntensityMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Intensity_MD")) rbAddScalePMA = cmds.createNode("plusMinusAverage", name=extraCtrlName.replace("_Ctrl", "_AddScale_PMA")) rbScaleClp = cmds.createNode("clamp", name=extraCtrlName.replace("_Ctrl", "_Scale_Clp")) rbBlendCB = cmds.createNode("blendColors", name=extraCtrlName.replace("_Ctrl", "_Blend_BC")) cmds.connectAttr(worldRef+"."+limbVVAttr, rbBlendCB+".blender", force=True) cmds.setAttr(rbBlendCB+".color2", 1, 1, 1, type="double3") cmds.connectAttr(rbNormalizeMD+".outputX", rbProportionMD+".input1X", force=True) cmds.setAttr(rbProportionMD+".input2X", proportionList[i]) cmds.connectAttr(rbProportionMD+".outputX", rbIntensityMD+".input1X", force=True) cmds.connectAttr(worldRef+"."+limbManualVVAttr, rbIntensityMD+".input2X", force=True) cmds.connectAttr(rbIntensityMD+".outputX", rbAddScalePMA+".input1D[1]", force=True) cmds.connectAttr(rbAddScalePMA+".output1D", rbScaleClp+".inputR", force=True) cmds.connectAttr(worldRef+"."+limbMinVVAttr, rbScaleClp+".minR") cmds.setAttr(rbScaleClp+".maxR", 1000000) cmds.connectAttr(rbScaleClp+".outputR", rbBlendCB+".color1.color1R", force=True) cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleY", force=True) cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleZ", force=True) # update i i = i + 1 locatorsGrp = cmds.group(bttm_Loc[0], top_Loc[0], mid_Loc[0], n=name+'_Loc_Grp') skinJntGrp = cmds.group(rb_Jnt, n=name+'_Jnt_Grp') finalSystemGrp = cmds.group(ribbon, locatorsGrp, skinJntGrp, n=name+'_RibbonSystem_Grp') #do the controller joints skin and the ribbon ribbonShape = cmds.listRelatives(ribbon, shapes=True) skin = cmds.skinCluster(drv_Jnt[0:3], ribbonShape, tsb=True, mi=2, dr=1) #skin presets for the ribbon (that's amazing!) if not horizontal: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[0:1][9]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][8]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1)) else: if numJoints == 3: cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 5: cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) elif numJoints == 7: cmds.skinPercent(skin[0], ribbon + '.cv[9][0:1]', tv=(drv_Jnt[2], 1)) cmds.skinPercent(skin[0], ribbon + '.cv[8][0:1]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)]) cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)]) cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)]) cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)]) cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1)) constr = [] if guias: top = guias[0] bottom = guias[1] constr.append(cmds.parentConstraint(top, bttm_Loc[0], mo=False, name=bttm_Loc[0]+"_ParentConstraint")) constr.append(cmds.parentConstraint(bottom, top_Loc[0], mo=False, name=top_Loc[0]+"_ParentConstraint")) #fix orientation issues cmds.delete(ori) cmds.orientConstraint(bttm_Loc[0], aux_Jnt[0], weight=0.5, mo=True, name=aux_Jnt[0]+"_OrientConstraint") #fix loc_Grp scale if guias: from math import sqrt, pow auxLoc1 = cmds.spaceLocator(name='auxLoc1')[0] auxLoc2 = cmds.spaceLocator(name='auxLoc2')[0] cmds.delete(cmds.parentConstraint(top, auxLoc1, mo=False, w=1)) cmds.delete(cmds.parentConstraint(bottom, auxLoc2, mo=False, w=1)) a = cmds.xform(auxLoc1, ws=True, translation=True, q=True) b = cmds.xform(auxLoc2, ws=True, translation=True, q=True) dist = sqrt(pow(a[0]-b[0], 2.0)+pow(a[1]-b[1], 2.0)+pow(a[2]-b[2], 2.0)) scale = dist/float(numJoints) cmds.setAttr(locatorsGrp+'.s', scale, scale, scale) cmds.delete(auxLoc1, auxLoc2) # baseTwist: if not upCtrl == None: bttm_LocGrp = cmds.group(bttm_Loc[2], name=bttm_Loc[2]+"_Grp") bttm_LocPos = cmds.xform(bttm_Loc[0], query=True, worldSpace=True, translation=True) cmds.move(bttm_LocPos[0], bttm_LocPos[1], bttm_LocPos[2], bttm_LocGrp+".scalePivot", bttm_LocGrp+".rotatePivot", absolute=True) cmds.connectAttr(upCtrl+".baseTwist", bttm_LocGrp+".rotateZ", force=True) #updating values cmds.setAttr(rbScaleMD+".input2X", cmds.getAttr(curveInfoNode+".arcLength")) for jnt in rb_Jnt: rbAddScalePMA = jnt.replace("_Jnt", "_AddScale_PMA") cmds.setAttr(rbAddScalePMA+".input1D[0]", 1-cmds.getAttr(rbAddScalePMA+".input1D[1]")) #change renderStats ribbonShape = cmds.listRelatives(ribbon, s=True, f=True)[0] cmds.setAttr(ribbonShape+'.castsShadows', 0) cmds.setAttr(ribbonShape+'.receiveShadows', 0) cmds.setAttr(ribbonShape+'.motionBlur', 0) cmds.setAttr(ribbonShape+'.primaryVisibility', 0) cmds.setAttr(ribbonShape+'.smoothShading', 0) cmds.setAttr(ribbonShape+'.visibleInReflections', 0) cmds.setAttr(ribbonShape+'.visibleInRefractions', 0) cmds.setAttr(ribbonShape+'.doubleSided', 1) retDict['name'] = name retDict['locsList'] = [top_Loc[0], mid_Loc[0], bttm_Loc[0]] retDict['skinJointsList'] = rb_Jnt retDict['scaleGrp'] = locatorsGrp retDict['finalGrp'] = finalSystemGrp retDict['middleCtrl'] = mid_Ctrl retDict['constraints'] = constr retDict['bendGrpList'] = [top_Loc[0], bttm_Loc[0]] retDict['extraCtrlGrp'] = extraCtrlGrp retDict['extraCtrlList'] = extraCtrlList retDict['rbScaleMD'] = rbScaleMD retDict['rbNormalizeMD'] = rbNormalizeMD cmds.setAttr(finalSystemGrp+'.v', v) return retDict
def makeStretchyRun(self,*args): #Store Values cl = args[0] #Will be set to 1 if called from the command line if cl == 1: pass else: #If not called by command line, get values from GUI self.solverVal = mc.radioButtonGrp(self.solverField,query=True,sl=True) self.stretchVal = mc.radioButtonGrp(self.stretchField,query=True,sl=True) self.axisVal = mc.radioButtonGrp(self.axisField,query=True,sl=True) self.ikHandle = mc.textFieldButtonGrp(self.ikHandleField,query=True,text=True) self.clusterVal = mc.radioButtonGrp(self.clustersField,query=True,sl=True) self.joints = mc.ikHandle(self.ikHandle,query=True,jl=True) if(self.axisVal == 1): self.axis = 'X' if(self.axisVal == 2): self.axis = 'Y' if(self.axisVal == 3): self.axis = 'Z' try: temp = mc.ikHandle(self.ikHandle,query=True,c=True) temp = temp.split('|') curve = temp[1] except: pass #Create clusters along curve if(self.clusterVal == 1): #Get Shape node temp = mc.listRelatives(curve,s=True) #These values added together tell us the number of CVs on the curve backSpans = mc.getAttr(temp[0]+".spans") backDegree = mc.getAttr(temp[0]+".degree") numClusters = backSpans + backDegree clusterNames = [] x = 0 while(x<numClusters): clusterNames.append( mc.cluster(curve+".cv["+str(x)+"]") ) x = x + 1 if(self.solverVal == 1): #RP solver self.rpStretchy() if(self.solverVal == 2): #Spline #Get the curve curve = mc.ikHandle(self.ikHandle,query=True,c=True) curve = curve.split("|") for each in curve: if("Shape" in each): continue if(each == " "): continue curve = each #CurveInfo node creation curveInfoNode = mc.arclen(curve,ch=True) #create MD node mdNode = mc.createNode("multiplyDivide") mc.setAttr(mdNode + ".operation",2) mc.connectAttr(curveInfoNode + ".arcLength", mdNode + ".i1x") arcLen = mc.getAttr(curveInfoNode + ".arcLength") mc.setAttr(mdNode + ".i2x", arcLen) if(self.stretchVal == 1): #Get existing translation values translateValues = [] for each in self.joints: translateValues.append(mc.getAttr(each + ".translate" + self.axis)) #now lets hook up the MD nodes for each joint, except the base. x = 0 for each in self.joints: #Skip for base joint. #if(each == joints[0]): # continue #create second MD node and set it up, connect it. transMD = mc.createNode("multiplyDivide") mc.setAttr(transMD + ".i2x",translateValues[x]) mc.connectAttr(mdNode + ".outputX",transMD + ".i1x") mc.connectAttr(transMD + ".outputX",each + ".translate" + self.axis) x = x + 1 #mc.connectAttr(mdNode + ".outputX",each + ".translate" + self.axis) if(self.stretchVal == 2): for each in self.joints: mc.connectAttr(mdNode + ".outputX",each + ".scale" + self.axis)
def locatorCurve(curve,controlPoints=[],locatorScale=0.05,local=False,freeze=True,prefix='',suffix='loc'): ''' Creates locators for each control point for the specified curve. Locator world positions are connected to the curves ".controlPoints[*]" attribute. @param curve: Curve to operate on @type curve: str @param controlPoints: List of control points to connect to locator positions @type controlPoints: list @param locatorScale: Control the relative scale of the locators to the length of curve @type locatorScale: float @param local: Use local translate values instead of worldPosition @type local: bool @param freeze: Freeze translate values. Only applicable when local mode is False. @type freeze: float @param prefix: Name prefix for newly created nodes @type prefix: str ''' # ========== # - Checks - # ========== # Check Curve if not isCurve(curve): raise Exception('Object '+curve+ ' is not a valid curve!') # Check Curve Shape curveShape=None if mc.objectType(curve) == 'transform': curveShape = mc.listRelatives(curve,s=1,ni=1)[0] else: curveShape = curve curve = mc.listRelatives(curve,p=1)[0] # Check Prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(curve) # Check CVs controlPointList = [] if controlPoints: controlPointList = glTools.utils.component.getComponentIndexList(controlPoints)[curveShape] else: controlPointList = range(glTools.utils.component.getComponentCount(curve)) # =================== # - Create Locators - # =================== # Initialize Return List locatorList = [] # Set Locator Scale locatorScale *= mc.arclen(curve) # Iterate Over CVs for i in controlPointList: # Generate String Index ind = glTools.utils.stringUtils.stringIndex(i,1) # Get CV Position pos = mc.pointPosition(curve+'.cv['+str(i)+']') # Create Locator locator = mc.spaceLocator(n=prefix+'_cv'+ind+'_'+suffix)[0] # Position Locator mc.xform(locator,ws=True,t=pos) mc.setAttr(locator+".localScale",locatorScale,locatorScale,locatorScale) # Add CV ID Attribute mc.addAttr(locator,ln='cvID',at='long',dv=i) # Connect to CV if local: mc.connectAttr(locator+'.translate',curve+'.controlPoints['+str(i)+']') else: if freeze: mc.makeIdentity(locator,apply=True,t=1,r=1,s=1,n=0) mc.connectAttr(locator+'.worldPosition[0]',curve+'.controlPoints['+str(i)+']') # Append to Return List locatorList.append(locator) # ================= # - Return Result - # ================= return locatorList
def install(self): # startJoint = cmds.duplicate(self.joints[0], name=self.nodes['joint_01'], parentOnly=True)[0] # endJoint = cmds.duplicate(self.joints[-1], name=self.nodes['joint_%02d' %(self.ikCount)], parentOnly=True)[0] # cmds.parent(endJoint, startJoint, absolute=True) # cmds.parent(startJoint, world=True) startJoint = cmds.joint(name=self.nodes['joint_01']) endJoint = cmds.joint(name=self.nodes['joint_%02d' %(self.ikCount)]) cmds.delete(cmds.parentConstraint(self.joints[0], startJoint, maintainOffset=False)) cmds.delete(cmds.parentConstraint(self.joints[-1], endJoint, maintainOffset=False)) splitJoints = utils_rigging.splitJoint(joint=startJoint, split=self.ikCount-1, prefix=self.prefix) for i in range(1, self.ikCount-1): cmds.rename(splitJoints[i], self.nodes['joint_%02d' %(i+1)]) for i in range(0, self.ikCount): bJoint.BindJoint(joint=self.nodes['joint_%02d' %(i+1)]) cmds.group(name=self.moduleGrp, empty=True) cmds.parent(self.moduleGrp, self.deformerGroup) startJointPos = cmds.xform(startJoint, ws=True, q=True, translation=True) endJointPos = cmds.xform(endJoint, ws=True, q=True, translation=True) ikCurve = cmds.curve(d=1, p=[(startJointPos[0],startJointPos[1],startJointPos[2]), (endJointPos[0], endJointPos[1], endJointPos[2])], name=self.prefix+"_ikCurve") cmds.rebuildCurve(ikCurve, ch=0, s=2, d=3) cmds.setAttr(ikCurve + ".inheritsTransform", 0) cmds.parent(ikCurve, self.moduleGrp) cvCount = len(cmds.getAttr(ikCurve+".cv[*]")) cvList = [] cvCluster = [] cvClusterHandle = [] for x in range(0, cvCount): cvClusterInfo = cmds.cluster(ikCurve+".cv[%d]" %x, name=self.prefix+ "_cv%d" %x + "_cluster") cvCluster.append(cvClusterInfo[0]) cvClusterHandle.append(cvClusterInfo[1]) cmds.setAttr(cvClusterInfo[1] + ".visibility", 0) cvList.append(ikCurve+".cv[%d]" %x) startGrp = cmds.group(empty=True, name=self.prefix+"_start") cmds.delete(cmds.parentConstraint(startJoint, startGrp, maintainOffset=False)) cmds.parent(cvClusterHandle[0], startGrp, absolute=True) endGrp = cmds.group(empty=True, name=self.prefix+"_end") cmds.delete(cmds.parentConstraint(endJoint, endGrp, maintainOffset=False)) cmds.parent(cvClusterHandle[-1], endGrp, absolute=True) startGrpZro = utils_transforms.createZeroGroup(startGrp, name=startGrp+'_zro') endGrpZro = utils_transforms.createZeroGroup(endGrp, name=endGrp+'_zro') cmds.parent(startGrpZro, endGrpZro, self.moduleGrp) counter = 1 for c in cvClusterHandle[1:-1]: weight = 1.0 / (cvCount - 1) * counter counter += 1 cGrp = cmds.group(empty=True, name=c+"_rotate") cmds.delete(cmds.pointConstraint(c, cGrp, maintainOffset=False)) cGrpX = cmds.duplicate(cGrp, name=c+'_x')[0] cGrpY = cmds.duplicate(cGrp, name=c+'_y')[0] cGrpZ = cmds.duplicate(cGrp, name=c+'_z')[0] cmds.parent(c, cGrp, absolute=True) cmds.parent(cGrp, cGrpZ, absolute=True) cmds.parent(cGrpZ, cGrpY, absolute=True) cmds.parent(cGrpY, cGrpX, absolute=True) cmds.parent(cGrpX, self.moduleGrp, absolute=True) for grp, skipTranslate in zip ([cGrp, cGrpX, cGrpY, cGrpZ], [['x','y','z'], ['y','z'],['x','z'],['x','y']]): if grp == cGrp : pCon = cmds.parentConstraint(startGrp, endGrp, grp, maintainOffset=True, skipTranslate=skipTranslate, name=grp+"_pConst")[0] else: pCon = cmds.parentConstraint(startGrp, endGrp, grp, maintainOffset=True, skipTranslate=skipTranslate, skipRotate=['x','y','z'], name=grp+"_pConst")[0] targets = cmds.parentConstraint(pCon, q=True, wal=True) attr = grp+"_blend" cmds.addAttr(self.customAttribute, at='float', ln=attr, k=True, max=1, min=0, dv=weight) cmds.connectAttr(self.customAttribute + "." + attr, pCon+"."+targets[1]) grpPM = cmds.createNode('plusMinusAverage', name = grp+"_plusMinus") cmds.setAttr(grpPM + ".operation", 2) #subtract cmds.setAttr(grpPM + ".input1D[0]", 1) cmds.connectAttr(self.customAttribute + "." + attr, grpPM + ".input1D[1]") cmds.connectAttr(grpPM+".output1D", pCon+"."+targets[0]) ikHandle, ikEffector = cmds.ikHandle(sj=startJoint, ee=endJoint, sol='ikSplineSolver', ccv=False, pcv=False, curve=ikCurve, ns=4, name=self.prefix+"_ikHandle") cmds.rename(ikEffector, self.prefix+'_ikEffector') cmds.parent(ikHandle, self.moduleGrp) cmds.setAttr(ikHandle+".visibility", 0) #build strechty curveInfo = cmds.arclen(ikCurve, ch=True) curveInfo = cmds.rename(curveInfo, self.prefix+"_curveInfo" ) length = cmds.getAttr(curveInfo + ".arcLength") normalizedScaleMD = cmds.createNode('multiplyDivide', name = self.prefix + "_normalizedScaleMD") cmds.setAttr(normalizedScaleMD+'.operation', 2) globalScaleMD = cmds.createNode('multiplyDivide', name = self.prefix + "_globalScaleMD") cmds.connectAttr(self.customAttribute + '.globalScale', globalScaleMD + ".input1X") cmds.setAttr(globalScaleMD + ".input2X", length) cmds.connectAttr(curveInfo + ".arcLength", normalizedScaleMD + ".input1X") cmds.connectAttr(globalScaleMD + '.outputX', normalizedScaleMD + ".input2X") for i in range(0, self.ikCount): cmds.connectAttr(normalizedScaleMD + '.outputX', self.nodes['joint_%02d' %(i+1)] + ".scaleX") # # for joint in ikJoints: # cmds.connectAttr(normalizedScaleMD + '.outputX', joint + ".scaleX") #twist cmds.setAttr(ikHandle+".dTwistControlEnable", 1) cmds.setAttr(ikHandle+".dWorldUpType", 4) #object rotation up (start/endFollow) cmds.setAttr(ikHandle+".dWorldUpAxis", 0) cmds.setAttr(ikHandle+".dWorldUpVectorY", 1) cmds.setAttr(ikHandle+".dWorldUpVectorEndY", 1) cmds.connectAttr(startGrp+".worldMatrix[0]", ikHandle+".dWorldUpMatrix") cmds.connectAttr(endGrp+".worldMatrix[0]", ikHandle+".dWorldUpMatrixEnd") #======================================================================= #parent ik start / end #======================================================================= if self.nodes['endFollow']: cmds.parentConstraint(self.nodes['endFollow'], endGrp, maintainOffset=True) if self.nodes['rootFollow']: cmds.parentConstraint(self.nodes['rootFollow'], startGrp, maintainOffset=True)