def deformerBeforeSkin(top,bs): geoshape=cmds.ls(top,dag=1,g=1,ni=1) for g in geoshape: deform=cmds.listHistory(g,pdo=True,il=True) sn=cmds.ls(deform,type='skinCluster') if sn: cmds.reorderDeformers(sn[0], bs, g)
def deformerBeforeSkin(top, bs): geoshape = cmds.ls(top, dag=1, g=1, ni=1) for g in geoshape: deform = cmds.listHistory(g, pdo=True, il=True) sn = cmds.ls(deform, type='skinCluster') if sn: cmds.reorderDeformers(sn[0], bs, g)
def reorderDeformersByOrderedList(obj, deformerOrder): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Reorders deformers on an object by a list of deformers ARGUMENTS: obj(string) deformerOrder(list) - list of the order youw ant RETURNS: Success(bool) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ deformers = returnObjectDeformers(obj) orderedDeformers = [] existsCheck = True if deformers: # pair up the list orderedDeformerPairs = lists.parseListToPairs(deformerOrder) for pair in orderedDeformerPairs: mc.reorderDeformers(pair[0],pair[1],obj) return True else: print ('No deformers on ' + obj) return False
def importDeformer(dagnode, j): if dagnode not in j: rigUtils.log('Dagnode not found in json file: %s' % dagnode) return # temporarily disable deleteComponent nodes for delComp in cmds.ls('deleteComponent*'): cmds.setAttr('%s.nodeState' % delComp, 1) skincluster = rigUtils.findSkinClusterOnNode(dagnode) dict = j[dagnode] for deformer in dict: if deformer == 'skinCluster': continue if not cmds.objExists(deformer): continue pointdata = dict[deformer] set = '%sSet' % deformer existingdeformers = mel.eval('findRelatedDeformer "%s"' % dagnode) # ffd if cmds.objectType(deformer, isType='ffd'): i = 0 while(True): if i == len(pointdata): break if pointdata[i] == '1' and cmds.objExists(set): cmds.sets('%s.vtx[%s]' % (dagnode, i), add=set) i = i + 1 if skincluster: cmds.reorderDeformers(skincluster,deformer,dagnode) continue # all other deformers if not deformer in existingdeformers: if cmds.objExists(set): cmds.sets(dagnode, add=set) i = 0 while(True): if i == len(pointdata): break value = pointdata[i] cmds.percent(deformer, '%s.vtx[%s]' % (dagnode, i), v=float(value)) i = i + 1 if skincluster: cmds.reorderDeformers(skincluster, deformer, dagnode) rigUtils.log('Deformer weighting updated: %s' % deformer) # turn deleteComponent nodes back on for delComp in cmds.ls('deleteComponent*'): cmds.setAttr('%s.nodeState' % delComp, 0)
def addBsNode(cls, *args): if cls.isCorBsNode(): cmds.confirmDialog( title='Warning', message= "Correct blendshape node is exists.\nPlease use existing one.", button='OK') return # Add blendshape node bsNode = cmds.blendShape(cls.geo, frontOfChain=True, n='correctShape_bs#')[0] # Move bsNode to the last order in all inputs. allDfms = tak_lib.getAllDfms(cls.geo) # print allDfms # Set right deformation order. First is blendshape in the list and second is skincluster last is "correctShape_bs". orderedDfms = [] for dfm in allDfms[:-1]: if cmds.nodeType(dfm) == "blendShape": orderedDfms.insert(0, dfm) elif cmds.nodeType(dfm) == "skinCluster": orderedDfms.insert(len(orderedDfms), dfm) extraDfms = list(set(allDfms[:-1]) - set(orderedDfms)) # print ">>> Inordered Deformers: " + str(orderedDfms) # print ">>> Extra Deformers: " + str(extraDfms) dfmsAfterBsNode = orderedDfms + extraDfms # print dfmsAfterBsNode for dfm in dfmsAfterBsNode: cmds.reorderDeformers(bsNode, dfm, cls.geo) # Delete and populate blendshape node option menu bsOptItems = cmds.optionMenu(UI.widgets['bsNodeOptMenu'], q=True, itemListLong=True) if bsOptItems != None: for bsOptItem in bsOptItems: cmds.deleteUI(bsOptItem) cmds.menuItem(label=bsNode, p=UI.widgets['bsNodeOptMenu']) cls.bsNodeName = cmds.optionMenu(UI.widgets['bsNodeOptMenu'], q=True, v=True) cls.populateCorrectiveTrgList()
def eelFinSwimmer (controlSurface,waveControlObject): #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>auto swim stuff """ Creating our deformation surface """ deformMeshBuffer = mc.duplicate (controlSurface) deformMesh = mc.rename (deformMeshBuffer[0],(controlSurface+'_defmesh')) """ Creates our wave deformer """ deformerBuffer = mc.nonLinear (deformMesh, type = 'wave', name = 'swimWave') waveDeformer = mc.rename (deformerBuffer[0], 'waveDeformer') waveDeformerHandle = mc.rename (deformerBuffer[1], 'waveDeformerHandle') """ move the handle """ mc.setAttr ((waveDeformerHandle+'.rx'),90) mc.setAttr ((waveDeformerHandle+'.ry'),90) """ set some variables """ mc.setAttr ((waveDeformer+'.dropoff'),1) mc.setAttr ((waveDeformer+'.dropoffPosition'),1) mc.setAttr ((waveDeformer+'.maxRadius'),2) """ make our blendshape node and reorder things""" blendshapeNode = mc.blendShape (deformMesh, controlSurface, name = 'swim_bsNode' ) mc.reorderDeformers ("tweak5", blendshapeNode[0],controlSurface) """ add some attrs to our wave control object """ attributes.addSectionBreakAttrToObj (waveControlObject, 'swim') attributes.addFloatAttributeToObject (waveControlObject, 'auto', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'speed', -100, 100, 0) attributes.addFloatAttributeToObject (waveControlObject, 'wavelength', 0, 10, 5) attributes.addFloatAttributeToObject (waveControlObject, 'amplitude', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'dropoff', 0, 1, 1) attributes.addFloatAttributeToObject (waveControlObject, 'dropoffPosition', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'minRadius', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'maxRadius', 0, 10, 10) """ connect a few attrs """ mc.connectAttr ((waveControlObject+'.auto'),(blendshapeNode[0]+'.'+deformMesh)) mc.connectAttr ((waveControlObject+'.wavelength'),(waveDeformer+'.wavelength')) mc.connectAttr ((waveControlObject+'.amplitude'),(waveDeformer+'.amplitude')) mc.connectAttr ((waveControlObject+'.dropoff'),(waveDeformer+'.dropoff')) mc.connectAttr ((waveControlObject+'.dropoffPosition'),(waveDeformer+'.dropoffPosition')) mc.connectAttr ((waveControlObject+'.minRadius'),(waveDeformer+'.minRadius')) mc.connectAttr ((waveControlObject+'.maxRadius'),(waveDeformer+'.maxRadius')) """ set some good base values """ mc.setAttr ((waveControlObject+'.speed'),1) mc.setAttr ((waveControlObject+'.wavelength'),4) mc.setAttr ((waveControlObject+'.amplitude'),.3) mc.setAttr ((waveControlObject+'.dropoff'),1) mc.setAttr ((waveControlObject+'.dropoffPosition'),1) mc.setAttr ((waveControlObject+'.maxRadius'),2) """ sets up swim speed """ nodes.offsetCycleSpeedControlNodeSetup (waveDeformer,(waveControlObject+'.speed'),90,-10)
def reorder_history(sels=[]): def_types = [ 'wrap', 'sculpt', 'deformBend', 'deformSquash', 'deformFlare', 'deformSine', 'deformTwist', 'deformWave', 'nonLinear', 'wire', 'ffd', 'skinCluster', 'clusterMains', 'clusterSquash', 'cluster', 'blendShape', 'tweak' ] sels = get_sels(sels) for sel in sels: input_history = {} inputs = cmds.listHistory(sel, interestLevel=2, pruneDagObjects=True) for this_input in inputs: input_type = cmds.nodeType(this_input) if input_type in def_types: if input_type == 'nonLinear': handle = cmds.connectionInfo('%s.deformerData' % this_input, sfd=True) input_type = cmds.nodeType(handle) if input_type == 'cluster': if 'main' in this_input.lower(): input_type = 'clusterMains' elif 'squash' in this_input.lower(): input_type = 'clusterSquash' if input_type in input_history: input_history[input_type].append(this_input) else: input_history[input_type] = [this_input] last_input = '' for def_type in def_types: if def_type in input_history: for def_input in sorted(input_history[def_type]): if last_input: try: cmds.reorderDeformers(last_input, def_input, sel) except: pass last_input = def_input cmds.select(sels, r=True) print 'Reordered History' return
def convert_pre_deformation(target): u"""指定ノードをpre-deformationに変換する Args: target (unicode): 対象のノード """ histories = cmds.listHistory(target, gl=True, pdo=True, lf=True, f=False, il=2) last_blend_shape = None for h in histories: object_type = cmds.objectType(h) if object_type == "skinCluster": last_skin_cluster = h continue if object_type == "blendShape": last_blend_shape = h cmds.reorderDeformers(last_skin_cluster, last_blend_shape, target)
def reorderDeformersByType(obj, deformerOrder = ['skinCluster','blendShape','tweak']): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ACKNOWLEDGEMENT Reorders deformers on an object by deformer type DESCRIPTION: Returns a list of deformers on an object in order from top to bottom ARGUMENTS: obj(string) deformerOrder(list) - (['skinCluster','blendShape','tweak']) >>>> Options are sculpt, cluster, jointCluster, lattice, wire, jointLattice, boneLattice, blendShape. RETURNS: Success(bool) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ deformers = returnObjectDeformers(obj) orderedDeformers = [] if deformers: for deformerType in deformerOrder: for deformer in deformers: if search.returnObjectType(deformer) == deformerType: orderedDeformers.append(deformer) deformers.remove(deformer) for deformer in deformers: orderedDeformers.append(deformer) # pair up the list orderedDeformerPairs = lists.parseListToPairs(orderedDeformers) for pair in orderedDeformerPairs: mc.reorderDeformers(pair[0],pair[1],obj) return True else: print ('No deformers on ' + obj) return False
def applyData(self, nodes): ''' Applies the data for the given nodes. There is an optional arguments so you can apply data only to specific attributes. :param nodes: Array of nodes you want to apply the data to. :type nodes: list | tuple ''' # loop through the nodes and apply the data. for node in nodes: if self._data.has_key(node): if len(self._data[node]["deformerOrder"]) > 1: orderCurrent = mc.ls(mc.listHistory(node, il=2, pdo=1), type='geometryFilter') or [] if not orderCurrent: continue orderStored = self._data[node]["deformerOrder"] for index, deformer in enumerate(orderStored): if index == len(orderStored) - 1: break nextDeformer = orderStored[index + 1] # Check if the deformers are on the object if not set([nextDeformer, deformer ]).issubset(orderCurrent): continue # Test if the deformer order is all ready correct indexNextDeformerCurrent = orderCurrent.index( nextDeformer) indexCurrent = orderCurrent.index(deformer) if indexNextDeformerCurrent != indexCurrent + 1: mc.reorderDeformers(deformer, nextDeformer, [node]) # Update order current so it can be tested orderCurrent = mc.ls(mc.listHistory( node, il=2, pdo=1), type='geometryFilter') or []
def rigSpine (crvName,tailCntrlJoints,waveControlObject,splitJoints): """ Rebuild curve - with actual curve in it!""" """ first have to make our reg spine""" mc.rebuildCurve (crvName, ch=0, rpo=1, rt=0, end=0, kr=0, kcp=0, kep=1, kt=0, s=(splitJoints), d=1, tol=5) """ Make joint chains""" spineJoints = joints.createJointsFromCurve (crvName,'spine') """ set joint radius """ joints.setGoodJointRadius (spineJoints,1) """ Orienting the joint chain """ joints.orientJointChain (spineJoints, 'xyz', 'zup') """ Renaming the joint chain """ spineJointsBuffer = names.renameJointChainList (spineJoints, 'tailStart', 'tail') spineJoints = spineJointsBuffer """ removing initial bind from the spine curve """ mc.delete ('bindPose1') mc.delete ('skinCluster1') """ Makes our control surface """ controlSurface = makeJointControlSurfaceFish(spineJoints[0],tailCntrlJoints,'y','tail') """ parenting the tail joints """ rigging.parentListToHeirarchy (tailCntrlJoints) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>auto swim stuff """ Creating our deformation surface """ deformMeshBuffer = mc.duplicate (controlSurface) deformMesh = mc.rename (deformMeshBuffer[0],(controlSurface[0]+'_defmesh')) """ Creates our wave deformer """ deformerBuffer = mc.nonLinear (deformMesh, type = 'wave', name = 'swimWave') waveDeformer = mc.rename (deformerBuffer[0], 'waveDeformer') waveDeformerHandle = mc.rename (deformerBuffer[1], 'waveDeformerHandle') """ move the handle """ position.movePointSnap (waveDeformerHandle,spineJoints[0]) mc.setAttr ((waveDeformerHandle+'.rx'),90) mc.setAttr ((waveDeformerHandle+'.ry'),90) """ set some variables """ mc.setAttr ((waveDeformer+'.dropoff'),1) mc.setAttr ((waveDeformer+'.dropoffPosition'),1) mc.setAttr ((waveDeformer+'.maxRadius'),2) """ make our blendshape node and reorder things""" blendshapeNode = mc.blendShape (deformMesh, controlSurface[0], name = 'swim_bsNode' ) mc.reorderDeformers ("tweak2", blendshapeNode[0],controlSurface[0]) """ add some attrs to our wave control object """ attributes.addSectionBreakAttrToObj (waveControlObject, 'swim') attributes.addFloatAttributeToObject (waveControlObject, 'auto', min = 0, max = 1, dv =0) attributes.addFloatAttributeToObject (waveControlObject, 'speed', -100, 100, 0) attributes.addFloatAttributeToObject (waveControlObject, 'wavelength', 0, 10, 5) attributes.addFloatAttributeToObject (waveControlObject, 'amplitude', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'dropoff', 0, 1, 1) attributes.addFloatAttributeToObject (waveControlObject, 'dropoffPosition', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'minRadius', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'maxRadius', 0, 10, 10) """ connect a few attrs """ mc.connectAttr ((waveControlObject+'.auto'),(blendshapeNode[0]+'.'+deformMesh)) mc.connectAttr ((waveControlObject+'.wavelength'),(waveDeformer+'.wavelength')) mc.connectAttr ((waveControlObject+'.amplitude'),(waveDeformer+'.amplitude')) mc.connectAttr ((waveControlObject+'.dropoff'),(waveDeformer+'.dropoff')) mc.connectAttr ((waveControlObject+'.dropoffPosition'),(waveDeformer+'.dropoffPosition')) mc.connectAttr ((waveControlObject+'.minRadius'),(waveDeformer+'.minRadius')) mc.connectAttr ((waveControlObject+'.maxRadius'),(waveDeformer+'.maxRadius')) """ set some good base values """ mc.setAttr ((waveControlObject+'.speed'),1) mc.setAttr ((waveControlObject+'.wavelength'),4) mc.setAttr ((waveControlObject+'.amplitude'),.3) mc.setAttr ((waveControlObject+'.dropoff'),1) mc.setAttr ((waveControlObject+'.dropoffPosition'),1) mc.setAttr ((waveControlObject+'.maxRadius'),2) """ sets up swim speed """ nodes.offsetCycleSpeedControlNodeSetup (waveDeformer,(waveControlObject+'.speed'),90,-10) #>>>>>>>>>>>>>>>>>>>>>>>>>>>> Head control and joint headJointBuffer = mc.duplicate ('head_anim') headJoint = mc.rename (headJointBuffer, 'head_jnt') headCtrlGrp = rigging.groupMeObject ('head_anim',True) #mc.parent (headJoint, spineJoints[0]) mc.parent (headJoint, 'move_anim') contsBuffer = mc.parentConstraint (spineJoints[0], headCtrlGrp, maintainOffset = True) mc.rename (contsBuffer,(headCtrlGrp+'_prntConst')) contsBuffer = mc.parentConstraint ('head_anim', headJoint, maintainOffset = True) mc.rename (contsBuffer,(headJoint+'_prntConst')) mc.parent (headCtrlGrp,'move_anim') #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Clean stuff """ deform group """ deformGrp = mc.group (n= 'swimDeform_grp', w=True, empty=True) mc.parent (waveDeformerHandle,deformGrp) mc.parent (deformMesh,deformGrp) mc.setAttr ((deformGrp+'.v'), 0) mc.setAttr ((controlSurface[0]+'.v'),0) """ delete placement stuff """ mc.delete ('curvePlacementStuff') mc.parent (tailCntrlJoints[0],waveControlObject) mc.parent (deformGrp, 'rigStuff_grp') #>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ctrl Joints to Ctrls ctrlSize = (distance.returnAverageDistanceBetweenObjects (tailCntrlJoints)) curves.parentShape ('head_anim', 'sampleCtrlZ') for ctrl in tailCntrlJoints: rigging.makeObjCtrl (ctrl,ctrlSize) #>>>>>>>>>>>>>>>>>>>>>Store skin joint data """ check for master skin info group """ name = 'spine' if mc.objExists ('master_skinJntList_grp'): masterSkinJointList = ('master_skinJntList_grp') else: masterSkinJointList = mc.group (n= ('master_skinJntList_grp'), w=True, empty=True) mc.parent(masterSkinJointList,'rigStuff_grp') """ check for segment skin info group """ if mc.objExists (name+'_skinJntList_grp'): skinJointList = (name+'_skinJntList_grp') else: skinJointList = mc.group (n= (name+'_skinJntList_grp'), w=True, empty=True) mc.parent (skinJointList,masterSkinJointList) attributes.storeObjNameToMessage (skinJointList,masterSkinJointList) """ store the skin joint data """ for jnt in spineJoints: attributes.storeObjNameToMessage (jnt,skinJointList) attributes.storeObjNameToMessage (headJoint,skinJointList)
def reorderHistory (listOrder,geos): for geo in geos: blendShapes = [] clusters = [] mainClusters = [] ffds = [] skinClusters = [] wires = [] nonLinears = [] bends = [] squashes = [] sculpts = [] if cmds.nodeType(geo) == 'transform': geo = cmds.listRelatives(type = 'shape') history = cmds.listHistory(geo,il = 2,pdo = 1) for input in history: if cmds.nodeType(input) == 'blendShape': blendShapes.append(input) if cmds.nodeType(input) == 'cluster': clusters.append(input) if cmds.nodeType(input) == 'ffd': ffds.append(input) if cmds.nodeType(input) == 'wire': wires.append(input) if cmds.nodeType(input) == 'nonLinear': nonLinears.append(input) if cmds.nodeType(input) == 'sculpt': sculpts.append(input) if cmds.nodeType(input) == 'skinCluster': skinClusters.append(input) for cluster in clusters[:]: try: match = re.search('Main',cluster) s = match.start() mainClusters.append(cluster) clusters.remove(cluster) except: pass for deformer in nonLinears[:]: try: match = re.search('squash',deformer.lower()) s = match.start() squashes.append(deformer) nonLinears.remove(deformer) print 'added squash' except: try: match = re.search('bend',deformer.lower()) s = match.start() bends.append(deformer) nonLinears.remove(deformer) print 'added bend' except: pass blendShapes.sort() clusters.sort() mainClusters.sort() ffds.sort() skinClusters.sort() wires.sort() nonLinears.sort() bends.sort() squashes.sort() sculpts.sort() allDeformers = {} allDeformers['blendshapes'] = blendShapes allDeformers['clusters'] = [mainClusters,clusters] allDeformers['ffds'] = ffds allDeformers['skinClusters'] = skinClusters allDeformers['wires'] = wires allDeformers['nonLinears'] = [bends,squashes,nonLinears] allDeformers['sculpts'] = sculpts orderedDeformers = [] for i in range(len(listOrder)): if listOrder[i] == 'clusters': for set in allDeformers['clusters']: for deformer in set: orderedDeformers.append(deformer) elif listOrder[i] == 'nonLinears': for set in allDeformers['nonLinears']: for deformer in set: orderedDeformers.append(deformer) else: deformers = allDeformers.get(listOrder[i]) if not deformers == None: for deformer in deformers: orderedDeformers.append(deformer) print orderedDeformers for i in range(len(orderedDeformers)-1): print (orderedDeformers[i],orderedDeformers[i-1]) try: cmds.reorderDeformers(orderedDeformers[i],orderedDeformers[i+1],geo) print 'reodered' except: pass
def convertWiresToSkinCluster(newSkinName, targetGeometry, wireDeformerList, keepWires=False, rootParentNode="rig", rootPreMatrixNode="trs_aux", jointDepth=2): ''' This function will take in a wire deformer list and create a new skinCluster :param newSkinName: This is the name we will use for the new skinCluster we're creating. :type newSkinName: str :param targetGeometry: This is the geometry we will be putting the skinCluster onto. :type targetGeometry: str ''' target = targetGeometry base = mc.duplicate(target)[0] # Get existing wire deformers from the wireDeformerList convertWireList = mc.ls(wireDeformerList, type="wire") # Store the connection to the shape geo_input = mc.listConnections(targetGeometry+'.inMesh', p=1)[0] # Store deformation order deformer_order = mc.listHistory(target, pdo=1, il=2) reorder_deformer = None for deformer in wireDeformerList: orderIndex = deformer_order.index(deformer) if orderIndex: if not deformer_order[orderIndex-1] in wireDeformerList: reorder_deformer = deformer_order[orderIndex-1] # Delete current skinCluster connections # TODO: What should be done when multiple skinClusters already exist? # TODO: Make a function for activating and deactiviing skinClusters # 1. Disconnect all the existing skinClusters and storing their # connections. # 2. Build the new skinCluster # 3. Reconnect all the skinClusters in reverse order sc_hist_list = mc.ls(mc.listHistory(target, pdo=1, il=2), type='skinCluster') sc_list = [] for sc in sc_hist_list: # OUTGOING # # Get the outgoing geom connection of the skinCluster sc_data = [sc] sc_out = mc.listConnections(sc+'.outputGeometry[0]', p=1)[0] sc_data.append(sc_out) # INCOMING # Get the group parts node of the skinCluster (incoming connection) sc_gp = mc.listConnections(sc+'.input[0].inputGeometry')[0] sc_data.append(sc_gp) # Get the connection coming into the group parts node sc_pre_dfmr = mc.listConnections(sc_gp+'.inputGeometry', p=1)[0] sc_data.append(sc_pre_dfmr) # Remove the connection mc.disconnectAttr(sc_pre_dfmr, sc_gp+'.inputGeometry') # Store connection information sc_list.append(sc_data) # Disconnect the incoming connection # Bypass the skinCluster by connecting the incoming group parts connection # into the outgoing skinCluster destination connection mc.connectAttr(sc_pre_dfmr, sc_out, f=1) # create a base joint that we can put weights on. baseJnt = "root_preMatrix_jnt" if not mc.objExists(baseJnt): jnt = mc.createNode("joint",name="root_preMatrix_jnt") mc.setAttr("{}.v".format(jnt), 0) mc.parent(baseJnt,rootParentNode) # create a target skinCluster that will replace the wire defomer targetSkinCluster = mc.skinCluster(target, baseJnt, tsb=1, name=newSkinName)[0] # get the influences to be used for the target skinCluster preMatrixNodeList = list() influenceList = list() weightList = list() curveList = list() for wireDeformer in convertWireList: # get the curve curve = mc.wire(wireDeformer, q=True, wire=True)[0] curveList.append(curve) # get the skinCluster associated with that curve curveSkin = mc.ls(mc.listHistory(curve, il=1, pdo=True), type="skinCluster")[0] # get the influences associated with the skinCluster curveSkinInfluenceList = mc.skinCluster(curveSkin, q=True, inf=True) # get the nuls to use as bindPreMatrix nodes curveSkinPreMatrixNodes = list() for jnt in curveSkinInfluenceList: # Travel up the ancestry of the joint, jointDepth number of times to find # the transform to be used for the preMatrix connection preMatrixNode = jnt for i in xrange(jointDepth): parent = mc.listRelatives(preMatrixNode, p=True)[0] if i == (jointDepth - 1): curveSkinPreMatrixNodes.append(parent) preMatrixNode = parent # Compile the influences and preMatrix nodes for all curves influenceList.extend(curveSkinInfluenceList) preMatrixNodeList.extend(curveSkinPreMatrixNodes) # connect the influences to the matrices and the nuls as the bind preMatrix # YANK IT!!!!!! for jnt, preMatrixNode in zip(curveSkinInfluenceList, curveSkinPreMatrixNodes): # create a temp influence we will use to connect the curveSkin to tempInf = mc.duplicate(jnt, po=1)[0] # get the connections through the worldMatrix connection matrixCon = mc.listConnections(jnt+'.worldMatrix[0]', p=1, d=1, s=0) # Get inf index # TODO: This should just use # TODO: rigrepo.libs.skinCluster.getInfIndex(targetSkinCluster, jnt) infIndex = None for con in matrixCon: node = con.split('.')[0] if node == curveSkin: infIndex = con.split('[')[1].split(']')[0] # Yank if infIndex: # connect the temp influence mc.connectAttr(tempInf+'.worldMatrix[0]', curveSkin+'.matrix[{}]'.format(infIndex), f=1) # move the influence mc.move( 1, 0, 0, tempInf, r=1, worldSpaceDistance=1) # get the delta to put into weightList weightList.append(rigrepo.libs.shape.getDeltas(base, target)) # recconect the joint and delete the temp influence. mc.connectAttr(jnt+'.worldMatrix[0]', curveSkin+'.matrix[{}]'.format(infIndex), f=1) mc.delete(tempInf) # Add curve joints as influces to targetSkinCluster and hook up bindPreMatrix nuls # TODO: i var is not doing anything here i=0 for jnt, preMatrixNode in zip(influenceList,preMatrixNodeList): # Add jnt as influnce mc.skinCluster(targetSkinCluster, e=1, ai=jnt) # Get index index = rigrepo.libs.skinCluster.getInfIndex(targetSkinCluster, jnt) # Connect bindPreMatrixNode mc.connectAttr("{}.worldInverseMatrix[0]".format(preMatrixNode), "{}.bindPreMatrix[{}]".format(targetSkinCluster, index), f=True) i += 1 # connect the base joint so we have somewhere to put the weights not being used. # Hook up the bind preMatrix node for the root joint index = rigrepo.libs.skinCluster.getInfIndex(targetSkinCluster, baseJnt) mc.connectAttr("{}.worldInverseMatrix[0]".format(rootPreMatrixNode), "{}.bindPreMatrix[{}]".format(targetSkinCluster, index), f=True) # RECONNECT other skinClusters # sc_list.reverse() for sc_data in sc_list: sc, sc_out, sc_gp, sc_pre_dfmr = sc_data mc.connectAttr(sc_pre_dfmr, sc_gp+'.inputGeometry', f=1) if '.inMesh' in sc_out: targ_sc_gp = mc.listConnections(targetSkinCluster+'.input[0].inputGeometry')[0] mc.connectAttr(sc+'.outputGeometry[0]', targ_sc_gp+'.inputGeometry', f=1) else: mc.connectAttr(sc+'.outputGeometry[0]', sc_out, f=1) # make sure we have the correct weights for the baseJnt # Create a numpy array the length of the number of verts and assigning # a value of 1.0 to each index # TODO: This can be simplified to baseJntArray = numpy.ones(mc.polyEvaluate(target, v=1)) baseJntArray = numpy.array([1.0 for id in mc.ls("{}.cp[*]".format(target), fl=True)]) # Update the base joints weights by subtracting the curve joint weights for weights in weightList: baseJntArray = baseJntArray - weights # add the baseJnt weights first by itself. influenceList.insert(0, baseJnt) weightList.insert(0, baseJntArray) # Set all the weights on the new target skinCluster rigrepo.libs.weights.setWeights(targetSkinCluster, rigrepo.libs.weightObject.WeightObject(maps=influenceList, weights=weightList)) # delete the base that we were using to compare deltas from mc.delete(base) # delete the wire deformers if not keepWires: # If the curve is being used for multiple wire deforms we need to disconnect it first # or maya will delete it delete_curves = True for wire in convertWireList: # wire curve = mc.listConnections(wire+'.deformedWire[0]', p=1) curveOutputs = mc.listConnections(curve[0]) if len(curveOutputs) > 1: delete_curves = False mc.disconnectAttr(curve[0], wire+'.deformedWire[0]') # base wire curve = mc.listConnections(wire+'.baseWire[0]', p=1) curveOutputs = mc.listConnections(curve[0]) if len(curveOutputs) > 1: mc.disconnectAttr(curve[0], wire+'.baseWire[0]') # Delete the wire and curves mc.delete(convertWireList) if delete_curves: mc.delete(curveList) # Reorder deformers if reorder_deformer: mc.reorderDeformers(reorder_deformer, targetSkinCluster, target)
def copyDeformer(deformer, target): ''' Make a copy of the passed deformers on the target :param target: Target transform of shape :param deformers: deformers to copy :return: Copied deformers ''' deformerOrder = mc.ls(mc.listHistory(target, pdo=1, il=1), type="geometryFilter") print('order', deformerOrder) orderIndex = deformerOrder.index(deformer) if mc.nodeType(deformer) == 'wire': # Get data curve = mc.wire(deformer, q=1, wire=1)[0] baseCurve = mc.listConnections(deformer + '.baseWire[0]', p=1)[0] # Note: wire command has issues when passing the shape, so get the transform curve = mc.listRelatives(curve, p=1)[0] rotation = mc.getAttr(deformer + '.rotation') dropOffDistance = mc.getAttr(deformer + '.dropoffDistance[0]') mc.select(cl=1) newDeformer = mc.wire(target, groupWithBase=False, envelope=1.00, crossingEffect=0.00, localInfluence=0.00, wire=curve, name="{}_wire".format(target))[0] # Replace base curve newBaseCurve = mc.listConnections(newDeformer + '.baseWire[0]') mc.connectAttr(baseCurve, newDeformer + '.baseWire[0]', f=1) mc.delete(newBaseCurve) # set the default values for the wire deformer mc.setAttr("{}.rotation".format(newDeformer), rotation) mc.setAttr("{}.dropoffDistance[0]".format(newDeformer), dropOffDistance) if mc.nodeType(deformer) == 'cluster': mc.select(cl=1) deformerWts = rigrepo.libs.weights.getWeights(deformer, geometry=target) bindPreMatrixAttr = mc.listConnections( '{}.bindPreMatrix'.format(deformer), source=True, plugs=True)[0] handle = mc.listConnections('{}.matrix'.format(deformer), source=True)[0] newDeformer = mc.cluster(target, name="{}_{}".format(target, deformer), wn=[handle, handle])[0] mc.connectAttr('{}.worldMatrix'.format(target), '{}.geomMatrix[0]'.format(newDeformer), f=True) mc.connectAttr(bindPreMatrixAttr, '{}.bindPreMatrix'.format(newDeformer), f=True) rigrepo.libs.weights.setWeights(newDeformer, deformerWts, geometry=target) # Reorder deformer if orderIndex: mc.reorderDeformers(deformerOrder[orderIndex - 1], newDeformer, target) return newDeformer
def importDeformersByMirroredObject(dagnode, file): # look for the mapping if not os.path.exists(file): rigUtils.log('Skin file not found - skipping: %s' % file) return rigUtils.log('Reading file: %s' % file) f = open(file, 'r') j = json.loads(f.read()) f.close() # get the mirrored object buffer = dagnode.split('_') locus = buffer[0][-1] if locus == 'R': buffer[0] = '%sL' % buffer[0][:-1] mirror = string.join(buffer, '_') elif locus == 'L': buffer[0] = '%sR' % buffer[0][:-1] mirror = string.join(buffer, '_') else: rigUtils.log('Select a valid mesh') return if mirror not in j: rigUtils.log('Mirror object not found in json file: %s' % mirror) return # get the skin cluster on the target object skincluster = rigUtils.findSkinClusterOnNode(dagnode) # step through the deformers of the mirrored object dict = j[mirror] for mirrorDeformer in dict: if mirrorDeformer == 'skinCluster': continue if not cmds.objExists(mirrorDeformer): continue # get the corresponding deformer on the target object buffer = mirrorDeformer.split('_') locus = buffer[0][-1] if locus == 'R': buffer[0] = '%sL' % buffer[0][:-1] deformer = string.join(buffer, '_') elif locus == 'L': buffer[0] = '%sR' % buffer[0][:-1] deformer = string.join(buffer, '_') else: deformer = mirrorDeformer pointdata = dict[mirrorDeformer] set = '%sSet' % deformer # ffd if cmds.objectType(deformer, isType='ffd'): i = 0 while(True): if i == len(pointdata): break if pointdata[i] == '1' and cmds.objExists(set): cmds.sets('%s.vtx[%s]' % (dagnode, i), add=set) i = i + 1 continue # if the corresponding deformer isn't influencing the target object, make it so existingdeformers = mel.eval('findRelatedDeformer "%s"' % dagnode) if not deformer in existingdeformers: if cmds.objExists(set): cmds.sets(dagnode, add=set) # step through each vert and update the weights for the target objects deformer i = 0 while(True): if i == len(pointdata): break value = pointdata[i] cmds.percent(deformer, '%s.vtx[%s]' % (dagnode, i), v=float(value)) i = i + 1 # rearrange the deformers to come before any skincluster if skincluster: cmds.reorderDeformers(skincluster, deformer, dagnode) rigUtils.log('Deformer weighting updated: %s' % deformer)
def gen_deformer(self, training_type='differential', deformer_type='tensorflow'): """ generates a bssNNDeform deformer :param str training_type: the type of training. Valid options are differential and local_offset """ if not mc.pluginInfo("bssNNDeform.so", loaded=True, q=True): mc.loadPlugin("bssNNDeform.so") input_config = self.training_data.get_config() input_handle = configparser.ConfigParser() input_handle.read(input_config) range_file = input_handle.get('training_config', 'limit_file') joint_relation_file = input_handle.get('training_config', 'joint_relation_file') inclusion_file = input_handle.get('training_config', 'inclusion_file') anchor_file = input_handle.get('training_config', 'anchor_file') if not self._mesh: self._mesh = input_handle.get('training_config', 'mesh') mover_ranges = dp.MoverRanges() mover_ranges.import_(range_file) joint_relations = dp.JointRelations() joint_relations.import_(joint_relation_file) data_inclusion = dp.DataInclusion() data_inclusion.import_(inclusion_file) anchor_points = dp.AnchorPoints() anchor_points.import_(anchor_file) joint_dict = joint_relations.parent_dict deformers = mc.listHistory(self._mesh) deformers = [ d for d in deformers if 'geometryFilter' in mc.nodeType(d, inherited=True) ] deformers = [d for d in deformers if mc.nodeType(d) != 'tweak'] cur_skin = None if deformers: cur_skin = deformers[0] deformer = mc.deformer(self._mesh, type="bssNNDeform")[0] if cur_skin: mc.reorderDeformers(cur_skin, deformer, self._mesh) i = 0 for joint in joint_relations.get_all_joints(): if not mc.objExists(joint): logger.warning("%s doesn't exist" % joint) continue if not data_inclusion.is_included(joint): continue joint_parent = joint_relations.parent_dict.get(joint, None) if not joint_parent or not mc.objExists(joint_parent): mc.connectAttr('%s.worldMatrix[0]' % joint, '%s.matrixInfluences[%i]' % (deformer, i)) else: mult_node = 'mult_matrix_%s' % joint mc.createNode('multMatrix', name=mult_node) mc.connectAttr('%s.worldMatrix[0]' % joint, '%s.matrixIn[0]' % mult_node) mc.connectAttr('%s.worldInverseMatrix[0]' % joint_parent, '%s.matrixIn[1]' % mult_node) mc.connectAttr('%s.matrixSum' % mult_node, '%s.matrixInfluences[%i]' % (deformer, i)) i = i + 1 i = 0 numeric_min = [] numeric_max = [] for inc in mover_ranges.numeric_controls: if not data_inclusion.is_included(inc): continue mc.connectAttr(inc, '%s.numericInfluences[%i]' % (deformer, i)) cmin, cmax = mover_ranges.limits[inc] numeric_min.append(cmin) numeric_max.append(cmax) i = i + 1 mc.setAttr('%s.numericInputMin' % deformer, numeric_min, type='floatArray') mc.setAttr('%s.numericInputMax' % deformer, numeric_max, type='floatArray') if training_type == 'differential': mc.setAttr( '%s.jointInputMin' % deformer, self.training_params['differential_joint_translate_min']) mc.setAttr( '%s.jointInputMax' % deformer, self.training_params['differential_joint_translate_max']) mc.setAttr('%s.normalizeInput' % deformer, self.training_params['differential_normalize']) mc.setAttr('%s.differentialOutputMin' % deformer, self.training_params['differential_min']) mc.setAttr('%s.differentialOutputMax' % deformer, self.training_params['differential_max']) mc.setAttr('%s.differentialNormalizeOutput' % deformer, self.training_params['differential_normalize']) diff_model_path = os.path.join(self.output_path, 'differential', 'model.pb') mc.setAttr('%s.differentialNetworkPath' % deformer, diff_model_path, type='string') mc.setAttr('%s.anchorOutputMin' % deformer, self.training_params['anchor_min']) mc.setAttr('%s.anchorOutputMax' % deformer, self.training_params['anchor_max']) mc.setAttr('%s.anchorNormalizeOutput' % deformer, self.training_params['anchor_normalize']) anchor_model_path = os.path.join(self.output_path, 'anchor', 'model.pb') mc.setAttr('%s.anchorNetworkPath' % deformer, anchor_model_path, type='string') # assuming the training type is the same for differential and anchor: try: mc.setAttr( '%s.networkType' % deformer, 1 if self.training_params['differential_framework'] == 'mxnet' else 0) except: print("Warning: couldn't set network type") self._cal_matrices() mc.setAttr('%s.affectedVertices' % deformer, self.vertex_ids['differential'], type='Int32Array') mc.setAttr('%s.laplacianMatrixRows' % deformer, self._laplacian_row, type='Int32Array') mc.setAttr('%s.laplacianMatrixColumns' % deformer, self._laplacian_col, type='Int32Array') mc.setAttr('%s.laplacianMatrixValues' % deformer, self._laplacian_val, type='floatArray') cholesky_row = [] cholesky_col = [] cholesky_val = [] row_ct, col_ct = self._cholesky_matrix.shape tol = 0.00000001 for i in range(row_ct): for j in range(i + 1): val = self._cholesky_matrix[i][j] if abs(val) >= tol: cholesky_row.append(i) cholesky_col.append(j) cholesky_val.append(float(val)) mc.setAttr('%s.choleskyMatrixRows' % deformer, cholesky_row, type='Int32Array') mc.setAttr('%s.choleskyMatrixColumns' % deformer, cholesky_col, type='Int32Array') mc.setAttr('%s.choleskyMatrixValues' % deformer, cholesky_val, type='floatArray') rcm_list = list(self._reverse_cuthill_mckee_order) rcm_list = [int(i) for i in rcm_list] mc.setAttr('%s.reverseCuthillMckeeOrder' % deformer, rcm_list, type='Int32Array') augmented_valences = self._valences[:] augmented_valences.extend([self.anchor_weight] * len(anchor_points.pts)) mc.setAttr('%s.valences' % deformer, augmented_valences, type='floatArray') mc.setAttr( '%s.differentialInputName' % deformer, self.training_params['differential_network_input'].split( ':')[0], type='string') mc.setAttr( '%s.differentialOutputName' % deformer, self.training_params['differential_network_output'].split( ':')[0], type='string') mc.setAttr( '%s.anchorInputName' % deformer, self.training_params['anchor_network_input'].split(':')[0], type='string') anchor_names = self.training_params['anchor_network_output'].split( ',') anchor_names = [i.split(':')[0] for i in anchor_names] mc.setAttr('%s.anchorOutputName' % deformer, ','.join(anchor_names), type='string') mc.setAttr('%s.isDifferential' % deformer, True) else: mc.setAttr('%s.isDifferential' % deformer, False) mc.setAttr( '%s.jointInputMin' % deformer, self.training_params['local_offset_joint_translate_min']) mc.setAttr( '%s.jointInputMax' % deformer, self.training_params['local_offset_joint_translate_max']) mc.setAttr('%s.normalizeInput' % deformer, self.training_params['local_offset_normalize']) self.read_prediction_data(training_types=['local_offset'], ground_truth=True) mc.setAttr('%s.anchorOutputMin' % deformer, self.training_params['local_offset_min']) mc.setAttr('%s.anchorOutputMax' % deformer, self.training_params['local_offset_max']) mc.setAttr('%s.anchorNormalizeOutput' % deformer, self.training_params['local_offset_normalize']) anchor_model_path = os.path.join(self.output_path, 'local_offset', 'model.pb') mc.setAttr('%s.anchorNetworkPath' % deformer, anchor_model_path, type='string') mc.setAttr('%s.affectedVertices' % deformer, self.vertex_ids['local_offset'], type='Int32Array') mc.setAttr( '%s.anchorInputName' % deformer, self.training_params['local_offset_network_input'].split( ':')[0], type='string') anchor_names = self.training_params[ 'local_offset_network_output'].split(',') anchor_names = [i.split(':')[0] for i in anchor_names] mc.setAttr('%s.anchorOutputName' % deformer, ','.join(anchor_names), type='string')
def create_deformer_blend(prefix, limb_ribbon_sfc, geo_skin_cluster, ctrl=None, foll_jnts_list=None, num_jnts=0): sine_bs_sfc = cmds.duplicate(limb_ribbon_sfc, name=prefix + '_ribbon_sfc_sine_bs')[0] twist_bs_sfc = cmds.duplicate(limb_ribbon_sfc, name=prefix + '_ribbon_sfc_twist_bs')[0] jnt_bs_sfc = cmds.duplicate(limb_ribbon_sfc, name=prefix + '_ribbon_sfc_joint_bs')[0] limb_bs = cmds.blendShape(sine_bs_sfc, twist_bs_sfc, jnt_bs_sfc, limb_ribbon_sfc, n=prefix + '_ribbon_blendShape')[0] cmds.setAttr(limb_bs + '.' + sine_bs_sfc, 1) cmds.setAttr(limb_bs + '.' + twist_bs_sfc, 1) cmds.setAttr(limb_bs + '.' + jnt_bs_sfc, 1) cmds.select(limb_ribbon_sfc) cmds.reorderDeformers(geo_skin_cluster, limb_bs) #setup sine sine_deformer = cmds.nonLinear(sine_bs_sfc, type='sine') cmds.setAttr(sine_deformer[0] + '.dropoff', 1) cmds.addAttr(ctrl, shortName='amplitude', keyable=True, defaultValue=0.0, minValue=-5.0, maxValue=5.0) cmds.addAttr(ctrl, shortName='wavelength', keyable=True, defaultValue=2.0, minValue=0.5, maxValue=10) cmds.addAttr(ctrl, shortName='offset', keyable=True, defaultValue=0.0, minValue=-10.0, maxValue=10.0) cmds.connectAttr(ctrl + '.amplitude', sine_deformer[0] + '.amplitude') cmds.connectAttr(ctrl + '.wavelength', sine_deformer[0] + '.wavelength') cmds.connectAttr(ctrl + '.offset', sine_deformer[0] + '.offset') #setup twist twist_deformer = cmds.nonLinear(twist_bs_sfc, type='twist') cmds.addAttr(ctrl, shortName='twist', keyable=True, defaultValue=0.0, minValue=-800.0, maxValue=800.0) cmds.connectAttr(ctrl + '.twist', twist_deformer[0] + '.startAngle') #setup joint-based blendshape num_jnts += 2 joint_bs_jnt_list = [] joint_bs_jnt_ofst_list = [] joint_bs_ctrl_list = [] foll_jnts_index_list = [] for i in range(num_jnts): # index_list.append(i/(num_jnts-1.00)) index = ceil((i / (num_jnts - 1.00)) * len(foll_jnts_list)) if index - 1 >= 0: index -= 1 joint_bs_jnt_list.append( cmds.duplicate(foll_jnts_list[index], name=prefix + '_ribbon_bs_jnt_' + str(i).zfill(2))[0]) foll_jnts_index_list.append(index) if index != 0 and index != len(foll_jnts_list) - 1: joint_bs_ctrl_list.append( control.Control(shape='spine_ctrl_template', prefix=prefix + '_joint_bs_' + str(i).zfill(2), translate_to=foll_jnts_list[index], scale=0.5, lock_channels=['s'])) for jnt in joint_bs_jnt_list: cur_grp = cmds.group(em=True, n=jnt + '_ofst_grp', w=True) transform.snap_pivot(jnt, cur_grp) cmds.parent(jnt, cur_grp) joint_bs_jnt_ofst_list.append(cur_grp) cmds.group(joint_bs_jnt_ofst_list, n=prefix + '_ribbon_bs_jnts_grp', w=True) cmds.select(joint_bs_jnt_list, jnt_bs_sfc) jnt_bs_clstr = cmds.skinCluster(tsb=True, dr=4.5) for i in range(len(joint_bs_ctrl_list)): cmds.parentConstraint(foll_jnts_list[foll_jnts_index_list[i + 1]], joint_bs_ctrl_list[i].ofst, mo=True) #cmds.parentConstraint(joint_bs_ctrl_list[i].ctrl, joint_bs_jnt_ofst_list[i+1]) cmds.connectAttr(joint_bs_ctrl_list[i].ctrl + '.translate', joint_bs_jnt_ofst_list[i + 1] + '.translate') cmds.connectAttr(joint_bs_ctrl_list[i].ctrl + '.rotate', joint_bs_jnt_ofst_list[i + 1] + '.rotate')
def __create_blendshape_setup(self): """ Create the blendShape setup """ #--- duplicate the surface plane for the blendShape version bsp_name = self.surface + 'BlendShape' self.bsp_surface = cmds.duplicate(self.surface, name=bsp_name)[0] #--- reposition the bsp_plane goe.setAttr(self.bsp_surface + '.t', 0, 0, -5) #--- create a curve and store it's arcLen info crv = curve.Curve(side=self._side, mod=self._mod, name=self._name + 'Wire', suffix='CRV', degree=2, point=[[-5, 0, -5], [0, 0, -5], [5, 0, -5]]) self.curve = crv #--- get the cv of the curve cv_start = crv.cv[0] cv_mid = crv.cv[1] cv_end = crv.cv[2] #--- create a cluster on each cv clstr_start = deformer.cluster(mod=self._mod, side=self._side, name=self._name + 'Start', suffix='CLS', geometry=cv_start, parent=self.cluster_grp) clstr_mid = deformer.cluster(mod=self._mod, side=self._side, name=self._name + 'Mid', suffix='CLS', geometry=cv_mid, parent=self.cluster_grp) clstr_end = deformer.cluster(mod=self._mod, side=self._side, name=self._name + 'End', suffix='CLS', geometry=cv_end, parent=self.cluster_grp) self.clstr_mid_grp = clstr_mid[0].split('CLS')[0] + 'GRP' if self._follow: node.pointConstraint(objA=[clstr_start[0], clstr_end[0]], objB=self.clstr_mid_grp, maintainOffset=False) #--- create a wire deformer on the curve affecting the blendShape surface wire = deformer.wire(mod=self._mod, side=self._side, name=self._name, suffix='DEF', wire=crv.transform, geometry=self.bsp_surface, dropoffDistance=20, parent=self.extra_nodes) #--- create a twist deformer on the blendShape surface, rename them twist = deformer.twist(mod=self._mod, side=self._side, name=self._name, suffix='DEF', geometry=self.bsp_surface, rotation=[0, 0, 90], parent=self.extra_nodes) #--- reorder the input order properly cmds.reorderDeformers(wire[0], twist[0], self.bsp_surface) #--- create the blendShape deformer.blendshape(mod=self._mod, side=self._side, name=self._name, suffix='BSP', shapes=self.bsp_surface, target=self.surface, shapeAttr=self.bsp_surface, shapeValue=1, lockAttr=self.bsp_surface) #--- do the proper control, cluster and deformer connections goe.connectAttr(self.control_down.transform + '.t', clstr_start[0] + '.t') goe.connectAttr(self.control_up.transform + '.t', clstr_end[0] + '.t') goe.connectAttr(self.control_mid.transform + '.t', clstr_mid[0] + '.t') goe.connectAttr(self.control_down.transform + '.rx', twist[-1] + '.endAngle') goe.connectAttr(self.control_up.transform + '.rx', twist[-1] + '.startAngle') #--- parent the nodes to the extra nodes group cmds.parent(self.bsp_surface, self.extra_nodes)
#code to reorder the deformers so the scales happen (tweak, lattice) sel = cmds.ls(sl=True) baseAttr = "COG_CTRL.scalesPuffer" for obj in sel: #get tweak deformer on obj shape = cmds.listRelatives(obj, s=True) tweak = cmds.listConnections(shape)[8] #here should use tweak = cmds.listConnections(shape, type="tweak") #print(tweak) #reorder two deformers cmds.reorderDeformers(tweak, "ffd1", obj) cmds.connectAttr(baseAttr, "%s.ry"%obj) # to stick a group in btween (group orient after the fact) import maya.cmds as cmds objs = cmds.ls(sl=True) for obj in objs: parent = cmds.listRelatives(obj, p=True)[0] rot = cmds.xform(obj, q=True, ws=True, ro=True) pos =cmds.xform(obj, q=True, ws=True, rp=True) grp = cmds.group(empty=True, n=(obj+"_GRP")) cmds.xform(grp, ws=True, ro=rot) cmds.xform(grp, ws=True, t=pos)
def preserveLength(name='spineIk', curve='spineIk_curve', primary_control='chest', rotate_controls=['chest', 'chest_ik', 'torso'], no_rotate_cvs=[2, 3], parent='spine', position_output_child='chest_top_nul'): curve_full = name # Create length curves curve_full = mc.duplicate(curve, n=curve_full)[0] mc.parent(curve_full, parent) mc.hide(curve_full) # Remove orig shapes mc.delete(mc.ls(mc.listRelatives(curve_full, s=1), io=1)) # Make nuls for each of the rotate controls and connect the rotates. # This is so we only get rotation deforming the curves for i in xrange(len(rotate_controls)): nul = mc.createNode('transform', n=rotate_controls[i] + '_input', p=rotate_controls[i]) mc.delete(mc.parentConstraint(rotate_controls[i], nul)) mc.connectAttr(rotate_controls[i] + '.r', nul + '.r') if not i: top_nul = mc.duplicate(nul, n=name + '_rotate_input')[0] mc.parent(nul, top_nul) mc.parent(top_nul, parent) else: mc.parent(nul, lastNul) lastNul = nul # Create clusters to rotate the cvs for i in no_rotate_cvs: cluster, handle = mc.cluster(curve_full + '.cv[{}]'.format(i), name=name + '_no_rotate_cluster_{}'.format(i)) rigrepo.libs.cluster.localize(cluster, parent, parent, weightedCompensation=True) mc.parent(handle, nul) mc.hide(handle) # Create scale pivot pos = mc.pointPosition(curve + '.cv[0]') scale_pivot = mc.createNode('transform', n=name + '_scale_pivot', p=parent) mc.xform(scale_pivot, ws=1, t=pos) # Create position output nul, this will be the parent of everything that is a child of the spine # that needs to move with the length change pos_output_parent = mc.listRelatives(position_output_child, p=1)[0] pos_output_nul = mc.createNode('transform', n=position_output_child + '_length_input', p=pos_output_parent) # Create position constraint target, that is child of the scale pivot position_constraint_target = mc.duplicate( pos_output_nul, n=name + '_translate_constraint_target')[0] mc.parent(position_constraint_target, scale_pivot) # Put the output child under the newly created node so everything moves with it mc.parent(position_output_child, pos_output_nul) # Create output nuls for the translate position_constraint_base_nul = mc.duplicate(position_constraint_target, n=name + '_translate_output_nul')[0] mc.parent(position_constraint_base_nul, parent) position_constraint_base = mc.createNode('transform', n=name + '_translate_output', p=position_constraint_base_nul) # Translate output constraint mc.pointConstraint(position_constraint_target, position_constraint_base) # connect the constrained nul to the position output nul mc.connectAttr(position_constraint_base + '.t', pos_output_nul + '.t') # Create scale cluster scale_cluster, scale_cluster_handle = mc.cluster(curve, n=name + '_scale_cluster') mc.hide(scale_cluster_handle) mc.parent(scale_cluster_handle, scale_pivot) rigrepo.libs.cluster.localize(scale_cluster, parent, parent, weightedCompensation=True) # Move scale cluster to front of deformation order tweak = mc.ls(mc.listHistory(curve, pdo=1, il=2), type='tweak')[0] mc.reorderDeformers(tweak, scale_cluster, curve) # Curve infos for measuring length info_full = mc.createNode('curveInfo', n=name + '_full_curveInfo') mc.connectAttr(curve_full + '.local', info_full + '.inputCurve') # Divide distances length_mul = mc.createNode('multiplyDivide', n=name + '_length_divide') mc.setAttr(length_mul + '.operation', 2) arc_length = mc.getAttr(info_full + '.arcLength') mc.setAttr(length_mul + '.input1X', arc_length) mc.connectAttr(info_full + '.arcLength', length_mul + '.input2X') # Add length preservation dial attribute mc.addAttr(primary_control, ln='preserveLength', min=0, max=1, dv=1, at='double', k=1) # Add diagnostic attributes # Current Length #mc.addAttr(primary_control, ln='currentLength', min=0, max=1, dv=1, at='double') #mc.setAttr(primary_control + '.currentLength', cb=1) #comp_mul = mc.createNode('multiplyDivide', n=name + '_current_length_mul') #mc.setAttr(comp_mul + '.operation', 2) #arc_length = mc.getAttr(info_full+'.arcLength') #mc.setAttr(comp_mul+'.input2X', arc_length) #info_main = mc.ls(mc.listConnections(mc.listRelatives(curve, s=1, ni=1)[0]), type='curveInfo')[0] #mc.connectAttr(info_main+'.arcLength', comp_mul+'.input1X') #mc.connectAttr(comp_mul + '.outputX', primary_control + '.currentLength') ## Compensated Length #mc.addAttr(primary_control, ln='compensatedLength', min=0, max=1, dv=1, at='double') #mc.setAttr(primary_control + '.compensatedLength', cb=1) #mc.connectAttr(length_mul + '.outputX', primary_control+'.compensatedLength') # Create blend node for dial attribute blend = mc.createNode('blendTwoAttr', n=name + '_attr_blend') mc.connectAttr(primary_control + '.preserveLength', blend + '.attributesBlender') mc.setAttr(blend + '.input[0]', 1) mc.connectAttr(length_mul + '.outputX', blend + '.input[1]') # Connect the blend output to the scale pivot mc.connectAttr(blend + '.output', scale_pivot + '.sy')
def flexi_plane(self, *args): # create nurbs plane w/ x attrs # nurbsPlane -p 0 0 0 -ax 0 1 0 -w 5 -lr 0.2 -d 3 -u 5 -v 1 -ch 1; nurbs_plane = cmds.nurbsPlane(ax=(0, 1, 0), w=10, lengthRatio=0.2, d=3, u=5, v=1, ch=0, n='flexi_surface_01') attrs = [ 'castsShadows', 'receiveShadows', 'motionBlur', 'primaryVisibility', 'smoothShading', 'visibleInReflections', 'visibleInRefractions' ] for attr in attrs: cmds.setAttr('flexi_surface_01Shape.{0}'.format(attr), 0) # create new material # cmds.shadingNode('lambert',asShader=1,n='flexi_surface_mat_01') # make material light blue and lower transparency # asign material to nurbs plane if cmds.checkBox(self.matCheckBox, q=1, v=1) == True: flexi_mat = cmds.shadingNode('lambert', asShader=1, n='flexi_surface_mat_01') cmds.setAttr(flexi_mat + '.color', 0.0, 1.0, 1.0, type='double3') cmds.setAttr(flexi_mat + '.transparency', 0.75, 0.75, 0.75, type='double3') cmds.select(nurbs_plane) cmds.hyperShade(assign=flexi_mat) elif cmds.checkBox(self.matCheckBox, q=1, v=1) == False: print 'no surface material created' # create follicle system # create 5 flcs flc_a01 = cmds.createNode('follicle', skipSelect=1) cmds.rename('follicle1', 'flexi_flcs_a01') flc_b01 = cmds.createNode('follicle', skipSelect=1) cmds.rename('follicle1', 'flexi_flcs_b01') flc_c01 = cmds.createNode('follicle', skipSelect=1) cmds.rename('follicle1', 'flexi_flcs_c01') flc_d01 = cmds.createNode('follicle', skipSelect=1) cmds.rename('follicle1', 'flexi_flcs_d01') flc_e01 = cmds.createNode('follicle', skipSelect=1) cmds.rename('follicle1', 'flexi_flcs_e01') # hide flcs shape vis and set up node network shapeNodes = cmds.listRelatives('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01', shapes=1) for shape in shapeNodes: cmds.setAttr("{0}.visibility".format(shape), 0) cmds.connectAttr('flexi_surface_01Shape.local', '{0}.inputSurface'.format(shape), f=1) cmds.connectAttr('flexi_surface_01Shape.worldMatrix[0]', '{0}.inputWorldMatrix'.format(shape), f=1) # node network cont. sel_shape = cmds.listRelatives('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01', shapes=1) sel = cmds.ls('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01') count = -1 for shape in sel_shape: count = count + 1 cmds.connectAttr('{0}.outRotate'.format(sel_shape[count]), '{0}.rotate'.format(sel[count]), f=1) cmds.connectAttr('{0}.outTranslate'.format(sel_shape[count]), '{0}.translate'.format(sel[count]), f=1) # move the U & V parameters for each flc sel = cmds.ls('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01') count = -0.1 for each in sel: count = count + 0.2 cmds.setAttr('{0}.parameterU'.format(each), count) cmds.setAttr('{0}.parameterV'.format(each), 0.5) # lock trans and rot on flcs sel = cmds.ls('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01') attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz'] for each in sel: for attr in attrs: cmds.setAttr('{0}.{1}'.format(each, attr), l=1) # group flcs w/ name flexi_flcs_grp_01 cmds.group('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01', n='flexi_flcs_grp_01') # create square CV , CP , end of plane, name flexi_icon_a01, change color to yellow, repeat for other end # curve -d 1 -p -6 0 -1 -p -6 0 1 -p -4 0 1 -p -4 0 -1 -p -6 0 -1 -k 0 -k 1 -k 2 -k 3 -k 4 ; ctrl_a01 = cmds.curve(d=1, p=[(-5.6, 0, -0.6), (-4.4, 0, -0.6), (-4.4, 0, 0.6), (-5.6, 0, 0.6), (-5.6, 0, -0.6)], k=[0, 1, 2, 3, 4], n='flexi_icon_a01') cmds.xform(ctrl_a01, cp=1) cmds.select(cl=1) ctrl_b01 = cmds.curve(d=1, p=[(4.4, 0, -0.6), (5.6, 0, -0.6), (5.6, 0, 0.6), (4.4, 0, 0.6), (4.4, 0, -0.6)], k=[0, 1, 2, 3, 4], n='flexi_icon_b01') cmds.xform(ctrl_b01, cp=1) shapeNodes = cmds.listRelatives(ctrl_a01, ctrl_b01, shapes=1) for shape in shapeNodes: cmds.setAttr("{0}.overrideEnabled".format(shape), 1) cmds.setAttr("{0}.overrideColor".format(shape), 17) cmds.select(cl=1) # duplicate plane, translate Z axis -5, reanme to flexi_bShp_surface_01 bShp_surface = cmds.duplicate(nurbs_plane, n='flexi_bShp_surface_01') cmds.select(bShp_surface) cmds.xform(t=[0, 0, -5]) # create blendshape w/ default settings, name flexi_bShpNode_surface_01 cmds.blendShape(bShp_surface, nurbs_plane, n='flexi_bShpNode_surface_01') # output settings to always on = 1 cmds.setAttr('flexi_bShpNode_surface_01.flexi_bShp_surface_01', 1) # CV w/ 3 pts on dup plane, degree-2, rename to flexi_wire_surface_01 wire_surface = cmds.curve(d=2, p=[(-5, 0, -5), (0, 0, -5), (5, 0, -5)], k=[0, 0, 1, 1], n='flexi_wire_surface_01') # create cluster w/ relative=ON, on left and mid cv points, rename to flexi_cl_a01 cmds.select(cl=1) clus = cmds.cluster(['flexi_wire_surface_01.cv[0:1]'], rel=1, n='flexi_clus_') clus_sel = cmds.select('flexi_clus_Handle') clus_1 = cmds.rename(clus_sel, 'flexi_cl_a01') # set cluster origin=-6 cmds.setAttr('|flexi_cl_a01|flexi_cl_a01Shape.originX', -6) # move pivot to end of dup plane cmds.xform(piv=[-5, 0, -5]) # repeat previous steps for other side cmds.select(cl=1) clus = cmds.cluster(['flexi_wire_surface_01.cv[1:2]'], rel=1, n='flexi_clus_') clus_sel = cmds.select('flexi_clus_Handle') clus_2 = cmds.rename(clus_sel, 'flexi_cl_b01') cmds.setAttr('|flexi_cl_b01|flexi_cl_b01Shape.originX', 6) cmds.xform(piv=[5, 0, -5]) # repeat for middle cmds.select(cl=1) clus = cmds.cluster(['flexi_wire_surface_01.cv[1]'], rel=1, n='flexi_clus_') clus_sel = cmds.select('flexi_clus_Handle') clus_3 = cmds.rename(clus_sel, 'flexi_cl_mid01') # select mid CV point, component editor, weighted deformer tab, a & b node set to 0.5 # select -r flexi_wire_surface_01.cv[1] ; # percent -v 0.5 flexi_cl_a01Cluster flexi_wire_surface_01.cv[1] ; # percent -v 0.5 flexi_cl_b01Cluster flexi_wire_surface_01.cv[1] ; cmds.select(cl=1) cmds.select('flexi_wire_surface_01.cv[1]') cmds.percent('flexi_cl_a01Cluster', v=0.5) cmds.percent('flexi_cl_b01Cluster', v=0.5) cmds.select(cl=1) # wire deformer, select CV then the dup plane and press enter, dropoff distance to 20 # mel.eval('wire -gw false -dds 0 20 -en 1.000000 -ce 0.000000 -li 0.000000 -w flexi_wire_surface_01 flexi_bShp_surface_01;') cmds.wire('flexi_bShp_surface_01', groupWithBase=0, dropoffDistance=(0, 20), envelope=1.0, crossingEffect=0.0, localInfluence=0.0, wire=wire_surface, n='flexi_wireAttrs_surface_01') cmds.select(cl=1) # select start control, start cluster, open conection editor, connect translate to translate # connectAttr -f flexi_icon_a01.translate flexi_cl_a01.translate; cmds.connectAttr('flexi_icon_a01.translate', 'flexi_cl_a01.translate', f=1) # repeat for other end cmds.connectAttr('flexi_icon_b01.translate', 'flexi_cl_b01.translate', f=1) # group the 3 clusters together, name it flexi_cls_01 cmds.group(clus_1, clus_2, clus_3, n='flexi_cls_01') # create group for 2 current controls, name it flexi_icons_01 cmds.group('flexi_icon_a01', 'flexi_icon_b01', n='flexi_icons_01') # lock and hide transform channels of groups attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'] for attr in attrs: cmds.setAttr('flexi_cls_01.{0}'.format(attr), l=1, k=0) cmds.setAttr('flexi_icons_01.{0}'.format(attr), l=1, k=0) # create center control, name it flexi_midBend_01 # sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 1; mid_ctrl = cmds.sphere(pivot=[0, 0, 0], ax=[0, 1, 0], startSweep=0, endSweep=360, ch=0, r=0.3, d=3, useTolerance=0, tol=0.8, spans=4, n='flexi_midBend_01') attrs = [ 'castsShadows', 'receiveShadows', 'motionBlur', 'primaryVisibility', 'smoothShading', 'visibleInReflections', 'visibleInRefractions' ] for attr in attrs: cmds.setAttr('flexi_midBend_01Shape.{0}'.format(attr), 0) # new material, surface shader, yellow color, name flexi_ss_midBend_01 if cmds.checkBox(self.matCheckBox, q=1, v=1) == True: flexi_mat_2 = cmds.shadingNode('surfaceShader', asShader=1, n='flexi_mid_mat_01') cmds.setAttr(flexi_mat_2 + '.outColor', 1.0, 1.0, 0.0, type='double3') cmds.select(mid_ctrl) cmds.hyperShade(assign=flexi_mat_2) elif cmds.checkBox(self.matCheckBox, q=1, v=1) == False: print 'no mid ctrl material created' # connect translates for new mid control to mid cluster cmds.connectAttr('flexi_midBend_01.translate', 'flexi_cl_mid01.translate', f=1) # create group for mid control, name flexi_grp_midBend_01 cmds.group('flexi_midBend_01', n='flexi_grp_midBend_01') # point constraint, select 2 outside controls, then ctrl click mid control, point constraint cmds.pointConstraint('flexi_icon_a01', 'flexi_icon_b01', 'flexi_grp_midBend_01', mo=1) # parent midBend grp under icons grp cmds.parent('flexi_grp_midBend_01', 'flexi_icons_01') # group all nodes under single group, name flexiPlane_rig_01 cmds.group('flexi_surface_01', 'flexi_flcs_grp_01', 'flexi_bShp_surface_01', 'flexi_wire_surface_01', 'flexi_wire_surface_01BaseWire', 'flexi_cls_01', 'flexi_icons_01', n='flexiPlane_rig_01') # lock and hide group transforms attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'] for attr in attrs: cmds.setAttr('flexiPlane_rig_01.{0}'.format(attr), l=1, k=0) # group flexi surface and icons grp, name flexi_globalMove_01 cmds.group('flexi_surface_01', 'flexi_icons_01', n='flexi_globalMove_01') # group all but global, name flexi_extraNodes_01 cmds.group('flexi_flcs_grp_01', 'flexi_bShp_surface_01', 'flexi_wire_surface_01', 'flexi_wire_surface_01BaseWire', 'flexi_cls_01', n='flexi_extraNodes_01') cmds.select(cl=1) # scale constrain each follicle to the global move grp sel = cmds.ls('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01') for each in sel: cmds.scaleConstraint('flexi_globalMove_01', '{0}'.format(each), mo=0) # build global control ctrl_global = cmds.curve(d=1, p=[(0, 0, -1.667542), (-0.332458, 0, -2), (0.332458, 0, -2), (0, 0, -1.667542), (0, 0, 1.667542), (0.332458, 0, 2), (-0.332458, 0, 2), (0, 0, 1.667542)], k=[0, 1, 2, 3, 4, 5, 6, 7], n='flexi_icon_global_01') cmds.xform(ctrl_global, cp=1) shapeNodes = cmds.listRelatives(ctrl_global, shapes=1) for shape in shapeNodes: cmds.setAttr("{0}.overrideEnabled".format(shape), 1) cmds.setAttr("{0}.overrideColor".format(shape), 17) cmds.select(cl=1) # parent global ctrl under main flexi grp cmds.parent('flexi_icon_global_01', 'flexiPlane_rig_01') # parent global grp under ctrl cmds.parent('flexi_globalMove_01', 'flexi_icon_global_01') cmds.select(cl=1) # create 5 joints, positioned at each follicle, w/ name of flexi_bind_a01 ... e01 cmds.joint(p=[-4, 0, 0], n='flexi_bind_a01') cmds.select(cl=1) cmds.joint(p=[-2, 0, 0], n='flexi_bind_b01') cmds.select(cl=1) cmds.joint(p=[0, 0, 0], n='flexi_bind_c01') cmds.select(cl=1) cmds.joint(p=[2, 0, 0], n='flexi_bind_d01') cmds.select(cl=1) cmds.joint(p=[4, 0, 0], n='flexi_bind_e01') cmds.select(cl=1) # turn on local rotation axis for 5 joints sel = cmds.ls('flexi_bind_a01', 'flexi_bind_b01', 'flexi_bind_c01', 'flexi_bind_d01', 'flexi_bind_e01') for obj in sel: # mel.eval('ToggleLocalRotationAxes') cmds.toggle(sel, localAxis=1) cmds.select(cl=1) # parent each joint under its respective follicle sel_parent = cmds.ls('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01') sel_child = cmds.ls('flexi_bind_a01', 'flexi_bind_b01', 'flexi_bind_c01', 'flexi_bind_d01', 'flexi_bind_e01') count = -1 for each in sel_parent: count = count + 1 cmds.parent('{0}'.format(sel_child[count]), '{0}'.format(sel_parent[count])) cmds.select(cl=1) # select bShp surface and create twist deformer # nonLinear -type twist -lowBound -1 -highBound 1 -startAngle 0 -endAngle 0; cmds.nonLinear('flexi_bShp_surface_01', typ='twist') # rotate twist node 90 degrees in z axis cmds.xform('twist*Handle', ro=(0, 0, 90)) # rename twist to flexi_twist_surface_01 cmds.rename('twist*Handle', 'flexi_twist_surface_01') # cmds.rename('twist1','flexi_twistAttrs_surface_01') twist_list = cmds.ls(exactType='nonLinear') refined_list = cmds.select(twist_list[-1]) cmds.rename(refined_list, 'flexi_twistAttrs_surface_01') # parent twist under the extra grp cmds.parent('flexi_twist_surface_01', 'flexi_extraNodes_01') # connect rotate x of start/end ctrls to start/end angles of twist deformer via direct connections # select deformer input node, then the controls # connect b01 control to the start angle and vice versa cmds.connectAttr('flexi_icon_b01.rotateX', 'flexi_twistAttrs_surface_01.startAngle') cmds.connectAttr('flexi_icon_a01.rotateX', 'flexi_twistAttrs_surface_01.endAngle') # change rotate order for ctrls to XZY cmds.xform('flexi_icon_a01', 'flexi_icon_b01', roo='xzy') # select bShp surface and change input order, twist between wire & tweak # reorderDeformers "flexi_wireAttrs_surface_01" "flexi_twistAttrs_surface_01" # "flexiPlane_rig_01|flexi_extraNodes_01|flexi_bShp_surface_01"; cmds.reorderDeformers( 'flexi_wireAttrs_surface_01', 'flexi_twistAttrs_surface_01', 'flexiPlane_rig_01|flexi_extraNodes_01|flexi_bShp_surface_01') # remove tranforms on flexi plane surface attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'] for attr in attrs: cmds.setAttr('flexi_surface_01.{0}'.format(attr), l=1, k=0) # hide bshp surface, cls grp, twist surface obj = cmds.ls('flexi_bShp_surface_01', 'flexi_cls_01', 'flexi_twist_surface_01') for each in obj: cmds.setAttr("{0}.visibility".format(each), 0) # turn off objecy display - visibility for follicles shapeNodes = cmds.listRelatives('flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01', shapes=1) for shape in shapeNodes: cmds.setAttr("{0}.visibility".format(shape), 0) cmds.select(cl=1) # create volume attr on global ctrl cmds.addAttr('flexi_icon_global_01', longName='VOLUME', attributeType='enum', enumName='--------:', k=1) cmds.addAttr('flexi_icon_global_01', longName='Enable', k=1, attributeType='enum', enumName='OFF:ON:') cmds.select(cl=1) # set up node editor # select -r flexi_wire_surface_01 ; # mel.eval('arclen -ch 1;') cmds.arclen('flexi_wire_surface_01', ch=1) cmds.rename('curveInfo1', 'flexi_curveInfo_01') # shadingNode -asUtility multiplyDivide; # // multiplyDivide1 // cmds.shadingNode('multiplyDivide', asUtility=1, n='flexi_div_squashStretch_length_01') # setAttr "multiplyDivide1.operation" 2; cmds.setAttr('flexi_div_squashStretch_length_01.operation', 2) # connectAttr -f flexi_curveInfo_01.arcLength flexi_div_squashStretch_length_01.input1X; cmds.connectAttr('flexi_curveInfo_01.arcLength', 'flexi_div_squashStretch_length_01.input1X', f=1) # setAttr "flexi_div_squashStretch_length_01.input2X" 10; cmds.setAttr('flexi_div_squashStretch_length_01.input2X', 10) # duplicate -rr;setAttr "flexi_div_volume_01.input1X" 1; cmds.shadingNode('multiplyDivide', asUtility=1, n='flexi_div_volume_01') cmds.setAttr('flexi_div_volume_01.operation', 2) cmds.setAttr('flexi_div_volume_01.input1X', 1) # connectAttr -f flexi_div_squashStretch_length_01.outputX flexi_div_volume_01.input2X; cmds.connectAttr('flexi_div_squashStretch_length_01.outputX', 'flexi_div_volume_01.input2X', f=1) # shadingNode -asUtility condition; # // condition1 // cmds.shadingNode('condition', asUtility=1, n='flexi_con_volume_01') # setAttr "flexi_con_volume_01.secondTerm" 1; cmds.setAttr('flexi_con_volume_01.secondTerm', 1) # connectAttr -f flexi_icon_global_01.Enable flexi_con_volume_01.firstTerm; cmds.connectAttr('flexi_icon_global_01.Enable', 'flexi_con_volume_01.firstTerm', f=1) # connectAttr -f flexi_div_volume_01.outputX flexi_con_volume_01.colorIfTrueR; cmds.connectAttr('flexi_div_volume_01.outputX', 'flexi_con_volume_01.colorIfTrueR', f=1) # connect volume condition out color r to joints a-e scale y & z # connectAttr -f flexi_con_volume_01.outColorR flexi_bind_a01.scaleY; # connectAttr -f flexi_con_volume_01.outColorR flexi_bind_a01.scaleZ; sel = cmds.ls('flexi_bind_a01', 'flexi_bind_b01', 'flexi_bind_c01', 'flexi_bind_d01', 'flexi_bind_e01') for each in sel: cmds.connectAttr('flexi_con_volume_01.outColorR', '{0}.scaleY'.format(each), f=1) cmds.connectAttr('flexi_con_volume_01.outColorR', '{0}.scaleZ'.format(each), f=1) # hide wire cmds.setAttr('flexi_wire_surface_01.visibility', 0) cmds.select(cl=1) # create indy controls for joints indy_1 = cmds.circle(normal=[1, 0, 0], r=0.8, d=3, sections=8, ch=0, n='flexi_indy_icon_a01') cmds.xform(t=[-4, 0, 0]) cmds.parent('flexi_indy_icon_a01', 'flexi_flcs_a01') cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0) cmds.parent('flexi_bind_a01', 'flexi_indy_icon_a01') indy_2 = cmds.circle(normal=[1, 0, 0], r=0.8, d=3, sections=8, ch=0, n='flexi_indy_icon_b01') cmds.xform(t=[-2, 0, 0]) cmds.parent('flexi_indy_icon_b01', 'flexi_flcs_b01') cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0) cmds.parent('flexi_bind_b01', 'flexi_indy_icon_b01') indy_3 = cmds.circle(normal=[1, 0, 0], r=0.8, d=3, sections=8, ch=0, n='flexi_indy_icon_c01') cmds.xform(t=[0, 0, 0]) cmds.parent('flexi_indy_icon_c01', 'flexi_flcs_c01') cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0) cmds.parent('flexi_bind_c01', 'flexi_indy_icon_c01') indy_4 = cmds.circle(normal=[1, 0, 0], r=0.8, d=3, sections=8, ch=0, n='flexi_indy_icon_d01') cmds.xform(t=[2, 0, 0]) cmds.parent('flexi_indy_icon_d01', 'flexi_flcs_d01') cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0) cmds.parent('flexi_bind_d01', 'flexi_indy_icon_d01') indy_5 = cmds.circle(normal=[1, 0, 0], r=0.8, d=3, sections=8, ch=0, n='flexi_indy_icon_e01') cmds.xform(t=[4, 0, 0]) cmds.parent('flexi_indy_icon_e01', 'flexi_flcs_e01') cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0) cmds.parent('flexi_bind_e01', 'flexi_indy_icon_e01') cmds.select(cl=1) # recolor indy controls to magenta shapeNodes = cmds.listRelatives(indy_1, indy_2, indy_3, indy_4, indy_5, shapes=1) for shape in shapeNodes: cmds.setAttr("{0}.overrideEnabled".format(shape), 1) cmds.setAttr("{0}.overrideColor".format(shape), 31) cmds.select(cl=1) # visibility control for indy controls cmds.addAttr('flexi_midBend_01', longName='VIS', attributeType='enum', enumName='--------:', k=1) cmds.addAttr('flexi_midBend_01', longName='Indy_Ctrls', k=1, attributeType='enum', enumName='OFF:ON:') cmds.setAttr('flexi_midBend_01.Indy_Ctrls', 1) # connect indy ctrl vis to on/off switch # flexi_indy_icon_c01Shape.visibility sel = cmds.ls('flexi_indy_icon_a01Shape', 'flexi_indy_icon_b01Shape', 'flexi_indy_icon_c01Shape', 'flexi_indy_icon_d01Shape', 'flexi_indy_icon_e01Shape') for each in sel: cmds.connectAttr('flexi_midBend_01.Indy_Ctrls', '{0}.visibility'.format(each), f=1) cmds.select(cl=1) # select all created objects orig_names = cmds.select( 'flexi_surface_01', 'flexi_flcs_grp_01', 'flexi_flcs_a01', 'flexi_flcs_b01', 'flexi_flcs_c01', 'flexi_flcs_d01', 'flexi_flcs_e01', 'flexi_icon_a01', 'flexi_icon_b01', 'flexi_bShp_surface_01', 'flexi_bShpNode_surface_01', 'flexi_wire_surface_01', 'flexi_cl_a01', 'flexi_cl_b01', 'flexi_cl_mid01', 'flexi_wireAttrs_surface_01', 'flexi_cls_01', 'flexi_wire_surface_01BaseWire', 'flexi_icons_01', 'flexi_midBend_01', 'flexi_grp_midBend_01', 'flexiPlane_rig_01', 'flexi_globalMove_01', 'flexi_extraNodes_01', 'flexi_icon_global_01', 'flexi_bind_a01', 'flexi_bind_b01', 'flexi_bind_c01', 'flexi_bind_d01', 'flexi_bind_e01', 'flexi_twist_surface_01', 'flexi_twistAttrs_surface_01', 'flexi_curveInfo_01', 'flexi_div_squashStretch_length_01', 'flexi_div_volume_01', 'flexi_con_volume_01', 'flexi_indy_icon_a01', 'flexi_indy_icon_b01', 'flexi_indy_icon_c01', 'flexi_indy_icon_d01', 'flexi_indy_icon_e01') if cmds.checkBox(self.matCheckBox, q=1, v=1) == True: cmds.select('flexi_surface_mat_01', 'flexi_mid_mat_01', add=1) elif cmds.checkBox(self.matCheckBox, q=1, v=1) == False: print 'no materials added to rig' sel = cmds.ls(sl=1, o=1) prefix = cmds.textFieldGrp(self.prefixText, q=1, text=1) for each in sel: cmds.select(each) cmds.rename(each, prefix + '_' + each) cmds.select(cl=1)
def setupControl(self,*args): #Load variables name = cmds.textFieldButtonGrp(self.nameField,q=True,text=True) control = cmds.textFieldButtonGrp(self.controlField,q=True,text=True) rivet = cmds.textFieldButtonGrp(self.rivetField,q=True,text=True) constObj = cmds.textFieldButtonGrp(self.jointField,q=True,text=True) #Load selection verts = cmds.ls(sl=True,fl=True) #Create Cluster clusterName,clusterHandle = cmds.cluster(rel=True,n=name+'_clstr') #Delete Rivet's aim constraint because it causes flipping if the rivets lofted nurbs plane flips. #Add parent constraint to object.(constObj) try: temp = cmds.listConnections(rivet) cmds.delete(temp[1]) except: # No constraint to delete on rivet pass #Rivet WS location rivetLocation = cmds.xform(rivet,q=True,ws=True,t=True) #Snap Cluster pivots to rivetLocation self.move(clusterHandle, rivetLocation,t=False,sp=True,rp=True) #Snap Controls pivots to rivetLocation self.move(control, rivetLocation,t=False,sp=True,rp=True) #Group Cluster clusterGrp = cmds.group(clusterHandle) clusterGrp = cmds.rename(clusterGrp, name + 'Cluster_' + clusterHandle) #Create over ride group or_grp = cmds.group(em=True,name=name+"OR1") or2_grp = cmds.group(em=True,name=name+"OR2") #Parent override group to rivet cmds.parent(or_grp,or2_grp) cmds.parent(or2_grp,rivet) #Freeze transforms on override group cmds.makeIdentity(or_grp,apply=True,t=True,r=True,s=True,n=True) #Zero Control zeroNode = cmds.group(em=True,n=name + "nullGrp") pos = cmds.xform( control, q=1, ws=True, t=1) cmds.xform( zeroNode, ws=True, t=[pos[0], pos[1], pos[2]]) rot = cmds.xform( control, q=1, ws=True, ro=1) cmds.xform( zeroNode, ws=True, ro=[rot[0], rot[1], rot[2]]) scale = cmds.xform( control, q=1, r=1, s=1) cmds.xform( zeroNode, ws=True, s=[scale[0], scale[1], scale[2]]) #Snap zeroNode pivot to control controlLocation = cmds.xform(control,q=True,ws=True,rp=True) self.move(zeroNode, controlLocation, t=False, sp=True, rp=True) #parent control to OverRide group cmds.parent(control, zeroNode, a=True) cmds.parent(zeroNode,or_grp) #Connect control t,r,s to cluster, then hide the cluster and rivet group cmds.connectAttr(control + ".translate", clusterHandle + ".translate") cmds.connectAttr(control + ".rotate", clusterHandle + ".rotate") cmds.connectAttr(control + ".scale", clusterHandle + ".scale") #Create utility node and negate double transform #by reversing the transformation of or_grp <---- Cause of double transforms mdNode = cmds.createNode("multiplyDivide") nodeName = name + "_MD" cmds.rename(mdNode,nodeName) mdNode = nodeName #Unparent control cmds.parent(zeroNode,w=True) #Set up the MD node cmds.setAttr( "%s.input2X"%mdNode, -1) cmds.setAttr( "%s.input2Y"%mdNode, -1) cmds.setAttr( "%s.input2Z"%mdNode, -1) #Connect the nodes # control ---> mdNode cmds.connectAttr("%s.translateX"%control,"%s.input1X"%mdNode,f=True) cmds.connectAttr("%s.translateY"%control,"%s.input1Y"%mdNode,f=True) cmds.connectAttr("%s.translateZ"%control,"%s.input1Z"%mdNode,f=True) #mdNode ---> or_grp cmds.connectAttr("%s.outputX"%mdNode,"%s.translateX"%or_grp,f=True) cmds.connectAttr("%s.outputY"%mdNode,"%s.translateY"%or_grp,f=True) cmds.connectAttr("%s.outputZ"%mdNode,"%s.translateZ"%or_grp,f=True) #Reparent control cmds.parent(zeroNode,or_grp) #Get mesh name # ex. "meshName.vtx[35]" mesh = verts[0].split('.')[0] #Get meshDeformer meshDeformer = mel.eval('findRelatedSkinCluster("%s");'%mesh) """ history = cmds.listHistory(mesh) for each in history: #print " History: " + each if("skinCluster" in str(each)): #Possible match for meshDeformer if("Group" not in str(each)): meshDeformer = each if("cMuscleSystem" in str(each)): if("Group" not in str(each)): meshDeformer = each """ #Reorder deformer nodes #Move cluster + meshDeformer to top of deformer stack cmds.reorderDeformers(clusterHandle,meshDeformer,mesh) #Move meshDeformer to top of deformer stack cmds.reorderDeformers(meshDeformer,clusterHandle,mesh) #Create final group topGrp = cmds.group(em=True,name=name+"_followCnt_grp") cmds.parent(clusterGrp,rivet,topGrp) #Orient constrain rivet to constrain object cmds.orientConstraint(constObj,rivet,mo=True) #Hide cluster grp cmds.setAttr(clusterGrp + ".visibility",0) #Hide the rivet rivetShape = cmds.listRelatives(rivet,shapes=True) cmds.setAttr(rivetShape[0] + ".visibility",0) #Clear selection cmds.select(clear=True)
def build ( char=None, cleanUp=False ): ''' Builds the specified character ''' #Build root structure rootSys = root.build() if not char: char = 'defaultChar' # import geo geoList = geo.importGeo(char) for g in geoList: cmds.parent( g, rootSys['geoGrp'] ) # Import joints joints.importSkel(char) # Parent joints to root defJnts group jnts = cmds.ls(type='joint') for j in jnts: p = cmds.listRelatives(j, p=1) if not p: cmds.parent(j, rootSys['defJntsGrp']) # Build spine spineSys = spine.build( hips='cn_spine_01_defJnt', chest='cn_spine_06_defJnt', head='cn_spine_11_defJnt',numSpineJoints=6, numHeadJoints=6, twistAxis='x', bendAxis='y', cleanUp=cleanUp ) cmds.parent(spineSys['xformGrp'], rootSys['systemsGrp']) spineTarg = cmds.group(empty=True) spineTarg = cmds.rename(spineTarg, common.getName(side='cn', rigPart='spine', function='const', nodeType='grp')) common.align(spineTarg, spineSys['xformGrp']) cmds.parent(spineTarg, rootSys['constGrp']) cmds.parentConstraint( spineTarg, spineSys['xformGrp'] ) # Build limbs lf_arm = anom.systems.limb.build( startJoint='lf_shoulder_1_defJnt', middleJoint='lf_arm_1_defJnt', endJoint='lf_hand_defJnt', extraJoint='lf_hand_end_defJnt', side='lf', name='arm', twistJointCount=6 ) cmds.parent( lf_arm['limbSystem_grp'], rootSys['systemsGrp'] ) rt_arm = anom.systems.limb.build( startJoint='rt_shoulder_1_defJnt', middleJoint='rt_arm_1_defJnt', endJoint='rt_hand_defJnt', extraJoint='rt_hand_end_defJnt', side='rt', name='arm', twistJointCount=6 ) cmds.parent( rt_arm['limbSystem_grp'], rootSys['systemsGrp'] ) lf_leg = anom.systems.limb.build( startJoint='lf_leg_1_defJnt', middleJoint='lf_knee_1_defJnt', endJoint='lf_foot_defJnt', extraJoint='lf_foot_end_defJnt', side='lf', name='leg', twistJointCount=5, isLeg=True ) cmds.parent( lf_leg['limbSystem_grp'], rootSys['systemsGrp'] ) rt_leg = anom.systems.limb.build( startJoint='rt_leg_1_defJnt', middleJoint='rt_knee_1_defJnt', endJoint='rt_foot_defJnt', extraJoint='rt_foot_end_defJnt', side='rt', name='leg', twistJointCount=5, isLeg=True ) cmds.parent( rt_leg['limbSystem_grp'], rootSys['systemsGrp'] ) # Build hands lf_hand = anom.systems.hand.build( side='lf', root='lf_hand_root_defJnt', fingerDict={'thumb':'lf_hand_thumb1_defJnt', 'index':'lf_hand_index1_defJnt', 'mid':'lf_hand_mid1_defJnt', 'pinky':'lf_hand_pinky1_defJnt'}, cleanUp=cleanUp ) cmds.parent (lf_hand['systemGrp'], rootSys['systemsGrp']) cmds.parentConstraint( lf_arm['jointList'][2], lf_hand['systemGrp'], mo=1 ) # Sorry - I know it's horrible but time's running out!! (Bad, bad Duncan... :p) rt_hand = anom.systems.hand.build( side='rt', root='rt_hand_root_defJnt', fingerDict={'thumb':'rt_hand_thumb1_defJnt', 'index':'rt_hand_index1_defJnt', 'mid':'rt_hand_mid1_defJnt', 'pinky':'rt_hand_pinky1_defJnt'}, cleanUp=cleanUp ) cmds.parent (rt_hand['systemGrp'], rootSys['systemsGrp']) cmds.parentConstraint( rt_arm['jointList'][2], rt_hand['systemGrp'], mo=1 ) # Build feet lf_foot = reverseFoot.build( side = 'lf', jntFoot = lf_leg['jointList'][-1], ctrlFoot = lf_leg['end_ctrl'], ikHandleLeg = lf_leg['ikHandle'], mesh = 'cn_body_render_mesh', stretchLoc = lf_leg['stretch_positions'][1], cleanUp = cleanUp ) cmds.parent( lf_foot['systemsGrp'], rootSys['systemsGrp']) rt_foot = reverseFoot.build( side = 'rt', jntFoot = rt_leg['jointList'][-1], ctrlFoot = rt_leg['end_ctrl'], ikHandleLeg = rt_leg['ikHandle'], mesh = 'cn_body_render_mesh', stretchLoc = rt_leg['stretch_positions'][1], cleanUp = cleanUp ) cmds.parent( rt_foot['systemsGrp'], rootSys['systemsGrp']) # Build AutoHips lf_autoHip = autoHip.createAutoHip(lf_leg['start_ctrl'], spineSys['hipCtrl'][0], lf_leg['end_ctrl']) rt_autoHip = autoHip.createAutoHip(rt_leg['start_ctrl'], spineSys['hipCtrl'][0], rt_leg['end_ctrl']) cmds.parent( lf_autoHip['autoHipSystem_grp'], rt_autoHip['autoHipSystem_grp'], rootSys['systemsGrp']) # Build Rivets lf_shoulder_rivet = rivet.build( targ=lf_arm['start_ctrl'], mesh='cn_body_render_mesh', side='lf', rigPart='arm', cleanUp=cleanUp ) cmds.parent( lf_shoulder_rivet['follicle'], rootSys['constGrp'] ) cmds.pointConstraint( lf_shoulder_rivet['constGrp'], cmds.listRelatives(lf_arm['start_ctrl'], p=1)[0] ) rt_shoulder_rivet = rivet.build( targ=rt_arm['start_ctrl'], mesh='cn_body_render_mesh', side='rt', rigPart='arm', cleanUp=cleanUp ) cmds.parent( rt_shoulder_rivet['follicle'], rootSys['constGrp'] ) cmds.pointConstraint( rt_shoulder_rivet['constGrp'], cmds.listRelatives(rt_arm['start_ctrl'], p=1)[0] ) lf_eye_rivet = rivet.build( targ='lf_head_eye_defJnt', mesh='cn_body_render_mesh', side='lf', rigPart='eye', cleanUp=cleanUp ) cmds.parent( lf_eye_rivet['follicle'], rootSys['constGrp'] ) rt_eye_rivet = rivet.build( targ='rt_head_eye_defJnt', mesh='cn_body_render_mesh', side='rt', rigPart='eye', cleanUp=cleanUp ) cmds.parent( rt_eye_rivet['follicle'], rootSys['constGrp'] ) connectToPuppet() # Bind skin cmds.select( cmds.listRelatives(rootSys['geoGrp']) ) anom.core.skinWeights.rebindSkinClusters( char ) anom.core.skinWeights.setSkinWeights( char ) cmds.reorderDeformers( 'lf_foot_contact_ffd', 'skincluster_cn_body_render_mesh', 'cn_body_render_mesh' ) # Make everything follow root the evil way | global scale cmds.parentConstraint( rootSys['constGrp'][0], rootSys['systemsGrp'][0], mo=1 ) cmds.scaleConstraint ( rootSys['constGrp'][0], rootSys['systemsGrp'][0], mo=1 ) cmds.connectAttr( rootSys['systemsGrp'][0] + '.scale', rootSys['defJntsGrp'][0] + '.scale' ) invScale = cmds.shadingNode( 'multiplyDivide', asUtility = True, name = 'root_systems_invScale_md' ) cmds.setAttr( invScale + '.operation', 2 ) cmds.setAttr( invScale + '.input1', 1, 1, 1, type='double3' ) cmds.connectAttr( rootSys['systemsGrp'][0] + '.scale', invScale + '.input2' ) #connect autoHip to inverse world scale cmds.connectAttr( invScale + '.output', lf_autoHip['placer'][0] + '.scale' ) cmds.connectAttr( invScale + '.output', rt_autoHip['placer'][0] + '.scale' ) #connect follicles to systemGrp scale this fixes errors from the offset at extreme scaling values for fol in [ lf_shoulder_rivet['follicle'], rt_shoulder_rivet['follicle'], lf_eye_rivet['follicle'], rt_eye_rivet['follicle'] ]: cmds.connectAttr( rootSys['systemsGrp'][0] + '.scale', fol+'.scale' ) cmds.setAttr( fol+'.v', 0 ) # finally hide defJnts if cleanUp: cmds.setAttr( rootSys['offsetCtrl'][0].control +'.jointsVisibility', 0 ) # create a Layer for the meshes cmds.createDisplayLayer( name='MESH_layer', empty=True ) cmds.editDisplayLayerMembers( 'MESH_layer', rootSys['geoGrp'], noRecurse=True ) cmds.setAttr( 'MESH_layer.displayType', 2 ) # unselectable cmds.select( clear=True )
def build( pelvis_jnt, spine_jnts, prefix='spine', rig_scale=1.0, base_rig=None ): """ @param spine_jnts: list(str), list of 6 spine jnts @param root_jnt: str, root_jnt @param prefix: str, prefix to name new object @param rig_scale: float, scale factor for size of controls @param base_rig: instance of base.module.Base class @return: dictionary with rig module objects """ #make rig module rig_module = module.Module(prefix=prefix, base_obj=base_rig, create_dnt_grp=True) #make spine controls body_ctrl = control.Control(shape='body_ctrl_template', prefix='body', translate_to=pelvis_jnt, scale=rig_scale, parent=rig_module.ctrl_grp, lock_channels=['s', 'v']) hip_ctrl = control.Control(shape='hip_ctrl_template', prefix='hip', translate_to=pelvis_jnt, scale=rig_scale, parent=body_ctrl.ctrl, lock_channels=['s', 'v']) ctrl_shape = cmds.listRelatives(hip_ctrl.ctrl, shapes=True)[0] cmds.setAttr(ctrl_shape + '.ove', 1) cmds.setAttr(ctrl_shape + '.ovc', 18) chest_ctrl = control.Control(shape='chest_ctrl_template', prefix='chest', translate_to=spine_jnts[len(spine_jnts)-1], scale=rig_scale, parent=body_ctrl.ctrl, lock_channels=['s', 'v']) spine_ctrl = control.Control(shape='spine_ctrl_template', prefix=prefix, translate_to=[hip_ctrl.ctrl, chest_ctrl.ctrl], scale=rig_scale, parent=body_ctrl.ctrl, lock_channels=['s', 'r', 'v']) ctrl_shape = cmds.listRelatives(spine_ctrl.ctrl, shapes=True)[0] cmds.setAttr(ctrl_shape + '.ove', 1) cmds.setAttr(ctrl_shape + '.ovc', 18) #SET UP RIBBON #create ribbon surface and add follicles ribbon.create_cv_curve('temp_spine_ribbon_crv_01', spine_jnts) ribbon_sfc = ribbon.loft_using_curve('temp_spine_ribbon_crv_01', 8, 'x', prefix) cmds.rebuildSurface(ribbon_sfc, su=0, sv=3, du=1, dv=3, ch=True) spine_follicles = ribbon.add_follicles(ribbon_sfc, 4, on_edges=True) spine_ik_jnts = joint.duplicate(spine_jnts, prefix='ik') spine_follicles_grp = '_'.join([prefix,'follicles','grp']) cmds.group(spine_follicles, n=spine_follicles_grp) for i in range(len(spine_ik_jnts)): cmds.parent(spine_ik_jnts[i], spine_follicles[i]) #create ribbon_wire_curve to drive the surface using wire deformer ribbon_wire_curve = 'ribbon_wire_crv' create_ep_curve(curve=ribbon_wire_curve, pos_ref_list=[spine_jnts[0], spine_jnts[len(spine_jnts)-1]], degree=2) #create and add clusters ribbon_clstr_list = [] for i in range(ribbon.get_curve_num_cvs(ribbon_wire_curve)): cmds.select(ribbon_wire_curve+'.cv[%d]' % i) temp_clstr_name = 'ribbon_clstr_'+str(i).zfill(2)+'_' ribbon_clstr_list.append(cmds.cluster(name=temp_clstr_name)[1]) cmds.setAttr(temp_clstr_name+'Handle.visibility', 0) ribbon_clstrs_grp = cmds.group(ribbon_clstr_list, n='ribbon_clstrs_grp') #create wire deformer cmds.wire(ribbon_sfc, w=ribbon_wire_curve, dds=(0,50)) ribbon_wire_grp = cmds.group([ribbon_wire_curve, ribbon_wire_curve+'BaseWire'], n='ribbon_wire_grp') #fix orientations for spine_ik_jnts for i in range(1,len(spine_ik_jnts))[::-1]: temp_jnt_driver = '_'.join(['ik', prefix, str(i+1).zfill(2)]) temp_jnt_driven = '_'.join(['ik', prefix, str(i).zfill(2)]) cmds.aimConstraint(temp_jnt_driver, temp_jnt_driven, aim=(1.0,0.0,0.0), wut='objectrotation', wuo=temp_jnt_driver) #setup ribbon twist ribbon_twist_sfc = 'spine_ribbon_twist_surface' cmds.duplicate(ribbon_sfc, n=ribbon_twist_sfc) twist_handle = ribbon.create_twist_deformer(sfc=ribbon_twist_sfc, prefix=prefix) twist_angle_plus_minus_node = connect_body_ctrl_to_ribbon(body_ctrl, twist_handle) connect_twist_ribbon(prefix, hip_ctrl, twist_angle_plus_minus_node, 'start') connect_twist_ribbon(prefix, chest_ctrl, twist_angle_plus_minus_node, 'end') twist_mult_node = 'spine_twist_master_mult_node' cmds.createNode('multiplyDivide', n=twist_mult_node) cmds.connectAttr(base_rig.master_ctrl.ctrl+'.rotateY', twist_mult_node+'.input1X') cmds.setAttr(twist_mult_node+'.input2X', -1) cmds.connectAttr(twist_mult_node+'.outputX', 'start'+twist_angle_plus_minus_node+'.input1D[2]') cmds.connectAttr(twist_mult_node+'.outputX', 'end'+twist_angle_plus_minus_node+'.input1D[2]') ribbon_bs = prefix+'_ribbon_blendshape' cmds.blendShape(ribbon_twist_sfc, ribbon_sfc, n=ribbon_bs) cmds.setAttr(ribbon_bs+'.'+ribbon_twist_sfc, 1) cmds.select(hip_ctrl.ctrl, chest_ctrl.ctrl) cmds.xform(rotateOrder='yzx') cmds.select(ribbon_sfc) cmds.reorderDeformers('wire1', ribbon_bs) #set up skel constraints cmds.select(d=True) for i in range(len(spine_jnts)-1): driver = spine_ik_jnts[i] driven = spine_jnts[i] cmds.pointConstraint(driver, driven, maintainOffset=False) cmds.orientConstraint(driver, driven, maintainOffset=False) ik_spine_04_orient_jnt = spine_ik_jnts[3]+'_orient' cmds.duplicate(spine_ik_jnts[3], n=ik_spine_04_orient_jnt) cmds.parent(ik_spine_04_orient_jnt, chest_ctrl.ctrl) cmds.makeIdentity(ik_spine_04_orient_jnt, t=0, r=1, s=0, apply=True) cmds.pointConstraint(ik_spine_04_orient_jnt, spine_jnts[3], maintainOffset=False) cmds.orientConstraint(ik_spine_04_orient_jnt, spine_jnts[3], maintainOffset=False) pelvis_orient_jnt = 'pelvis_orient' cmds.duplicate('pelvis', n=pelvis_orient_jnt, rc=True) cmds.delete(cmds.listRelatives(pelvis_orient_jnt)) cmds.parent(pelvis_orient_jnt, hip_ctrl.ctrl) cmds.makeIdentity(pelvis_orient_jnt, t=0, r=1, s=0, apply=True) cmds.pointConstraint(pelvis_orient_jnt, 'pelvis', maintainOffset=False) cmds.orientConstraint(pelvis_orient_jnt, 'pelvis', maintainOffset=False) #AUTO MOVEMENT FOR spine_ctrl spine_ctrl_drv = 'spine_ctrl_drv' cmds.select(d=True) cmds.group(n=spine_ctrl_drv, em=True) cmds.delete(cmds.parentConstraint(spine_ctrl.ofst, spine_ctrl_drv)) cmds.parent(spine_ctrl_drv, spine_ctrl.ofst) cmds.parent(spine_ctrl.ctrl, spine_ctrl_drv) #create joint for spine_ctrl create_spine_ctrl_auto_jnts(hip_ctrl, 'bottom', spine_ctrl, spine_ctrl_drv) create_spine_ctrl_auto_jnts(chest_ctrl, 'top', spine_ctrl, spine_ctrl_drv) #spine_ctrl auto switch cmds.addAttr(chest_ctrl.ctrl, shortName='midInfluence', keyable=True, defaultValue=0.0, minValue=0.0, maxValue=1.0) create_spine_ctrl_auto_switch(chest_ctrl, spine_ctrl_drv) #set up ctrl constraints cmds.parentConstraint(hip_ctrl.ctrl, ribbon_clstr_list[0], mo=True) cmds.parentConstraint(spine_ctrl.ctrl, ribbon_clstr_list[1], mo=True) cmds.parentConstraint(chest_ctrl.ctrl, ribbon_clstr_list[2], mo=True) #cleanup spine_sfc_grp = 'spine_sfc_grp' spine_deformers_grp = 'spine_deformers_grp' cmds.group([ribbon_sfc, ribbon_twist_sfc], name=spine_sfc_grp) cmds.group(twist_handle, name=spine_deformers_grp) cmds.parent([spine_follicles_grp, ribbon_wire_grp, ribbon_clstrs_grp, spine_sfc_grp, spine_deformers_grp], rig_module.dnt_grp) return [chest_ctrl, spine_ctrl, hip_ctrl, body_ctrl]
def base(self, *args): if self.update is False: mc.file(new=True, force=True) # Create base rig self.baseRig = nc_module.Base(characterName=self.characterName, scale=self.sceneScale, globalCtrlScale=self.globalCtrlScale) if self.pathSkeleton: mc.file(self.pathSkeleton, i=1) if not self.pathSkinCluster: mc.parent(self.rootJnt, self.baseRig.jointsGrp) if self.pathModel: before = mc.ls(assemblies=True) mc.file(self.pathModel, i=1) after = mc.ls(assemblies=True) # Using the before and after variable # to determine the model node model_node = set(after).difference(before).pop() mc.parent(model_node, self.baseRig.modelGrp) if self.pathSkinCluster: geo_list = defo.get_geo(model_grp=self.baseRig.modelGrp) joint_list = defo.get_joints(root_joint='root') defo.load_weights(weight_dir=self.pathSkinCluster, geo_list=geo_list, joint_list=joint_list) mc.parent(self.rootJnt, self.baseRig.jointsGrp) if self.pathBlendshapes: before = mc.ls(assemblies=True) mc.file(self.pathBlendshapes, i=1) after = mc.ls(assemblies=True) # Using the before and after variable # to determine the model node bs_node = set(after).difference(before).pop() bs_list = defo.get_geo(bs_node) mc.blendShape(bs_list, self.blendshapes_to, name='{}_bs'.format(self.characterName)) mc.select('{}_body_geo'.format(self.characterName)) mc.reorderDeformers('{}_body_scls'.format(self.characterName), '{}_bs'.format(self.characterName)) mc.parent(bs_node, self.baseRig.modelGrp) mc.select(d=True) else: baseRig = nc_module.Base(characterName=self.characterName, scale=self.sceneScale, globalCtrlScale=15) mc.parent(self.rootJnt, baseRig.jointsGrp) mc.parent(self.pathModel, baseRig.modelGrp) # Create visibility attributes mc.addAttr(self.baseRig.globalCtrl.C, at='bool', shortName='jnts', longName='Joints') mc.connectAttr(self.baseRig.globalCtrl.C + '.Joints', self.baseRig.jointsGrp + '.v') mc.setAttr(self.baseRig.globalCtrl.C + '.Joints', edit=True, channelBox=True) # Create informational attributes mc.addAttr(self.baseRig.infoGrp, shortName='baserig', longName='BASERIG', at="enum", enumName="biped", keyable=False) mc.setAttr(self.baseRig.infoGrp + '.baserig', edit=True, channelBox=True) mc.addAttr(self.baseRig.infoGrp, shortName='charname', longName='CHARACTERNAME', at="enum", enumName=self.characterName, keyable=False) mc.setAttr(self.baseRig.infoGrp + '.charname', edit=True, channelBox=True)