def create_curveSphere(name, radius): circGrp = pm.group(n=name, em=True) circ1 = pm.circle(nr=[1, 0, 0], ch=True)[0] circ2 = pm.circle(nr=[1, 0, 0], ch=True)[0] circ3 = pm.circle(nr=[1, 0, 0], ch=True)[0] circs = [circ1, circ2, circ3] circGrp.overrideEnabled.set(1) circGrp.overrideColorRGB.set(1, 1, 0) circGrp.overrideRGBColors.set(1) pm.xform(circGrp, s=[radius, radius, radius]) pm.xform(circ2, ro=[0, 90, 0]) pm.xform(circ3, ro=[0, 0, 90]) pm.makeIdentity([circ1, circ2, circ3], a=True, t=True, r=True, s=True, n=False) circ1_shape = pm.listRelatives(circ1, s=True)[0] circ2_shape = pm.listRelatives(circ2, s=True)[0] circ3_shape = pm.listRelatives(circ3, s=True)[0] pm.parent([circ1_shape, circ2_shape, circ3_shape], circGrp, r=True, s=True) pm.delete([circ1, circ2, circ3]) return circGrp
def bdBuildSplineSolverScale(self,condition): print 'asdas' self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0] effector = pm.listConnections(self.ikSpline ,source=True, type='ikEffector')[0] endJoint = pm.listConnections(effector,source=True, type='joint')[0] startJointChild = pm.listRelatives(self.startJoint,c=True, type='joint')[0] self.jointChain = [] self.jointChain.append(self.startJoint) self.jointChain.append(startJointChild) while startJointChild.name() != endJoint.name(): startJointChild = pm.listRelatives(startJointChild,c=True, type='joint')[0] self.jointChain.append(startJointChild) self.splineCurveScl = pm.duplicate(self.splineCurve,name = self.splineCurve.name().replace('crv','crv_scl')) strArclenSCL = pm.arclen(self.splineCurveScl,ch=True) strArclenCRV = pm.arclen(self.splineCurve,ch=True) arclenSCL = pm.ls( strArclenSCL ) [0] arclenCRV = pm.ls( strArclenCRV ) [0] arclenSCL.rename(self.splineCurveScl[0].name() + '_length') arclenCRV.rename(self.splineCurve.name() + '_length') mdScaleFactor = pm.createNode('multiplyDivide', name = self.splineCurve.name().replace('crv','crv_scaleFactor_md')) arclenCRV.arcLength.connect(mdScaleFactor.input1X) arclenSCL.arcLength.connect(mdScaleFactor.input2X) mdScaleFactor.operation.set(2) for jnt in self.jointChain: mdScaleFactor.outputX.connect(jnt.scaleX)
def test_clusterPlane(self): fr = FollowRibbon.FollowRibbon(name="blah") plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=0.1, ch=0)[0] ctrls = [] ctrls.append(pm.circle(n="blah_ctrl_01")[0].name()) ctrls.append(pm.circle(n="blah_ctrl_02")[0].name()) mainGrp = pm.group(em=1, name="main") result = fr._clusterPlane(plane=plane, controls=ctrls, mainGrp="main") self.testLib.assertListEqual(result, ["blah_cluster_01Handle", "blah_cluster_02Handle"]) self.assertTrue(pm.objExists("blah_cluster_01")) self.assertTrue(pm.objExists("blah_cluster_02")) self.assertTrue(pm.listRelatives(result[0], parent=True), "main") self.assertTrue(pm.listRelatives(result[1], parent=True), "main") self.assertTrue(pm.listRelatives(result[0], parent=1)[0], "blah_ctrlsGrp") self.assertTrue(pm.listRelatives(result[1], parent=1)[0], "blah_ctrlsGrp") hist = pm.listHistory(plane) hitA = 0 hitB = 0 for each in hist: if each.name() == "blah_cluster_01": hitA = 1 if each.name() == "blah_cluster_02": hitB = 1 self.assertTrue(hitA) self.assertTrue(hitB) self.assertTrue(pm.isConnected("blah_ctrl_01.translate", "blah_cluster_01Handle.translate")) self.assertTrue(pm.isConnected("blah_ctrl_02.translate", "blah_cluster_02Handle.translate"))
def FTV_getFluidElements( fluid ): '''this function consider the type of parameter fluid to not be exactly known but output anyway the fluid Transform and the fluid Shape''' if fluid is None: raise FTV_msCommandException('Please select a Fluid') fldTrs = None fldShp = None if pm.nodeType(fluid)== 'transform': childs = pm.listRelatives(fluid, s=True) if len(childs)>0 and pm.nodeType(childs[0]) == 'fluidShape' : fldTrs = fluid fldShp = childs[0] else : raise FTV_msCommandException('selection is invalid, you must select a fluid') elif pm.nodeType(fluid)== 'fluidShape': par = pm.listRelatives(fluid, p=True) if len(par)>0 and pm.nodeType(par[0]) == 'transform' : fldTrs = par[0] fldShp = fluid else : raise FTV_msCommandException('selection is invalid, you must select a fluid') else : raise FTV_msCommandException('selection is invalid, you must select a fluid') return (fldTrs,fldShp)
def getControlLocator(self): try: parent = pc.listRelatives(self.camera, p=True)[0] control_locator = pc.listRelatives(parent, p=True)[0] except: control_locator = '' return control_locator
def symCtrl(s, root): parent = pm.listRelatives(s, parent = True) children = pm.listRelatives(s, children = True, type = 'transform') # deparent children for c in children: c.setParent(world = True) # duplicate group parent for p in parent : newGroup = pm.duplicate(parent, renameChildren = True, name = p.name().replace('R_', 'L_')) # rename children child = pm.listRelatives(newGroup, children = True, type = 'transform') print(child) for c in child: pm.rename(c, c.name().replace('R_', 'L_')) # reparent children for c in children: c.setParent(s) # deparent copy print(children) tempGrp = pm.group(em = True, world = True, name = "tempMirrorGrp" ) for grp in newGroup: grp.setParent(tempGrp) # reverse tempGrp.scaleX.set(-1) # parent copy group parent to world to world grp.setParent(world = True) # parent copy to facial 'facial_ctrl_grp' grp.setParent(root) pm.delete(tempGrp)
def _parentSurfaceFLCL(self, constrained_obj, geo, deleteCPOMS=1): """ Parents object to follicle at closest point on surface. Select child transform, then select mesh to hold parent follicle. """ cpos = pmc.createNode('closestPointOnSurface', n='cpos_flcl_' + geo) mc.connectAttr(pmc.listRelatives(geo, shapes=True, children=True)[0] + '.local', cpos + '.inputSurface') obj_mtx = pmc.xform(constrained_obj, q=True, m=True) pmc.setAttr(cpos + '.inPosition', [obj_mtx[12], obj_mtx[13], obj_mtx[14]]) flclShape = pmc.createNode('follicle', n='flclShape' + geo) flcl = pmc.listRelatives(flclShape, type='transform', parent=True) pmc.rename(flcl, 'flcl_' + geo + '_1') mc.connectAttr(flclShape + '.outRotate', flcl[0] + '.rotate') mc.connectAttr(flclShape + '.outTranslate', flcl[0] + '.translate') mc.connectAttr(geo + '.worldMatrix', flclShape + '.inputWorldMatrix') mc.connectAttr(geo + '.local', flclShape + '.inputSurface') mc.setAttr(flclShape + '.simulationMethod', 0) u = mc.getAttr(cpos + '.result.parameterU') v = mc.getAttr(cpos + '.result.parameterV') pmc.setAttr(flclShape + '.parameterU', u) pmc.setAttr(flclShape + '.parameterV', v) pmc.parent(constrained_obj, flcl) if deleteCPOMS == 1: pmc.delete(cpos) return flcl
def _createNode(self): try: cam = pm.ls(sl=True, type="camera")[0] except: raise AttributeError("Please select a camera shape!") node = pm.nodetypes.ImagePlane() # adapted from cameraImagePlaneUpdate.mel node.message.connect(cam.imagePlane, nextAvailable=True) cam.horizontalFilmAperture.connect(node.sizeX) cam.verticalFilmAperture.connect(node.sizeY) cam.orthographicWidth.connect(node.width) cam.orthographicWidth.connect(node.height) node.attr("center").set(cam.getWorldCenterOfInterest()) for item in pm.listRelatives(cam, parent=True): pm.showHidden(item, below=True) for modelPanel in pm.getPanel(type="modelPanel"): modelCamera = pm.modelPanel(modelPanel, query=True) if modelCamera != "": for shape in pm.listRelatives(modelCamera, shapes=True): if shape == cam: editor = pm.modelPanel(modelPanel, query=True, modelEditor=True) pm.modelEditor(editor, edit=True, updateColorMode=True) break return node
def bdBuildRPSolverScale(self,condition): print 'RP Solver' #self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0] pm.select(cl=True) ikGrp = pm.group(n=self.ikSpline.name() + '_GRP') ikParent = self.ikSpline.getParent() ikPos = self.ikSpline.getTranslation(space= 'world') ikGrp.setTranslation(ikPos) pm.parent(ikGrp,ikParent) pm.parent(self.ikSpline,ikGrp) sclJnt = pm.duplicate(self.startJoint, parentOnly = True , name = self.startJoint.name().replace('JNT','SCL'))[0] effector = pm.listConnections(self.ikSpline ,source=True, type='ikEffector')[0] endJoint = pm.listConnections(effector,source=True, type='joint')[0] startJointChild = pm.listRelatives(self.startJoint,c=True, type='joint')[0] self.jointChain = [] self.jointChain.append(self.startJoint) self.jointChain.append(startJointChild) while startJointChild.name() != endJoint.name(): startJointChild = pm.listRelatives(startJointChild,c=True, type='joint')[0] self.jointChain.append(startJointChild) jntPos = [] for jnt in self.jointChain: pos = jnt.getTranslation(space= 'world') jntPos.append(pos) self.splineCurveScl = pm.curve(p=jntPos, degree =1, n = self.startJoint.name().replace('01_JNT','CRV_SCL')) self.splineCurveScl.setPivots(jntPos[0]) pm.parent(self.splineCurveScl, sclJnt) strArclenSCL = pm.arclen(self.splineCurveScl,ch=True) arclenSCL = pm.ls( strArclenSCL ) [0] arclenSCL.rename(self.splineCurveScl.name() + '_length') distanceNode = pm.createNode('distanceBetween',name = self.startJoint.name().replace('_01_JNT','distance')) sclJnt.rotatePivotTranslate.connect(distanceNode.point1) ikGrp.rotatePivotTranslate.connect(distanceNode.point2) sclJnt.worldMatrix.connect(distanceNode.inMatrix1) ikGrp.worldMatrix.connect(distanceNode.inMatrix2) mdScaleFactor = pm.createNode('multiplyDivide', name = self.splineCurveScl.name().replace('CRV_SCL','CRV_scaleFactor_MD')) distanceNode.distance.connect(mdScaleFactor.input1X) arclenSCL.arcLength.connect(mdScaleFactor.input2X) mdScaleFactor.operation.set(2) cndScaleFactor = pm.createNode('condition', name = self.splineCurveScl.name().replace('CRV_SCL','CRV_scaleFactor_CND')) distanceNode.distance.connect(cndScaleFactor.firstTerm) arclenSCL.arcLength.connect(cndScaleFactor.secondTerm) mdScaleFactor.outputX.connect(cndScaleFactor.colorIfTrueR) cndScaleFactor.operation.set(2) for jnt in self.jointChain: cndScaleFactor.outColorR.connect(jnt.scaleX)
def __init__(self): selectedObjects = pm.ls(selection = True, transforms = True) filteredGroups = [] for obj in selectedObjects: if obj.find("Group__") == 0: filteredGroups.append(obj) if len(filteredGroups) == 0: return # Recursively find and store grouped module namespaces in a list groupContainer = "Group_container" modules = [] for group in filteredGroups: modules.extend(self.FindChildModules(group)) # Store all the grouped container nodes in a list moduleContainers = [groupContainer] for module in modules: moduleContainer = "%s:module_container" %module moduleContainers.append(moduleContainer) # Unlock containers for container in moduleContainers: pm.lockNode(container, lock = False, lockUnpublished = False) # Ungroup for group in filteredGroups: childCount = len(pm.listRelatives(group, children = True)) if childCount > 1: pm.ungroup(group, absolute = True) for attr in ["t", "r", "globalScale"]: pm.container(groupContainer, edit = True, unbindAndUnpublish = "%s.%s" %(group, attr)) parentGroup = pm.listRelatives(group, parent = True) pm.delete(group) # Recursively delete empty parent groups if len(parentGroup) != 0: parentGroup = parentGroup[0] children = pm.listRelatives(parentGroup, children = True) children = pm.ls(children, transforms = True) if len(children) == 0: pm.select(parentGroup, replace = True) UngroupSelected() # Lock module containers after ungrouping is finished for container in moduleContainers: if pm.objExists(container): pm.lockNode(container, lock = True, lockUnpublished = True)
def getCtrlMainGrp(self,ctrl): chainParents = [] parent = pm.listRelatives(ctrl,p=1) chainParents.append(parent) while parent : parent = pm.listRelatives(parent ,p=1) chainParents.append(parent ) chainParents.pop() return chainParents[-1][0]
def exploreFurther(selected, elements): relatives = pc.listRelatives(selected) # Dig deeper in the hierarchy to find the shapes for relative in relatives: if len(pc.listRelatives(relative)) != 0: exploreFurther(relative, elements) elif relative.type() == 'mesh': for element in elements.keys(): pc.setAttr(relative+'.'+element, elements[element])
def buildShoulderNoRoll(self): ''' Setup no roll shoulder. Assumes Elbow is child of Shoulder. ''' self.logger.info('buildShoulderNoRoll(): Starting...') # Get the shoulder / elbow / wrist joint shldrJ = str(self.ui.shldrJointLineEdit.text()) elbowJ = str(self.ui.elbowJointLineEdit.text()) wristJ = str(self.ui.wristJointLineEdit.text()) parentJ = str(self.ui.jointChainLineEdit.text()) # Get as PyNodes pm.select(elbowJ,r=1) elbowJ = pm.ls(sl=1)[0] pm.select(shldrJ,r=1) shldrJ = pm.ls(sl=1)[0] pm.select(wristJ,r=1) wristJ = pm.ls(sl=1)[0] #--- No roll rig nfShldr = self.noRollRig( startJnt=shldrJ ) # Get the nfWrist joint for each in pm.listRelatives( nfShldr, children=1 ): if each.type() == 'joint': nfWrist = each self.logger.info('buildShoulderNoRoll(): Selected noroll wrist: %s'%nfWrist) break #--- Create the spline joint chain numJoints = self.ui.clavJointLcdNumber.value() startJ, endJ = self.createJoints( startJnt=shldrJ, endJnt=elbowJ, numJoints=numJoints ) #--- Setup the Ik Spline with Advanced Twist ikHandle, ikCurve = self.advancedSplineIK( startJ=startJ, endJ=endJ, start=shldrJ, nfStart=nfShldr ) pm.parentConstraint(shldrJ, ikCurve, mo=True) #--- Create twist result joint twistJnt = self.createTwistJnt(jnt=elbowJ, nfJnt=nfShldr, ikHandle=ikHandle) #--- Create rig grp grp = pm.group(em=True, name='%s_noroll_grp'%shldrJ) pm.delete(pm.parentConstraint(shldrJ, grp, mo=False)) pm.parent(nfShldr, grp) pm.parent(ikHandle, grp) pm.parent(ikCurve, grp) clavJ = pm.listRelatives(shldrJ, parent=True) pm.parentConstraint(clavJ, grp, mo=True) pm.pointConstraint(shldrJ,nfShldr,mo=True) pm.parent(startJ, parentJ) self.logger.info('buildShoulderNoRoll(): End.')
def check(self): nodes = [pm.listRelatives(n, parent=True) for n in pm.ls(type="mesh")] for node in nodes: if not pm.listRelatives(node, parent=True): self.selection.append(node) if self.selection: names = ", ".join([str(node) for node in self.selection]) msg = self.fail_msg.format(len(self.selection), names) return False, msg return True, self.pass_msg
def createTwistJnt(self, jnt=None, nfJnt=None, ikHandle=None): ''' Setup twist joint to use as angular diff object from no_roll jnt ''' twistJnt =pm.duplicate(jnt, n=jnt.name()+'_twistResult')[0] pm.delete(pm.listRelatives(twistJnt)) nfEnd = [x for x in pm.listRelatives(nfJnt, children=True) if x.type()=='joint'][0] pm.parent(twistJnt, nfJnt) pm.aimConstraint(nfEnd, twistJnt, aimVector=(1,0,0), worldUpVector=(0,1,0), wuo=jnt, wut='objectrotation') #--- Connect twist result to ikSpline twist pm.connectAttr('%s.rotateX'%twistJnt, '%s.twist'%ikHandle, f=True) return twistJnt
def findCameraInSelection(self): selection = pm.ls(sl=True) assert len(selection)>0, "Nothing is selected. Select a camera" assert len(selection)<2, "Multiple objects selected. Select camera only" if pm.nodeType(selection[0])=='transform': camShapeLst = pm.listRelatives(selection[0], type='camera') assert len(camShapeLst)>0, "No camera selected" return (selection[0], camShapeLst[0]) elif pm.nodeType(selection[0])=='camera': parentTransform = pm.listRelatives(selection[0], parent=True) return (parentTransform,selection[0]) raise StandardError("No camera is selected")
def rebuildDagPose(): """ Walks through bind pose data in selected skeleton and consolidates it down to one new bindPose node Directly inspired by Nathan Horne's NT_rebuildDagPose.mel script """ dagPoses = set() connectedSkinClusters = set() selection = pmc.selected() joints = pmc.listRelatives(selection[0], path=True, allDescendents=True, type="joint") joints.insert(0, selection[0]) for jnt in joints: dagPoses.update(jnt.listConnections(type="dagPose")) for dag in dagPoses: connectedSkinClusters.update(dag.listConnections(type="skinCluster")) pmc.delete(dagPoses) pmc.select(joints, replace=True) newDagPose = pmc.dagPose(save=True, selection=True, bindPose=True) print "New dagPose, {0}, created".format(newDagPose.shortName()) for sc in connectedSkinClusters: print "Connecting {0}.message to {1}.bindPose".format(newDagPose.shortName(), sc.shortName()) newDagPose.message.connect(sc.bindPose)
def lock_child(self): selection = pm.selected() child_locker = pm.createNode("transform", name="PKD_child_locker") child_joint = pm.listRelatives(self.joint)[0] pm.parentConstraint(child_locker, child_joint, maintainOffset=True) if selection: pm.select(selection)
def create_point_on_mesh(geo, position, sticky_target, free_rotation=True): """ Create point on mesh setup @param position: @param geo: @parem sticky: @return: """ pom = pm.createNode("closestPointOnMesh") pom.inPosition.set(position) geo.worldMatrix[0] >> pom.inputMatrix geo.worldMesh[0] >> pom.inMesh pom.position >> sticky_target.translate index = pom.closestVertexIndex.get() locator = pm.spaceLocator() libUtilities.snap(locator, geo.vtx[index], rotate=False) libUtilities.freeze_transform(locator) pm.pointOnPolyConstraint(geo.vtx[index], locator, maintainOffset=True) pm.delete(pom) constraint = pm.listRelatives(locator, type="constraint")[0] if free_rotation: for attr in ["rx", "rz", "ry"]: libUtilities.break_connection(locator, attr) locator.attr(attr).set(0) return {"constraint": constraint, "locator": locator}
def defineFootStructure(sel = None): # test ankle selection if not sel.getAttr("type") == 18 and not sel.getAttr("otherType") == "ankle": om.MGlobal_displayWarning("bad selection") return # collect ankle print sel footDict = {} allJnt = pm.listRelatives(sel, allDescendents = True, type= "joint") allJnt.append(sel) for j in allJnt: if(j.getAttr("type") == 18): print(j.getAttr("otherType")) if (j.getAttr("otherType") == "ankle"): footDict["ankle"] = j elif (j.getAttr("otherType") == "end"): footDict["end"] = j elif (j.getAttr("otherType") == "toes"): footDict["toes"] = j elif (j.getAttr("otherType") == "ball"): footDict["ball"] = j elif (j.getAttr("otherType") == "heel"): footDict["heel"] = j return footDict
def handControlSetup(self, *args): """ Create attributes on hand_cnt and connect them as needed. """ pm.addAttr(self.hand_cnt,ln='FK_IK',at='float',dv=0,min=0,max=1,k=True) # IK/FK blend color nodes pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.shldr_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.elbow1_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.elbow1_node2 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.wrist_node1 ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.blender'%self.wrist_node2 ) #IK/FK controls vis switch pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.visibility'%self.ikChain[0] ) pm.connectAttr( '%s.FK_IK'%self.hand_cnt, '%s.visibility'%self.ikControl[0] ) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=1, v=0) pm.setDrivenKeyframe(self.fkChain[0], cd='%s.FK_IK' % self.hand_cnt, at='visibility', dv=0, v=1) # Zero hand control and parent to the following joint chian. self.zero(self.hand_cnt) bufferNode = pm.listRelatives(self.hand_cnt,parent=True) pm.parentConstraint(self.jointChain[2],bufferNode,mo=True)
def export_hierarchy_obj(self): """Export the individual meshes in the hierarchy""" file_info = {} # Reverse the geo list so that the deepest geo is deleted first in case there is a geo inside geo geo_list = self.geo_list geo_list.reverse() for self.current_target in geo_list: pm.delete(self.current_target, ch=1) parent = pm.listRelatives(self.current_target, parent=True) pm.parent(self.current_target, w=True) pm.select(self.current_target) path = libFile.linux_path(libFile.join(self.export_dir, self.current_target + ".obj")) # Load the obj plugin cmds.file(path, pr=1, typ="OBJexport", force=1, options="groups=0;ptgroups=0;materials=0;smoothing=0;normals=0", es=1) file_info[self.current_target] = path logger.info("Exporting\n%s" % file_info[self.current_target]) if not self.new_scene and self.cleansing_mode: pm.delete(self.current_target) pm.refresh() else: pm.parent(self.current_target, parent) self.update_progress() # Write the geo file_info self.geo_file_info = file_info
def getShape(transform=None): ''' returns the first shape of the specified transform ''' shape = pmc.listRelatives( transform, children=1, shapes=1 )[ 0 ] return shape
def bdAddExtraGrp(nameMaskCon,grpType,empty): controllers = pm.ls(nameMaskCon,type = 'transform') conPyNodes = [] for con in controllers: conPyNodes.append(con) for node in conPyNodes: if empty: pm.select(cl=True) conGrp = pm.group(name = node.name() + '_' + grpType) pos = node.getTranslation(space='world') rot = node.getRotation(space='world') conGrp.setTranslation(pos) conGrp.setRotation(rot) parent = node.getParent() pm.parent(conGrp,parent) else: conGrp = pm.duplicate(node,name = node.name().replace('CON',grpType)) ''' for axis in ['X','Y','Z']: conGrp[0].attr('translate' + axis).setKeyable(True) conGrp[0].attr('translate' + axis).setLocked(False) ''' conGrpRelatives = pm.listRelatives(conGrp,ad = True) #print sdkConRelatives pm.delete(conGrpRelatives) pm.parent(node,conGrp)
def assignToSelected(self, layerIndex, channelIndex): for obj in pm.selected(): materialChannelList = [".diffuse", ".diffuse_weight", ".transparency", ".reflectivity", ".refl_gloss", ".cutout_opacity", ".bump", ".normal"] shapeNode = pm.listRelatives(obj, c=True, s=True) shadingGrp = pm.listConnections(shapeNode, type="shadingEngine")[0] mat = list(set( pm.listConnections(shadingGrp, type=['mia_material_x', 'mia_material_x_passes', 'lambert', 'phong'])))[ 0] try: currentItem = self.layeredTextureTreeModel.itemFromIndex(layerIndex[0]).node except: pm.cmds.warning("Please select a texture from the list.") try: if channelIndex < 6: outAttr = ".outColor" if channelIndex != 0: outAttr = ".outAlpha" currentItemOutColor = currentItem + outAttr materialInput = mat + materialChannelList[channelIndex] pm.connectAttr(currentItemOutColor, materialInput, f=True) elif channelIndex == 6: createBump(currentItem, mat) else: createBump(currentItem, mat, normal=True) except: pm.cmds.warning("Could not connect materials to " + obj)
def makeOffsetGrp( object, prefix = '' ): """ make offset group for given object @param object: transform object to get offset group @param prefix: str, prefix to name new objects @return: str, name of new offset group """ #if not prefix: # prefix = name.removeSuffix( object ) self.namer.name.set(prefix) self.namer.type.set('offsetgrp') offsetGrp = pm.group( n = self.namer.get(), em = 1 ) objectParents = pm.listRelatives( object, p = 1 ) if objectParents: pm.parent( offsetGrp, objectParents[0] ) # match object transform pm.delete( pm.parentConstraint( object, offsetGrp ) ) pm.delete( pm.scaleConstraint( object, offsetGrp ) ) # parent object under offset group pm.parent( object, offsetGrp ) return offsetGrp
def checkMultipleShapes(cls, transform, *args, **kwargs): ''' ''' shapes = pm.listRelatives(transform, fullPath=True, shapes=True) if len(shapes)>1: return None else: return shapes[0]
def FTV_createMainFluidTextViewControl( inputsGrp , fluidSpaceTransform): ''' creation of the main control for the viewer''' circle = pm.circle( n='fluidTextureViewerCtrl#', c=(0,0,0), nr=(0,1,0), sw=360, r=1, ut=False,s=8, ch=False ) pm.parent(circle[0],fluidSpaceTransform,r=True) size = 0.5 ptList = [(-size,-size,-size), (size,-size,-size), (size,-size,size), (-size,-size,size), (-size,-size,-size), (-size,size,-size), (size,size,-size), (size,size,size), (-size,size,size), (-size,size,-size), (size,size,-size),(size,-size,-size),(size,-size,size),(size,size,size),(-size,size,size),(-size,-size,size)] cube = pm.curve( p = ptList, d=1, n='tempNameCubeNurbs#') grpDummyTransform = pm.group(em=True,n='dummyFluidSizeToMatrix#') pm.connectAttr( inputsGrp+'.dimensionsW', grpDummyTransform+'.scaleX') pm.connectAttr( inputsGrp+'.dimensionsH', grpDummyTransform+'.scaleY') pm.connectAttr( inputsGrp+'.dimensionsD', grpDummyTransform+'.scaleZ') FTV_lockAndHide( grpDummyTransform, ['tx','ty','tz','rx','ry','rz','sx','sy','sz','v']) circleShape = FTV_createTransformedGeometry(circle,'local', 'create',grpDummyTransform) cubeShape = FTV_createTransformedGeometry(cube,'local', 'create',grpDummyTransform) pm.setAttr(cubeShape+'.template',True) allCubeShapes = pm.listRelatives(cube,s=True) parentShapeRes = pm.parent(allCubeShapes, circle, add=True, s=True) pm.delete(cube) pm.rename( parentShapeRes[0],'BBFluidShapeSrc#' ) retShape = pm.rename( parentShapeRes[1],'BBFluidShape#' ) FTV_lockAndHide(circle[0], ['rx','ry','rz','sx','sy','sz','v']) # attributes connections addMainAttributesToObject(circle[0],True) FTV_multiConnectAutoKeyableNonLocked( circle[0], inputsGrp, ['translateX','translateY','translateZ']) pm.parent(grpDummyTransform,fluidSpaceTransform,r=True) return circle[0], retShape
def CreateFKControl(self, _joint, _parent, _moduleContainer): jointName = utils.StripAllNamespaces(_joint)[1] containedNodes = [] name = "%s_fkControl" %jointName controlObjectInstance = controlObject.ControlObject() fkControlInfo = controlObjectInstance.Create(name, "sphere.ma", self, _lod = 1, _translation = False, _rotation = True, _globalScale = False, _spaceSwitching = False) fkControl = fkControlInfo[0] pm.connectAttr("%s.rotateOrder" %_joint, "%s.rotateOrder" %fkControl) orientGrp = pm.group(name = "%s_orientGrp", empty = True, parent = _parent) containedNodes.append(orientGrp) pm.delete(pm.parentConstraint(_joint, orientGrp, maintainOffset = False)) jointParent = pm.listRelatives(_joint, parent = True)[0] orientGrp_parentConstraint = pm.parentConstraint(jointParent, orientGrp, maintainOffset = True, name = "%s_parentConstraint" %orientGrp) orientGrp_scaleConstraint = pm.scaleConstraint(jointParent, orientGrp, maintainOffset = True, name = "%s_scaleConstraint" %orientGrp) pm.parent(fkControl, orientGrp, relative = True) orientConstraint = pm.orientConstraint(fkControl, _joint, maintainOffset = False, name = "%s_orientConstraint" %_joint) containedNodes.extend([orientGrp_parentConstraint, orientGrp_scaleConstraint, orientConstraint]) utils.AddNodeToContainer(_moduleContainer, containedNodes) return fkControl
def colorCtrl(containers): '''colors the control yellow. Ugly! rewrite! ''' pm.select(containers["ctrl"], r=1) shape = pm.listRelatives(s) pm.setAttr((shape[0]+".overrideEnabled"),1) pm.setAttr((shape[0]+".overrideColor"),17)
def mayaNodes_replaceByArchive(mainWindow): dictFamily = dict() tmpNodeList = list() tmpArcList = list() allParents = [item for item in gl.getParentNodes(None, 'mesh', 1)] allParentsCopy = copy.copy(allParents) ''' EXCEPTION FOR VRAY PROXY''' for node in allParents: if "proxy" in node: newNode = pm.rename(node, node.replace("proxy", "")).longName() allParentsCopy.remove(node) allParentsCopy.append(newNode) else: allParentsCopy.append(node) allParents = list(set(copy.copy(allParentsCopy))) hierarchyList = list() organizeList = list() for item in allParents: hierarchyList.append(pm.PyNode(item).parentAtIndex(0).name(long=True)) hierarchyList = list(set(hierarchyList)) for elem in hierarchyList: nodeList = [ node.longName() for node in pm.listRelatives(elem, c=True, type="transform") if node.longName() not in hierarchyList ] #check if ends with digit allObj_digit = list( set([ item.replace( item.split('|')[-1], item.split('|')[-1].replace('_' + item.split('_')[-1], '')) for item in nodeList if item.split('_')[-1].isdigit() ])) allObj_nodigit = [ item.replace(item.split('|')[-1], item.split('|')[-1]) for item in nodeList if not item.split('_')[-1].isdigit() ] allObjLong = list( set([item for item in (allObj_digit + allObj_nodigit)])) for obj in allObjLong: organizeList.append([elem, obj]) ''' CREATE DICTFAMILY VALUE : NODES, PARENT''' i = 0 for item in organizeList: fam = item[1].split('|')[-1] dictFamily[fam + '_' + str(i)] = {'nodes': [], 'parent': item[0]} i += 1 for node in allParents: parentNode = pm.PyNode(node).parentAtIndex(0).name(long=True) matchName = node.split('|')[-1].replace('_' + node.split('_')[-1], '') for key, value in dictFamily.iteritems(): keyName = key.replace(('_' + key.split('_')[-1]), '') if keyName == matchName and value['parent'] == parentNode: dictFamily[key]['nodes'].append(node) ''' MATCH ARCHIVE AND REPLACE NODE''' allArchive = [ node.parentAtIndex(0).name(long=True) for node in pm.ls(type='archiveNode') ] for key, value in dictFamily.iteritems(): tmpNodeList = list() tmpArcList = list() mainWindow.setupProgressBar(len(value['nodes']), 'replacing members of ' + key) for node in value['nodes']: matchName = node.split('|')[-1].replace('_' + node.split('_')[-1], '') for arc in allArchive: if arc.split('|')[-1] == matchName: tmpNodeList.append(node) matrix = gl.getNodeMatrix(pm.PyNode(node)) newArc = pm.duplicate(arc)[0].rename(node) tmpArcList.append(newArc) gl.setNodeMatrix(newArc, matrix) mainWindow.growBar() pm.delete(tmpNodeList) pm.parent(tmpArcList, value['parent'])
def renameModule(self,newname): allChildren = pm.listRelatives(self.moduleGrp,ad=1) print allChildren
Its a bit neater in python """ import pymel.core as pm #desactivar la seleccióón activa pm.select( clear=True ) #desactivar selección #seleccion por tipos (locator en el ejemplo) pm.select(pm.listRelatives(pm.ls('loc*',type='locator'),parent=True)) # seleccion de todos los descendientes de un grupo de objetos import pymel.core as pm pm.select("Environment_GRP") nodes = pm.ls(sl=True) nodes += pm.listRelatives(nodes, allDescendents=True) #seleccionar toda la jerarquia pm.select(nodes) # more about listrelatives http://help.autodesk.com/cloudhelp/2017/ENU/Maya-Tech-Docs/PyMel/generated/functions/pymel.core.general/pymel.core.general.listRelatives.html
def toggleSmoothMeshPreviewForSelected(self, namespaceString): #check if namespace is root if (namespaceString == 'root'): namespaceString = '' #check if namespace is root if not (namespaceString): if (self.verbose): print('Please select namespace different from root') return None #get selectionList selectionList = pm.ls(sl=True, fl=True, type='transform') #check if something is selected if not (selectionList): if (self.verbose): print('Empty Selection') return None #iterate selectionList for transformNode in selectionList: #check if object is piece manip #check parent #get ParentConstraint try: parentspaceConstraint = pm.listRelatives( transformNode.getParent().getParent(), typ='parentConstraint')[0] except: if (self.verbose): print('Parentspace Constraint not found for object ' + transformNode.name() + '. Continuing...') continue #check for name if not (transformNode.name().split(':')[-1].split('_')[0] + '_' + transformNode.name().split(':')[-1].split('_')[1] == 'manip_piece'): if (self.verbose): print( 'Name of selected transform node ' + transformNode.name() + ' does not match manipulator name for pieces. Continuing...' ) continue #If succesfully managed checks execute viz toggle #get index of selected manip manipPieceIndex = transformNode.name().split(':')[-1].split( '_')[-1] #grpList grpList = ['intermediary_grp'] #Iterate grpList for groupName in grpList: try: #Check if topGrp exists if not (pm.objExists(namespaceString + ':' + groupName)): if (self.verbose): print('Object ' + namespaceString + ':' + groupName + ' does not exists. Continuing') continue #get piecesTopGrp piecesTopGrp = pm.PyNode(namespaceString + ':' + groupName) #iterate children of piecesTopGrp for pieceGrp in piecesTopGrp.getChildren(): #if name of child matches index get execute smooth mesh toggle if (pieceGrp.name().split(':')[-1] == 'piece_' + manipPieceIndex): #iterate list of transform children for pieceGrpChild in pm.listRelatives( pieceGrp, typ='transform'): #toggleSmoothMeshPreview self.toggleSmoothMeshPreview(pieceGrpChild) #success msg if (self.verbose): print( 'Succesfully toggled smooth mesh preview for piece_' + manipPieceIndex + ' in ' + namespaceString + ':' + groupName + '. Continuing...') except: if (self.verbose): print('Error toggling smooth mesh preview for piece_' + manipPieceIndex + 'in ' + namespaceString + ':' + groupName + '. Continuing...')
def do_selection_cmd(self, *args): """Runs the code with the collected data from the buttons, locators and menus of the UI. Gathers the number for the ctrls, type of the ctrl crvs, and color of the ctrl crvs. :param args: :return: None """ # ctrl number menu gives the number of ctrls between the locators self.number = pm.optionMenuGrp(self.ctrl_number_menu, q=True, v=True) # crv types menu provides the choice of crv types only self.crv_type = pm.optionMenuGrp(self.crv_types_menu, q=True, v=True) # palette port provides the selected crv color self.color_index = pm.palettePort(self.color_palette, q=True, setCurCell=True) # right now fk ctrls scale of ikd is divided by 2. fk_scale = (self.ik_ctrl_s_scale[0] / 2, self.ik_ctrl_s_scale[1] / 2, self.ik_ctrl_s_scale[2] / 2) # if the selection is FK if self.type_selection == 0: self.check = True # fk ctrl creation # create jnt chain self.jnt_chain = self.create_jnt_chain() pm.select(self.jnt_chain[0], r=1) root_jnt = pm.ls(sl=1) self.ctrl_list = ctrl_chain(root_jnt, "", self.crv_type, self.color_index, fk_scale, self.check) pm.group(root_jnt, n='{}{}setup'.format(self.name, self.infix), w=True) pm.delete(self.ref_jnt, self.ref_jntend) # if the selection is IK if self.type_selection == 1: # ik ctrl creation self.jnt_chain = self.create_jnt_chain() self.create_ik_spline() pm.select(pm.listRelatives(self.ref_jnt, children=True, path=True), r=True) pm.select(self.ref_jntend, d=True) pm.select('{}_iks'.format(self.name), add=True) pm.group(n='{}_setup'.format(self.name), w=True) pm.group(self.top_start_grp, self.top_end_grp, n='{}_ctrl_setup'.format(self.name)) pm.delete(self.ref_jnt, self.ref_jntend) # strechy option self.stretchy = True if self.stretchy: stretchy(self.name, self.jnt_chain, self.distance) # if the selection is IKD if self.type_selection == 2: self.check = False # ik driver ctrl creation self.jnt_chain = self.create_jnt_chain() pm.select(self.jnt_chain[0], r=1) root_jnt = pm.ls(sl=1) self.ctrl_list = ctrl_chain(root_jnt, "", self.crv_type, self.color_index, fk_scale, False) self.create_ik_spline() pm.parent(self.top_start_grp, self.ctrl_list[0]) pm.parent(self.top_end_grp, self.ctrl_list[int(self.number) - 1]) pm.group(root_jnt, n='{}{}_jnt_setup'.format(self.name, self.infix), w=True) pm.select(pm.listRelatives(self.ref_jnt, children=True, path=True), r=True) pm.select(self.ref_jntend, d=True) pm.select('{}_iks'.format(self.name), add=True) pm.group(n='{}{}_setup'.format(self.name, self.infix), w=True) pm.delete(self.ref_jnt, self.ref_jntend) # strechy option self.stretchy = True if self.stretchy: stretchy(self.name, self.jnt_chain, self.distance)
### select crv cv import pymel.core as pm selection_list = pm.ls(sl=True) crv_list = pm.listRelatives(selection_list, ad=True, type='nurbsCurve') crv_list = list(set(crv_list)) offset = 3 to_select_list = [] for crv in crv_list: crvShape = crv crv = crv.getParent() spans = crvShape.spans.get() degree = crvShape.getAttr('degree') cv = int(spans) + int(degree) to_select_list.append('{0}.cv[0:{1}]'.format(crv, cv - offset)) pm.select(to_select_list) ### renameCrv import pymel.core as pm sel_list = pm.ls(sl=True)
def read_skc_file(skc_path, mesh_name): file = open(skc_path, "r") line = file.readline() vertexArray = OpenMaya.MFloatPointArray() uArray = OpenMaya.MFloatArray() vArray = OpenMaya.MFloatArray() polygonCounts = OpenMaya.MIntArray() polygonConnects = OpenMaya.MIntArray() vertexWeights = [] material_num = 0 material_sets = [] while True: line = file.readline() if not line: break line = strip_space_line(line) if line.find("Materials") != -1: line = strip_space_line(line) material_num = int(line.split(":")[1]) for i in range(0, int(material_num)): material_sets.append(0) elif line.find("Vertices") != -1: print line elif line[0] == "v": vertex_data = parse_pos_uv_weight(line) pos = vertex_data[0] v = OpenMaya.MFloatPoint(pos[0], pos[1], pos[2]) vertexArray.append(v) uv = vertex_data[1] uArray.append(uv[0]) vArray.append(1.0 - uv[1]) # bone weights skin_data = vertex_data[2] weight_num = skin_data[0] weights = [] for bi in range(0, int(weight_num)): tmp_bone_idx = skin_data[int(1 + 2 * bi)] tmp_bone_name = bone_name_list[int(tmp_bone_idx)] tmp_bone_weight = skin_data[int(2 + 2 * bi)] key_value = (tmp_bone_name, tmp_bone_weight) weights.append(key_value) vertexWeights.append(weights) elif line.find("Triangles") != -1: print line elif line[0] == "f": face_data = parse_face(line) polygonCounts.append(3) polygonConnects.append(int(face_data[2])) polygonConnects.append(int(face_data[3])) polygonConnects.append(int(face_data[4])) # assign material material_sets[int(face_data[1])] += 1 mFn_Mesh = OpenMaya.MFnMesh() m_DagMod = OpenMaya.MDagModifier() new_object = m_DagMod.createNode('transform') mFn_Mesh.create(vertexArray, polygonCounts, polygonConnects, uArray, vArray, new_object) mFn_Mesh.setName(mesh_name) m_DagMod.doIt() new_mesh = pmc.PyNode(mesh_name) new_transform = pmc.listRelatives(new_mesh, type='transform', parent=True)[0] mFn_Mesh.assignUVs(polygonCounts, polygonConnects, 'map1') node_name = mesh_name + "_mesh" pmc.select(new_transform) pmc.rename(new_transform, node_name) pmc.rotate(0, -90.0, 0) # create material # pCylinder1.f[14:17] _mesh.f[{0}:{1}].format() material_starts = [] material_ends = [] mesh_selcte_sets = [] material_starts.append(0) material_ends.append(material_sets[0] - 1) mesh_selcte_sets.append( node_name + ".f[{0}:{1}]".format(int(material_starts[0]), int(material_ends[0]))) for i in range(1, len(material_sets)): material_starts.append(material_ends[int(i - 1)] + 1) material_ends.append(material_ends[int(i - 1)] + material_sets[i]) mesh_selcte_sets.append(node_name + ".f[{0}:{1}]".format( int(material_starts[i]), int(material_ends[i]))) for i in range(0, len(mesh_selcte_sets)): shader_name = "p_shader{0}".format(int(i)) new_shader = pmc.shadingNode("lambert", asShader=True, name=shader_name) new_shadinggroup = pmc.sets(renderable=True, noSurfaceShader=True, empty=True, name='{}_SG'.format(shader_name)) pmc.connectAttr(new_shader.outColor, new_shadinggroup.surfaceShader) pmc.select(mesh_selcte_sets[i]) pmc.hyperShade(assign=new_shadinggroup) # skin cluster pmc.select(bone_name_list[0], add=True) skin_cluster = pmc.skinCluster(bindMethod=0, skinMethod=1, normalizeWeights=0, maximumInfluences=4, obeyMaxInfluences=True) pmc.select(node_name, r=True) pmc.skinPercent(skin_cluster, node_name, normalize=False, pruneWeights=100) for v in range(0, len(vertexWeights)): pmc.skinPercent(skin_cluster, "{0}.vtx[{1}]".format(node_name, v), transformValue=vertexWeights[v], normalize=True)
def test_createDriveControls(self): fr = FollowRibbon.FollowRibbon(name='blah') plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=.1, ch=0)[0] grps, jnts, cposNodes = fr._createPlaneControls(plane=plane, direction='u', number=4) mainGrp, ctrls = fr._createDriveControls(grps=grps, cposNodes=cposNodes) self.assertEqual(mainGrp, 'blah_ctrlsGrp') self.testLib.assertListEqual( ctrls, ['blah_ctrl_01', 'blah_ctrl_02', 'blah_ctrl_03', 'blah_ctrl_04']) for index in range(4): self.assertTrue( pm.objExists('blah_ctrlTopGrp_%s' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_ctrlMidGrp_%s' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_ctrlBtmGrp_%s' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_InvertMdNode_%s' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_ctrl_%s' % str(index + 1).zfill(2))) self.assertEqual( pm.listRelatives('blah_ctrlTopGrp_%s' % str(index + 1).zfill(2), parent=1)[0].name(), 'blah_ctrlsGrp') self.testLib.assertConstrained(grps[index].name(), 'blah_ctrlTopGrp_%s' % str(index + 1).zfill(2), type='parent') self.assertTrue( pm.isConnected( 'blah_ctrl_%s.translate' % str(index + 1).zfill(2), 'blah_InvertMdNode_%s.input1' % str(index + 1).zfill(2))) self.assertTrue( pm.isConnected( 'blah_InvertMdNode_%s.output' % str(index + 1).zfill(2), 'blah_ctrlBtmGrp_%s.translate' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_ctrl_%s.uParam' % str(index + 1).zfill(2))) self.assertTrue( pm.objExists('blah_ctrl_%s.vParam' % str(index + 1).zfill(2))) self.assertTrue( pm.isConnected( 'blah_ctrl_%s.uParam' % str(index + 1).zfill(2), 'blah_drvCPOS_%s.parameterU' % str(index + 1).zfill(2))) self.assertTrue( pm.isConnected( 'blah_ctrl_%s.vParam' % str(index + 1).zfill(2), 'blah_drvCPOS_%s.parameterV' % str(index + 1).zfill(2)))
def bake(self): buttons = export, create, cancel = '.abc 저장', '씬 안에 생성', '취소' option = questionbox( parent=self, title='출력형태 지정', message='베이크할 카메라의 출력 형태를 선택하세요.', icon='question', button=buttons, default=export, cancel=cancel, dismiss=cancel, ) if option == cancel: return cam_file = None if option == export: optionvar = 'camviewmgr_last_exported_path' if pm.optionVar(exists=optionvar): last_dir = pm.optionVar(query=optionvar) else: last_dir = '' response = QFileDialog.getSaveFileName( caption='카메라가 저장될 위치를 지정하세요', dir=last_dir, filter='Alembic File (*.abc)', parent=self, ) if not response[0]: return cam_file = response[0] dirs(os.path.dirname(cam_file)) pm.optionVar(stringValue=(optionvar, os.path.dirname(cam_file))) cam = pm.PyNode(self.currentItem().text()) if not cam: return cam_shape = cam.getShape() pm.undoInfo(openChunk=True) dup_cam = pm.duplicate(cam)[0] dup_cam_shape = dup_cam.getShape() for child in pm.listRelatives(dup_cam, children=True): if child.nodeType() == 'camera': continue pm.delete(child) dup_cam_shape.focalLength.set(lock=False, keyable=True) dup_cam_shape.nearClipPlane.set(lock=False, keyable=True) dup_cam_shape.farClipPlane.set(lock=False, keyable=True) cam_shape.focalLength.connect(dup_cam_shape.focalLength, force=True) cam_shape.nearClipPlane.connect(dup_cam_shape.nearClipPlane, force=True) cam_shape.farClipPlane.connect(dup_cam_shape.farClipPlane, force=True) for child in pm.listRelatives(dup_cam, children=True): if child.nodeType() == 'camera': continue pm.delete(child) for ch in ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']: attr = dup_cam.attr(ch) attr.set(lock=False) for attr in dup_cam.listAttr(userDefined=True): try: attr.set(lock=False) pm.deleteAttr(attr) except: pass pm.parent(dup_cam, world=True) pm.rename(dup_cam, cam.name() + '_baked') constraint = pm.parentConstraint(cam, dup_cam) st = pm.playbackOptions(query=True, minTime=True - 2) ed = pm.playbackOptions(query=True, maxTime=True + 2) pm.bakeResults( [dup_cam, dup_cam_shape], shape=True, simulation=True, time=(st, ed), ) pm.delete(constraint) pm.undoInfo(closeChunk=True) if cam_file: pm.rename(dup_cam, cam.name()) pm.select(dup_cam, replace=True) pm.delete(pm.ls(type='unknown')) pm.mel.eval( 'AbcExport -j "-frameRange {} {} -noNormals -eulerFilter -dataFormat ogawa -root {} -file {}"' .format(st, ed, dup_cam.name(), cam_file)) if option != create: pm.delete(dup_cam)
def rp_cr(): """..............................................................................................//""" ncj = int(pm.intField('NCJ', q=1, v=1)) # > input data # > control joints pcj = int(pm.intField('PCJ', q=1, v=1)) # > pow control joints nj = ((ncj * pcj) - (pcj - 1)) # > joints pm.intField('NJ', e=1, v=(nj - 1)) oj = int(pm.intField('OJ', q=1, v=1)) # > orient joint # > selection list s = pm.ls(sl=1) rp_check(s) ss = pm.listRelatives(s[0], s=1) # > selection shape tss = str(pm.objectType(ss[0])) # > type selection shape typ = 0 if pm.mel.gmatch(tss, "nurbsCurve"): typ = 0 if pm.mel.gmatch(tss, "bezierCurve"): typ = 1 rp_del() pm.delete(s[0], ch=1) if typ == 0: pm.rebuildCurve(s[0], s=(nj - 1), kt=1, d=3, kep=1) pm.setAttr((s[0] + ".it"), 0) # > curve info is_ = str(rp_info(s)) iv = float(pm.getAttr(is_ + ".al")) # > group folders rg = str(pm.group(em=1, n=(s[0] + "_rig"))) sg = str(pm.group(em=1, n=(s[0] + "_sistem"))) # > twist joint sj = [] ds = str(pm.curve(p=[(0, 0, 0), (iv, 0, 0)], k=[0, 1], d=1, n=(s[0] + "_tw"))) pm.rebuildCurve(ds, s=(nj - 1), ch=0, d=1, kep=1) if nj == 3: pm.delete(ds + ".cv[1]") pm.delete(ds + ".cv[2]") for i in range(0, nj): t = (pm.xform((ds + ".cv[" + str(i) + "]"), q=1, ws=1, t=1)) sj[i] = str(pm.joint(p=((t.x), (t.y), (t.z)), rad=1, n=(s[0] + "_tw_" + str((i + 1))))) pm.setAttr((sj[i] + ".ro"), 3) pm.pm.cmds.rotate(oj, 0, 0, sj[0], r=1, os=1) pm.makeIdentity(sj[0], a=1, r=1) h = pm.ikHandle(c=s[0], ee=sj[nj], ccv=0, sol="ikSplineSolver", n=(s[0] + "_tw_hl"), sj=sj[0]) pm.parent(sj[0], h[0], sg) pm.delete(ds) # > control joint pm.select(s[0], r=1) pm.mel.selectCurveCV("all") cv = pm.ls(fl=1, sl=1) p = (((len(cv)) + 2) / 3) pm.select(cl=1) cj = [] if pm.checkBoxGrp('CTJP', q=1, v1=1): pm.setAttr((s[0] + ".it"), 1) # > create joints for i in range(0, (len(cv))): t = (pm.xform(cv[i], q=1, ws=1, t=1)) pm.select(cl=1) cj[i] = str(pm.joint(p=((t.x), (t.y), (t.z)), rad=2, n=(s[0] + "_ctj_" + str((i + 1))))) pm.setAttr((cj[i] + ".ro"), 3) # > aim joints for i in range(0, ((len(cv)) - 1)): pm.aimConstraint(cj[i], cj[i + 1], w=1, o=(0, 180, 0)) pm.aimConstraint(cj[1], cj[0], w=1, o=(0, 0, 0)) pm.delete(cj, cn=1) pm.makeIdentity(cj, a=1, r=1) # > correct aim joints for i in range(0, (p - 1)): pm.aimConstraint(cj[i + (2 * i)], cj[i + 1 + (2 * i)], w=1, o=(0, 0, 0)) for i in range(1, (p - 0)): pm.aimConstraint(cj[i + (2 * i)], cj[i - 1 + (2 * i)], w=1, o=(0, 0, 0)) pm.delete(cj, cn=1) pm.makeIdentity(cj, a=1, r=1) else: for i in range(0, ncj): t = (pm.xform(sj[(i * pcj)], q=1, ws=1, t=1)) pm.select(cl=1) cj[i] = str(pm.joint(p=((t.x), (t.y), (t.z)), rad=2, n=(s[0] + "_ctj_" + str((i + 1))))) pm.setAttr((cj[i] + ".ro"), 3) pm.parentConstraint(sj[(i * pcj)], cj[i], w=1) pm.delete(cj[i], cn=1) pm.makeIdentity(cj[i], a=1, r=1) pm.parent(cj, sg) pm.parent(sg, s[0], rg) # > connect scale sw = str(pm.createNode('multiplyDivide', n=(s[0] + "_s"))) pm.setAttr((sw + ".op"), 2) pm.connectAttr((is_ + ".al"), (sw + ".i1x"), f=1) pm.connectAttr((rg + ".sx"), (sw + ".i2x"), f=1) sx = str(pm.createNode('multiplyDivide', n=(s[0] + "_sx"))) pm.setAttr((sx + ".op"), 2) pm.connectAttr((sw + ".ox"), (sx + ".i1x"), f=1) pm.setAttr((sx + ".i2x"), iv) for i in range(0, nj): pm.connectAttr((sx + ".ox"), (sj[i] + ".sx"), f=1) if pm.checkBoxGrp('CTJ', q=1, v1=1): cg = str(pm.group(em=1, n=(s[0] + "_control"))) # > add control if pm.checkBoxGrp('CTJP', q=1, v1=1): c = [] t = [] for i in range(0, (len(cv))): pm.connectAttr((cj[i] + ".t"), (ss[0] + ".cp[" + str(i) + "]"), f=1) ct = rp_create_control(s, i) c[i] = ct[0] t[i] = ct[1] pm.parentConstraint(cj[i], ct[1], w=1) pm.delete(ct[1], cn=1) pm.makeIdentity(ct[1], a=1, t=1) pm.parentConstraint(ct[0], cj[i], mo=1, w=1) pm.parent(ct[1], cg) scg = [] for i in range(0, p): scg[i] = str(pm.group(em=1, n=("scGrp_" + s[0] + "_" + str((i + 1))))) scgpc = pm.parentConstraint(c[i + (2 * i)], scg[i], w=1) pm.delete(scgpc[0]) pm.makeIdentity(scg[i], a=1, t=1) pm.parent(scg[i], c[i + (2 * i)]) pm.connectAttr((c[i + (2 * i)] + ".change"), (scg[i] + ".sx"), f=1) pm.connectAttr((c[i + (2 * i)] + ".change"), (scg[i] + ".sy"), f=1) pm.connectAttr((c[i + (2 * i)] + ".change"), (scg[i] + ".sz"), f=1) for i in range(0, (p - 1)): pm.parent(t[i + 1 + (2 * i)], scg[i]) pm.setAttr((t[i + 1 + (2 * i)] + ".sx"), 0.5) pm.setAttr((t[i + 1 + (2 * i)] + ".sy"), 0.5) pm.setAttr((t[i + 1 + (2 * i)] + ".sz"), 0.5) pm.setAttr((c[i + 1 + (2 * i)] + ".bezier"), cb=0, k=0, l=1) pm.setAttr((c[i + 1 + (2 * i)] + ".change"), cb=0, k=0, l=1) pm.setAttr((c[i + 1 + (2 * i)] + ".rx"), cb=0, k=0, l=1) pm.setAttr((c[i + 1 + (2 * i)] + ".ry"), cb=0, k=0, l=1) pm.setAttr((c[i + 1 + (2 * i)] + ".rz"), cb=0, k=0, l=1) pm.connectAttr((c[i + (2 * i)] + ".bezier"), (t[i + 1 + (2 * i)] + ".v"), f=1) for i in range(1, (p - 0)): pm.parent(t[i - 1 + (2 * i)], scg[i]) pm.setAttr((t[i - 1 + (2 * i)] + ".sx"), 0.5) pm.setAttr((t[i - 1 + (2 * i)] + ".sy"), 0.5) pm.setAttr((t[i - 1 + (2 * i)] + ".sz"), 0.5) pm.setAttr((c[i - 1 + (2 * i)] + ".bezier"), cb=0, k=0, l=1) pm.setAttr((c[i - 1 + (2 * i)] + ".change"), cb=0, k=0, l=1) pm.setAttr((c[i - 1 + (2 * i)] + ".rx"), cb=0, k=0, l=1) pm.setAttr((c[i - 1 + (2 * i)] + ".ry"), cb=0, k=0, l=1) pm.setAttr((c[i - 1 + (2 * i)] + ".rz"), cb=0, k=0, l=1) pm.connectAttr((c[i + (2 * i)] + ".bezier"), (t[i - 1 + (2 * i)] + ".v"), f=1) else: for i in range(0, (len(cj))): ct = rp_create_control(s, i) pm.parentConstraint(cj[i], ct[1], w=1) pm.delete(ct[1], cn=1) pm.makeIdentity(ct[1], a=1, t=1) pm.parentConstraint(ct[0], cj[i], mo=1, w=1) pm.parent(ct[1], cg) pm.connectAttr((ct[0] + ".change"), (cj[i] + ".sx"), f=1) pm.connectAttr((ct[0] + ".change"), (cj[i] + ".sy"), f=1) pm.connectAttr((ct[0] + ".change"), (cj[i] + ".sz"), f=1) pm.parent(cg, rg) if pm.checkBoxGrp('CTJP', q=1, v1=1) == 0: pm.skinCluster(cj, s[0], mi=2, rui=1, dr=2.0, n=(s[0] + "_skin")) # > connection control to curve pm.select(h[0]) # > end pm.ToggleLocalRotationAxes() pm.select(s[0]) pm.mel.rp_Twist() print " :) > rope riging curve > " + s[0] + "\n"
def get_all_geo_trans(): return pm.listRelatives(pm.ls(geometry=True), p=True)
import pymel.core as pm sel = pm.ls(sl=1) for i, object in enumerate(sel): hi = pm.listRelatives(object, c=1)[0] shapeName = '{}{}'.format(object.name(), 'Shape') if hi.name() != shapeName: pm.rename(hi, shapeName) print 'shape name replace =', hi
def bdBuildRPSolverScale(self, condition): print 'RP Solver' # self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0] pm.select(cl=True) ikGrp = pm.group(n=self.ikSpline.name() + '_grp') ikParent = self.ikSpline.getParent() ikPos = self.ikSpline.getTranslation(space='world') ikGrp.setTranslation(ikPos) pm.parent(ikGrp, ikParent) pm.parent(self.ikSpline, ikGrp) sclJnt = pm.duplicate(self.startJoint, parentOnly=True, name=self.startJoint.name().replace('ik', 'scl'))[0] effector = pm.listConnections(self.ikSpline, source=True, type='ikEffector')[0] endJoint = pm.listConnections(effector, source=True, type='joint')[0] startJointChild = pm.listRelatives(self.startJoint, c=True, type='joint')[0] self.jointChain = [] self.jointChain.append(self.startJoint) self.jointChain.append(startJointChild) while startJointChild.name() != endJoint.name(): startJointChild = pm.listRelatives(startJointChild, c=True, type='joint')[0] self.jointChain.append(startJointChild) jntPos = [] for jnt in self.jointChain: pos = jnt.getTranslation(space='world') jntPos.append(pos) self.splineCurveScl = pm.curve(p=jntPos, degree=1, n=self.startJoint.name().replace( 'ik', 'crv_scl')) self.splineCurveScl.setPivots(jntPos[0]) pm.parent(self.splineCurveScl, sclJnt) strArclenSCL = pm.arclen(self.splineCurveScl, ch=True) arclenSCL = pm.ls(strArclenSCL)[0] arclenSCL.rename(self.splineCurveScl.name() + '_length') distanceNode = pm.createNode('distanceBetween', name=self.startJoint.name().replace( 'ik', 'db')) sclJnt.rotatePivotTranslate.connect(distanceNode.point1) ikGrp.rotatePivotTranslate.connect(distanceNode.point2) sclJnt.worldMatrix.connect(distanceNode.inMatrix1) ikGrp.worldMatrix.connect(distanceNode.inMatrix2) mdScaleFactor = pm.createNode('multiplyDivide', name=self.splineCurveScl.name().replace( 'crv_scl', 'crv_scaleFactor_md')) distanceNode.distance.connect(mdScaleFactor.input1X) arclenSCL.arcLength.connect(mdScaleFactor.input2X) mdScaleFactor.operation.set(2) cndScaleFactor = pm.createNode('condition', name=self.splineCurveScl.name().replace( 'crv_scl', 'crv_scaleFactor_cnd')) distanceNode.distance.connect(cndScaleFactor.firstTerm) arclenSCL.arcLength.connect(cndScaleFactor.secondTerm) mdScaleFactor.outputX.connect(cndScaleFactor.colorIfTrueR) cndScaleFactor.operation.set(2) for jnt in self.jointChain[:2]: cndScaleFactor.outColorR.connect(jnt.scaleX)
def sendSelectedToEd(): """ there is the special case where there is one type of mesh in the scene with edited geometry but an AssetPath pointing to the unedited file if the user wants that object to be exported as a new asset and don't overwrite the existing asset, (our automation couldn't detect that, because all assets with same path have same geometry) the user would have to call sendSelectedAsNew in that case? Then we would make sure that the user is provided with the UI to change the assetPath of those objects on export. If the user does not choose sendAsNew, we assume he wants to overwrite any files on disk for sure. There is also the case where we don't want to export objects that are already in the editor, because reimporting takes time, if we didn't change the asset, don't ask. Also, we maybe don't want to overwrite files that already are on disk, because that takes time. We only want to create the map from the objects we have and add those objects that we don't have. So we need a third option "sendSelectedAddMissingOnly" We might intelligently do a check on file-date, import-date in editor and maybe a import-date in program for one or the other case to determine if a reimport or a file overwrite is necessary or not What is the "AssetPath" supposed to be? It is the file path, including the file-extension, relative to the current projects Art-Source folder. No absolute paths, but that is depending on the actual pipeline-implementation, since all functions that deal with file paths will be delegated to a pipeline module, and that may be replaced by the user. 1. get selected objects 2. for each object, get the "AssetPath" attribute 3. if the object has no such attribute, save it in a untagged list if it has, save it in a tagged list entry (filepath:[objects]) 4. for each object in the tagged list, check if the file exists on disk fancy: check each object with same file if the gemometry is same - if not, tell user that objects with same file path differ and that he should export as new. - do that by adding all objects with same geometry to a list - then ask the user how to rename that asset - replace the assetPath value on all assets in that list and add them to the tagged unique list 5. if it does not, export one of the associated objects as asset (overwrite any file found) 6. for each object in the untagged list fancy: check all other objects in the untagged list if the geometry is same for each where it is same, insert in an association list (firstObject:[matchingObjects]) fancy2: ask the user if the "unique" objects as found are ok, if not, he has to split objects into a new "unique" group for each first object in that association list check if the geometry is the same as in any of the tagged list uniques if it is, set the AssetPath attrib on all matching objects to that of the unique if it is not, export it as a new Asset and set the AssetPath attrib on all matching objects add all those to the tagged association list 7. for each unique object in the tagged list tell the editor to import the associated file 8. for each selected object tell the editor to add an actor with the AssetPath as asset extend to send lights and stuff like that this function will perform something between O(n) and O(n^2) would need to analyze this a little more only counting objects... vertex count may be different in scenes, and the heavier the vert count, again the heavier the check will be... """ #1. get selected objects (only transform nodes) selectedObjects = pm.selected(type="transform") # filter out transforms that don't have a mesh-shape node selectedMeshes = list() for obj in selectedObjects: meshShapes = pm.listRelatives(obj, shapes=True, type="mesh") if len(meshShapes)>0: selectedMeshes.append(obj) _lg.debug("found %i selected meshes" % len(selectedMeshes)) # TODO: maybe filter other transferable stuff like lights or so #2. for each object get the "AssetPath" attribute untaggedList = list() taggedDict = {} for obj in selectedMeshes: if obj.hasAttr("AssetPath"): assetPathAttr = obj.attr("AssetPath") assetPathValue = assetPathAttr.get() if len(assetPathValue)>0: taggedDict.setdefault(assetPathValue,[]).append(obj) else: # if the ass path is empty, that is equal to the attr not being there untaggedList.append(obj) else: # unknown asset, we will handle those later untaggedList.append(obj) _lg.debug("found %i untagged" % len(untaggedList)) _lg.debug("found %i tagged" % len(taggedDict)) #3. do the geometry check for tagged objects # this assembles the taggedUniqueDict taggedDiscrepancyDetected = False taggedUniqueDict = {} for lis in taggedDict.values(): #for obj in lis: #we modify lis, so iterator won't work while len(lis)>0: # use while instead obj = lis[0] taggedUniqueDict[obj]=[] # compare this object against all others in the list. for otherObj in lis[1:]: if 0 == pm.polyCompare(obj, otherObj, vertices=True): # if the geometry matches, add the other to the unique list # with this object as key, and remove from the old list taggedUniqueDict[obj].append(otherObj) lis.remove(otherObj) else: taggedDiscrepancyDetected = True lis.remove(obj) # we are done with this object too _lg.debug("found %i tagged uniques" % len(taggedUniqueDict)) #3. do the geometry check for untagged objects untaggedUniquesDetected = False while len(untaggedList)>0: obj = untaggedList[0] if not obj.hasAttr("AssetPath"): pm.addAttr(obj.name(), longName="AssetPath", dataType="string", keyable=False) foundUniqueForMe = False # compare against one of the tagged uniques for other in taggedUniqueDict.keys(): # if that geometry matches, we found the unique for this obj if 0 == pm.polyCompare(obj, other, vertices=True): taggedUniqueDict[other].append(obj) # set "AssetPath" attr to match that of the unique obj.attr("AssetPath").set(other.attr("AssetPath").get()) # we are done with this object untaggedList.remove(obj) foundUniqueForMe = True _lg.debug("found a unique key (%s) for %s" %(other.name(), obj.name())) break if not foundUniqueForMe: untaggedUniquesDetected = True # make this a new unique, simply take the objects name as AssetPath npath = obj.shortName() + "_AutoExport" + ".fbx" obj.attr("AssetPath").set(npath) taggedUniqueDict[obj]=[] untaggedList.remove(obj) _lg.debug("assuming new untagged unique: "+obj.shortName()) # we will automatically compare to all other untagged to find # members for our new unique in the next loop iteration _lg.debug("found %i uniques (with untagged)" % len(taggedUniqueDict)) # TODO: 4. UI-stuff... #4. if taggedDiscrepancy or untaggedUniques were detected, # list all uniques in the UI and let the user change names # force him to change names for taggedUniques with same AssetPath of course # if taggedDiscrepancyDetected: #for unique in taggedUniqueDict.keys(): # it is up to the UI to do that and let the user # set a new assetPath on any of those unique guy's lists #5. export files stuff for obj in taggedUniqueDict.keys(): exportObjectAsAsset(obj.name(), obj.attr("AssetPath").get()) #6. tell the editor to import all the uniques fileList = [] for obj in taggedUniqueDict.keys(): fileList.append(obj.attr("AssetPath").get()) m2u.core.getEditor().importAssetsBatch(fileList) #7. tell the editor to assemble the scene objInfoList = [] for obj in selectedMeshes: # TODO: make that a new function objInfo = ObjectInfo(name = obj.shortName(), typeInternal = "mesh", typeCommon = "mesh") objTransforms = m2u.maya.mayaObjectTracker.getTransformationFromObj(obj) objInfo.pos = objTransforms[0] objInfo.rot = objTransforms[1] objInfo.scale = objTransforms[2] objInfo.AssetPath = obj.attr("AssetPath").get() objInfoList.append(objInfo) m2u.core.getEditor().addActorBatch(objInfoList)
def addSpaceSwitch(node, name, spaces, type='parent', ctrlNode=None, targetNodes=[]): enumString = '' startIndex = 0 asset = getComponentFromName(node) choice = hasSpaceSwitch(node)[type] attr = None add = 0 if choice: add = 1 ctrlNode = pmc.listConnections(choice.selector, d=0)[0] attr = pmc.listConnections(choice.selector, d=0, p=1)[0] attrName = attr.name().split('.')[-1] enumString = pmc.attributeQuery(attrName, node=ctrlNode, listEnum=1)[0] + ':' startIndex = len(enumString.split(':')) - 1 pmc.deleteAttr(attr) else: choice = pmc.createNode('choice', name='%s_%s_%sSpaceChoice_utl' % (asset, name, type)) if not ctrlNode: ctrlNode = node for space in spaces: enumString += (space + ':') pmc.addAttr(ctrlNode, ln='%sSpace' % type, at='enum', enumName=enumString, k=1, h=0) attr = pmc.Attribute('%s.%sSpace' % (ctrlNode.name(), type)) attr.connect(choice.selector) targets = [] for i in range(len(spaces)): space = spaces[i] g = coreUtils.addChild(getComponentGroup(node, group='input'), 'group', name='%s_%s_%s_%s_in_srt' % (asset, name, space, type)) #coreUtils.align(g, node) #g.worldMatrix[0].connect(pmc.Attribute('%s.input[%s]' % (choice.name(), i + startIndex))) targets.append(g) if len(targetNodes) == len(spaces): targetNode = targetNodes[i] if getComponentFromName(node) == getComponentFromName(targetNode): if targetNode in pmc.listRelatives( getComponentGroup(targetNode, 'rig'), c=1, ad=1) or targetNode in pmc.listRelatives( getComponentGroup(targetNode, 'input'), c=1, ad=1): g.setParent(targetNode) elif targetNode in pmc.listRelatives(getComponentGroup( targetNode, 'interface'), c=1, ad=1): g.setParent(getComponentGroup(targetNode, 'rig')) d = coreUtils.isDecomposed(targetNode) coreUtils.connectDecomposedMatrix(d, g) else: connectIO(g, targetNode, space) offset = coreUtils.addChild(g, 'group', name='%s_%s_%s_%s_offset_srt' % (asset, name, space, type)) coreUtils.align(offset, node) offset.worldMatrix[0].connect( pmc.Attribute('%s.input[%s]' % (choice.name(), i + startIndex))) if not add: d = coreUtils.decomposeMatrix(choice.output, name='%s_%s_%sSpaceMtxToSrt_utl' % (asset, name, type)) if type == 'parent': coreUtils.connectDecomposedMatrix(d, node) elif type == 'translate': d.outputTranslate.connect(node.t) elif type == 'rotate': d.outputRotate.connect(node.r) return targets
def setupFootBehavior(self): """ Main proc for creating the IK / FK switch """ # create locators for the blending arm and groups. # and then position into the right place footPositions = { 'ankle': (0, 0, 0), 'heel': (0, 0, 0), 'ball': (0, 0, 0), 'toe': (0, 0, 0) } # convert rigHelpers to PyNodes ankleHelper = pm.PyNode(self.side + '_leg_2_rigHelper') heelHelper = pm.PyNode(self.side + '_leg_3_rigHelper') ballHelper = pm.PyNode(self.side + '_leg_4_rigHelper') toeHelper = pm.PyNode(self.side + '_leg_5_rigHelper') # get rigHelpers positions footPositions['ankle'] = ankleHelper.getTranslation('world') footPositions['heel'] = heelHelper.getTranslation('world') footPositions['ball'] = ballHelper.getTranslation('world') footPositions['toe'] = toeHelper.getTranslation('world') # create locators for the blending and groups them orientFKLoc = pm.spaceLocator(name=self.side + '_footFKOrient_loc') orientIKLoc = pm.spaceLocator(name=self.side + '_footIKOrient_loc') orientFKGrp = pm.group(name=self.side + '_footFKOrient_grp', em=True) orientIKGrp = pm.group(name=self.side + '_footIKOrient_grp', em=True) locFKShape = pm.listRelatives(orientFKLoc, s=1)[0] locIKShape = pm.listRelatives(orientIKLoc, s=1)[0] # setup a smaller locator and moves to the ankle joint for loc in [locFKShape, locIKShape]: for scale in ['.localScaleX', '.localScaleY', '.localScaleZ']: pm.setAttr(loc + scale, 0.0005) pm.move(loc, (footPositions['ankle'][0], footPositions['ankle'][1], footPositions['ankle'][2])) # parent each locator to the corresponding group for loc, grp in zip([orientFKLoc, orientIKLoc], [orientFKGrp, orientIKGrp]): pm.parent(loc, grp) # parent each locator group (IK and FK) to the right place pm.parent(orientIKGrp, self.side + '_leg_ik_ctrl') pm.parent(orientFKGrp, self.side + '_leg1_FK_ctrl') pm.parent(self.side + '_leg_limb_ikh', self.side + '_leg_ik_ctrl') footPointConst = pm.pointConstraint(orientIKLoc, orientFKLoc, self.side + '_foot_grp') footOrientConst = pm.orientConstraint(orientIKLoc, orientFKLoc, self.side + '_foot_grp') # connect orientConstraint weights to footCtrl to be able to switch the weights from the FK/IK attribute pm.connectAttr( self.side + '_foot_ctrl.FK_IK', footOrientConst + '.' + self.side + '_footFKOrient_locW1') footReverseNode = pm.createNode('reverse', name=self.side + '_footRev') pm.connectAttr(self.side + '_foot_ctrl.FK_IK', footReverseNode + '.input.inputX') pm.connectAttr( footReverseNode + '.output.outputX', footOrientConst + '.' + self.side + '_footIKOrient_locW0') pm.connectAttr( self.side + '_foot_ctrl.FK_IK', footPointConst + '.' + self.side + '_footFKOrient_locW1') footPointReverseNode = pm.createNode('reverse', name=self.side + '_footPointConsRev') pm.connectAttr(self.side + '_foot_ctrl.FK_IK', footPointReverseNode + '.input.inputX') pm.connectAttr( footPointReverseNode + '.output.outputX', footPointConst + '.' + self.side + '_footIKOrient_locW0') # create groups setup for the foot footIkGrp = pm.group(name=self.side + '_footlRollIk_grp', em=True) heelIkGrp = pm.group(name=self.side + '_heelRollIk_grp', em=True) toeIkGrp = pm.group(name=self.side + '_toeRollIk_grp', em=True) ballIkGrp = pm.group(name=self.side + '_ballRollIk_grp', em=True) pm.move(heelIkGrp, (footPositions['heel'][0], footPositions['heel'][1], footPositions['heel'][2])) pm.move(toeIkGrp, (footPositions['toe'][0], footPositions['toe'][1], footPositions['toe'][2])) pm.move(ballIkGrp, (footPositions['ball'][0], footPositions['ball'][1], footPositions['ball'][2])) pm.move(footIkGrp, (footPositions['ankle'][0], footPositions['ankle'][1], footPositions['ankle'][2])) pm.parent(ballIkGrp, toeIkGrp) pm.parent(toeIkGrp, heelIkGrp) pm.parent(heelIkGrp, footIkGrp) pm.parent(self.side + '_leg_limb_ikh', ballIkGrp) pm.parent(footIkGrp, self.side + '_foot_ctrl') for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_heelRoll_grp.rotate' + rot, heelIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_toeRoll_grp.rotate' + rot, toeIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_ballRoll_grp.rotate' + rot, ballIkGrp + '.rotate' + rot) for rot in ['.rx', '.ry', '.rz']: pm.connectAttr(self.side + '_foot_ctrl.rotate' + rot, footIkGrp + '.rotate' + rot) pm.parent(self.side + '_foot_grp', 'main_ctrl') pm.parent(self.side + '_foot0_jnt', self.side + '_foot_grp')
def connectIO(dest, source, connectionName): ''' checks for an output from source. If it finds one, creates a corresponding input on dest's component input group If an input already exists it will be used instead. Also creates an offset group under the input which is the node to decompose and connect things to within the component :param dest: node to drive from the new input (usually a ctrl's buffer_srt :param source: node to connect the input to :param connectionName: name for the new input connection :return: offset group under new input node ''' if dest.getParent() == getComponentGroup(dest, 'input'): # check whether source is in worldspace. If so apply a direct connection offset = coreUtils.addChild( getComponentGroup(dest, 'input'), 'group', '%s_%s_in_srt' % (getComponentFromName(dest), connectionName)) if source.worldMatrix.get() == source.matrix.get(): source.t.connect(offset.t) source.r.connect(offset.r) source.s.connect(offset.s) else: d = coreUtils.isDecomposed(source) coreUtils.connectDecomposedMatrix(d, offset) dest.setParent(offset) elif getComponentFromName(dest) == getComponentFromName(source): if dest.getParent() == getComponentGroup( dest, 'interface') or dest.getParent() == getComponentGroup( dest, 'rig'): print 'creating rig input' # This means source and dest are in the same component and a target can be added to the rig group offset = coreUtils.createAlignedNode( dest, 'group', '%s_%s_%sOffset_srt' % (getComponentFromName(dest), connectionName, dest.name().split('_')[2])) rels = pmc.listRelatives(getComponentGroup(dest, 'rig'), ad=1, c=1) if source in rels: offset.setParent(source) else: input = coreUtils.addChild( getComponentGroup(dest, 'rig'), 'group', '%s_%s_%s_srt' % (getComponentFromName(dest), connectionName, dest.name().split('_')[2])) if source.worldMatrix.get() == source.matrix.get(): source.t.connect(input.t) source.r.connect(input.r) source.s.connect(input.s) else: d = coreUtils.isDecomposed(source) coreUtils.connectDecomposedMatrix(d, input) offset.setParent(input) d = coreUtils.isDecomposed(offset) coreUtils.connectDecomposedMatrix(d, dest) else: output = getOutput(source) if not output: output = exposeOutput(source) input = getInput(dest, output) print 'creating new input' input = exposeInput(dest, output, connectionName) conns = pmc.listConnections(dest.t, d=0, type='decomposeMatrix') offset = None if conns: offset = pmc.listConnections(conns[0].inputMatrix, d=0)[0] if offset.getParent() != input: offset.setParent(input) offset.rename(offset.getParent().name().replace( '_srt', '_%sOffset_srt' % dest.name().split('_')[2])) else: offset = coreUtils.createAlignedNode( dest, 'group', '%s_%s_in_%sOffset_srt' % (getComponentFromName(dest), connectionName, dest.name().split('_')[2])) offset.setParent(input) # Check whether dest is in worldspace. If so, use a direct connection. Otherwise, multiply by parent mtx if dest.worldMatrix.get() != dest.matrix.get(): m = coreUtils.multiplyMatrices( [ offset.worldMatrix[0], dest.getParent().worldInverseMatrix ], '%s_%s_localMtx_utl' % (getComponentFromName(dest), connectionName)) d = coreUtils.decomposeMatrix( m.matrixSum, '%s_%s_localMtxToSrt_utl' % (getComponentFromName(dest), connectionName)) coreUtils.connectDecomposedMatrix(d, dest) else: d = coreUtils.isDecomposed(offset) coreUtils.connectDecomposedMatrix(d, dest) return offset
def Finger(rootJnts=None): if not rootJnts: rootJnts = pm.ls(sl=True) else: rootJnts = pm.ls(rootJnts) for rootJnt in rootJnts: jnts = pm.listRelatives(rootJnt, ad=True) jnts.append(rootJnt) jnts.reverse() # create ctrls with zero groups for each joint ctrls = [] for i in range(len(jnts) - 1): ctrls.append( pm.curve(d=1, p=[(0, -1, 1), (0, 1, 1), (0, 1, -1), (0, -1, -1), (0, -1, 1)], k=[0, 1, 2, 3, 4], name='%s_ctrl' % jnts[i].name())) pm.delete(pm.pointConstraint(jnts[i], ctrls[i])) pm.delete(pm.orientConstraint(jnts[i], ctrls[i])) try: pm.parent(ctrls[i], ctrls[i - 1]) except: try: pm.parent(ctrls[i], world=True) except: pass # create zero groups ctrlsZerosAndOfss = ZeroGrp(ctrls) ctrlsZeros = ctrlsZerosAndOfss[0] ctrlsOfss = ctrlsZerosAndOfss[1] jntsZerosAndOfss = ZeroGrp(jnts) jntsZeros = jntsZerosAndOfss[0] jntsOfss = jntsZerosAndOfss[1] # connect transforms of ctrls to joints for i in range(len(ctrlsZeros)): ctrls[i].translate >> jntsOfss[i].translate ctrls[i].rotate >> jntsOfss[i].rotate ctrls[i].scale >> jntsOfss[i].scale # create a group for reverse scale ctrlScaleGrps = [] jntScaleGrps = [] for i in range(len(jnts) - 1): # create one for each ctrl ctrlScaleGrps.append( pm.group(em=True, name='%s_ctrl_scaleGrp' % jnts[i].name())) if i == len( jnts ): # if last joint, no need to position as where child is pm.delete(pm.pointConstraint(jnts[i], ctrlScaleGrps[i])) else: pm.delete(pm.pointConstraint(jnts[i + 1], ctrlScaleGrps[i])) pm.delete(pm.orientConstraint(jnts[i], ctrlScaleGrps[i])) # we need one more for each jnt as well jntScaleGrps.append(pm.duplicate(ctrlScaleGrps[i])[0]) pm.rename(jntScaleGrps[i], '%s_jnt_scaleGrp' % jnts[i].name()) # set hierarchy if i < len( jnts) - 2: # if last ctrl, do not parent anything under it ctrlScaleGrps[i].setParent(ctrls[i]) ctrlsZeros[i + 1].setParent(ctrlScaleGrps[i]) else: ctrlScaleGrps[i].setParent(ctrls[i]) if i < len(jnts ) - 1: # if last joint, do not parent anything under it jntScaleGrps[i].setParent(jnts[i]) jntsZeros[i + 1].setParent(jntScaleGrps[i]) # reverse the scale and connect it to next ctrlScaleGrps for i in range(len(ctrlsZeros) - 1): scaleRev = pm.createNode('multiplyDivide', name='%s_scaleRev' % ctrlsZeros[i].name()) scaleRev.input1.set(1, 1, 1) scaleRev.operation.set(2) ctrls[i].scale >> scaleRev.input2 scaleRev.output >> ctrlScaleGrps[i].scale for i in range(len(jntsZeros) - 1): scaleRev = pm.createNode('multiplyDivide', name='%s_scaleRev' % jntsZeros[i].name()) scaleRev.input1.set(1, 1, 1) scaleRev.operation.set(2) jntsOfss[i].scale >> scaleRev.input2 scaleRev.output >> jntScaleGrps[i].scale
def RibbonCreation(self, Object01, Object02, foliculeNumber=5): print 'creating riboon in %s and %s' % (Object01, Object02) self.baseObjects.append(Object01) self.baseObjects.append(Object02) VP1 = om.MVector(pm.xform(Object01, a=True, ws=True, q=True, rp=True)) VP2 = om.MVector(pm.xform(Object02, a=True, ws=True, q=True, rp=True)) plano = self.nurbPlaneBetweenObjects(Object01, Object02) planoShape = pm.listRelatives(plano, shapes=True)[0] pm.select(cl=True) RibbonSize = VP1 - VP2 print "plano = %s" % plano print "len = %s" % RibbonSize.length() MainSkeleton = pm.group(em=True, name="%sTo%sRibbon" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(MainSkeleton, useName=True) HairGroup = pm.group(em=True, name="%sTo%sHairSystem" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(HairGroup, useName=True) nstep = 1.0 / (foliculeNumber - 1.0) Hys = pm.language.Mel.eval('createNode hairSystem') Hys = "hairSystem1" ArrayJoints = [] HairSystemIndex = [0] folicules = [] for n in range(foliculeNumber): pm.language.Mel.eval( 'createHairCurveNode("%s", "%s" ,%s ,.5 , 1 ,0 ,0 ,0 ,0 ,"" ,1.0 ,{%s} ,"" ,"" ,2 );' % (Hys, planoShape, nstep * n, n)) NewFolicule = self.name_conv.rename_name_in_format("follicle1") folicules.append(NewFolicule) pm.parent(NewFolicule, HairGroup) self.folicules = folicules pm.delete(pm.listRelatives(Hys, p=True)) index = 0 skinedJoints = pm.group(em=True, name="%sTo%sskinedJoints" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(skinedJoints, useName=True) for eachFolicule in folicules: ArrayJoints.append( pm.joint(name="%sTo%sRibbonJoints" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02)))) self.name_conv.rename_name_in_format(ArrayJoints[index], useName=True) pm.matchTransform(ArrayJoints[index], eachFolicule) pm.parentConstraint(eachFolicule, ArrayJoints[index]) index += 1 self.jointStructure = ArrayJoints controles = [] resetControles = [] locatorControlesList = [] locatorLookAtList = [] jointsLookAtList = [] groupLookAtList = [] GroupControls = pm.group(empty=True, name="%sTo%sControls" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(GroupControls, useName=True) GroupJoints = pm.group(empty=True, name="%sTo%sGroupJointsLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(GroupJoints, useName=True) self.allControls.append(GroupControls) self.joints.append(GroupJoints) for iloop in range(3): resetControlGroup, control = self.rig_controls.RMCircularControl( Object01, radius=RibbonSize.length() / 3, name="%sTo%sCtrl" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) controles.append(control) resetControles.append(resetControlGroup) locatorControl = pm.spaceLocator( name="%sTo%sLocatorCntrl" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(locatorControl, useName=True) locatorControlesList.append(locatorControl) pm.matchTransform(locatorControl, Object01) locatorLookAt = pm.spaceLocator( name="%sTo%sLocatorLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(locatorLookAt, useName=True) locatorLookAtList.append(locatorLookAt) pm.matchTransform(locatorLookAt, Object01) pm.select(clear=True) jointsLookAt = pm.joint( name="%sTo%sJointsLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(jointsLookAt, useName=True) jointsLookAtList.append(jointsLookAt) pm.matchTransform(jointsLookAt, Object01) groupLookAt = pm.group(empty=True, name="%sTo%sGroupLookAt" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.rename_name_in_format(groupLookAt, useName=True) self.kinematics.append(groupLookAt) groupLookAtList.append(groupLookAt) pm.matchTransform(groupLookAt, Object01) for each in groupLookAtList: pm.parent(each, MainSkeleton) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, resetControlGroup, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, locatorControl, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 1, locatorLookAt, r=True, os=True, moveXYZ=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, jointsLookAt, r=True, os=True, moveX=True) pm.move(RibbonSize.length() / 2 * iloop, 0, 0, groupLookAt, r=True, os=True, moveX=True) pm.parent(resetControlGroup, GroupControls) pm.parent(locatorControl, groupLookAt) pm.parent(locatorLookAt, groupLookAt) pm.parent(jointsLookAt, GroupJoints) pm.makeIdentity(control, apply=True, t=1, r=0, s=1, n=0) pm.makeIdentity(jointsLookAt, apply=True, t=1, r=0, s=1, n=0) pm.parentConstraint(locatorControl, jointsLookAt) pm.parentConstraint(control, groupLookAt) self.controls = controles self.resetControls = resetControles self.resetControls = resetControles pm.aimConstraint(controles[1], locatorControlesList[0], aim=[1, 0, 0], upVector=[0, 0, 1], wut='object', worldUpObject=locatorLookAtList[0]) pm.aimConstraint(controles[1], locatorControlesList[2], aim=[1, 0, 0], upVector=[0, 0, 1], wut='object', worldUpObject=locatorLookAtList[2]) pm.parent(GroupJoints, MainSkeleton) # pm.select(plano, replace=True) # print jointsLookAtList # for eachJoint in jointsLookAtList: # pm.select(eachJoint, add=True) pm.skinCluster(jointsLookAtList, plano) pm.parent(plano, HairGroup)
def switchParentspace(self, weightChrystal=1, weightWorld=0, weightWildcard1=0, weightWildcard2=0, weightWildcard3=0, weightWildcard4=0): #get selectionList selectionList = pm.ls(sl=True, fl=True, type='transform') pm.select(cl=True) #check if something is selected if not (selectionList): if (self.verbose): print('Empty Selection') return None #Iterate selectionList and set parentConstraint weights for transformNode in selectionList: try: #Get transform matrix of transformNode in ws transformMatrixWs = pm.xform(transformNode, q=True, m=True, ws=True) #get ParentConstraint try: parentspaceConstraint = pm.listRelatives( transformNode.getParent().getParent(), typ='parentConstraint')[0] except: if (self.verbose): print('Parentspace Constraint not found for object ' + transformNode.name() + '. Continuing...') continue #Set Weightvalues pm.setAttr(parentspaceConstraint.chrystal_master_jW0, weightChrystal) pm.setAttr(parentspaceConstraint.world_parent_dummy_locW1, weightWorld) pm.setAttr(parentspaceConstraint.manip_wildcard_1W2, weightWildcard1) pm.setAttr(parentspaceConstraint.manip_wildcard_2W3, weightWildcard2) pm.setAttr(parentspaceConstraint.manip_wildcard_3W4, weightWildcard3) pm.setAttr(parentspaceConstraint.manip_wildcard_4W5, weightWildcard4) #set transformation back pm.xform(transformNode, m=transformMatrixWs, ws=True) #Verbose if (self.verbose): print('Succesfully switched parentspaces for node: ' + transformNode.name()) except: if (self.verbose): print('Error settings weights for selected node: ' + transformNode.name()) #Redo selection pm.select(selectionList, r=True)
def rig( eyeMesh=None, edgeLoop="", blinkH=20, namePrefix="eye", offset=0.05, rigidLoops=2, falloffLoops=4, headJnt=None, doSkin=True, parent_node=None, ctlName="ctl", sideRange=False, customCorner=False, intCorner=None, extCorner=None, ctlSet=None, defSet=None, upperVTrack=0.02, upperHTrack=0.01, lowerVTrack=0.02, lowerHTrack=0.01, aim_controller="", deformers_group="", ): """Create eyelid and eye rig Args: eyeMesh (TYPE): Description edgeLoop (TYPE): Description blinkH (TYPE): Description namePrefix (TYPE): Description offset (TYPE): Description rigidLoops (TYPE): Description falloffLoops (TYPE): Description headJnt (TYPE): Description doSkin (TYPE): Description parent_node (None, optional): Description ctlName (str, optional): Description sideRange (bool, optional): Description customCorner (bool, optional): Description intCorner (None, optional): Description extCorner (None, optional): Description ctlSet (None, optional): Description defSet (None, optional): Description upperVTrack (None, optional): Description upperHTrack (None, optional): Description lowerVTrack (None, optional): Description lowerHTrack (None, optional): Description aim_controller (None, optional): Description deformers_group (None, optional): Description Returns: TYPE: Description """ ########################################## # INITIAL SETUP ########################################## # getters edgeLoopList = get_edge_loop(edgeLoop) eyeMesh = get_eye_mesh(eyeMesh) # checkers if not edgeLoopList or not eyeMesh: return if doSkin: if not headJnt: pm.displayWarning( "Please set the Head Jnt or unCheck " "Compute Topological Autoskin" ) return # Convert data blinkH = blinkH / 100.0 # Initial Data bboxCenter = meshNavigation.bboxCenter(eyeMesh) extr_v = meshNavigation.getExtremeVertexFromLoop(edgeLoopList, sideRange) upPos = extr_v[0] lowPos = extr_v[1] inPos = extr_v[2] outPos = extr_v[3] edgeList = extr_v[4] vertexList = extr_v[5] # Detect the side L or R from the x value if inPos.getPosition(space="world")[0] < 0.0: side = "R" inPos = extr_v[3] outPos = extr_v[2] normalPos = outPos npw = normalPos.getPosition(space="world") normalVec = npw - bboxCenter else: side = "L" normalPos = outPos npw = normalPos.getPosition(space="world") normalVec = bboxCenter - npw # Manual Vertex corners if customCorner: if intCorner: try: if side == "R": inPos = pm.PyNode(extCorner) else: inPos = pm.PyNode(intCorner) except pm.MayaNodeError: pm.displayWarning("%s can not be found" % intCorner) return else: pm.displayWarning("Please set the internal eyelid corner") return if extCorner: try: normalPos = pm.PyNode(extCorner) npw = normalPos.getPosition(space="world") if side == "R": outPos = pm.PyNode(intCorner) normalVec = npw - bboxCenter else: outPos = pm.PyNode(extCorner) normalVec = bboxCenter - npw except pm.MayaNodeError: pm.displayWarning("%s can not be found" % extCorner) return else: pm.displayWarning("Please set the external eyelid corner") return # Check if we have prefix: if namePrefix: namePrefix = string.removeInvalidCharacter(namePrefix) else: pm.displayWarning("Prefix is needed") return def setName(name, ind=None): namesList = [namePrefix, side, name] if ind is not None: namesList[1] = side + str(ind) name = "_".join(namesList) return name if pm.ls(setName("root")): pm.displayWarning( "The object %s already exist in the scene. Please " "choose another name prefix" % setName("root") ) return ########################################## # CREATE OBJECTS ########################################## # Eye root eye_root = primitive.addTransform(None, setName("root")) eyeCrv_root = primitive.addTransform(eye_root, setName("crvs")) # Eyelid Main crvs try: upEyelid_edge = meshNavigation.edgeRangeInLoopFromMid( edgeList, upPos, inPos, outPos ) up_crv = curve.createCurveFromOrderedEdges( upEyelid_edge, inPos, setName("upperEyelid"), parent=eyeCrv_root ) upCtl_crv = curve.createCurveFromOrderedEdges( upEyelid_edge, inPos, setName("upCtl_crv"), parent=eyeCrv_root ) pm.rebuildCurve(upCtl_crv, s=2, rt=0, rpo=True, ch=False) lowEyelid_edge = meshNavigation.edgeRangeInLoopFromMid( edgeList, lowPos, inPos, outPos ) low_crv = curve.createCurveFromOrderedEdges( lowEyelid_edge, inPos, setName("lowerEyelid"), parent=eyeCrv_root ) lowCtl_crv = curve.createCurveFromOrderedEdges( lowEyelid_edge, inPos, setName("lowCtl_crv"), parent=eyeCrv_root ) pm.rebuildCurve(lowCtl_crv, s=2, rt=0, rpo=True, ch=False) except UnboundLocalError: if customCorner: pm.displayWarning( "This error is maybe caused because the custom " "Corner vertex is not part of the edge loop" ) pm.displayError(traceback.format_exc()) return # blendshape curves. All crv have 30 point to allow blendshape connect upDriver_crv = curve.createCurveFromCurve( up_crv, setName("upDriver_crv"), nbPoints=30, parent=eyeCrv_root ) upDriver_crv.attr("lineWidth").set(5) lowDriver_crv = curve.createCurveFromCurve( low_crv, setName("lowDriver_crv"), nbPoints=30, parent=eyeCrv_root ) lowDriver_crv.attr("lineWidth").set(5) upRest_target_crv = curve.createCurveFromCurve( up_crv, setName("upRest_target_crv"), nbPoints=30, parent=eyeCrv_root ) lowRest_target_crv = curve.createCurveFromCurve( low_crv, setName("lowRest_target_crv"), nbPoints=30, parent=eyeCrv_root ) upProfile_target_crv = curve.createCurveFromCurve( up_crv, setName("upProfile_target_crv"), nbPoints=30, parent=eyeCrv_root, ) lowProfile_target_crv = curve.createCurveFromCurve( low_crv, setName("lowProfile_target_crv"), nbPoints=30, parent=eyeCrv_root, ) # mid driver midUpDriver_crv = curve.createCurveFromCurve( up_crv, setName("midUpDriver_crv"), nbPoints=30, parent=eyeCrv_root ) midLowDriver_crv = curve.createCurveFromCurve( low_crv, setName("midLowDriver_crv"), nbPoints=30, parent=eyeCrv_root ) # curve that define the close point of the eyelid closeTarget_crv = curve.createCurveFromCurve( up_crv, setName("closeTarget_crv"), nbPoints=30, parent=eyeCrv_root ) eyeCrv_root.attr("visibility").set(False) # localBBOX localBBox = eyeMesh.getBoundingBox(invisible=True, space="world") wRadius = abs((localBBox[0][0] - localBBox[1][0])) dRadius = abs((localBBox[0][1] - localBBox[1][1]) / 1.7) # Groups if not ctlSet: ctlSet = "rig_controllers_grp" try: ctlSet = pm.PyNode(ctlSet) except pm.MayaNodeError: pm.sets(n=ctlSet, em=True) ctlSet = pm.PyNode(ctlSet) if not defSet: defSet = "rig_deformers_grp" try: defset = pm.PyNode(defSet) except pm.MayaNodeError: pm.sets(n=defSet, em=True) defset = pm.PyNode(defSet) # Calculate center looking at averagePosition = ( upPos.getPosition(space="world") + lowPos.getPosition(space="world") + inPos.getPosition(space="world") + outPos.getPosition(space="world") ) / 4 if side == "R": negate = False offset = offset over_offset = dRadius else: negate = False over_offset = dRadius if side == "R" and sideRange or side == "R" and customCorner: axis = "z-x" # axis = "zx" else: axis = "z-x" t = transform.getTransformLookingAt( bboxCenter, averagePosition, normalVec, axis=axis, negate=negate ) over_npo = primitive.addTransform( eye_root, setName("center_lookatRoot"), t ) # over_ctl = icon.create( # over_npo, # setName("over_%s" % ctlName), # t, # icon="square", # w=wRadius, # d=dRadius, # ro=datatypes.Vector(1.57079633, 0, 0), # po=datatypes.Vector(0, 0, over_offset), # color=4, # ) # node.add_controller_tag(over_ctl) # attribute.addAttribute(over_ctl, "isCtl", "bool", keyable=False) # attribute.add_mirror_config_channels(over_ctl) # attribute.setKeyableAttributes( # over_ctl, # params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"], # ) # if side == "R": # over_npo.attr("rx").set(over_npo.attr("rx").get() * -1) # over_npo.attr("ry").set(over_npo.attr("ry").get() + 180) # over_npo.attr("sz").set(-1) # if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": # pass # else: # pm.sets(ctlSet, add=over_ctl) center_lookat = primitive.addTransform( over_npo, setName("center_lookat"), t ) # Tracking # Eye aim control t_arrow = transform.getTransformLookingAt( bboxCenter, averagePosition, upPos.getPosition(space="world"), axis="zy", negate=False, ) radius = abs((localBBox[0][0] - localBBox[1][0]) / 1.7) arrow_ctl = None arrow_npo = None if aim_controller: arrow_ctl = pm.PyNode(aim_controller) else: arrow_npo = primitive.addTransform( eye_root, setName("aim_npo"), t_arrow ) arrow_ctl = icon.create( arrow_npo, setName("aim_%s" % ctlName), t_arrow, icon="arrow", w=1, po=datatypes.Vector(0, 0, radius), color=4, ) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=arrow_ctl) attribute.setKeyableAttributes(arrow_ctl, params=["rx", "ry", "rz"]) attribute.addAttribute(arrow_ctl, "isCtl", "bool", keyable=False) # tracking custom trigger if side == "R": tt = t_arrow else: tt = t aimTrigger_root = primitive.addTransform( center_lookat, setName("aimTrigger_root"), tt ) # For some unknown reason the right side gets scewed rotation values mgear.core.transform.resetTransform(aimTrigger_root) aimTrigger_lvl = primitive.addTransform( aimTrigger_root, setName("aimTrigger_lvl"), tt ) # For some unknown reason the right side gets scewed rotation values mgear.core.transform.resetTransform(aimTrigger_lvl) aimTrigger_lvl.attr("tz").set(1.0) aimTrigger_ref = primitive.addTransform( aimTrigger_lvl, setName("aimTrigger_ref"), tt ) # For some unknown reason the right side gets scewed rotation values mgear.core.transform.resetTransform(aimTrigger_ref) aimTrigger_ref.attr("tz").set(0.0) # connect trigger with arrow_ctl pm.parentConstraint(arrow_ctl, aimTrigger_ref, mo=True) # Blink driver controls # upper ctl p = upRest_target_crv.getCVs(space="world")[15] ut = transform.setMatrixPosition(datatypes.Matrix(), p) npo = primitive.addTransform(over_npo, setName("upBlink_npo"), ut) up_ctl = icon.create( npo, setName("upBlink_ctl"), ut, icon="arrow", w=2.5, d=2.5, ro=datatypes.Vector(1.57079633, 1.57079633, 0), po=datatypes.Vector(0, 0, offset), color=4, ) attribute.setKeyableAttributes(up_ctl, ["ty"]) # use translation of the object to drive the blink blink_driver = primitive.addTransform(up_ctl, setName("blink_drv"), ut) # lowe ctl p_low = lowRest_target_crv.getCVs(space="world")[15] p[1] = p_low[1] lt = transform.setMatrixPosition(ut, p) npo = primitive.addTransform(over_npo, setName("upBlink_npo"), lt) low_ctl = icon.create( npo, setName("lowBlink_ctl"), lt, icon="arrow", w=1.5, d=1.5, ro=datatypes.Vector(1.57079633, 1.57079633, 1.57079633 * 2), po=datatypes.Vector(0, 0, offset), color=4, ) attribute.setKeyableAttributes(low_ctl, ["ty"]) # Controls lists upControls = [] trackLvl = [] track_corner_lvl = [] corner_ctl = [] ghost_ctl = [] # upper eyelid controls upperCtlNames = ["inCorner", "upInMid", "upMid", "upOutMid", "outCorner"] cvs = upCtl_crv.getCVs(space="world") if side == "R" and not sideRange: # if side == "R": cvs = [cv for cv in reversed(cvs)] for i, cv in enumerate(cvs): if utils.is_odd(i): color = 14 wd = 0.3 icon_shape = "circle" params = ["tx", "ty", "tz"] else: color = 4 wd = 0.6 icon_shape = "circle" params = [ "tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz", ] t = transform.setMatrixPosition(t, cvs[i]) npo = primitive.addTransform( center_lookat, setName("%s_npo" % upperCtlNames[i]), t ) npoBase = npo # track for corners and mid point level if i in [0, 2, 4]: # we add an extra level to input the tracking ofset values npo = primitive.addTransform( npo, setName("%s_trk" % upperCtlNames[i]), t ) if i == 2: trackLvl.append(npo) else: track_corner_lvl.append(npo) if i in [1, 2, 3]: ctl = primitive.addTransform( npo, setName("%s_loc" % upperCtlNames[i]), t ) # ghost controls if i == 2: gt = ut else: gt = t npo_g = primitive.addTransform( up_ctl, setName("%sCtl_npo" % upperCtlNames[i]), gt ) ctl_g = icon.create( npo_g, setName("%s_%s" % (upperCtlNames[i], ctlName)), gt, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color, ) # define the ctl_param to recive the ctl configuration ctl_param = ctl_g ghost_ctl.append(ctl_g) # connect local SRT rigbits.connectLocalTransform([ctl_g, ctl]) else: ctl = icon.create( npo, setName("%s_%s" % (upperCtlNames[i], ctlName)), t, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color, ) # define the ctl_param to recive the ctl configuration ctl_param = ctl attribute.addAttribute(ctl_param, "isCtl", "bool", keyable=False) attribute.add_mirror_config_channels(ctl_param) node.add_controller_tag(ctl_param, over_npo) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=ctl_param) attribute.setKeyableAttributes(ctl_param, params) upControls.append(ctl) # add corner ctls to corner ctl list for tracking if i in [0, 4]: corner_ctl.append(ctl) if side == "R": npoBase.attr("ry").set(180) npoBase.attr("sz").set(-1) # adding parent constraints to odd controls for i, ctl in enumerate(upControls): if utils.is_odd(i): cns_node = pm.parentConstraint( upControls[i - 1], upControls[i + 1], ctl.getParent(), mo=True ) # Make the constraint "noFlip" cns_node.interpType.set(0) # adding parent constraint ghost controls cns_node = pm.parentConstraint( ghost_ctl[1], upControls[0], ghost_ctl[0].getParent(), mo=True ) cns_node.interpType.set(0) cns_node = pm.parentConstraint( ghost_ctl[1], upControls[-1], ghost_ctl[2].getParent(), mo=True ) cns_node.interpType.set(0) # lower eyelid controls lowControls = [upControls[0]] lowerCtlNames = [ "inCorner", "lowInMid", "lowMid", "lowOutMid", "outCorner", ] cvs = lowCtl_crv.getCVs(space="world") if side == "R" and not sideRange: cvs = [cv for cv in reversed(cvs)] for i, cv in enumerate(cvs): # we skip the first and last point since is already in the uper eyelid if i in [0, 4]: continue if utils.is_odd(i): color = 14 wd = 0.3 icon_shape = "circle" params = ["tx", "ty", "tz"] else: color = 4 wd = 0.6 icon_shape = "circle" params = [ "tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz", ] t = transform.setMatrixPosition(t, cvs[i]) npo = primitive.addTransform( center_lookat, setName("%s_npo" % lowerCtlNames[i]), t ) npoBase = npo if i in [1, 2, 3]: if i == 2: # we add an extra level to input the tracking ofset values npo = primitive.addTransform( npo, setName("%s_trk" % lowerCtlNames[i]), t ) trackLvl.append(npo) ctl = primitive.addTransform( npo, setName("%s_loc" % lowerCtlNames[i]), t ) # ghost controls if i == 2: gt = lt else: gt = t # ghost controls npo_g = primitive.addTransform( low_ctl, setName("%sCtl_npo" % lowerCtlNames[i]), gt ) ctl_g = icon.create( npo_g, setName("%s_%s" % (lowerCtlNames[i], ctlName)), gt, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color, ) # define the ctl_param to recive the ctl configuration ctl_param = ctl_g ghost_ctl.append(ctl_g) # connect local SRT rigbits.connectLocalTransform([ctl_g, ctl]) else: ctl = icon.create( npo, setName("%s_%s" % (lowerCtlNames[i], ctlName)), t, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color, ) # define the ctl_param to recive the ctl configuration ctl_param = ctl attribute.addAttribute(ctl_param, "isCtl", "bool", keyable=False) attribute.add_mirror_config_channels(ctl_param) lowControls.append(ctl) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=ctl_param) attribute.setKeyableAttributes(ctl_param, params) # mirror behaviout on R side controls if side == "R": npoBase.attr("ry").set(180) npoBase.attr("sz").set(-1) for lctl in reversed(lowControls[1:]): node.add_controller_tag(lctl, over_npo) lowControls.append(upControls[-1]) # adding parent constraints to odd controls for i, ctl in enumerate(lowControls): if utils.is_odd(i): cns_node = pm.parentConstraint( lowControls[i - 1], lowControls[i + 1], ctl.getParent(), mo=True, ) # Make the constraint "noFlip" cns_node.interpType.set(0) # adding parent constraint ghost controls cns_node = pm.parentConstraint( ghost_ctl[4], upControls[0], ghost_ctl[3].getParent(), mo=True ) cns_node.interpType.set(0) cns_node = pm.parentConstraint( ghost_ctl[4], upControls[-1], ghost_ctl[5].getParent(), mo=True ) cns_node.interpType.set(0) ########################################## # OPERATORS ########################################## # Connecting control crvs with controls applyop.gear_curvecns_op(upCtl_crv, upControls) applyop.gear_curvecns_op(lowCtl_crv, lowControls) # adding wires w1 = pm.wire(up_crv, w=upDriver_crv)[0] w2 = pm.wire(low_crv, w=lowDriver_crv)[0] w3 = pm.wire(upProfile_target_crv, w=upCtl_crv)[0] w4 = pm.wire(lowProfile_target_crv, w=lowCtl_crv)[0] # connect blink driver pm.pointConstraint(low_ctl, blink_driver, mo=False) rest_val = blink_driver.ty.get() up_div_node = node.createDivNode(up_ctl.ty, rest_val) low_div_node = node.createDivNode(low_ctl.ty, rest_val * -1) # contact driver minus_node = node.createPlusMinusAverage1D( [rest_val, blink_driver.ty], operation=2 ) contact_div_node = node.createDivNode(minus_node.output1D, rest_val) # wire tension for w in [w1, w2, w3, w4]: w.dropoffDistance[0].set(100) # TODO: what is the best solution? # trigger using proximity # remap_node = pm.createNode("remapValue") # contact_div_node.outputX >> remap_node.inputValue # remap_node.value[0].value_Interp.set(2) # remap_node.inputMin.set(0.995) # reverse_node = node.createReverseNode(remap_node.outColorR) # for w in [w1, w2]: # reverse_node.outputX >> w.scale[0] # trigger at starting movement for up and low # up remap_node = pm.createNode("remapValue") up_ctl.ty >> remap_node.inputValue remap_node.value[0].value_Interp.set(2) remap_node.inputMax.set(rest_val / 10) reverse_node = node.createReverseNode(remap_node.outColorR) reverse_node.outputX >> w1.scale[0] # low remap_node = pm.createNode("remapValue") low_ctl.ty >> remap_node.inputValue remap_node.value[0].value_Interp.set(2) remap_node.inputMin.set((rest_val / 10) * -1) remap_node.outColorR >> w2.scale[0] # mid position drivers blendshapes bs_midUpDrive = pm.blendShape( lowRest_target_crv, upProfile_target_crv, midUpDriver_crv, n="midUpDriver_blendShape", ) bs_midLowDrive = pm.blendShape( upRest_target_crv, lowProfile_target_crv, midLowDriver_crv, n="midlowDriver_blendShape", ) bs_closeTarget = pm.blendShape( midUpDriver_crv, midLowDriver_crv, closeTarget_crv, n="closeTarget_blendShape", ) pm.connectAttr( up_div_node.outputX, bs_midUpDrive[0].attr(lowRest_target_crv.name()), ) pm.connectAttr( low_div_node.outputX, bs_midLowDrive[0].attr(upRest_target_crv.name()), ) pm.setAttr(bs_closeTarget[0].attr(midUpDriver_crv.name()), 0.5) pm.setAttr(bs_closeTarget[0].attr(midLowDriver_crv.name()), 0.5) # Main crv drivers bs_upBlink = pm.blendShape( lowRest_target_crv, closeTarget_crv, upProfile_target_crv, upDriver_crv, n="upBlink_blendShape", ) bs_lowBlink = pm.blendShape( upRest_target_crv, closeTarget_crv, lowProfile_target_crv, lowDriver_crv, n="lowBlink_blendShape", ) # blink contact connections cond_node_up = node.createConditionNode( contact_div_node.outputX, 1, 3, 0, up_div_node.outputX ) pm.connectAttr( cond_node_up.outColorR, bs_upBlink[0].attr(lowRest_target_crv.name()), ) cond_node_low = node.createConditionNode( contact_div_node.outputX, 1, 3, 0, low_div_node.outputX ) pm.connectAttr( cond_node_low.outColorR, bs_lowBlink[0].attr(upRest_target_crv.name()), ) cond_node_close = node.createConditionNode( contact_div_node.outputX, 1, 2, 1, 0 ) cond_node_close.colorIfFalseR.set(0) pm.connectAttr( cond_node_close.outColorR, bs_upBlink[0].attr(closeTarget_crv.name()), ) pm.connectAttr( cond_node_close.outColorR, bs_lowBlink[0].attr(closeTarget_crv.name()), ) pm.setAttr(bs_upBlink[0].attr(upProfile_target_crv.name()), 1) pm.setAttr(bs_lowBlink[0].attr(lowProfile_target_crv.name()), 1) # joints root jnt_root = primitive.addTransformFromPos( eye_root, setName("joints"), pos=bboxCenter ) if deformers_group: deformers_group = pm.PyNode(deformers_group) pm.parentConstraint(eye_root, jnt_root, mo=True) pm.scaleConstraint(eye_root, jnt_root, mo=True) deformers_group.addChild(jnt_root) # head joint if headJnt: try: headJnt = pm.PyNode(headJnt) jnt_base = headJnt except pm.MayaNodeError: pm.displayWarning("Aborted can not find %s " % headJnt) return else: # Eye root jnt_base = jnt_root eyeTargets_root = primitive.addTransform(eye_root, setName("targets")) eyeCenter_jnt = rigbits.addJnt( arrow_ctl, jnt_base, grp=defset, jntName=setName("center_jnt") ) # Upper Eyelid joints ################################################## cvs = up_crv.getCVs(space="world") upCrv_info = node.createCurveInfoNode(up_crv) # aim constrain targets and joints upperEyelid_aimTargets = [] upperEyelid_jnt = [] upperEyelid_jntRoot = [] for i, cv in enumerate(cvs): # aim targets trn = primitive.addTransformFromPos( eyeTargets_root, setName("upEyelid_aimTarget", i), pos=cv ) upperEyelid_aimTargets.append(trn) # connecting positions with crv pm.connectAttr( upCrv_info + ".controlPoints[%s]" % str(i), trn.attr("translate") ) # joints jntRoot = primitive.addJointFromPos( jnt_root, setName("upEyelid_jnt_base", i), pos=bboxCenter ) jntRoot.attr("radius").set(0.08) jntRoot.attr("visibility").set(False) upperEyelid_jntRoot.append(jntRoot) applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root) jnt_ref = primitive.addJointFromPos( jntRoot, setName("upEyelid_jnt_ref", i), pos=cv ) jnt_ref.attr("radius").set(0.08) jnt_ref.attr("visibility").set(False) jnt = rigbits.addJnt( jnt_ref, jnt_base, grp=defset, jntName=setName("upEyelid_jnt", i) ) upperEyelid_jnt.append(jnt) # Lower Eyelid joints ################################################## cvs = low_crv.getCVs(space="world") lowCrv_info = node.createCurveInfoNode(low_crv) # aim constrain targets and joints lowerEyelid_aimTargets = [] lowerEyelid_jnt = [] lowerEyelid_jntRoot = [] for i, cv in enumerate(cvs): if i in [0, len(cvs) - 1]: continue # aim targets trn = primitive.addTransformFromPos( eyeTargets_root, setName("lowEyelid_aimTarget", i), pos=cv ) lowerEyelid_aimTargets.append(trn) # connecting positions with crv pm.connectAttr( lowCrv_info + ".controlPoints[%s]" % str(i), trn.attr("translate") ) # joints jntRoot = primitive.addJointFromPos( jnt_root, setName("lowEyelid_base", i), pos=bboxCenter ) jntRoot.attr("radius").set(0.08) jntRoot.attr("visibility").set(False) lowerEyelid_jntRoot.append(jntRoot) applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root) jnt_ref = primitive.addJointFromPos( jntRoot, setName("lowEyelid_jnt_ref", i), pos=cv ) jnt_ref.attr("radius").set(0.08) jnt_ref.attr("visibility").set(False) jnt = rigbits.addJnt( jnt_ref, jnt_base, grp=defset, jntName=setName("lowEyelid_jnt", i) ) lowerEyelid_jnt.append(jnt) # Adding channels for eye tracking upVTracking_att = attribute.addAttribute( up_ctl, "vTracking", "float", upperVTrack, minValue=0 ) upHTracking_att = attribute.addAttribute( up_ctl, "hTracking", "float", upperHTrack, minValue=0 ) lowVTracking_att = attribute.addAttribute( low_ctl, "vTracking", "float", lowerVTrack, minValue=0 ) lowHTracking_att = attribute.addAttribute( low_ctl, "hTracking", "float", lowerHTrack, minValue=0 ) # vertical tracking connect up_mult_node = node.createMulNode( upVTracking_att, aimTrigger_ref.attr("ty") ) low_mult_node = node.createMulNode( lowVTracking_att, aimTrigger_ref.attr("ty") ) # remap to use the low or the up eyelid as driver contact base on # the eyetrack trigger direction uT_remap_node = pm.createNode("remapValue") aimTrigger_ref.attr("ty") >> uT_remap_node.inputValue uT_remap_node.inputMax.set(0.1) uT_remap_node.inputMin.set(-0.1) up_mult_node.outputX >> uT_remap_node.outputMax low_mult_node.outputX >> uT_remap_node.outputMin # up u_remap_node = pm.createNode("remapValue") contact_div_node.outputX >> u_remap_node.inputValue u_remap_node.value[0].value_Interp.set(2) u_remap_node.inputMin.set(0.9) up_mult_node.outputX >> u_remap_node.outputMin uT_remap_node.outColorR >> u_remap_node.outputMax # low l_remap_node = pm.createNode("remapValue") contact_div_node.outputX >> l_remap_node.inputValue l_remap_node.value[0].value_Interp.set(2) l_remap_node.inputMin.set(0.9) low_mult_node.outputX >> l_remap_node.outputMin uT_remap_node.outColorR >> l_remap_node.outputMax # up connect and turn down to low when contact pm.connectAttr(u_remap_node.outColorR, trackLvl[0].attr("ty")) pm.connectAttr(l_remap_node.outColorR, trackLvl[1].attr("ty")) # horizontal tracking connect mult_node = node.createMulNode(upHTracking_att, aimTrigger_ref.attr("tx")) # Correct right side horizontal tracking if side == "R": mult_node = node.createMulNode(mult_node.attr("outputX"), -1) pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("tx")) mult_node = node.createMulNode(lowHTracking_att, aimTrigger_ref.attr("tx")) # Correct right side horizontal tracking if side == "R": mult_node = node.createMulNode(mult_node.attr("outputX"), -1) pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("tx")) # adding channels for corner tracking # track_corner_lvl for i, ctl in enumerate(corner_ctl): VTracking_att = attribute.addAttribute( ctl, "vTracking", "float", 0.1, minValue=0 ) mult_node = node.createMulNode(VTracking_att, up_ctl.ty) mult_node2 = node.createMulNode(VTracking_att, low_ctl.ty) plus_node = node.createPlusMinusAverage1D( [mult_node.outputX, mult_node2.outputX] ) pm.connectAttr(plus_node.output1D, track_corner_lvl[i].attr("ty")) ########################################### # Reparenting ########################################### if parent_node: try: if isinstance(parent_node, string_types): parent_node = pm.PyNode(parent_node) parent_node.addChild(eye_root) except pm.MayaNodeError: pm.displayWarning( "The eye rig can not be parent to: %s. Maybe " "this object doesn't exist." % parent_node ) ########################################### # Auto Skinning ########################################### if doSkin: # eyelid vertex rows totalLoops = rigidLoops + falloffLoops vertexLoopList = meshNavigation.getConcentricVertexLoop( vertexList, totalLoops ) vertexRowList = meshNavigation.getVertexRowsFromLoops(vertexLoopList) # we set the first value 100% for the first initial loop skinPercList = [1.0] # we expect to have a regular grid topology for r in range(rigidLoops): for rr in range(2): skinPercList.append(1.0) increment = 1.0 / float(falloffLoops) # we invert to smooth out from 100 to 0 inv = 1.0 - increment for r in range(falloffLoops): for rr in range(2): if inv < 0.0: inv = 0.0 skinPercList.append(inv) inv -= increment # this loop add an extra 0.0 indices to avoid errors for r in range(10): for rr in range(2): skinPercList.append(0.0) # base skin geo = pm.listRelatives(edgeLoopList[0], parent=True)[0] # Check if the object has a skinCluster objName = pm.listRelatives(geo, parent=True)[0] skinCluster = skin.getSkinCluster(objName) if not skinCluster: skinCluster = pm.skinCluster( headJnt, geo, tsb=True, nw=2, n="skinClsEyelid" ) eyelidJoints = upperEyelid_jnt + lowerEyelid_jnt pm.progressWindow( title="Auto skinning process", progress=0, max=len(eyelidJoints) ) firstBoundary = False for jnt in eyelidJoints: pm.progressWindow(e=True, step=1, status="\nSkinning %s" % jnt) skinCluster.addInfluence(jnt, weight=0) v = meshNavigation.getClosestVertexFromTransform(geo, jnt) for row in vertexRowList: if v in row: it = 0 # iterator inc = 1 # increment for i, rv in enumerate(row): try: perc = skinPercList[it] t_val = [(jnt, perc), (headJnt, 1.0 - perc)] pm.skinPercent( skinCluster, rv, transformValue=t_val ) if rv.isOnBoundary(): # we need to compare with the first boundary # to check if the row have inverted direction # and offset the value if not firstBoundary: firstBoundary = True firstBoundaryValue = it else: if it < firstBoundaryValue: it -= 1 elif it > firstBoundaryValue: it += 1 inc = 2 except IndexError: continue it = it + inc pm.progressWindow(e=True, endProgress=True) # Eye Mesh skinning skinCluster = skin.getSkinCluster(eyeMesh) if not skinCluster: skinCluster = pm.skinCluster( eyeCenter_jnt, eyeMesh, tsb=True, nw=1, n="skinClsEye" )
import pymel.core as pm value = .33 selection_list = pm.ls(sl=True) for selection in selection_list: crv_shape_list = pm.listRelatives(selection, type='nurbsCurve') crv_shape_list = list(set(crv_shape_list)) for shape in crv_shape_list: if shape.isIntermediate(): crv_shape_list.remove(shape) bsh_list = pm.listConnections(crv_shape_list, type='blendShape') bsh_list = list(set(bsh_list)) for bsh in bsh_list: if 'OUTPUT' in bsh.nodeName(): attrNm = bsh.stripNamespace().split('_BS')[0] pm.setAttr('{0}.{1}Shape'.format(bsh.nodeName(), attrNm), value)
def jointUnder(self, joint): jointUnder = pm.listRelatives(joint, c=1, type="joint") if not len(jointUnder): pm.setAttr(joint.jointOrient, (0, 0, 0)) return None return jointUnder
def eyeRig(eyeMesh, edgeLoop, blinkH, namePrefix, offset, rigidLoops, falloffLoops, headJnt, doSkin, parent=None, ctlName="ctl", sideRange=False, customCorner=False, intCorner=None, extCorner=None, ctlGrp=None, defGrp=None): """Create eyelid and eye rig Args: eyeMesh (TYPE): Description edgeLoop (TYPE): Description blinkH (TYPE): Description namePrefix (TYPE): Description offset (TYPE): Description rigidLoops (TYPE): Description falloffLoops (TYPE): Description headJnt (TYPE): Description doSkin (TYPE): Description parent (None, optional): Description ctlName (str, optional): Description sideRange (bool, optional): Description customCorner (bool, optional): Description intCorner (None, optional): Description extCorner (None, optional): Description ctlGrp (None, optional): Description defGrp (None, optional): Description Returns: TYPE: Description """ # Checkers if edgeLoop: edgeLoopList = [pm.PyNode(e) for e in edgeLoop.split(",")] else: pm.displayWarning("Please set the edge loop first") return if eyeMesh: try: eyeMesh = pm.PyNode(eyeMesh) except pm.MayaNodeError: pm.displayWarning("The object %s can not be found in the " "scene" % (eyeMesh)) return else: pm.displayWarning("Please set the eye mesh first") if doSkin: if not headJnt: pm.displayWarning("Please set the Head Jnt or unCheck " "Compute Topological Autoskin") return # Initial Data bboxCenter = meshNavigation.bboxCenter(eyeMesh) extr_v = meshNavigation.getExtremeVertexFromLoop(edgeLoopList, sideRange) upPos = extr_v[0] lowPos = extr_v[1] inPos = extr_v[2] outPos = extr_v[3] edgeList = extr_v[4] vertexList = extr_v[5] # Detect the side L or R from the x value if inPos.getPosition(space='world')[0] < 0.0: side = "R" inPos = extr_v[3] outPos = extr_v[2] normalPos = outPos npw = normalPos.getPosition(space='world') normalVec = npw - bboxCenter else: side = "L" normalPos = outPos npw = normalPos.getPosition(space='world') normalVec = bboxCenter - npw # Manual Vertex corners if customCorner: if intCorner: try: if side == "R": inPos = pm.PyNode(extCorner) else: inPos = pm.PyNode(intCorner) except pm.MayaNodeError: pm.displayWarning("%s can not be found" % intCorner) return else: pm.displayWarning("Please set the internal eyelid corner") return if extCorner: try: normalPos = pm.PyNode(extCorner) npw = normalPos.getPosition(space='world') if side == "R": outPos = pm.PyNode(intCorner) normalVec = npw - bboxCenter else: outPos = pm.PyNode(extCorner) normalVec = bboxCenter - npw except pm.MayaNodeError: pm.displayWarning("%s can not be found" % extCorner) return else: pm.displayWarning("Please set the external eyelid corner") return # Check if we have prefix: if namePrefix: namePrefix = string.removeInvalidCharacter(namePrefix) else: pm.displayWarning("Prefix is needed") return def setName(name, ind=None): namesList = [namePrefix, side, name] if ind is not None: namesList[1] = side + str(ind) name = "_".join(namesList) return name if pm.ls(setName("root")): pm.displayWarning("The object %s already exist in the scene. Please " "choose another name prefix" % setName("root")) return # Eye root eye_root = primitive.addTransform(None, setName("root")) eyeCrv_root = primitive.addTransform(eye_root, setName("crvs")) # Eyelid Main crvs try: upEyelid = meshNavigation.edgeRangeInLoopFromMid( edgeList, upPos, inPos, outPos) upCrv = curve.createCurveFromOrderedEdges(upEyelid, inPos, setName("upperEyelid"), parent=eyeCrv_root) upCrv_ctl = curve.createCurveFromOrderedEdges(upEyelid, inPos, setName("upCtl_crv"), parent=eyeCrv_root) pm.rebuildCurve(upCrv_ctl, s=2, rt=0, rpo=True, ch=False) lowEyelid = meshNavigation.edgeRangeInLoopFromMid( edgeList, lowPos, inPos, outPos) lowCrv = curve.createCurveFromOrderedEdges(lowEyelid, inPos, setName("lowerEyelid"), parent=eyeCrv_root) lowCrv_ctl = curve.createCurveFromOrderedEdges(lowEyelid, inPos, setName("lowCtl_crv"), parent=eyeCrv_root) pm.rebuildCurve(lowCrv_ctl, s=2, rt=0, rpo=True, ch=False) except UnboundLocalError: if customCorner: pm.displayWarning("This error is maybe caused because the custom " "Corner vertex is not part of the edge loop") pm.displayError(traceback.format_exc()) return upBlink = curve.createCurveFromCurve(upCrv, setName("upblink_crv"), nbPoints=30, parent=eyeCrv_root) lowBlink = curve.createCurveFromCurve(lowCrv, setName("lowBlink_crv"), nbPoints=30, parent=eyeCrv_root) upTarget = curve.createCurveFromCurve(upCrv, setName("upblink_target"), nbPoints=30, parent=eyeCrv_root) lowTarget = curve.createCurveFromCurve(lowCrv, setName("lowBlink_target"), nbPoints=30, parent=eyeCrv_root) midTarget = curve.createCurveFromCurve(lowCrv, setName("midBlink_target"), nbPoints=30, parent=eyeCrv_root) rigCrvs = [ upCrv, lowCrv, upCrv_ctl, lowCrv_ctl, upBlink, lowBlink, upTarget, lowTarget, midTarget ] for crv in rigCrvs: crv.attr("visibility").set(False) # localBBOX localBBox = eyeMesh.getBoundingBox(invisible=True, space='world') wRadius = abs((localBBox[0][0] - localBBox[1][0])) dRadius = abs((localBBox[0][1] - localBBox[1][1]) / 1.7) # Groups if not ctlGrp: ctlGrp = "rig_controllers_grp" try: ctlSet = pm.PyNode(ctlGrp) except pm.MayaNodeError: pm.sets(n=ctlGrp, em=True) ctlSet = pm.PyNode(ctlGrp) if not defGrp: defGrp = "rig_deformers_grp" try: defset = pm.PyNode(defGrp) except pm.MayaNodeError: pm.sets(n=defGrp, em=True) defset = pm.PyNode(defGrp) # Calculate center looking at averagePosition = ( (upPos.getPosition(space='world') + lowPos.getPosition(space='world') + inPos.getPosition(space='world') + outPos.getPosition(space='world')) / 4) if side == "R": negate = False offset = offset over_offset = dRadius else: negate = False over_offset = dRadius if side == "R" and sideRange or side == "R" and customCorner: axis = "z-x" # axis = "zx" else: axis = "z-x" t = transform.getTransformLookingAt(bboxCenter, averagePosition, normalVec, axis=axis, negate=negate) over_npo = primitive.addTransform(eye_root, setName("center_lookatRoot"), t) over_ctl = icon.create(over_npo, setName("over_%s" % ctlName), t, icon="square", w=wRadius, d=dRadius, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, over_offset), color=4) node.add_controller_tag(over_ctl) attribute.add_mirror_config_channels(over_ctl) attribute.setKeyableAttributes( over_ctl, params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"]) if side == "R": over_npo.attr("rx").set(over_npo.attr("rx").get() * -1) over_npo.attr("ry").set(over_npo.attr("ry").get() + 180) over_npo.attr("sz").set(-1) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=over_ctl) center_lookat = primitive.addTransform(over_ctl, setName("center_lookat"), t) # Tracking # Eye aim control t_arrow = transform.getTransformLookingAt(bboxCenter, averagePosition, upPos.getPosition(space='world'), axis="zy", negate=False) radius = abs((localBBox[0][0] - localBBox[1][0]) / 1.7) arrow_npo = primitive.addTransform(eye_root, setName("aim_npo"), t_arrow) arrow_ctl = icon.create(arrow_npo, setName("aim_%s" % ctlName), t_arrow, icon="arrow", w=1, po=datatypes.Vector(0, 0, radius), color=4) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=arrow_ctl) attribute.setKeyableAttributes(arrow_ctl, params=["rx", "ry", "rz"]) # tracking custom trigger if side == "R": tt = t_arrow else: tt = t aimTrigger_root = primitive.addTransform(center_lookat, setName("aimTrigger_root"), tt) aimTrigger_lvl = primitive.addTransform(aimTrigger_root, setName("aimTrigger_lvl"), tt) aimTrigger_lvl.attr("tz").set(1.0) aimTrigger_ref = primitive.addTransform(aimTrigger_lvl, setName("aimTrigger_ref"), tt) aimTrigger_ref.attr("tz").set(0.0) # connect trigger with arrow_ctl pm.parentConstraint(arrow_ctl, aimTrigger_ref, mo=True) # Controls lists upControls = [] trackLvl = [] # upper eyelid controls upperCtlNames = ["inCorner", "upInMid", "upMid", "upOutMid", "outCorner"] cvs = upCrv_ctl.getCVs(space="world") if side == "R" and not sideRange: # if side == "R": cvs = [cv for cv in reversed(cvs)] for i, cv in enumerate(cvs): if utils.is_odd(i): color = 14 wd = .5 icon_shape = "circle" params = ["tx", "ty", "tz"] else: color = 4 wd = .7 icon_shape = "square" params = [ "tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz" ] t = transform.setMatrixPosition(t, cvs[i]) npo = primitive.addTransform(center_lookat, setName("%s_npo" % upperCtlNames[i]), t) npoBase = npo if i == 2: # we add an extra level to input the tracking ofset values npo = primitive.addTransform(npo, setName("%s_trk" % upperCtlNames[i]), t) trackLvl.append(npo) ctl = icon.create(npo, setName("%s_%s" % (upperCtlNames[i], ctlName)), t, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color) attribute.add_mirror_config_channels(ctl) node.add_controller_tag(ctl, over_ctl) upControls.append(ctl) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=ctl) attribute.setKeyableAttributes(ctl, params) if side == "R": npoBase.attr("ry").set(180) npoBase.attr("sz").set(-1) # adding parent average contrains to odd controls for i, ctl in enumerate(upControls): if utils.is_odd(i): pm.parentConstraint(upControls[i - 1], upControls[i + 1], ctl.getParent(), mo=True) # lower eyelid controls lowControls = [upControls[0]] lowerCtlNames = [ "inCorner", "lowInMid", "lowMid", "lowOutMid", "outCorner" ] cvs = lowCrv_ctl.getCVs(space="world") if side == "R" and not sideRange: cvs = [cv for cv in reversed(cvs)] for i, cv in enumerate(cvs): # we skip the first and last point since is already in the uper eyelid if i in [0, 4]: continue if utils.is_odd(i): color = 14 wd = .5 icon_shape = "circle" params = ["tx", "ty", "tz"] else: color = 4 wd = .7 icon_shape = "square" params = [ "tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz" ] t = transform.setMatrixPosition(t, cvs[i]) npo = primitive.addTransform(center_lookat, setName("%s_npo" % lowerCtlNames[i]), t) npoBase = npo if i == 2: # we add an extra level to input the tracking ofset values npo = primitive.addTransform(npo, setName("%s_trk" % lowerCtlNames[i]), t) trackLvl.append(npo) ctl = icon.create(npo, setName("%s_%s" % (lowerCtlNames[i], ctlName)), t, icon=icon_shape, w=wd, d=wd, ro=datatypes.Vector(1.57079633, 0, 0), po=datatypes.Vector(0, 0, offset), color=color) attribute.add_mirror_config_channels(ctl) lowControls.append(ctl) if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost": pass else: pm.sets(ctlSet, add=ctl) attribute.setKeyableAttributes(ctl, params) # mirror behaviout on R side controls if side == "R": npoBase.attr("ry").set(180) npoBase.attr("sz").set(-1) for lctl in reversed(lowControls[1:]): node.add_controller_tag(lctl, over_ctl) lowControls.append(upControls[-1]) # adding parent average contrains to odd controls for i, ctl in enumerate(lowControls): if utils.is_odd(i): pm.parentConstraint(lowControls[i - 1], lowControls[i + 1], ctl.getParent(), mo=True) # Connecting control crvs with controls applyop.gear_curvecns_op(upCrv_ctl, upControls) applyop.gear_curvecns_op(lowCrv_ctl, lowControls) # adding wires w1 = pm.wire(upCrv, w=upBlink)[0] w2 = pm.wire(lowCrv, w=lowBlink)[0] w3 = pm.wire(upTarget, w=upCrv_ctl)[0] w4 = pm.wire(lowTarget, w=lowCrv_ctl)[0] # adding blendshapes bs_upBlink = pm.blendShape(upTarget, midTarget, upBlink, n="blendShapeUpBlink") bs_lowBlink = pm.blendShape(lowTarget, midTarget, lowBlink, n="blendShapeLowBlink") bs_mid = pm.blendShape(lowTarget, upTarget, midTarget, n="blendShapeLowBlink") # setting blendshape reverse connections rev_node = pm.createNode("reverse") pm.connectAttr(bs_upBlink[0].attr(midTarget.name()), rev_node + ".inputX") pm.connectAttr(rev_node + ".outputX", bs_upBlink[0].attr(upTarget.name())) rev_node = pm.createNode("reverse") pm.connectAttr(bs_lowBlink[0].attr(midTarget.name()), rev_node + ".inputX") pm.connectAttr(rev_node + ".outputX", bs_lowBlink[0].attr(lowTarget.name())) rev_node = pm.createNode("reverse") pm.connectAttr(bs_mid[0].attr(upTarget.name()), rev_node + ".inputX") pm.connectAttr(rev_node + ".outputX", bs_mid[0].attr(lowTarget.name())) # setting default values bs_mid[0].attr(upTarget.name()).set(blinkH) # joints root jnt_root = primitive.addTransformFromPos(eye_root, setName("joints"), pos=bboxCenter) # head joint if headJnt: try: headJnt = pm.PyNode(headJnt) jnt_base = headJnt except pm.MayaNodeError: pm.displayWarning("Aborted can not find %s " % headJnt) return else: # Eye root jnt_base = jnt_root eyeTargets_root = primitive.addTransform(eye_root, setName("targets")) eyeCenter_jnt = rigbits.addJnt(arrow_ctl, jnt_base, grp=defset, jntName=setName("center_jnt")) # Upper Eyelid joints ################################################## cvs = upCrv.getCVs(space="world") upCrv_info = node.createCurveInfoNode(upCrv) # aim constrain targets and joints upperEyelid_aimTargets = [] upperEyelid_jnt = [] upperEyelid_jntRoot = [] for i, cv in enumerate(cvs): # aim targets trn = primitive.addTransformFromPos(eyeTargets_root, setName("upEyelid_aimTarget", i), pos=cv) upperEyelid_aimTargets.append(trn) # connecting positions with crv pm.connectAttr(upCrv_info + ".controlPoints[%s]" % str(i), trn.attr("translate")) # joints jntRoot = primitive.addJointFromPos(jnt_root, setName("upEyelid_jnt_base", i), pos=bboxCenter) jntRoot.attr("radius").set(.08) jntRoot.attr("visibility").set(False) upperEyelid_jntRoot.append(jntRoot) applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root) jnt_ref = primitive.addJointFromPos(jntRoot, setName("upEyelid_jnt_ref", i), pos=cv) jnt_ref.attr("radius").set(.08) jnt_ref.attr("visibility").set(False) jnt = rigbits.addJnt(jnt_ref, jnt_base, grp=defset, jntName=setName("upEyelid_jnt", i)) upperEyelid_jnt.append(jnt) # Lower Eyelid joints ################################################## cvs = lowCrv.getCVs(space="world") lowCrv_info = node.createCurveInfoNode(lowCrv) # aim constrain targets and joints lowerEyelid_aimTargets = [] lowerEyelid_jnt = [] lowerEyelid_jntRoot = [] for i, cv in enumerate(cvs): if i in [0, len(cvs) - 1]: continue # aim targets trn = primitive.addTransformFromPos(eyeTargets_root, setName("lowEyelid_aimTarget", i), pos=cv) lowerEyelid_aimTargets.append(trn) # connecting positions with crv pm.connectAttr(lowCrv_info + ".controlPoints[%s]" % str(i), trn.attr("translate")) # joints jntRoot = primitive.addJointFromPos(jnt_root, setName("lowEyelid_base", i), pos=bboxCenter) jntRoot.attr("radius").set(.08) jntRoot.attr("visibility").set(False) lowerEyelid_jntRoot.append(jntRoot) applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root) jnt_ref = primitive.addJointFromPos(jntRoot, setName("lowEyelid_jnt_ref", i), pos=cv) jnt_ref.attr("radius").set(.08) jnt_ref.attr("visibility").set(False) jnt = rigbits.addJnt(jnt_ref, jnt_base, grp=defset, jntName=setName("lowEyelid_jnt", i)) lowerEyelid_jnt.append(jnt) # Channels # Adding and connecting attributes for the blink up_ctl = upControls[2] blink_att = attribute.addAttribute(over_ctl, "blink", "float", 0, minValue=0, maxValue=1) blinkMult_att = attribute.addAttribute(over_ctl, "blinkMult", "float", 1, minValue=1, maxValue=2) midBlinkH_att = attribute.addAttribute(over_ctl, "blinkHeight", "float", blinkH, minValue=0, maxValue=1) mult_node = node.createMulNode(blink_att, blinkMult_att) pm.connectAttr(mult_node + ".outputX", bs_upBlink[0].attr(midTarget.name())) pm.connectAttr(mult_node + ".outputX", bs_lowBlink[0].attr(midTarget.name())) pm.connectAttr(midBlinkH_att, bs_mid[0].attr(upTarget.name())) low_ctl = lowControls[2] # Adding channels for eye tracking upVTracking_att = attribute.addAttribute(up_ctl, "vTracking", "float", .02, minValue=0, maxValue=1, keyable=False, channelBox=True) upHTracking_att = attribute.addAttribute(up_ctl, "hTracking", "float", .01, minValue=0, maxValue=1, keyable=False, channelBox=True) lowVTracking_att = attribute.addAttribute(low_ctl, "vTracking", "float", .01, minValue=0, maxValue=1, keyable=False, channelBox=True) lowHTracking_att = attribute.addAttribute(low_ctl, "hTracking", "float", .01, minValue=0, maxValue=1, keyable=False, channelBox=True) mult_node = node.createMulNode(upVTracking_att, aimTrigger_ref.attr("ty")) pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("ty")) mult_node = node.createMulNode(upHTracking_att, aimTrigger_ref.attr("tx")) pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("tx")) mult_node = node.createMulNode(lowVTracking_att, aimTrigger_ref.attr("ty")) pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("ty")) mult_node = node.createMulNode(lowHTracking_att, aimTrigger_ref.attr("tx")) pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("tx")) # Tension on blink node.createReverseNode(blink_att, w1.scale[0]) node.createReverseNode(blink_att, w3.scale[0]) node.createReverseNode(blink_att, w2.scale[0]) node.createReverseNode(blink_att, w4.scale[0]) ########################################### # Reparenting ########################################### if parent: try: if isinstance(parent, basestring): parent = pm.PyNode(parent) parent.addChild(eye_root) except pm.MayaNodeError: pm.displayWarning("The eye rig can not be parent to: %s. Maybe " "this object doesn't exist." % parent) ########################################### # Auto Skinning ########################################### if doSkin: # eyelid vertex rows totalLoops = rigidLoops + falloffLoops vertexLoopList = meshNavigation.getConcentricVertexLoop( vertexList, totalLoops) vertexRowList = meshNavigation.getVertexRowsFromLoops(vertexLoopList) # we set the first value 100% for the first initial loop skinPercList = [1.0] # we expect to have a regular grid topology for r in range(rigidLoops): for rr in range(2): skinPercList.append(1.0) increment = 1.0 / float(falloffLoops) # we invert to smooth out from 100 to 0 inv = 1.0 - increment for r in range(falloffLoops): for rr in range(2): if inv < 0.0: inv = 0.0 skinPercList.append(inv) inv -= increment # this loop add an extra 0.0 indices to avoid errors for r in range(10): for rr in range(2): skinPercList.append(0.0) # base skin geo = pm.listRelatives(edgeLoopList[0], parent=True)[0] # Check if the object has a skinCluster objName = pm.listRelatives(geo, parent=True)[0] skinCluster = skin.getSkinCluster(objName) if not skinCluster: skinCluster = pm.skinCluster(headJnt, geo, tsb=True, nw=2, n='skinClsEyelid') eyelidJoints = upperEyelid_jnt + lowerEyelid_jnt pm.progressWindow(title='Auto skinning process', progress=0, max=len(eyelidJoints)) firstBoundary = False for jnt in eyelidJoints: pm.progressWindow(e=True, step=1, status='\nSkinning %s' % jnt) skinCluster.addInfluence(jnt, weight=0) v = meshNavigation.getClosestVertexFromTransform(geo, jnt) for row in vertexRowList: if v in row: it = 0 # iterator inc = 1 # increment for i, rv in enumerate(row): try: perc = skinPercList[it] t_val = [(jnt, perc), (headJnt, 1.0 - perc)] pm.skinPercent(skinCluster, rv, transformValue=t_val) if rv.isOnBoundary(): # we need to compare with the first boundary # to check if the row have inverted direction # and offset the value if not firstBoundary: firstBoundary = True firstBoundaryValue = it else: if it < firstBoundaryValue: it -= 1 elif it > firstBoundaryValue: it += 1 inc = 2 except IndexError: continue it = it + inc pm.progressWindow(e=True, endProgress=True) # Eye Mesh skinning skinCluster = skin.getSkinCluster(eyeMesh) if not skinCluster: skinCluster = pm.skinCluster(eyeCenter_jnt, eyeMesh, tsb=True, nw=1, n='skinClsEye')
selection = pm.selected() for ctrl in selection: # Test whether the element is a controller try: pm.getAttr(str(ctrl) + ".childJoint") except: continue else: pm.xform(ctrl, translation=[0, 0, 0], rotation=[0, 0, 0], objectSpace=True) constraints = pm.listRelatives(ctrl, children=True, type=('orientConstraint', 'parentConstraint')) for constraint in constraints: parents = pm.listConnections(constraint, source=True, type='transform') ctrlParent = None for parent in parents: if str(parent) != ctrl and str(parent) != str(constraint): ctrlParent = parent break pm.parentConstraint(str(ctrlParent), str(constraint), e=True, maintainOffset=True)
pm.joint(i, edit = True, orientJoint = 'xyz', secondaryAxisOrient = 'zup', zeroScaleOrient = True) #orienting joint so it move appropriately from UpperArm2 pm.select(deselect = True) for i in jointList: #selecting joints pm.select(i, add = True) pm.parent(pm.ls(sl = True), mantleParent) #calc calcList = [] mantGroup = pm.group(name = 'mantleGroup', world = True, empty = True)#creating calc joints for i in pm.listRelatives(mantleParent): cal = pm.duplicate(i, name = i[:7] + '_Calc', parentOnly = True) pm.parent(cal, mantGroup) spaceLoc = pm.spaceLocator(name = 'simLoc_' + i[5:])#creating simloc locator pm.xform(spaceLoc, ws = True, translation = pm.xform(i, query = True, translation = True, ws = True))#moving it to the right place pm.xform(spaceLoc, relative = True, translation = [0, -25.627, 0]) pm.addAttr(spaceLoc, longName = 'momentumX', attributeType = 'float') pm.addAttr(spaceLoc, longName = 'momentumY', attributeType = 'float') pm.addAttr(spaceLoc, longName = 'momentumZ', attributeType = 'float') #creating expression to drive the SimLoc's translations pm.expression(object = spaceLoc, name = spaceLoc + '_translationExp', string = '$f = `currentTime -q`;\n$lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n%s.translateX = %s.translateX - (%s.translateX - $lastposX);\n$lastposY = `getAttr -t ($f - mantle_Control.Drag) %s.translateY`;\n%s.translateY = %s.translateY - (%s.translateY - $lastposY) - 25.627;\n$lastposZ = `getAttr -t ($f - mantle_Control.Drag) %s.translateZ`;\n%s.translateZ = %s.translateZ - (%s.translateZ - $lastposZ);' %(cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0], cal[0], spaceLoc, cal[0], cal[0])) ''' '$f = `currentTime -q`;\n $lastposX = `getAttr -t ($f - mantle_Control.Drag) %s.translateX`;\n %s.translateX = %s.translateX - (%s.translateX - $lastposX);\n
def __init__(self, **kwds): self.name = defaultReturn('rig_measure', 'name', param=kwds) self.start = defaultReturn(None, 'start', param=kwds) self.end = defaultReturn(None, 'end', param=kwds) self.parent = defaultReturn(None, 'parent', param=kwds) startConstrainer = self.start endConstrainer = self.end self.start = rig_transform( 0, name=self.name+'Start', type='locator', target=self.start ).object self.end = rig_transform( 0, name=self.name+'End', type='locator', target=self.end ).object pm.move(self.end, 0, 10, 0, r=True, os=True) #startAttr = pm.getAttr( self.start+'.translate' ) startAttr = pm.xform(self.start, translation=True, query=True, ws=True) #endAttr = pm.getAttr( self.end+'.translate' ) endAttr = pm.xform(self.end, translation=True, query=True, ws=True) self.shape = pm.distanceDimension(sp=startAttr, ep=endAttr) pm.move(self.end, 0, -10, 0, r=True, os=True) pm.rename(self.shape, self.name+'_distanceShape') self.distance = pm.rename(pm.listRelatives(self.shape, p=True)[0], self.name+'_distance') pm.pointConstraint( startConstrainer , self.start ) pm.pointConstraint( endConstrainer , self.end ) self.distanceVal = pm.getAttr(self.distance.distance) pm.addAttr(self.distance, longName='originalLength', at='float', k=True, dv=self.distanceVal ) self.distance.originalLength.set(cb=True) pm.addAttr(self.distance, longName='globalOriginalLength', at='float', k=True, dv=self.distanceVal) self.distance.globalOriginalLength.set(cb=True) pm.addAttr(self.distance, longName='originalPercent', at='float', k=True, dv=1) self.distance.originalPercent.set(cb=True) pm.addAttr(self.distance, longName='globalOriginalPercent', at='float', k=True, dv=1) self.distance.globalOriginalPercent.set(cb=True) ''' measurePnct = multiplyDivideNode(self.name + '_measurepcnt', 'divide', input1=[self.distance.distance,self.distance.distance, 1], input2=[self.distance.originalLength,self.distance.globalOriginalLength, 1], output=[self.distance.originalPercent, self.distance.globalOriginalPercent]) ''' measurePnct = multiplyDivideNode(self.name + '_measurepcnt', 'divide', input1=[self.distance.distance, self.distance.distance, 1], input2=[1, 1, 1], output=[self.distance.originalPercent, self.distance.globalOriginalPercent]) # make 0.001 the minimum originalMin_con = conditionNode(self.name + '_origZeroMin', 'equal', (self.distance, 'originalLength' ), ('', 0 ), ( '', 0.001 ), ( self.distance, 'originalLength' )) globalOriginalMin_con = conditionNode(self.name + '_globalOrigZeroMin', 'equal', (self.distance, 'globalOriginalLength' ), ('', 0 ), ( '', 0.001 ), ( self.distance, 'globalOriginalLength' )) pm.connectAttr( originalMin_con+'.outColorR', measurePnct+'.input2X' ) pm.connectAttr( globalOriginalMin_con + '.outColorR', measurePnct + '.input2Y') if pm.objExists('rig_GRP'): multiplyDivideNode(self.name + '_globalOriginalLength', 'multiply', input1=[self.distance.originalLength, 0, 0], input2=['rig_GRP.worldScale', 0, 0], output=[self.distance.globalOriginalLength]) if pm.objExists(self.parent): pm.parent( self.distance, self.start, self.end ,self.parent )
def orient_joint(**kwargs): """ Orient the joint @param kwargs: Takes the following keyword arguments - joint (node): the node which will be process. It picks up the default node by default - up (str): in which direction do move up and down the joint - forward (str): in which direction do you want to move it forward/back - flip_forward (bool): whether the joint forward direction will be reversed - flip up (bool): whether the joint up and down will be reversed - details (bool) @return the rotate order """ # Get all the keyword arguements selection = pm.selected() or [] try: target_joint = libUtilities.force_pynode(kwargs.get("joint") or pm.selected()[0]) except IndexError: pm.confirmDialog(title="User Error", message="{: <22}".format("Please select a joint"), icon="critical") return up = kwargs.get("up", "y").lower() forward = kwargs.get("forward", "z").lower() flip_forward = kwargs.get("flip_forward", False) flip_up = kwargs.get("flip_up", False) details = kwargs.get("details", False) # Get the preferred rotation axis prefered_axis = "{}{}".format(up, forward) # Get the joint mapping data reverse_lookup, rotate_secondary_axis, detailed_info = _get_joint_orient_info() rotate_order = reverse_lookup[prefered_axis] pm.undoInfo(openChunk=True) children_joints = get_joint_children(target_joint) libUtilities.freeze_rotation([target_joint] + children_joints) libUtilities.freeze_scale([target_joint] + children_joints) secondary_orient = rotate_secondary_axis[rotate_order] if children_joints: if flip_forward: secondary_orient = secondary_orient.replace("up", "down") pm.joint(target_joint, edit=True, zeroScaleOrient=True, children=True, orientJoint=rotate_order, secondaryAxisOrient=secondary_orient) if flip_up: joints = [target_joint] if len(children_joints) > 1: joints = reversed(joints + children_joints[:-1]) for flip_joint in joints: childJoint = pm.listRelatives(flip_joint)[0] childJoint.setParent(world=True) flip_joint.attr('r{}'.format(forward)).set(180) libUtilities.freeze_rotation([flip_joint]) libUtilities.freeze_scale([flip_joint]) childJoint.setParent(flip_joint) children_joints[-1].jointOrient.set(0, 0, 0) if details: for key in ["Pitch/Bend Forward", "Yaw/Twist", "Forward", "Up"]: print "{} : {}".format(key, detailed_info[rotate_order][key]) if flip_up: print "The joint chain was flipped up in the end" pm.select(selection) all_joints = [target_joint] + children_joints # Calculate the last axis to resolves last_axis = (set("xyz") - set(prefered_axis)).pop() preferred_rotate_order = "{}{}{}".format(last_axis, forward, up) # Set the rotate order set_rotate_order(preferred_rotate_order, all_joints) pm.undoInfo(closeChunk=True) return preferred_rotate_order
def create_editable_joints(): """ Create a proxy skeleton that can be used to edit bound joint positions. """ selection = pm.ls(sl=True, type='transform') if len(selection) == 0: log.info('Select one or more root joints') return # Get the hierarchy of all selected nodes. bind_joints = [] for node in selection: bind_joints.append(node) bind_joints.extend(pm.listRelatives(node, ad=True)) # Order them parents-first. This will also remove any duplicates. bind_joints = _get_nodes_depth_first(bind_joints) any_errors = False for bind_joint in bind_joints: if om.MVector(bind_joint.rotate.get()).length() > 0.0001: log.error('Joint %s has nonzero rotations', bind_joint.nodeName()) any_errors = True # Make sure that all joints are in bind position for all skinClusters they're # connected to. bind_joint_skin_cluster_attrs = _get_skin_cluster_attrs_for_joint( bind_joint) for skin_cluster_attr in bind_joint_skin_cluster_attrs: # Get this joint's bindPreMatrix on this skinCluster, and make sure that it's # the same as the current world matrix's inverse. skin_cluster = skin_cluster_attr.node() skin_cluster_idx = skin_cluster_attr.index() bind_pre_matrix = pm.datatypes.Matrix( skin_cluster.bindPreMatrix[skin_cluster_idx].get()) world_inverse_matrix = pm.datatypes.Matrix( bind_joint.worldInverseMatrix.get()) if not bind_pre_matrix.isEquivalent(world_inverse_matrix, tol=0.0001): log.error('Joint %s isn\'t in bind position', bind_joint.nodeName()) any_errors = True if any_errors: return _fix_skin_cluster_disconnection() # Create a top-level group to hold everything. edit_container = pm.createNode('transform', n='EditJoints') edit_container.inheritsTransform.set(False) _lock_transform(edit_container) bind_joint_to_edit_joint = {} for bind_joint in bind_joints: # If this isn't a joint, and it has no DAG children, skip it. This prevents # duplicating things like constraints, which is harmless but can be confusing. if not isinstance(bind_joint, pm.nodetypes.Joint) and len( bind_joint.getChildren()) == 0: continue # Duplicate the transform, without its its hierarchy or any shape nodes inside it. edit_joint = pm.duplicate(bind_joint, parentOnly=True)[0] pm.rename(edit_joint, 'Edit_%s' % bind_joint.nodeName()) edit_joint.visibility.set(True) bind_joint_to_edit_joint[bind_joint] = edit_joint # Place it in the corresponding parent. bind_joint_parent = bind_joint.getParent() edit_joint_parent = bind_joint_to_edit_joint.get(bind_joint_parent) if not edit_joint_parent: # If this joint's parent isn't in bind_joints, create a parent matching the joint's # parent, to match the joint's coordinate space. assert bind_joint_parent not in bind_joints edit_joint_parent = pm.createNode('transform', n='EditJoints_%s' % bind_joint.nodeName(), p=edit_container) _lock_transform(edit_joint_parent) pm.xform(edit_joint_parent, ws=True, m=pm.xform(bind_joint_parent, q=True, ws=True, m=True)) pm.parent(edit_joint, edit_joint_parent, r=True) # If this isn't a joint, we're just copying it to match the transformation # hierarchy and won't edit it. Lock its transform properties and don't do anything # else with it. if not isinstance(edit_joint, pm.nodetypes.Joint): _lock_transform(edit_joint) continue # The two skeletons are in the same place, and since we're binding to world space # transforms we can't put the edit skeleton off to the side. Increase the joint # radius slightly so they don't draw exactly on top of each other. Set an object # color, too. edit_joint.radius.set(edit_joint.radius.get() * 1.25) edit_joint.useObjectColor.set(True) edit_joint.objectColor.set(7) joint_matrix_before_edits = pm.datatypes.Matrix( pm.xform(edit_joint, q=True, ws=True, m=True)) # Transfer the joint's rotation from jointOrient to rotate. edit_joint.rotate.set(edit_joint.jointOrient.get()) edit_joint.jointOrient.set((0, 0, 0)) # jointOrient is always in rotate order XYZ, not the transform's rotateOrder, so # change the joint's rotateOrder to xyz. edit_joint.rotateOrder.set(0) # Lock transform properties that shouldn't be edited. Editing these would modify # the matrix we're sending to the skinCluster without making a corresponding change # to the joint. for attr in ('scale', 'rotateOrder', 'rotateAxis', 'jointOrient'): edit_joint.attr(attr).set(lock=True) joint_matrix_after_edits = pm.datatypes.Matrix( pm.xform(edit_joint, q=True, ws=True, m=True)) # Verify that our changes to the edit joint retained the same world matrix. assert joint_matrix_before_edits.isEquivalent(joint_matrix_after_edits) # When we duplicate a joint, its inverseScale is connected to its nearest ancestor joint's # scale, not whatever the joint we duplicated had its inverseScale set to. It usually gives # the same connection, but doesn't have to, which can make our duplicated joint's segment # scale compensate behave differently. We don't want this connected anyway, since any # scale changes are caused by animation and shouldn't apply to the edit joints. Just # disconnect any inverseScale connection, and set its value to the same value as the bind # joint. conns = pm.listConnections(edit_joint.inverseScale, s=True, d=False, p=True) if conns: conns[0].disconnect(edit_joint.inverseScale) edit_joint.inverseScale.set(bind_joint.inverseScale.get()) # Editing the edit joint's translation changes the bind joint's translation. # If any part of translation is connected or locked on the joint, lock it on # the edit joint. if bind_joint.translate.isConnected() or bind_joint.translate.isLocked( ): edit_joint.translate.set(lock=True) else: for attr in ('tx', 'ty', 'tz'): _connect_or_lock(edit_joint.attr(attr), bind_joint.attr(attr)) # Editing rotation changes its jointOrient. _connect_or_lock(edit_joint.rotate, bind_joint.jointOrient) bind_joint_skin_cluster_attrs = _get_skin_cluster_attrs_for_joint( bind_joint) for skin_cluster_attr in bind_joint_skin_cluster_attrs: skin_cluster = skin_cluster_attr.node() skin_cluster_idx = skin_cluster_attr.index() bind_pre_matrix = pm.datatypes.Matrix( skin_cluster.bindPreMatrix[skin_cluster_idx].get()) world_inverse_matrix = pm.datatypes.Matrix( bind_joint.worldInverseMatrix.get()) # Moving the edit joint around edits the bind position of the bind joint. edit_joint.worldInverseMatrix.connect( skin_cluster.bindPreMatrix[skin_cluster_idx]) pm.select(edit_container) return edit_container
def rp_surface(): """..............................................................................................//""" ncj = int(pm.intField('NCJ', q=1, v=1)) # > control joints rn = float(pm.intField('NJ', q=1, v=1)) bz = int(pm.checkBoxGrp('CTJP', q=1, v1=1)) s = pm.ls(sl=1) rp_check(s) if pm.objExists(s[0] + "_surface"): rp_del() rp_cr() cj = pm.ls((s[0] + "_ctj_*"), typ="joint") x = 0.0 if pm.optionMenuGrp('AXES', q=1, v=1) == "x": x = float(1) y = 0.0 if pm.optionMenuGrp('AXES', q=1, v=1) == "y": y = float(1) z = 0.0 if pm.optionMenuGrp('AXES', q=1, v=1) == "z": z = float(1) su = pm.extrude(s[0], upn=0, dl=3, ch=bz, d=(x, y, z), n=(s[0] + "_surface"), et=0, rn=0, po=0) pm.pm.cmds.move(((-1) * (x / 2)), ((-1) * (y / 2)), ((-1) * (z / 2)), su[0]) pm.makeIdentity(su[0], a=1, t=1) sj = pm.ls((s[0] + "_tw_*"), typ="joint") # pivot move t = (pm.xform(cj[0], q=1, ws=1, t=1)) pm.setAttr((su[0] + ".rpx"), (t.x)) pm.setAttr((su[0] + ".rpy"), (t.y)) pm.setAttr((su[0] + ".rpz"), (t.z)) pm.setAttr((su[0] + ".spx"), (t.x)) pm.setAttr((su[0] + ".spy"), (t.y)) pm.setAttr((su[0] + ".spz"), (t.z)) # hairs hsys = str(pm.createNode("hairSystem", n=(s[0] + "_position"))) hsysg = pm.listRelatives(hsys, p=1) pm.rename(hsysg[0], (s[0] + "_surface_grp_")) pm.select(su[0], hsys) pm.mel.createHair((len(sj)), 1, 2, 0, 0, 1, 1, 1, 0, 2, 2, 1) pm.delete((s[0] + "_surface_grp_"), (s[0] + "_surface_grp_OutputCurves")) # joints sg = pm.listRelatives((s[0] + "_surface_grp_Follicles"), c=1) pm.delete(s[0] + "_tw_hl") for i in range(0, (len(sj))): pm.parent(sj[i], sg[i]) pm.makeIdentity(sj[i], a=1, r=1) pm.connectAttr((s[0] + "_rig.s"), (sg[i] + ".s"), f=1) pm.parent(su[0], (s[0] + "_sistem")) pm.parent((s[0] + "_surface_grp_Follicles"), (s[0] + "_sistem")) # conection scale joints if bz == 0: if pm.checkBoxGrp('CTJ', q=1, v1=1): for i in range(0, (len(cj))): pm.disconnectAttr((s[0] + "_" + str((i + 1)) + "_CT.change"), (cj[i] + ".sy")) pm.disconnectAttr((s[0] + "_" + str((i + 1)) + "_CT.change"), (cj[i] + ".sz")) pm.delete((s[0] + "_sx"), (s[0] + "_s")) sx = str(pm.createNode('multiplyDivide', n=(s[0] + "_pow"))) # pow scale pm.setAttr((sx + ".op"), 2) pm.connectAttr((s[0] + "_rig.s"), (sx + ".i2"), f=1) pm.setAttr((sx + ".i1x"), 1) pm.setAttr((sx + ".i1y"), 1) pm.setAttr((sx + ".i1z"), 1) pm.connectAttr((sx + ".o"), (s[0] + "_surface_grp_Follicles.s"), f=1) # > skin fol = pm.ls((s[0] + "_surfaceFollicle*"), typ="transform") for i in range(0, (len(fol))): pm.setAttr((fol[i] + ".it"), 0) if bz == 0: pm.rebuildSurface(su[0], dv=1, du=3, sv=0, su=rn) pm.intField('NJ', e=1, v=rn) pm.skinCluster(cj, su[0], mi=2, rui=1, dr=2.0, n=(s[0] + "_skin_surface")) pm.setAttr((su[0] + ".it"), 0) pm.setAttr((su[0] + ".tmp"), 1) # > end pm.select(s[0])