def clampInfluences(self, mesh, maxInf, debug=0, force=False): ''' Sets max influences on skincluster of mesh / cutting off smallest ones ''' skinClust = self.findRelatedSkinCluster(mesh) lockedInfluences = self.checkLockedInfluences(skinClust) doit = True if lockedInfluences: if force: self.unlockLockedInfluences(skinClust) cmds.warning('Locked influences were unlocked on skinCluster') else: doit = False if doit: verts = self.checkMaxSkinInfluences(mesh, maxInf) print 'pruneVertWeights>> Pruning', len(verts), 'vertices' for v in verts: infs = cmds.skinPercent(skinClust, (mesh + ".vtx[" + str(v) + "]"), q=1, v=1) active = [] for inf in infs: if inf > 0.0: active.append(inf) active = list(reversed(sorted(active))) if debug: print 'Clamping vertex', v, 'to', active[maxInf] cmds.skinPercent(skinClust, (mesh + ".vtx[" + str(v) + "]"), pruneWeights=(active[maxInf]*1.001)) else: cmds.warning('Cannot clamp influences due to locked weights on skinCluster')
def doIt(self, argList): # get only the first object from argument list try: obj = misc.getArgObj(self.syntax(), argList)[0] except: cmds.warning("No object selected!") return if (cmds.objectType(obj) != 'transform'): cmds.error("Object is not of type transform!") return # get and cast array of MPoint-Objects to list structure (needed for ConvexHull) pSet = list([p.x, p.y, p.z] for p in misc.getPoints(obj)) # execute delaunay triangulation algorithm on point set of current object hull = Delaunay(pSet) # delaunay-triangulated tetrahedra are not ordered --> make sure implicit normal points outwards of each tetrahedra for tetra in hull.points[hull.simplices]: center = map(operator.add, map(operator.add, tetra[0], tetra[1]), map(operator.add, tetra[2], tetra[3])) center = map(operator.div, center, [4.0]*3) # check if tetrahedron is oriented in wrong direction (normals should point away from center) v1 = map(operator.sub, tetra[0], tetra[1]) v2 = map(operator.sub, tetra[0], tetra[2]) # check dot product: if smaller 0, swap vertices 0 and 2 if (np.dot(np.cross(v1, v2), map(operator.sub, tetra[0], center) ) > 0): # swap 0 and 2 tetra[[0,2]] = tetra[[2,0]] self.appendToResult(str(tetra.flatten().tolist())[1:-1])
def printCurvePoints(): """ Use: For printing to the console or write out to a file, the points of a new custom curve. This can be added to the curve Dictionary for quickly building more curves for all rigging tools using the curve Dictionary. @param toFile: if you would like to output the points to a text file in your home folder or not @type toFile: Boolean """ curvePoints = [] curSel = cmds.ls(sl = True) if not curSel: cmds.warning('Nothing selected for export.') pass else: for nurbsCurve in curSel: getDegree = cmds.getAttr(nurbsCurve + '.degree') getSpans = cmds.getAttr(nurbsCurve + '.spans') numPoints = int(getDegree) + int(getSpans) for x in range (numPoints): getWS = cmds.xform(nurbsCurve + '.cv[%s]' % x, query = True, t = True, ws = True) tempVar = [] for p in getWS: tempVar.append("{0:.2f}".format(p)) curvePoints.append(tempVar) tempVar = [] numKnots = numPoints + getDegree -1 sys.stdout.write('cmds.curve(name = "' + str(curSel[0]) + '", d = ' + str(getDegree) + ', p = ' + str(curvePoints) + ')')
def mtt_log(msg, add_tag=None, msg_type=None, verbose=True): """ Format output message '[TAG][add_tag] Message content' :param msg: (string) message content :param add_tag: (string or list) add extra tag to output :param msg_type: define message type. Accept : None, 'warning', 'error' :param verbose: (bool) enable headsUpMessage output """ # define tags tag_str = '[MTT]' # append custom tags if add_tag: if not isinstance(add_tag, list): add_tag = [add_tag] for tag in add_tag: tag_str += '[%s]' % tag.upper() # output message the right way if msg_type == 'warning': cmds.warning('%s %s' % (tag_str, msg)) elif msg_type == 'error': cmds.error('%s %s' % (tag_str, msg)) else: print '%s %s\n' % (tag_str, msg), if verbose and MTTSettings.value('showHeadsUp'): cmds.headsUpMessage(msg)
def _get_recommended_pivot_bank(self, geometries, tm_ref, tm_ref_dir, pos_toes, direction=1): """ Determine recommended position using ray-cast from the toes. TODO: If the ray-case fail, use a specified default value. return: The recommended position as a world pymel.datatypes.Vector """ # Sanity check, ensure that at least one point is in the bounds of geometries. # This can prevent rays from being fired from outside a geometry. # TODO: Make it more robust. filtered_geometries = [] for geometry in geometries: xmin, ymin, zmin, xmax, ymax, zmax = cmds.exactWorldBoundingBox(geometry.__melobject__()) bound = pymel.datatypes.BoundingBox((xmin, ymin, zmin), (xmax, ymax, zmax)) if bound.contains(pos_toes): filtered_geometries.append(geometry) dir = pymel.datatypes.Point(direction, 0, 0) * tm_ref_dir pos = libRigging.ray_cast_nearest(pos_toes, dir, filtered_geometries) if not pos: cmds.warning("Can't automatically solve FootRoll bank inn pivot.") pos = pos_toes pos.y = 0 return pos
def buildOceanNurbsPreviewPlane(xRes = 20, zRes = 20, size = 8, oceanShader = '', boatName = ''): """ Creates NURBS plane that moves along with ocean so we can intersect this with our boatName to create the emitter curves """ debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'Building NURBS Intersection plane now', verbose = False) if cmds.objExists('%s_NurbsIntersect_geo' % boatName): cmds.warning('Skipping %s_NurbsIntersect. Already exists in the scene!' % boatName) debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'Skipping %s_NurbsIntersect. Already exists in the scene!' % boatName, verbose = False) else: NURBSPlane = cmds.nurbsPlane( width=1,lengthRatio = 1,degree = 1, patchesU=xRes, patchesV=zRes, axis = (0,1,0) , constructionHistory = 0, name = '%s_NurbsIntersect_geo' % boatName) debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'Built NURBSPlane: %s' % NURBSPlane, verbose = False) ## Now set the attrs of the NURBSPlane cmds.setAttr ( "%s.rotate" % NURBSPlane[0], lock= True) cmds.setAttr ("%s.scaleY" % NURBSPlane[0], lock= True) cmds.setAttr ("%s.scaleX" % NURBSPlane[0], size) cmds.setAttr ("%s.scaleZ" % NURBSPlane[0], size) cmds.setAttr ( "%s.translateY" % NURBSPlane[0] , lock= True) #cmds.setAttr (NURBSPlane[0] + ".visibility",0) cmds.setAttr ("%s.primaryVisibility" % NURBSPlane[0],0) cmds.setAttr ("%s.visibleInReflections" % NURBSPlane[0],0) cmds.setAttr ("%s.visibleInRefractions" % NURBSPlane[0],0) debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'All Attrs set correctly', verbose = False) ## Cleanup the build _cleanupNURBSPlane(NURBSPlane, boatName) debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'Cleanup Performed Successfully', verbose = False) ## Build the expression _buildNURBSPlaneExpression(NURBSPlane, xRes, zRes, oceanShader) debug(None, method = 'buildOceanNurbsPreviewPlane', message = 'Expression Built Successfully', verbose = False)
def keyToOn(): controller = mc.ls(sl=True)[0] channelBox = mel.eval('global string $gChannelBoxName; $temp=$gChannelBoxName;') #fetch maya's main channelbox attrs = mc.channelBox(channelBox, q=True, sma=True) if attrs: channel = controller + "." + attrs[0] constraint = mc.listConnections(channel, type="constraint")[0] currentTime = mc.currentTime( query=True ) # save rest pose on constraint # mc.currentTime(currentTime-1) constraintChannels = mc.listConnections(constraint, type="animCurve") mc.parentConstraint(controller, constraint, edit=True, maintainOffset=True) for i in constraintChannels: value = mc.getAttr(mc.listConnections(i, plugs=True)[0]) setKeyframe(mc.listConnections(i, plugs=True)[0], currentTime, value) # set key on 1 for controller setKeyframe(channel, currentTime-1, value=0) setKeyframe(channel, currentTime, value=1) # mc.currentTime( currentTime ) else: mc.warning("Select constrain channel!")
def copy_user_attr(selparentshapes, seltargetshapes, copyUV=True): listattrvalue = {} listdatatype = {} userattr = cmds.listAttr(selparentshapes, ud=True) if copyUV and cmds.nodeType(seltargetshapes) == 'mesh' and cmds.nodeType(selparentshapes) == 'mesh': cmds.transferAttributes(selparentshapes, seltargetshapes, transferUVs=1, transferColors=2, searchMethod=3, sampleSpace=5, flipUVs=False) if userattr: for attr in userattr: nodetype = cmds.nodeType(selparentshapes) checkrendershape = cmds.getAttr(selparentshapes + '.intermediateObject') if checkrendershape != 1 or nodetype != 'mesh': key = attr value = cmds.getAttr("%s.%s" % (selparentshapes, key)) data = cmds.getAttr("%s.%s" % (selparentshapes, key), typ=True) listattrvalue[key] = value listdatatype[key] = data checkrendershape = cmds.getAttr(seltargetshapes + '.intermediateObject') if checkrendershape != 1: for key in listattrvalue: if not cmds.attributeQuery(key, node=seltargetshapes, ex=True): if listdatatype[key] == 'string': cmds.addAttr(seltargetshapes, longName=key, dataType=listdatatype[key]) cmds.setAttr("%s.%s" % (seltargetshapes, key), listattrvalue[key], type=listdatatype[key]) else: cmds.addAttr(seltargetshapes, longName=key) cmds.setAttr("%s.%s" % (seltargetshapes, key), listattrvalue[key]) else: cmds.warning('Attribute ' + key + ' already on ' + seltargetshapes) if cmds.getAttr("%s.%s" % (seltargetshapes, key), se=True): if listdatatype[key] == 'string': cmds.setAttr("%s.%s" % (seltargetshapes, key), listattrvalue[key], type=listdatatype[key]) else: cmds.setAttr("%s.%s" % (seltargetshapes, key), listattrvalue[key])
def saveFileToPublish(self): self.currentFilePath = cmds.file(q=1, sn=1) if self.currentFilePath: if '/work/' in self.currentFilePath: self.baseName = os.path.basename(self.currentFilePath) self.publishPath = self.currentFilePath.split(self.baseName)[0].replace('/work/', '/publish/') self.publishFilePath = os.path.join(self.publishPath, self.baseName) if os.listdir(self.publishPath): fileName = sorted(os.listdir(self.publishPath))[-1].replace('.ma', '.mb') newPublishFilePath = os.path.join(self.publishPath, fileName) curVersion = os.path.splitext(fileName)[0].split('.v')[-1] newVersion = int(curVersion) + 1 newVersionStr = '.v%03d' % newVersion self.publishFilePath = newPublishFilePath.replace('.v%03d' % int(curVersion), newVersionStr) cmds.file(f=1, save=1) cmds.file(rename=self.publishFilePath) cmds.file(f=1, save=1, type = 'mayaBinary') cmds.file(self.currentFilePath, f=1, open=1) return self.publishFilePath else: fileName = self.baseName.replace('.ma', '.mb') newPublishFilePath = os.path.join(self.publishPath, fileName) self.publishFilePath = newPublishFilePath cmds.file(f=1, save=1) cmds.file(rename=self.publishFilePath) cmds.file(f=1, save=1, type = 'mayaBinary') cmds.file(self.currentFilePath, f=1, open=1) return self.publishFilePath else: cmds.confirmDialog(m="File is not in work directory.. Kindly save your file in work directory and run this script", b="Ok") else: cmds.warning('Cannot find proper file. Please save our file and proceed....')
def doIt(self, argList): # get objects from argument list (size >= 2) try: obj = misc.getArgObj(self.syntax(), argList) if (len(obj) < 2): cmds.error("Select at least 2 objects!") return if (cmds.objectType(obj[0]) != 'transform' or cmds.objectType(obj[1]) != 'transform'): cmds.error("Object is not of type transform!") return except: cmds.warning("No objects selected or only one object given!") return argData = om.MArgParser(self.syntax(), argList) # read all arguments and set default values keepCD = argData.flagArgumentBool('keepConvexDecomposition', 0) if (argData.isFlagSet('keepConvexDecomposition')) else True nvol = argData.flagArgumentDouble('normVolume', 0) if ( argData.isFlagSet('normVolume')) else 100.0 norm = argData.flagArgumentBool('norm', 0) if ( argData.isFlagSet('norm')) else True s_file = os.path.abspath(argData.flagArgumentString('saveFile', 0)) if (argData.isFlagSet('saveFile')) else "" save = False if s_file != "": o_file = open(s_file, 'w') o_file.write("i0, i1, name0, name1, its_volume, dice\n") save = True # get all flags for vhacd over static parsing method vhacd_par = vhacd.vhacd.readArgs(argData) if (vhacd_par is None): cmds.error("V-HACD: one or more arguments are invalid!") return #norm the volume if norm: for o in obj: v = cmds.getVolume(o) scale_factor = (nvol/ v) ** (1./3) # cmds.xform(o, scale=[scale_factor, scale_factor, scale_factor]) cmds.scale(scale_factor, scale_factor, scale_factor, o, relative=True) cmds.makeIdentity(o, apply=True) intersection_matrix = np.matrix(str(cmds.intersection(obj, kcd=keepCD, matlabOutput=True, **vhacd_par))) dice_matrix = np.matrix(intersection_matrix) for i in range(0, intersection_matrix.shape[0]): for j in range(i, intersection_matrix.shape[1]): its_volume = intersection_matrix[i, j] dice_matrix[i, j] = (its_volume*2)/(intersection_matrix[i, i]+intersection_matrix[j, j]) if save: o_file.write(",".join((str(i), str(j), obj[i], obj[j], str(its_volume), str(dice_matrix[i, j])))) o_file.write("\n") o_file.flush() if save: o_file.close() self.setResult(str(dice_matrix))
def get_num_cvs(self, curve): ''' Desc: Get cvs lenght from a curve Parameter: curve = curve to get cvs positin list from coords_space = the coordinat space, can be "world" (default), or "local" Return: list with positions ''' # If curve is nod define or not correct release error if curve: # Get curve shape curve_shape = KstMaya.get_shape_node(curve) # Get degree degree = cmds.getAttr(curve_shape+".degree") # Get spans spans = cmds.getAttr(curve_shape+".spans") # Calulating ncvs with formula spans+degree ncvs = spans+degree # Return the list return ncvs else: cmds.warning("Curve %s, is not defined, or is not a curve, double check!" % curve) return None
def smarterActivateSet(*args): set = GetSetOptions() # print set.options, '_________' opt = str(len(set.options) - 1) if len(set.sel) != 0: if len(set.sel) > 1: # multi object selection activateSet(set.sel) cmds.warning('-- multiple objects set as character set --') return set.sel if set.current: if set.current in set.options: idx = set.options.index(set.current) if idx != len(set.options) - 1: activateSet(set.options[idx + 1]) message('set -- ' + set.options[idx + 1] + ' -- ' + str(idx + 1) + ' of ' + opt, maya=True) else: activateSet(set.options[0]) message('set -- ' + set.options[0] + ' -- ' + str(0) + ' of ' + opt, maya=True) else: activateSet(set.options[1]) message('set -- ' + set.options[1] + ' -- ' + str(1) + ' of ' + opt, maya=True) else: activateSet(set.options[1]) message('set -- ' + set.options[1] + ' -- ' + str(1) + ' of ' + opt, maya=True) else: activateSet(set.options[0])
def publish(): # Import Modules import shutil # Get SceneName and Root fullName = cmds.file(sceneName=True, q=True) paths = fullName.split("/") taskName = paths[-2].split("_")[2] assetCode = paths[-2].split("_")[1] assetName = Assets.getFullName(assetCode) outFolder = "/".join(paths[:-1]) + "/" + assetCode + "_" + taskName + "_OUT" outName = assetName + "_" + taskName cmds.file( save=True, type='mayaAscii' ) # Save File shutil.copy2(fullName, outFolder + "/" + outName + ".ma") # Copy File to MASTER cmds.warning("[Kroentlied Pipeline] Published !") # Copy File to BackUp oldFolder = outFolder + "/" + assetCode + "_" + taskName + "_OUT_OLD" backup = VersionControl.getLatest(oldFolder, 1) if not backup: # No Backup found yet backup = outName + "_BackUp_v001.ma" shutil.copy2(fullName, oldFolder + "/" + backup) print "[Kroentlied Pipeline] PublishBackup: " + backup return
def setPlanes(*args): """sets clipping planes for cameras based on float fields in UI. Depending on radio button, it will either do all camera or only selected""" all = cmds.radioButtonGrp("camRBG", q=True, sl=True) far = cmds.floatFieldGrp("farFFG", q=True, v1=True) near = cmds.floatFieldGrp("nearFFG", q=True, v1=True) cams = [] if all==1: cams.extend(cmds.ls(type="camera")) elif all==2: transf = cmds.ls(sl=True, type="transform") for each in transf: shape = cmds.listRelatives(each, s=True) if shape: if cmds.objectType(shape) == "camera": cams.extend(shape) #for each, set shape.farClipPlane 100000 if cams: print cams for cam in cams: try: cmds.setAttr("%s.farClipPlane"%cam, far) cmds.setAttr("%s.nearClipPlane"%cam, near) except: cmds.warning("Couldn't change the farClipPlane of %s"%cam)
def offsetCurveDragCmd(self, *args ): if not self._dragStart: selCurves = cmds.ls( sl=1 ) self._targetCurves = [] self._keepTargetCurveValues = [] for curve in selCurves: if cmds.attributeQuery( 'centerRate' , node = curve, ex=1 ): self._targetCurves.append( curve ) self._keepTargetCurveValues.append( cmds.getAttr( curve+'.centerRate' ) ) if not self._targetCurves: cmds.warning( "Select VolumeCurves" ) return None self._dragStart = True cmds.undoInfo( swf=0 ) multRate = cmds.floatSliderGrp( self._offsetCurve, q=1, v=1 ) for i in range( len( self._targetCurves ) ): targetCurve = self._targetCurves[i] value = self._keepTargetCurveValues[i] cmds.setAttr( targetCurve+'.centerRate', value*multRate )
def getFaceCam(): meta=generic.Meta() sel=cmds.ls(selection=True) faceCam='' if len(sel)<1: # warning if nothing is selected cmds.warning('Nothing is selected! Select a control first.') return else: node=sel[0] # warning if selection is not a control type if meta.getData(node)['type']!='control': cmds.warning('Selection is not a control! Select a control first.') return else: # getting root node root=meta.upStream(node,'root') # getting face camera from all cameras cameras=meta.downStream(root, 'camera',allNodes=True) for camera in cameras: if meta.getData(camera)['component']=='face': faceCam=cmds.listConnections('%s.message' % camera,type='transform')[0] return faceCam
def TappInstall_browse(*args): repoPath=cmds.fileDialog2(dialogStyle=1,fileMode=3) if repoPath: repoPath=repoPath[0].replace('\\','/') check=False #checking all subdirectories for name in os.listdir(repoPath): #confirm that this is the Tapp directory if name=='Tapp': check=True if check: #create the text file that contains the Tapp directory path path=cmds.internalVar(upd=True)+'Tapp.yml' f=open(path,'w') data='{launchWindowAtStartup: False, repositoryPath: \''+repoPath+'\'}' f.write(data) f.close() #run setup sys.path.append(repoPath) cmds.evalDeferred('import Tapp') #delete ui cmds.deleteUI('TappInstall_UI') else: cmds.warning('Selected directory is not the \'Tapp\' directory. Please try again')
def doIt(self, argList): # get only the first object from argument list try: obj = misc.getArgObj(self.syntax(), argList)[0] except: cmds.warning("No object selected!") return if (cmds.objectType(obj) != 'transform'): cmds.error("Object is not of type transform!") return # get and cast array of MPoint-Objects to list structure (needed for ConvexHull) pSet = list([p.x, p.y, p.z] for p in misc.getPoints(obj)) # execute convex hull algorithm on point set of current object hull = ConvexHull(pSet) # get empty mesh object mesh = om2.MFnMesh() # add each polygon (triangle) in incremental process to mesh center = cmds.centerPoint(obj) for i,tri in enumerate(hull.points[hull.simplices]): # triangle vertices are not ordered --> make sure all normals point away from object's center v1 = map(operator.sub, tri[0], tri[1]) v2 = map(operator.sub, tri[0], tri[2]) # cross product of v1 and v2 is the current face normal; if dot product with vector from origin is > 0 use vertex order 0,1,2 and if dot product < 0 reverse order (all triangles are defined clockwise when looking in normal direction -- counter-clockwise when looking onto front of face) if (np.dot(np.cross(v1, v2), map(operator.sub, tri[0], center) ) > 0 ): mesh.addPolygon( ( om2.MPoint(tri[0]), om2.MPoint(tri[1]), om2.MPoint(tri[2]) ) ) else: mesh.addPolygon( ( om2.MPoint(tri[0]), om2.MPoint(tri[2]), om2.MPoint(tri[1]) ) ) # get transform node of shapeNode and rename it to match object's name transformNode = cmds.listRelatives(mesh.name(), p = 1) transformNode = cmds.rename(transformNode, obj + "_ch") self.setResult(transformNode)
def _getFrames( frameRange ): fr = _getTextFieldValue( frameRange ) frames = [] if not re.search('^\d+(\s*[-,]?\s*\d+)*$', fr): _invalidFrameRange() fr = fr.replace(' ', '') frameRanges = fr.split(',') for f in frameRanges: if re.search('^[0-9]+[-][0-9]+$', f): start, end = f.split('-') if int(start) > int(end): cmds.warning( 'Start of range is greater than end. Will not create any frames.' ) for i in range(int(start), (int(end)+1)): frames.append(i) elif re.search('^[0-9]+$', f): frames.append( re.search('^[0-9]+$', f).group() ) else: _invalidFrameRange() if len(frames) == 0: _invalidFrameRange() return frames
def buttonReplacePhClicked(self): itemList = self.ui.placeholderList.selectedItems() selection = cmds.ls(sl=True, tr=True) if len(itemList) > 0 and len(selection) > 0: replacePHs(str(itemList[0].text())) else: cmds.warning("Please select a placeholder from the list.")
def reverseSelected(self,*args): selected = cmds.ls( sl=True ) reverseSelected = cmds.ls( sl=True ) parentResult = cmds.listRelatives( selected[0], parent=True ) if parentResult is not None: parent = parentResult[0] children = cmds.listRelatives( parent, children=True, pa=True ) reverseSelected.reverse() reverseIndex = 0 numberOfSelected = len(selected) for item in children: if reverseIndex < numberOfSelected and item == selected[reverseIndex]: cmds.reorder( reverseSelected[reverseIndex], back=True ) reverseIndex = reverseIndex+1 else: cmds.reorder( item, back=True ) cmds.select( reverseSelected ) else: cmds.warning( 'Selected objects are parented to the World, they need to be children of a transform' )
def symmetry(): #getting nodes sel = cmds.ls(selection=True) if len(sel) == 1: cmds.warning('Select the edited mesh first, then the original mesh last!') return if len(sel) > 2: cmds.warning('Select the edited mesh first, then the original mesh last!') return edit = sel[0] original = sel[1] #creating symmetry mesh mirror = mirrorBlendshape([edit], original)[0] copy = cmds.duplicate(original)[0] bldShp = cmds.blendShape(edit, mirror, copy)[0] cmds.setAttr('%s.%s' % (bldShp, edit), 1) cmds.setAttr('%s.%s' % (bldShp, mirror), 1) symmetry = cmds.duplicate(copy)[0] symmetry = cmds.rename(symmetry, edit + '_symmetry') cmds.delete(copy, mirror) return symmetry
def cb_drawLines(self, x=None) : if None in [ self.markerset, self.prefix ] : m.warning("No markerset or prefix") return print "drawing lines for " + str(self.prefix) self.markerset.drawLines( self.prefix )
def prepare(setname="cache_set", groupname="cache_group", prefix="cache_"): selection = cmds.ls(sl=True, l=True) if len(selection) == 0: cmds.warning("Please select objects!") return cmds.duplicate() dup = cmds.ls(sl=True, l=True) if cmds.objExists(groupname): cmds.parent(dup, groupname) else: cmds.group(w=True, n=groupname) cmds.select(groupname) dup = get_shapes() add_to_set_of_shapes(setname, dup) i = 0 for obj in dup: cmds.blendShape([selection[i], obj], w=(0, 1),o="world", foc=True) objects = [] objects.append(obj) addattr(objects, prefix+str(i)) i=i+1
def on_getObjectRegion_pressed(self): sel=cmds.ls(selection=True) #checking selection for meshes check=False for node in sel: shape=cmds.listRelatives(node,shapes=True) if shape: if cmds.nodeType(shape)=='mesh': check=True if check: regions=utils.getMeshAnimation() regionNode=self.getSelectedRegionNode() for r in regions: utils.setRegionNode(regionNode, r) else: cmds.warning('Nothing selected. Please select one or more meshes!')
def window(dismiss): if dismiss == "load": self.loadData() else: cmds.warning("If you want to load later, go to aTools menu/Animation Crash Recovery option box") self.saveBackup()
def rootsOnPath(path='X:/_image/_projects/SI/HOL/_Assets/ScareCrow/scenes/Anim_Asset/Path_v01.ma', reverse=False): allLocs = [] roots = rootList() if not nsPaths(): cn.uiEnable(controls='modelPanel') roots = nsHollow(roots) for root in roots: nsA = nsPaths() cmds.file(path, r=True, type="mayaAscii", gl=True, loadReferenceDepth="all", mergeNamespacesOnClash=False, namespace="Path_v01") nsB = nsPaths() ns = list(set(nsB) - set(nsA))[0] # segments off segmentsOff(ns=ns) cmds.select(root) cmds.select(ns + ':path', add=True) # pose the path pathPose(root=root, ns=ns) # attach allLocs.append(attach(up=ns + ':up', reverse=reverse)) # break cn.uiEnable(controls='modelPanel') for locs in allLocs: cmds.select(locs, add=True) else: cmds.warning('-- remove all path rigs before starting --')
def doIt(self, argList): # get only the first object from argument list try: obj = misc.getArgObj(self.syntax(), argList)[0] except: cmds.warning("No object selected!") return if (cmds.objectType(obj) != 'transform'): cmds.error("Object is not of type transform!") return # parse arguments and get flags argData = om.MArgParser (self.syntax(), argList) axisOrder = argData.flagArgumentString('axisOrder', 0) if (argData.isFlagSet('axisOrder')) else 'yzx' fast = argData.flagArgumentBool('fast', 0) if (argData.isFlagSet('fast')) else False # get eigenvectors as matrix (column-wise), reshape matrix and append extra row/column eig = np.matrix(cmds.eigenvector(obj, ao = axisOrder, f = fast)) eig.shape = (3,3) eig = np.append(eig, [[0,0,0]], axis = 0) eig = np.append(eig.transpose(), [[0,0,0,1]], axis = 0).transpose() # return 4x4 matrix as 16 float values util = om.MScriptUtil() util.createFromList(eig.getA1().tolist(), eig.size) self.setResult(om.MDoubleArray(util.asDoublePtr(), eig.size))
def loadSel(self,tF,loadNum): sels = cmds.ls(sl = True) if len(sels) == loadNum: sel = sels[0] cmds.textField(tF,e = True,text = str(sel)) else: cmds.warning ('place Load --' + str(loadNum) + ' --objects')
def getNodeType(node=cmds.ls(sl=True, long=True)): if node: nodeShape = cmds.listRelatives(node[0], shapes=True, f=True)[0] return cmds.nodeType(nodeShape) else: cmds.warning('Please select a node') return None
def set_attr_enhanced(self, obj, attribute, new_value): ''' Set attribute for the provided object using different methods depending on its type Parameters: obj (string): Name of the node/object. attribute (string): Name of the attribute to set. E.g. ".cacheFile" new_value (string): New value to update ''' #print(obj + ' ' + attribute + ' ' + new_value) # Debugging if cmds.objExists(obj): obj_type = cmds.objectType(obj) or '' else: obj_type = '' complex_types = ['cacheFile', 'reference'] if obj_type not in complex_types: cmds.setAttr(obj + attribute, new_value, type='string') else: if obj_type == 'cacheFile': format_path = os.path.splitext(new_value)[0].replace("\\", "/") file_name = format_path.split('/')[-1] format_path_no_file = format_path[::-1].split("/", 1)[-1][::-1] try: if os.path.isfile(format_path_no_file + '/' + file_name.replace('.xml', '') + '.xml'): cmds.setAttr(obj + '.cachePath', format_path_no_file, type='string') cmds.setAttr(obj + '.cacheName', file_name, type='string') return True else: return False except: return False if obj_type == 'reference': not_skipped = True try: cmds.referenceQuery(obj, isLoaded=True) except: not_skipped = False if not_skipped: if os.path.isfile(new_value): try: cmds.file(new_value, loadReference=obj) except: return False else: cmds.warning( 'Provided reference path : "' + new_value + '" doesn\'t lead to a valid file. Previous path was retained.' ) else: cmds.warning('Reference file inaccessible.')
def _call_pick_attribute(self): plugs = list_channelbox_highlited_plugs() if not plugs: return cmds.warning('No plug selected in channelbox') self._attribute.setText(plugs[-1]) self.update_wedging_tabs_states()
def warningFunc(key, *args): message = MESSAGE[key] title = TITLE[key] cmds.confirmDialog(t=title, m=message, b='OK') cmds.warning(message) logger.info(message)
def get_anim_curves_from_objects(nodes): """ Gets the animation curves connected to nodes. :param nodes: List with MFnDependencyNode :type nodes: list of om.MFnDependencyNode :return: Tuple of curves and plugs :rtype: (list of om.MFnDependencyNode, list of om.MPlug) """ curves = [] plugs = [] channelbox_attr = get_channelbox_attributes() animlayers.cache.reset( ) # always reset cache before querying for animation layers! has_anim_layers = animlayers.has_anim_layers() if has_anim_layers and animlayers.all_layers_locked(): cmds.warning('All animation layers are locked!') # get curves for node in nodes: # get all attributes attr_count = node.attributeCount() for index in range(attr_count): attr = node.attribute(index) plug = node.findPlug(attr, True) if plug.isLocked or not plug.isKeyable: continue connections = plug.connectedTo(True, False) # if the attribute has a connection if connections: conn_node = connections[0].node() api = conn_node.apiType() if api in ANIM_CURVE_TYPES: # filter out attributes not selected in channelbox if channelbox_attr: attr_name = om.MFnAttribute(attr).shortName if attr_name not in channelbox_attr: continue # add the node if it matches one of the types we want curves.append(om.MFnDependencyNode(conn_node)) plugs.append(plug) # find curve in animation layer elif has_anim_layers and api in animlayers.BLEND_NODE_TYPES: # filter out attributes not selected in channelbox if channelbox_attr: attr_name = om.MFnAttribute(attr).shortName if attr_name not in channelbox_attr: continue # for testing purposes # print('Attribute: %s' % plug) # benchmark_start = time.clock() best_layer = animlayers.get_best_layer(plug) if not best_layer: continue # for testing purposes # try: # print('-> Best layer is %s' % (om.MFnDependencyNode(best_layer).name())) # except Exception as e: # pass curve_node = animlayers.get_anim_curve(plug, best_layer) # animlayers.cache.benchmark += time.clock() - benchmark_start if curve_node: curves.append(om.MFnDependencyNode(curve_node)) plugs.append(plug) # sys.stdout.write('# Retrieved %d curves in %.4f sec\n' % (len(curve_list), animlayers.cache.benchmark)) return curves, plugs
def readCoreData(pathToUVXML='', parentGrp=''): tree = ET.parse(pathToUVXML) root = tree.getroot() #debug(None, method = 'care_archive_readXML.readCoreData', message = '{0:<10}{1}'.format('ASSETNAME: ', root.tag), verbose = False) if not cmds.objExists(root.tag): cmds.group(n=root.tag, em=True) ## CHeck for this assets core archive group if parentGrp: assetCoreArchive = '|%s|%s|geo_hrc|%s_CORE_ARCHIVES_hrc' % ( parentGrp, root.tag, root.tag) else: assetCoreArchive = '%s|geo_hrc|%s_CORE_ARCHIVES_hrc' % (root.tag, root.tag) coreArchiveGroupName = '%s_CORE_ARCHIVES_hrc' % root.tag if cmds.objExists(assetCoreArchive): try: cmds.delete(assetCoreArchive) except RuntimeError: pass ## Now build a fresh group cmds.group(n=coreArchiveGroupName, em=True) cmds.parent(coreArchiveGroupName, '%s|%s|geo_hrc' % (parentGrp, root.tag)) ## Now process the rest of the xml geoToProcess = root.getchildren() if not geoToProcess: cmds.warning('THERE IS NO DATA WRITTEN TO FILE: %s' % pathToUVXML) else: ## Process each geos data now for eachGeo in geoToProcess: coreData = eachGeo.getchildren() path = coreData[1].attrib['value'].replace('_iColoni_', ':').replace( '_iFwdSlashi_', '/') translateData = coreData[2].attrib['value'].split(' ') rotateData = coreData[3].attrib['value'].split(' ') scaleData = coreData[4].attrib['value'].split(' ') ## Get the parent group parent = '%s_%s' % (root.tag, coreData[0].attrib['value']) if not cmds.objExists('%s|%s' % (assetCoreArchive, parent)): cmds.group(n=parent, em=True) cmds.parent('|%s' % parent, assetCoreArchive) ## Now process the GEO geoName = '%s_%s' % (root.tag, eachGeo.tag.replace( '_iPipei_', '|').split('|')[-1]) longGeoName = '%s|%s|%s' % (assetCoreArchive, parent, geoName) if not cmds.objExists(longGeoName): try: cmds.group(n=geoName, em=True) cmds.parent('|%s' % geoName, '%s|%s' % (assetCoreArchive, parent)) except: cmds.warning( 'Failed to create group for core archive, missing assets parent group!' ) cmds.setAttr('%s.translate' % longGeoName, float(translateData[0]), float(translateData[1]), float(translateData[2])) cmds.setAttr('%s.rotate' % longGeoName, float(rotateData[0]), float(rotateData[1]), float(rotateData[2])) cmds.setAttr('%s.scale' % longGeoName, float(scaleData[0]), float(scaleData[1]), float(scaleData[2])) cmds.setAttr('%s.scale' % longGeoName, float(scaleData[0]), float(scaleData[1]), float(scaleData[2])) if not cmds.objExists('%s.mcAssArchive' % longGeoName): cmds.addAttr(longGeoName, ln='mcAssArchive', dt='string') cmds.setAttr('%s.mcAssArchive' % longGeoName, path, type='string')
def update(self, container, representation): import os from maya import cmds node = container["objectName"] path = api.get_representation_path(representation) # Get reference node from container members members = cmds.sets(node, query=True, nodesOnly=True) reference_node = self._get_reference_node(members) file_type = { "ma": "mayaAscii", "mb": "mayaBinary", "abc": "Alembic" }.get(representation["name"]) assert file_type, "Unsupported representation: %s" % representation assert os.path.exists(path), "%s does not exist." % path # Need to save alembic settings and reapply, cause referencing resets # them to incoming data. alembic_attrs = ["speed", "offset", "cycleType"] alembic_data = {} if representation["name"] == "abc": alembic_nodes = cmds.ls("{}:*".format(members[0].split(":")[0]), type="AlembicNode") if alembic_nodes: for attr in alembic_attrs: node_attr = "{}.{}".format(alembic_nodes[0], attr) alembic_data[attr] = cmds.getAttr(node_attr) else: cmds.warning("No alembic nodes found in {}".format( cmds.ls("{}:*".format(members[0].split(":")[0])))) try: content = cmds.file(path, loadReference=reference_node, type=file_type, returnNewNodes=True) except RuntimeError as exc: # When changing a reference to a file that has load errors the # command will raise an error even if the file is still loaded # correctly (e.g. when raising errors on Arnold attributes) # When the file is loaded and has content, we consider it's fine. if not cmds.referenceQuery(reference_node, isLoaded=True): raise content = cmds.referenceQuery(reference_node, nodes=True, dagPath=True) if not content: raise self.log.warning("Ignoring file read error:\n%s", exc) # Reapply alembic settings. if representation["name"] == "abc": alembic_nodes = cmds.ls("{}:*".format(members[0].split(":")[0]), type="AlembicNode") if alembic_nodes: for attr, value in alembic_data.items(): cmds.setAttr("{}.{}".format(alembic_nodes[0], attr), value) # Fix PLN-40 for older containers created with Avalon that had the # `.verticesOnlySet` set to True. if cmds.getAttr("{}.verticesOnlySet".format(node)): self.log.info("Setting %s.verticesOnlySet to False", node) cmds.setAttr("{}.verticesOnlySet".format(node), False) # Add new nodes of the reference to the container cmds.sets(content, forceElement=node) # Remove any placeHolderList attribute entries from the set that # are remaining from nodes being removed from the referenced file. members = cmds.sets(node, query=True) invalid = [x for x in members if ".placeHolderList" in x] if invalid: cmds.sets(invalid, remove=node) # Update metadata cmds.setAttr("{}.representation".format(node), str(representation["_id"]), type="string")
def exportFile(outputPath, topNode): mc.warning('export start') mc.select(topNode) mc.file(outputPath, typ='mayaAscii', f=True, es=True, pr=True) mc.warning('export end')
def create(self): import ui_menuEditor try: self.clearMenu() except: cmds.warning("Clear Mesh Error") try: self.clearPopupCa() except: cmds.warning("Clear Popup(Ctrl + Alt) Error") try: self.clearPopupSa() except: cmds.warning("Clear Popup(Shift + Alt) Error") if cmds.menu(self.mainMenu, q=1, ex=1): cmds.deleteUI(self.mainMenu) cmds.menu(self.mainMenu, p='MayaWindow', l=self.label, to=1) cmds.menuItem(l='UI - List Menu Paths', p=self.mainMenu, c=loadMenuPathEditor, image=os.path.dirname(__file__) + '/icons/list.png') cmds.menuItem(l='UI - Menu Editor', p=self.mainMenu, c=ui_menuEditor.show, image='') cmds.menuItem(d=1, dl="Main Menu", p=self.mainMenu) for menuPath in getMenuPaths(Menu_Global.menuListFile): menuChecked = self.isMenuChecked(menuPath) dirname = Menu_Global.getMenuLabel(menuPath) menuName = cmds.menuItem(l=dirname, p=self.mainMenu, cb=menuChecked) cmds.menuItem(menuName, e=1, c=partial(self.selectMenu, menuName, menuPath)) if menuChecked: self.selectMenu(menuName, menuPath) cmds.menuItem(d=1, dl="Popup Menu( Shift + alt + RMB )", p=self.mainMenu) popupShiftAlt = cmds.menuItem(l="Popup Menu( Shift + alt + RMB )", p=self.mainMenu, sm=1) cmds.radioMenuItemCollection(p=popupShiftAlt) cmds.menuItem(l="Clear", p=popupShiftAlt, rb=1, c=self.clearPopupSa) for menuPath in getMenuPaths(Menu_Global.popupListFile_sa): popupChecked = self.isPopupChecked(menuPath, 'sa') dirname = Menu_Global.getMenuLabel(menuPath) popupName = cmds.menuItem(l=dirname, p=popupShiftAlt, rb=popupChecked) cmds.menuItem(popupName, e=1, c=partial(self.selectPopup, menuPath, 'sa'), p=popupShiftAlt) if popupChecked: self.selectPopup(menuPath, 'sa') cmds.menuItem(d=1, dl="Popup Menu( Ctrl + alt + RMB )", p=self.mainMenu) popupCtrlAlt = cmds.menuItem(l="Popup Menu( Shift + alt + RMB )", p=self.mainMenu, sm=1) cmds.radioMenuItemCollection(p=popupCtrlAlt) cmds.menuItem(l="Clear", p=popupCtrlAlt, rb=1, c=self.clearPopupCa) for menuPath in getMenuPaths(Menu_Global.popupListFile_ca): popupChecked = self.isPopupChecked(menuPath, 'ca') dirname = Menu_Global.getMenuLabel(menuPath) popupName = cmds.menuItem(l=dirname, p=popupCtrlAlt, rb=popupChecked) cmds.menuItem(popupName, e=1, c=partial(self.selectPopup, menuPath, 'ca')) if popupChecked: self.selectPopup(menuPath, 'ca') cmds.menuItem(d=1, dl="", p=self.mainMenu) cmds.menuItem( l="Get Icon", p=self.mainMenu, c= "import webbrowser;url = 'http://www.flaticon.com/';webbrowser.open_new_tab( url )", image=os.path.dirname(__file__) + '/icons/search.png') cmds.menuItem(d=1, dl="", p=self.mainMenu) cmds.menuItem(l="Reload Modules", c=reloadModules, p=self.mainMenu) cmds.menuItem(d=1, dl="", p=self.mainMenu) cmds.menuItem(l="Reload Menu", c=loadMenu, p=self.mainMenu, image=os.path.dirname(__file__) + '/icons/reload.png')
def import_createHairSystemByCurveAttr(): beforeHairSystem = set( cmds.ls( exactType='hairSystem', l=True) ) selectedObj = cmds.ls(sl=True, l=True) curves = cmds.ls( selectedObj, l=True, exactType='nurbsCurve' ) temp = cmds.listRelatives( selectedObj, ad=True, f=True, type='nurbsCurve') if temp: temp = [c for c in temp if not cmds.getAttr( c+".intermediateObject") ] curves.extend( temp ) curves = tuple( set(curves) ) curvesList = {} curves = [c for c in curves if cmds.attributeQuery( 'hairData', node=c, exists=True)] for c in curves: try: hairData = json.loads( cmds.getAttr(c+'.hairData') ) hairName = hairData[ 'hairSystem'] if not curvesList.has_key( hairName ): curvesList[hairName] = [] except: print cmds.warning( '%s.hairData value loaded failed!'%(c) ) continue curvesList[hairName].append( c ) numHairSystem = len(curvesList.keys()) if not numHairSystem: return gMainProgressBar = mel.eval('$tmp = $gMainProgressBar') cmds.progressBar( gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Creating Hair System ...', maxValue=numHairSystem ) for hairName, curves in curvesList.iteritems(): cmds.progressBar(gMainProgressBar, edit=True, step=1 ) if not curves: continue cmds.select( curves, r=True) mel.eval( 'makeCurvesDynamic 2 { "0", "0", "0", "0", "1"}' ) cmds.progressBar(gMainProgressBar, edit=True, endProgress=True) #Transfer attributes from curve to hairSystem and follicle attributes objs = cmds.ls(l=True, exactType='hairSystem') #folAttrs = ('clumpWidthMult', 'densityMult', 'curlMult', 'clumpTwistOffset', 'colorBlend', 'colorR', 'colorG', 'colorB') for hair in objs: fols = cmds.listConnections( hair+'.inputHair', d=False, shapes=True) c = cmds.listConnections( fols[0]+'.startPosition', d=False, shapes=True)[0] hairData = json.loads( cmds.getAttr( c+'.hairData') ) hairSysName = hairData.get( 'hairSystem', None) if hairSysName and not cmds.attributeQuery('originalName', node=hair, exists=True): cmds.addAttr( hair, ln='originalName', dt='string' ) cmds.setAttr( hair+'.originalName', hairSysName, type='string') cmds.setAttr( hair+'.active', False) cmds.setAttr( hair+'.simulationMethod', 1) for fol in fols: c = cmds.listConnections( fol+'.startPosition', d=False, shapes=True)[0] hairData = json.loads( cmds.getAttr( c+'.hairData') ) hairData.pop( 'hairSystem', None) if hairData and not cmds.attributeQuery('oriAttrs', node=fol, exists=True): cmds.addAttr(fol, ln='oriAttrs', dt='string' ) cmds.setAttr( fol+'.oriAttrs', json.dumps(hairData), type='string' ) afterHairSystem = set( cmds.ls(exactType='hairSystem', l=True) ) newHairSystems = tuple( afterHairSystem.difference( beforeHairSystem ) ) hairSysGrp = cmds.group( newHairSystems, name='hairsystemGrp_#') newHairSystems = cmds.listRelatives(hairSysGrp, ad=True, type='hairSystem', f=True) pfxHairs = [] for hair in newHairSystems: pfxHairs.extend( cmds.listConnections( hair+'.outputRenderHairs', s=False) ) cmds.group( pfxHairs, name='pfxHairGrp_#' ) return newHairSystems
def refresh_table(self, is_repair_attempt=False, is_search_replace=False): ''' Main Refresh Function Parameters: is_repair_attempt=False (bool): Is attempting to auto repair paths? (Called by the Auto Path Repair Button) is_search_replace=False (bool): Is it doing a search and replace? (Called by the Search and Replace Button) ''' common_locations = [] # Locations where files were found is_search_dir_valid = False if is_repair_attempt: search_dir = self.filepath_le.text() if os.path.isdir(search_dir): is_search_dir_valid = True else: cmds.warning( 'The search directory doesn\'t exist. Please select a valid path and try again.' ) self.set_cell_changed_connection_enabled( False) # So it doesn't update it unecessarly self.table_wdg.setRowCount(0) # Remove all rows # Used to detect installed plugins node_types = cmds.ls(nodeTypes=True) # Common Nodes file_nodes = cmds.ls(type='file') path_nodes = file_nodes # Available Types available_node_types = ['audio', 'cacheFile', 'AlembicNode', 'gpuCache','BifMeshImportNode',\ 'RedshiftProxyMesh','RedshiftVolumeShape','RedshiftNormalMap','RedshiftDomeLight','RedshiftIESLight', \ 'MASH_Audio','aiPhotometricLight','aiStandIn','aiVolume', 'imagePlane'] # Add Types for Loaded Plugins path_node_types = [] for obj_type in available_node_types: if obj_type in node_types: path_node_types.append(obj_type) # Add Extra Nodes to Path Nodes for node_type in path_node_types: try: nodes_list = cmds.ls(type=node_type) path_nodes += nodes_list except: pass # Add References refs = cmds.ls(rf=True) path_nodes += refs # Populate Table for i in range(len(path_nodes)): ################ Start Directory Search ################ if is_repair_attempt and is_search_dir_valid: try: file_items = self.get_path_items( path_nodes[i] ) # (path, is_path_valid, node_type_string, icon, node_attr) progress_bar_name = 'Searching' query_path = file_items[0] initial_result = os.path.exists(query_path) query_path = query_path.replace( '\\', '/') # Format it - The main Query desired_file = query_path.split('/')[ -1] # Extract file name (short_name) accept_dir = False is_udim_file = False is_image_sequence = False # Check if using UDIMs or Image Sequences if file_items[2] == 'File': try: uv_tiling_mode = cmds.getAttr( path_nodes[i] + '.uvTilingMode') # Is it using UDIM? use_frame_extension = cmds.getAttr( path_nodes[i] + '.useFrameExtension' ) # Is it an image sequence? is_image_sequence = use_frame_extension if uv_tiling_mode != 0: udim_file_pattern = maya.app.general.fileTexturePathResolver.getFilePatternString( query_path, use_frame_extension, uv_tiling_mode) query_path = udim_file_pattern #.replace('<UDIM>','1001') Handled later using regex is_udim_file = True except: pass # Handle desired folder (instead of file) if file_items[2] == 'Bifrost Cache': if query_path.endswith('/'): desired_file = query_path.split('/')[-2] else: desired_file = query_path.split('/')[-1] accept_dir = True is_found = False if (initial_result != True) and ( len(common_locations) != 0 ): # If common locations are available try them first for loc in common_locations: formatted_path = loc.replace("\\", "/") formatted_path = formatted_path[::-1] formatted_path = formatted_path.split("/", 1)[-1] formatted_path = formatted_path[::-1] common_path_result = os.path.exists( formatted_path + "/" + desired_file) if common_path_result == True: resolved_path = (formatted_path + "/" + desired_file).replace( '/', '\\') #print(path_nodes[i] + ' found using known location.') # Debugging self.set_attr_enhanced(path_nodes[i], file_items[4], resolved_path) is_found = True # Full Search/Walk if (initial_result != True) and (is_found == False): search_count = 0 # How many folders to look into (walk) for the progress bar for path in os.walk( search_dir ): # generates the file names in a directory tree by walking the tree either top-b or b-top search_count += 1 resolved_path = query_path self.make_progress_bar( progress_bar_name, search_count ) # make_progress_bar(name, maxVal) - Max value is the number of folders for path, dirs, files in os.walk( search_dir ): # root_dir_path, sub_dirs, files in os.walk(my_dir) self.move_progress_bar(progress_bar_name, 1) path = path.replace('/', '\\') # Handle Files if desired_file in files: resolved_path = (path + '\\' + desired_file).replace( '/', '\\') common_locations.append(resolved_path) is_found = True # Handle Folders (instead of files) if accept_dir and desired_file in dirs: resolved_path = (path + '\\' + desired_file).replace( '/', '\\') common_locations.append(resolved_path) is_found = True # Handle UDIMs if is_udim_file and is_found == False: file_name = os.path.splitext( desired_file)[0].replace('<UDIM>', '') extension = os.path.splitext(desired_file)[1] pattern = re.compile(file_name + '\\d\\d\\d\\d' + extension) first_found_file = '' if any(pattern.match(line) for line in files): lines_to_log = [ line for line in files if pattern.match(line) ] first_found_file = lines_to_log[0] if first_found_file != '': resolved_path = (path + '\\' + first_found_file).replace( '/', '\\') if os.path.exists(resolved_path): common_locations.append(resolved_path) is_found = True # Handle Image sequences if is_image_sequence and is_found == False: file_name = os.path.splitext( desired_file)[0].replace('<f>', '').replace( '<F>', '') extension = os.path.splitext(desired_file)[1] pattern = re.compile(file_name + '\\d+' + extension) first_found_file = '' if any(pattern.match(line) for line in files): lines_to_log = [ line for line in files if pattern.match(line) ] first_found_file = lines_to_log[0] if first_found_file != '': resolved_path = (path + '\\' + first_found_file).replace( '/', '\\') if os.path.exists(resolved_path): common_locations.append(resolved_path) is_found = True if is_found: #print(path_nodes[i] + ' has a valid path.') # Debugging self.set_attr_enhanced(path_nodes[i], file_items[4], resolved_path) self.kill_progress_window( progress_bar_name) # Kill progress bar except: self.kill_progress_window(progress_bar_name) ################ End Directory Search ################ # Search and Replace if is_search_replace: try: file_items = self.get_path_items(path_nodes[i]) old_path = file_items[0] new_path = old_path.replace(self.search_string, self.replace_string) self.set_attr_enhanced( path_nodes[i], file_items[4], new_path ) #(path, is_path_valid, node_type_string, icon, node_attr) except: pass # Refresh Table file_items = self.get_path_items(path_nodes[i]) self.table_wdg.insertRow(i) self.table_wdg.setFocusPolicy(QtCore.Qt.NoFocus) # No highlight self.insert_item(i, 1, path_nodes[i], None, path_nodes[i]) if file_items: # (path, is_path_valid, node_type_string, icon, node_attr) if file_items[1]: self.insert_item(i, 2, file_items[2], None, cmds.objectType(path_nodes[i]), icon_path=file_items[3], editable=False) self.insert_icon(i, 0, ':confirm.png') else: self.insert_item(i, 2, file_items[2], None, cmds.objectType(path_nodes[i]), icon_path=file_items[3], editable=False) self.insert_icon(i, 0, ':error.png') self.insert_item(i, 3, file_items[0], file_items[4], file_items[0]) self.set_cell_changed_connection_enabled(True)
#TO-DO----------------create UI. . . (this is already done, btw) #TO-DO----------------options for showing values captured, for copying only selected attr. .. for multiple keys? ? #TO-DO----------------copy and store? or copy from the object at that frame (other object? import maya.cmds as cmds sel = cmds.ls(sl=True, type="transform") if (len(sel)) > 1: base = sel[0] objs = sel[1:] #get transforms pos = cmds.getAttr("%s.translate" % base) rot = cmds.getAttr("%s.rotate" % base) scale = cmds.getAttr("%s.scale" % base) #put transforms for obj in objs: cmds.setAttr("%s.translate" % obj, pos[0][0], pos[0][1], pos[0][2]) cmds.setAttr("%s.rotate" % obj, rot[0][0], rot[0][1], rot[0][2]) cmds.setAttr("%s.scale" % obj, scale[0][1], scale[0][1], scale[0][2]) else: cmds.warning("Must select more than one object!")
def alembic_import_hairAndShave( **kwargs): '''{'path':'Pipeline Cache/Alembic/alembic_import_hairAndShave( )ONLYSE', 'tip':'恢复shave和hair', 'icon':'$ICONDIR/alembic.png', 'html':'http://10.99.17.61/hq_maya/alembicPipeline', 'usage':""" #根据选择物体的hairData和shaveData以及messenger物体的attributePresets和shaveHairInitialState属性来恢复hair和shave #使用方法: 1.将保存了attributePresets和shaveHairInitialState属性的locator的名字赋给messenger # 2.选择要恢复hair和shave的物体的组。 messenger = 'F2_HanJXN_SC03_AN_mb_INOF' $fun( messenger=messenger)""", } ''' selectedObj = kwargs.get( 'objects', cmds.ls(sl=True, l=True)) if not selectedObj: raise IOError( "Select objects to create hair and shave!") #得到属性的json对象 hairAndShave = [] messenger = kwargs.get( 'messenger', None) if messenger: if not cmds.objExists( messenger): raise IOError( '%s is not exists!'%(messenger) ) if not cmds.attributeQuery( 'attributePresets', node=messenger, exists=True): raise IOError( '%s.attributePresets is not exists!'%(messenger) ) if not cmds.attributeQuery( 'shaveHairInitialState', node=messenger, exists=True): shaveInitialState = None else: shaveInitialState = cmds.getAttr( messenger+'.shaveHairInitialState' ) shaveInitialState = json.loads(shaveInitialState) #raise IOError( '%s.shaveHairInitialState is not exists!'%(messenger) ) jsonPreset = cmds.getAttr( messenger+'.attributePresets' ) else: jsonPreset = kwargs.get( 'jsonPreset', None) keyFromAttr = kwargs.get( 'keyFromAttr', 'originalName') #创建hairSystem hairSystems = import_createHairSystemByCurveAttr() if hairSystems: hairAndShave.extend( hairSystems ) #检查shave插件 loadedShave = False if not cmds.pluginInfo( 'shaveNode.mll', query=True, loaded=True): try: cmds.loadPlugin( 'shaveNode.mll' ) except: pass if cmds.pluginInfo( 'shaveNode.mll', query=True, loaded=True): loadedShave=True #创建shaveHair if loadedShave: cmds.select( selectedObj, r=True) shaveHairs = import_createShaveHairByObjectsAttr() if shaveHairs: hairAndShave.extend( shaveHairs ) if hairAndShave: #载入shaveHair和hairSystem的预设,从json对象中 qm.loadJsonAttrsPreset( objects=hairAndShave, jsonPreset=jsonPreset, keyFromAttr=keyFromAttr ) #创建并载入hairSystem的brush节点,并从jsonPrest中载入预设 if hairSystems: brushNodes = [] for hair in hairSystems: if cmds.attributeQuery('brushNode', node=hair, exists=True): pfxHair = cmds.listConnections( hair+'.outputRenderHairs', s=False, shapes=True) brushNode = cmds.listConnections( pfxHair[0]+'.brush', d=False, shapes=True) if not brushNode: cmds.select( hair, r=True) mel.eval('assignBrushToHairSystem;') brushNode = cmds.listConnections( pfxHair[0]+'.brush', d=False, shapes=True) qm.delAttr( brushNode, ['originalName',] ) cmds.addAttr( brushNode[0], ln='originalName', dt='string' ) cmds.setAttr( brushNode[0]+'.originalName', cmds.getAttr( hair+'.brushNode' ), type='string') brushNodes.append( brushNode[0] ) #Load brush attributes from jsonPreset if brushNodes: qm.loadJsonAttrsPreset( objects=brushNodes, jsonPreset=jsonPreset, keyFromAttr=keyFromAttr ) #Connect texture or shader to shaveHair for shave in hairAndShave: if cmds.attributeQuery( 'shaderData', node=shave, exists=True): shaderData = json.loads( cmds.getAttr( shave+'.shaderData') ) for fromAttr, toAttr in shaderData: try: cmds.connectAttr( fromAttr, shave+'.'+toAttr, f=True) except: pass #Initialize shaveHiar initial state if loadedShave and shaveInitialState and shaveHairs: gMainProgressBar = mel.eval('$tmp = $gMainProgressBar') cmds.progressBar( gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Initialize state of shaveHair....', maxValue=len(shaveHairs) ) startFrame = shaveInitialState.get('frame', None) if not startFrame: raise IOError( "没有得到shavehair的初始状态所在的帧") cmds.currentTime( startFrame, e=True) #allShaveHair = cmds.ls( exactType='shaveHair', l=True ) allShaveHair = shaveHairs shaveHairInitialData = {} for shave in allShaveHair: if cmds.attributeQuery( 'originalName', node=shave, exists=True): oriName = cmds.getAttr( shave+'.originalName' ) shaveHairInitialData[oriName] = ([], shave) for shave, curveDataList in shaveInitialState.iteritems(): cmds.progressBar(gMainProgressBar, edit=True, step=1 ) if shaveHairInitialData.has_key(shave): for curveData in curveDataList: newCurve = cmds.curve(degree=curveData[0], p=curveData[1:]) shaveHairInitialData[shave][0].append( newCurve ) cmds.progressBar(gMainProgressBar, edit=True, endProgress=True) for shave, objects in shaveHairInitialData.iteritems(): if objects[0]: cmds.select(objects[0], r=True) cmds.select(objects[1], add=True ) cmds.shaveCombFromCurves() else: cmds.warning( "%s skiped!"%(shave) ) cmds.delete( objects[0] ) return hairAndShave
def shaveReName(self): noShaveCacheFiles = [] allOnlyShaveShapes = [] PROJECT_PATH = mm.eval('getenv "OCTV_PROJECTS"') OCT_DRIVE = r'\\octvision.com\cg' allShaveShapes = mc.ls(type='shaveHair') for eachShape in allShaveShapes: allOnlyShaveShapes.append(eachShape.split("|")[-1]) allOnlyShaveShapes = list(set(allOnlyShaveShapes)) if len(allShaveShapes) > len(allOnlyShaveShapes): mc.warning(u"毛发Shave的shapes节点有重名的,将导致同名的Shave使用同一个缓存!") myshaveGlobals = "shaveGlobals" allOnlyShaveShapes = list(set(allOnlyShaveShapes)) myshaveGlobals = "shaveGlobals" if allShaveShapes and myshaveGlobals: shavePath = mc.getAttr("%s.tmpDir" % myshaveGlobals) if shavePath: if shavePath.find('${OCTV_PROJECTS}') >= 0: shavePath = shavePath.replace('${OCTV_PROJECTS}', PROJECT_PATH) elif shavePath.find('z:') >= 0: shavePath = shavePath.replace('z:', OCT_DRIVE) elif shavePath.find('Z:') >= 0: shavePath = shavePath.replace('Z:', OCT_DRIVE) if not os.path.isdir(shavePath): proPath = mc.workspace(q=True, rd=True) shavePath = os.path.normpath( os.path.join(proPath, shavePath)) if shavePath.find('z:') >= 0: shavePath = shavePath.replace('z:', OCT_DRIVE) elif shavePath.find('Z:') >= 0: shavePath = shavePath.replace('Z:', OCT_DRIVE) if os.path.isdir(shavePath): allSahveDirs = os.listdir(shavePath) if allSahveDirs: shaveNames = [] for eachDir in allSahveDirs: shaveNames.append(eachDir.split(".")[0]) shaveNames = list(set(shaveNames)) for eachShape in allShaveShapes: if mc.reference(eachShape, isNodeReferenced=True): mc.confirmDialog(message=u"请先导入参考的文件!") return myName = "" if ":" in eachShape.split("|")[-1]: shaveNames = eachShape.replace(":", "_") myName = mc.rename(eachShape, shaveNames) eachTran = mc.listRelatives(myName, f=True, p=True)[0] pathTran = eachTran.split("|") if ":" in pathTran[-1]: tranName = pathTran[-1].replace(":", "_") myName = mc.rename(pathTran[-1], tranName) else: noShaveCacheFiles.append(myshaveGlobals) if not noShaveCacheFiles: mc.confirmDialog(message=u"修改shave的名字成功!") return
def output_createHiarOutputCurve(hairSystemObjs = None, hasPfxHair=True, createMarked=False): if not hairSystemObjs: if not cmds.ls(sl=True): cmds.warning( 'Select a hairSystem node!' ) return None hairSystemObjs = cmds.ls(sl=True, l=True, exactType='hairSystem') if not hairSystemObjs: hairSystemObjs = cmds.listRelatives( cmds.ls(sl=True, l=True), shapes=True, type='hairSystem' ) if not hairSystemObjs: return None if isinstance(hairSystemObjs, (str,unicode) ): hairSystemObjs = [hairSystemObjs] #hairSystemObjs, hasPfxHair, createMarked = cmds.ls(exactType='hairSystem', l=True), False, False resultCruveGrps = [] allHairData = {} numFollicle = 0 for hair in hairSystemObjs: pfxHair = cmds.listConnections( hair+'.outputRenderHairs', s=False, shapes=True) if hasPfxHair and not pfxHair: continue allHairData[hair] = {} follicles = cmds.listConnections( hair+'.inputHair', d=False, shapes=True) if not follicles: continue #Connected attributes infomations to attributes of materials materialsInfo = [] mayaShader = cmds.listConnections( hair, d=False, p=True, c=True, type='shadingDependNode', shapes=True) aiHairs = cmds.listConnections( hair, d=False, p=True, c=True, type='aiHair', shapes=True ) if mayaShader: materialsInfo.extend( [ (mayaShader[i+1],mayaShader[i].split('.', 1)[-1] ) for i in range(0, len(mayaShader), 2) ] ) if aiHairs: materialsInfo.extend( [ (aiHairs[i+1],aiHairs[i].split('.', 1)[-1] ) for i in range(0, len(aiHairs), 2) ] ) if materialsInfo: qm.delAttr( hair, ['shaderData', 'brushAttrs']) cmds.addAttr( hair, ln='shaderData', dt='string') cmds.setAttr( hair+'.shaderData', json.dumps(materialsInfo), type='string' ) if not createMarked: tempFollicles = [] for fol in follicles: markedCurves = cmds.listConnections( fol+'.outCurve', s=False, shapes=True) if not markedCurves: tempFollicles.append( fol ) continue if not [c for c in markedCurves if cmds.attributeQuery('hairData', node=c, exists=True) ]: tempFollicles.append( fol ) continue if not tempFollicles: continue follicles = tempFollicles allHairData[hair] = follicles numFollicle = numFollicle+len( follicles ) if not numFollicle: return [] gMainProgressBar = mel.eval('$tmp = $gMainProgressBar') cmds.progressBar( gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Creating curve...', maxValue=numFollicle ) curNum = 1 folAttrs = {'clumpWidthMult':1, 'densityMult': 1, 'curlMult': 1, 'clumpTwistOffset': 0, 'colorBlend': 0, 'colorR': 0, 'colorG': 0, 'colorB': 0, } for hair, follicles in allHairData.iteritems(): outCurvesGrp = cmds.group( em=True, name='hairSystem_OutputCurves_#') for fol in follicles: if cmds.progressBar(gMainProgressBar, query=True, isCancelled=True ): break newCurve = cmds.createNode( "nurbsCurve") hairValue = {} hairValue['hairSystem'] = hair for attr, v in folAttrs.iteritems(): curV = cmds.getAttr( fol+'.'+attr ) if curV!=v: hairValue[attr] = curV jsonStr = json.dumps( hairValue ) cmds.addAttr( newCurve, ln='hairData', dt='string' ) cmds.setAttr( newCurve+'.hairData', jsonStr, type='string') curvePapa = cmds.listRelatives( newCurve, p=True, pa=True )[0] cmds.connectAttr( fol+'.outCurve', newCurve+'.create') if not cmds.listConnections( fol+'.currentPosition', d=False): hairSysAttr = cmds.listConnections( fol+'.outHair', p=True, s=False, shapes=True, type='hairSystem', exactType=True)[0] pIndex = re.match( r'.+\[(\d+)\]$', hairSysAttr).groups()[0] cmds.connectAttr( hair+'.outputHair[%s]'%(pIndex), fol+'.currentPosition') cmds.parent( curvePapa, outCurvesGrp, r=True ) cmds.progressBar(gMainProgressBar, edit=True, step=1, status='Creating curve %s/%s'%(curNum, numFollicle) ) curNum = curNum+1 resultCruveGrps.append( outCurvesGrp ) cmds.progressBar(gMainProgressBar, edit=True, endProgress=True) return resultCruveGrps
def build(self): ''' ''' super(Arm, self).build() # get the values from the user. Node attributes in the graph. clavicleCtrl = self.getAttributeByName('clavicleCtrl').getValue() swingCtrl = self.getAttributeByName('swingCtrl').getValue() MirrorSwing = self.getAttributeByName('MirrorSwing').getValue() swingNul, swingMirrorOrt, swingOrt, swingCtrl = control.create(name=swingCtrl, controlType="square", hierarchy=['nul','mirror_ort','ort']) clavicleNul, clavicleOrt, clavicleCtrl = control.create(name=clavicleCtrl, controlType="square", hierarchy=['nul','ort']) # position the clavicle in the correct location clavicleJointMatrix = mc.xform(self._clavicleJoint, q=True, ws=True, matrix=True) mc.xform(clavicleNul, ws=True, matrix=clavicleJointMatrix) # get the aim direction aimDistance = mc.getAttr("{}.t".format(self.jointList[1]))[0] aimAttr, aimVector = self._getDistanceVector(aimDistance) sidePos = mc.xform(self.jointList[1], q=True, ws=True, t=True) # set the Ort node to be mirrored from the other side if sidePos[0] < 0: mc.setAttr("{}.r{}".format(clavicleOrt, aimAttr.strip("-")), 180) mc.setAttr("{}.s{}".format(clavicleOrt, aimAttr.strip("-")), -1) # mirror the swing also if it is required by the build if MirrorSwing: mc.setAttr("{}.r{}".format(swingMirrorOrt, aimAttr.strip("-")), 180) mc.setAttr("{}.s{}".format(swingMirrorOrt, aimAttr.strip("-")), -1) # move the shoulderSwing control to the correct location. shoulderCtrlMatrix = mc.xform(self._fkControls[0], q=True, ws=True, matrix=True) mc.xform(swingNul, ws=True, matrix=shoulderCtrlMatrix) # Hookup clavicle connect nul, the direct connection for the rotate allow keeps the auto # clav from causint a double rotation on the shoulder clavicleConnect = mc.duplicate(clavicleCtrl, po=1, n=clavicleCtrl+'_connect')[0] mc.parent(clavicleConnect, clavicleNul) mc.connectAttr(clavicleCtrl+'.r', clavicleConnect+'.r') mc.connectAttr(clavicleCtrl+'.s', clavicleConnect+'.s') # This allows the translates to come through with auto clav clavicleConnectTranslate = mc.duplicate(swingNul, po=1, n=clavicleCtrl+'_connect_trans')[0] mc.parent(clavicleConnectTranslate, clavicleCtrl) mc.pointConstraint(clavicleConnectTranslate, clavicleConnect) # getting rid of the point constraint for now. Not sure we need it. #mc.pointConstraint(clavicleCtrl, self._clavicleJoint) mc.orientConstraint(clavicleCtrl, self._clavicleJoint) # parent the shoulderSwing control to the clavicle control. mc.parent((self._fkControls[0], self._stretchTargetJointList[0]), swingCtrl) mc.parent(swingNul, clavicleConnect) # Connect to passed anchor # anchor = self.getAttributeByName('anchor').getValue() if mc.objExists(anchor): mc.parent(clavicleNul, anchor) else: # parent the clavicle to the group of this part. mc.parent(clavicleNul, self.name) mc.warning('Anchor object [ {} ] does not exist.'.format(anchor)) # set the rotate order for the shoulder control mc.setAttr("{}.rotateOrder".format(self._fkControls[0]), 2) # set the rotate order for the swing control mc.setAttr("{}.rotateOrder".format(swingCtrl), 2) #self._fkControls.extend([clavicleCtrl,swingCtrl]) # PSD driver - transform that picks up the auto clav and anim control rotation clavicleDriverPar = mc.duplicate(clavicleConnect, po=1, n=clavicleCtrl+'_driver_par')[0] clavicleDriver = mc.duplicate(clavicleConnect, po=1, n=clavicleCtrl+'_driver')[0]
def __load_plugin(self): if not cmds.pluginInfo('push_deformer.py', l=True, q=True): if cmds.loadPlugin('push_deformer.py') == None: cmds.warning('Failed to load plugin.') return False return True
def publish_fbx_rig_file(versionUp=True, origScene=None, *args): """ requires an EXPORT_JNT_Grp group with one root for each export rig named: 'name_Root_Jnt' requires a GEO group with one folder for each export rig named: 'name_Geo_Grp' names should correspond ("fish_Root_Jnt", "fish_Geo_Grp") """ # all happens in current: if not origScene: cmds.warning("assetPublish.publish_fbx_rig_file: You haven't passed in a scene path!") return(False) pp = uf.PathParser(origScene) geoGrp = cmds.ls("GEO") jntGrp = cmds.ls("EXPORT_JNT_Grp") # check for geo grps if not geoGrp or len(geoGrp)>1: cmds.warning("AssetPublish.publish_fbx_rig_file:You either have no grp called 'GEO', or too many objects called 'GEO'.\n fbx export aborted!") return(False) geos = child_match_check(geoGrp, "*_Geo_Grp") if not geos: return(False) # check for jnt grps if not jntGrp or len(jntGrp)>1: cmds.warning("AssetPublish.publish_fbx_rig_file:You either have no grp called 'EXPORT_JNT_Grp', or too many objects called 'EXPORT_JNT_Grp'.\n fbx export aborted!") return(False) roots = child_match_check(jntGrp, "*_Root_Jnt") if not roots: return(False) # check correspondence correspond = check_correspondence(geos, roots) if not correspond: return(False) pubFbxPath = uf.fix_path(os.path.join(pp.phasePath, "Publish/FBX/")) tokens = pp.fileName.split("_") tokens[-2] = "Publish" pubFileName = "_".join(tokens)[:-3] + ".fbx" pubFilePath = uf.fix_path(os.path.join(pubFbxPath, pubFileName)) # check if there's any animation in the file (time based), abort if there is # check for references, etc. . # delete constraints cmds.delete(cmds.ls(type="constraint")) cmds.select(cl=True) # move jnts and geo into world parent for root in roots: basename = root.split("_Root_Jnt")[0] geo = "{0}_Geo_Grp".format(basename) cmds.parent([geo, root], w=True) # create filename tokens[-2] = basename pubFileName = "_".join(tokens)[:-3] + ".fbx" pubFilePath = uf.fix_path(os.path.join(pubFbxPath, pubFileName)) cmds.select([root, geo], r=True) # if this exists, should we overwrite? if os.path.isfile(pubFilePath): overwrite = cmds.confirmDialog(title="Overwrite Confirmation", message = "A publish FBX already exists for this file.\nShould we overwrite?", button = ("Overwrite", "Cancel"), defaultButton = "Overwrite", cancelButton = "Cancel", dismissString = "Cancel") if overwrite == "Cancel": print "Publish skipped for FBX file (.fbx) called {0}".format(pubFilePath) return(True) mel.eval('FBXLoadExportPresetFile -f "{0}";'.format(preset)) mel.eval('FBXExport -f "{0}" -s'.format(pubFilePath)) return(True)
def mayaToolsInstall_Cancel(*args): cmds.deleteUI("mayaToolsInstall_UI") cmds.warning("Maya Tools will not be setup")
def applyAnimData(animData, pasteInPlace=True, onlySelectedNodes=False, showProgress=None, status=None): if animData: status = "aTools - Applying animation data..." if not status else status objects = animData["objects"] if not onlySelectedNodes: #print "objects1", objects if len(objects) > 0: objects = [loopObj for loopObj in objects if loopObj is not None and cmds.objExists(loopObj)] #print "objects2", objects if len(objects) > 0: cmds.select(objects) else: objects = getObjsSel() if not objects: cmds.warning("No objects to apply.") return cmds.refresh(suspend=True) if showProgress: utilMod.startProgressBar(status) if pasteInPlace: currKey = cmds.currentTime(query=True) for aData in animData["animData"]: allKeys = [] keys = aData["keyframeData"] for n, key in enumerate(keys): timeChange = aData["keyframeData"][n][0] allKeys.append(timeChange) firstKey = 0 if allKeys: firstKey = min(allKeys) lastKey = max(allKeys) cutIn = currKey+firstKey cuOut = lastKey+firstKey else: cutIn = -49999 cuOut = 50000 objsAttrs = [loopItem["objAttr"] for loopItem in animData["animData"]] existObjsAttrs = [loopObjAttr for loopObjAttr in objsAttrs if cmds.objExists(loopObjAttr)] createDummyKey(existObjsAttrs) cmds.cutKey(existObjsAttrs, time=(cutIn, cuOut), clear=True) if showProgress: totalSteps = 0 firstStep = 0 thisStep = 0 estimatedTime = None startChrono = None for loopObjAttr in existObjsAttrs: index = objsAttrs.index(loopObjAttr) aData = animData["animData"][index] keys = aData["keyframeData"] totalSteps = totalSteps + len(keys) for loopObjAttr in existObjsAttrs: index = objsAttrs.index(loopObjAttr) aData = animData["animData"][index] weighted = aData["curveData"][0] infinity = aData["curveData"][1] keys = aData["keyframeData"] for n, key in enumerate(keys): if showProgress: if cmds.progressBar(G.progBar, query=True, isCancelled=True ): refresh() utilMod.setProgressBar(endProgress=True) return startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) #read values timeChange = aData["keyframeData"][n][0] valueChange = aData["keyframeData"][n][1] breakdown = aData["keyframeData"][n][2] inTangentType = aData["tangentData"][n][0] outTangentType = aData["tangentData"][n][1] ix = aData["tangentData"][n][2] iy = aData["tangentData"][n][3] ox = aData["tangentData"][n][4] oy = aData["tangentData"][n][5] lock = aData["tangentData"][n][6] weightLock = aData["tangentData"][n][7] if pasteInPlace: timeChange = timeChange-firstKey+currKey time = (timeChange,timeChange) # create key cmds.setKeyframe(loopObjAttr, time=time, value=valueChange, noResolve=True) if n == 0: cmds.keyTangent(loopObjAttr, weightedTangents=weighted) cmds.setInfinity(loopObjAttr, edit=True, preInfinite=infinity[0], postInfinite=infinity[1]) if breakdown: cmds.keyframe(loopObjAttr, edit=True, time=time, breakdown=True) cmds.keyTangent(loopObjAttr, time=time, ix=ix, iy=iy, ox=ox, oy=oy, lock=lock) if weighted: cmds.keyTangent(loopObjAttr, time=time, weightLock=weightLock) cmds.keyTangent(loopObjAttr, time=time, inTangentType=inTangentType, outTangentType=outTangentType) if showProgress: estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) thisStep += 1 deleteDummyKey(existObjsAttrs) if showProgress: refresh() utilMod.setProgressBar(endProgress=True)
def build(self): ''' ''' super(ArmOld, self).build() clavicleCtrl = self.getAttributeByName('clavicleCtrl').getValue() swingCtrl = self.getAttributeByName('swingCtrl').getValue() swingCtrlHierarchy = control.create(name=swingCtrl, controlType="square", hierarchy=['nul','ort']) clavicleCtrlHierarchy = control.create(name=clavicleCtrl, controlType="square", hierarchy=['nul','ort']) ''' clavicle = 'clavicle_l' child = 'shoulderSwing_l_nul' aimTarget = mc.duplicate(clavicle, po=1, n=clavicle + '_aim_target')[0] aim = mc.duplicate(clavicle, po=1, n=clavicle + '_aim')[0] mc.delete(mc.pointConstraint(child, aimTarget)) mc.parent(aimTarget, clavicle) mc.setAttr(aimTarget + '.tx', 1) mc.aimConstraint(aimTarget, aim, offset=[0, 0, 0], weight=1, aimVector=[1, 0, 0], worldUpType="none", upVector=[0, 0, 0]) mc.pointConstraint(aimTarget, child) ''' clavicleCtrl = clavicleCtrlHierarchy[-1] clavicleNul = clavicleCtrlHierarchy[0] swingCtrl = swingCtrlHierarchy[-1] swingNul = swingCtrlHierarchy[0] clavicleJointMatrix = mc.xform(self._clavicleJoint, q=True, ws=True, matrix=True) mc.xform(clavicleNul, ws=True, matrix=clavicleJointMatrix) # move the shoulderSwing control to the correct location. shoulderCtrlMatrix = mc.xform(self._fkControls[0], q=True, ws=True, matrix=True) mc.xform(swingNul, ws=True, matrix=shoulderCtrlMatrix) # Hookup clavicle connect nul, the direct connection for the rotate allow keeps the auto # clav from causint a double rotation on the shoulder clavicleConnect = mc.duplicate(clavicleCtrl, po=1, n=clavicleCtrl+'_connect')[0] mc.parent(clavicleConnect, clavicleNul) mc.connectAttr(clavicleCtrl+'.r', clavicleConnect+'.r') mc.connectAttr(clavicleCtrl+'.s', clavicleConnect+'.s') # PSD driver - transform that picks up the auto clav and anim control rotation clavicleDriver = mc.duplicate(clavicleConnect, po=1, n=clavicleCtrl+'_driver')[0] mc.orientConstraint(clavicleCtrl, clavicleDriver) # This allows the translates to come through with auto clav clavicleConnectTranslate = mc.duplicate(swingNul, po=1, n=clavicleCtrl+'_connect_trans')[0] mc.parent(clavicleConnectTranslate, clavicleCtrl) mc.pointConstraint(clavicleConnectTranslate, clavicleConnect) mc.pointConstraint(clavicleCtrl, self._clavicleJoint) mc.orientConstraint(clavicleCtrl, self._clavicleJoint) # parent the shoulderSwing control to the clavicle control. mc.parent(("{}_nul".format(self._fkControls[0]), self._stretchTargetJointList[0]), swingCtrl) mc.parent(swingNul, clavicleConnect) # parent constrain the shoulder ik joint to the clavicle joint. mc.parentConstraint(self._clavicleJoint, self.ikfkSystem.getIkJointList()[0], mo=True) # parent the clavicle to the group of this part. mc.parent(clavicleNul, self.name) # Connect to passed anchor # anchor = self.getAttributeByName('anchor').getValue() if mc.objExists(anchor): mc.parent(clavicleNul, anchor) else: mc.warning('Anchor object [ {} ] does not exist.'.format(anchor)) # set the rotate order for the shoulder control mc.setAttr("{}.rotateOrder".format(self._fkControls[0]), 2) # set the rotate order for the swing control mc.setAttr("{}.rotateOrder".format(swingCtrl), 2)
cmds.refresh(su=True) cmds.bakeResults(sNull, t=(iIn, iOut), simulation=True) cmds.delete('TempConst') cmds.refresh(su=False) ApplyConst(sNull, s) cmds.select(cl=True) restoreLayout('Custom_AnimWithCam') elif K == 13: # Ctl + Alt + Shift # Special Plot if not oSel: cmds.warning(' Please Select an obj first.') else: oCamera = '' oPanel = cmds.getPanel(wf=True) if 'modelPanel' in oPanel: oCamera = cmds.modelEditor(oPanel, q=True, camera=True).split('Shape')[0] if not cmds.objExists(oCamera): cmds.warning('View not selected!!') print 'Camera : ', oCamera if oCamera: aPlotList = [] # Create Plot Nulls for o in oSel:
def publish_fbx_anim_file(versionUp=True, origScene=None, *args): # THIS IS FOR ANIM EXPORTING if not origScene: cmds.warning("assetPublish.publish_fbx_anim_file: You haven't passed in a scene path!") return(False) # assuming references refs = cmds.file(q=True, r=True) if not refs: cmds.warning("There are no references in this scene. . .") return(False) if len(refs) > 1: cmds.warning("There are too many references in this scene. . .") return(False) # below would all be under a for loop for each reference in the stages? pp = uf.PathParser(origScene) # assuming a namespace geoGrp = cmds.ls("*:GEO") jntGrp = cmds.ls("*:EXPORT_JNT_Grp") # check for geo grps if not geoGrp or len(geoGrp)>1: cmds.warning("AssetPublish.publish_fbx_anim_file:You either have no grp called 'GEO' -IN A NAMESPACE-, or too many objects called 'GEO'.\n fbx export aborted!") return(False) geos = child_match_check(geoGrp[0], "*_Geo_Grp") if not geos: return(False) # check for jnt grps if not jntGrp or len(jntGrp)>1: cmds.warning("AssetPublish.publish_fbx_anim_file:You either have no grp called 'EXPORT_JNT_Grp' -IN A NAMESPACE-, or too many objects called 'EXPORT_JNT_Grp'.\n fbx export aborted!") return(False) roots = child_match_check(jntGrp[0], "*_Root_Jnt") if not roots: return(False) cmds.file(refs[0], ir=True) # check correspondence of geo and root jnts correspond = check_correspondence(geos, roots) if not correspond: return(False) pubFbxPath = uf.fix_path(os.path.join(pp.phasePath, "Publish/FBX/")) tokens = pp.fileName.split("_") tokens[-2] = "Publish" pubFileName = "_".join(tokens)[:-3] + ".fbx" pubFilePath = uf.fix_path(os.path.join(pubFbxPath, pubFileName)) # bake joints for r in roots: # get child roots if joints allD = cmds.listRelatives(r, allDescendents=True) jnts = [x for x in allD if cmds.objectType(x, isa="joint")] # function to bake selected for j in jnts: attr=["t","r","s"] co=["x","y","z"] attrLs=[] for at in attr: for c in co: attrLs.append("%s.%s%s"%(j,at,c)) for x in attrLs: try: mc.setAttr(x, k=1) except: pass namespace = cmds.file(refs[0], q=True, ns=True) uf.remove_namespaces() # delete constraints cmds.delete(cmds.ls(type="constraint")) cmds.select(cl=True) # move jnts and geo into world parent for root in roots: basename = root.split("_Root_Jnt")[0] geo = "{0}_Geo_Grp".format(basename) cmds.parent([geo, root], w=True) # create filename tokens[-2] = basename pubFileName = "_".join(tokens)[:-3] + ".fbx" pubFilePath = uf.fix_path(os.path.join(pubFbxPath, pubFileName)) cmds.select([root, geo], r=True) # if this exists, should we overwrite? if os.path.isfile(pubFilePath): overwrite = cmds.confirmDialog(title="Overwrite Confirmation", message = "A publish FBX already exists for this file.\nShould we overwrite?", button = ("Overwrite", "Cancel"), defaultButton = "Overwrite", cancelButton = "Cancel", dismissString = "Cancel") if overwrite == "Cancel": print "Publish skipped for FBX file (.fbx) called {0}".format(pubFilePath) return(True) mel.eval('FBXLoadExportPresetFile -f "{0}";'.format(preset)) mel.eval('FBXExport -f "{0}" -s'.format(pubFilePath)) return(True) # loop through namespaces/references: # import reference # delete namespace # loop through joint grps, geo grps: # bake jnts # clean up joints shit # "CloudStage_Tree_main_Rig1_A_v0001.fbx" # stage asset ns subgrp version # check for version folder, create it if it doesn't exist pass
def flexi_loft(add_ik=0, bind=0, loft=0, cluster=0, stretchy=0, name=""): raw_curves = mc.ls(sl=1) curves = [] ik_handle_list = [] ik_spline_crv_list = [] joint_list = [] joint_chain_dict = {} grp_list = [] # Creating brand new, clean curves out of selection for j, n in enumerate(raw_curves, 1): new_curve = mc.duplicate(n, n="{}_Loft_Crv{}".format(name, j)) try: mc.parent(new_curve, w=1) except: pass mc.makeIdentity(new_curve, apply=True, t=1, r=1, s=1, n=0) mc.delete(new_curve, ch=1) mc.xform(new_curve, cp=1) curves.append(new_curve[0]) # Joint chain and ikSpline section for n, n in enumerate(curves): crv_joint_list = joint_on_curve_cvs(path_crv=n) parent_in_order(sel=crv_joint_list) mc.joint(crv_joint_list, e=1, oj="xyz", secondaryAxisOrient="yup") joint_chain_dict.update({n: crv_joint_list}) joint_list.append(crv_joint_list[0]) mc.select(cl=1) if add_ik == 1: # Creating ikSpline - rename curve - append to grouping lists ik_handle_data = mc.ikHandle(sj=crv_joint_list[0], ee=crv_joint_list[-1], sol="ikSplineSolver", n=n + "_ikHandle") ik_crv = mc.rename(ik_handle_data[2], "{}_ikSpline_Crv{}".format(name, n + 1)) ik_handle_list.append(ik_handle_data[0]) ik_spline_crv_list.append(ik_crv) if stretchy == 1: make_stretchy_spline(crv_joint_list, ik_crv, new_curve[0]) if n == 0: # If it is the first loop - create groups - else - parent new items ik_grp = mc.group(ik_handle_data[0], n=name + "_ikHandle_Grp") spline_grp = mc.group(ik_crv, n=name + "_ikSpline_Crv_Grp") grp_list.append(ik_grp) grp_list.append(spline_grp) else: mc.parent(ik_handle_data[0], ik_grp) mc.parent(ik_crv, spline_grp) if bind == 1: mc.skinCluster(crv_joint_list, n) if loft == 1: loft_data = mc.loft(curves, ch=1, u=1, c=0, ar=0, d=3, ss=10, rn=0, po=1, rsn=1) loft_srf = mc.rename(loft_data[0], name + "_LoftSrf_Geo") loft_grp = mc.group(loft_srf, n=name + "_LoftSrf_Geo_Grp") grp_list.append(loft_grp) if cluster == 1 and add_ik == 1: # Creates clusters holding the same cv on each ikSpline curve # Calculating the number of Cv's for loop curve_deg = mc.getAttr(ik_spline_crv_list[0] + ".degree") curve_spa = mc.getAttr(ik_spline_crv_list[0] + ".spans") # CV's = degrees + spans cv_count = curve_deg + curve_spa cls_list = [] for n in range(cv_count): mc.select(cl=1) for j in ik_spline_crv_list: mc.select("{}.cv[{}]".format(j, n), add=1) cluster = mc.cluster(n="{}_Csl{}".format(name, n)) cls_list.append(cluster[1]) cluster_grp = mc.group(cls_list, n=name + "_Cls_Grp") grp_list.append(cluster_grp) else: mc.warning("addIk is off") curves_grp = mc.group(curves, n="{}_Loft_Crv_Grp".format(name)) joint_grp = mc.group(joint_list, n=name + "_Jnt_Grp") grp_list.append(curves_grp) grp_list.append(joint_grp) sys_grp = mc.group(grp_list, n=name + "_Sys_Grp") return sys_grp
def Add_Crv_Pick_Fun(self): if len(cmds.ls(sl=True)) > 0: Selection = cmds.ls(sl=True,l=1)[0] SelectionShape = cmds.listRelatives(Selection)[0] SelectionType = cmds.nodeType( SelectionShape ) if SelectionType == "nurbsCurve": self.Add_Crv_LE.setText(Selection) try : self.Add_Crv_Get.clicked.disconnect() except: pass self.Add_Crv_Get.clicked.connect(partial(self.Select_OBJ_Fun,cmds.ls(Selection)) else: cmds.warning(u"请选择nurbsCurve进行获取") cmds.headsUpMessage(u"请选择Curve进行获取") else : self.Add_Crv_LE.setText("") if self.Add_Crv_LE.text() != "": self.Add_Crv_Label.setVisible(False) self.Add_Crv_Get.setVisible(True) else: self.Add_Crv_Label.setVisible(True) self.Add_Crv_Get.setVisible(False) def Add_Loc_Pick_Fun(self): if len(cmds.ls(sl=True)) > 0 : Selection = cmds.ls(sl=True,l=1)[0] SelectionShape = cmds.listRelatives(Selection)[0] SelectionType = cmds.nodeType( SelectionShape ) if SelectionType == "locator": self.Add_Loc_LE.setText(Selection) try : self.Add_Loc_Get.clicked.disconnect() except: pass self.Add_Loc_Get.clicked.connect(partial(self.Select_OBJ_Fun,Selection)) else: cmds.warning(u"请选择Locator进行获取") cmds.headsUpMessage(u"请选择Locator进行获取") else : self.Add_Loc_LE.setText("") if self.Add_Loc_LE.text() != "": self.Add_Loc_Label.setVisible(False) self.Add_Loc_Get.setVisible(True) else: self.Add_Loc_Label.setVisible(True) self.Add_Loc_Get.setVisible(False) def Cam_Input_Toggle_Fn(self): if self.Cam_Input_Toggle_Check: self.Cam_Input_Toggle_Check = False self.Cam_Input_Toggle_Anim.setDirection(QAbstractAnimation.Forward) self.Cam_Input_Toggle_Anim.start() self.Cam_Input_Toggle.setText(u"▼输入设置") self.Cam_Input_Toggle.setStyleSheet('font:normal') else: self.Cam_Input_Toggle_Check = True self.Cam_Input_Toggle_Anim.setDirection(QAbstractAnimation.Backward) self.Cam_Input_Toggle_Anim.start() self.Cam_Input_Toggle.setText(u"■输入设置") self.Cam_Input_Toggle.setStyleSheet('font:bold') def Cam_Output_Toggle_Fn(self): if self.Cam_Output_Toggle_Check: self.Cam_Output_Toggle_Check = False self.Cam_Output_Toggle_Anim.setDirection(QAbstractAnimation.Forward) self.Cam_Output_Toggle_Anim.start() self.Cam_Output_Toggle.setText(u"▼输出设置") self.Cam_Output_Toggle.setStyleSheet('font:normal') else: self.Cam_Output_Toggle_Check = True self.Cam_Output_Toggle_Anim.setDirection(QAbstractAnimation.Backward) self.Cam_Output_Toggle_Anim.start() self.Cam_Output_Toggle.setText(u"■输出设置") self.Cam_Output_Toggle.setStyleSheet('font:bold') def Select_OBJ_Fun(self,selectTarget): if selectTarget != "": cmds.select(selectTarget)
def processSHDTemplate(self, tk, templateFile = '', assetDict = {}, selected = False): """ Used to fetch most recent publishes @param tk : tank instance @param templateFile: the tank template file specified in the shot_step.yml #param assetDict: dict in format assetName, assetParent @type templateFile: template """ debug(self.app, method = 'processTemplates', message = 'assetDict: %s' % assetDict, verbose = False) myFinalAssetDict = {} ## Now fetch all the SRF template paths from shotgun getTemplatePaths = tk.paths_from_template(templateFile, {'Step' : 'SRF'}) #debug(self.app, method = 'processTemplates', message = 'getTemplatePaths: %s' % getTemplatePaths, verbose = False) ## Now look for each assets template path: for key, var in assetDict.items(): debug(self.app, method = 'processTemplates', message = 'Processing asset %s now' % key, verbose = False) versions = [] for eachPath in getTemplatePaths: ### IN scene we get CHAR_Zip_hrc ### then we break this back to the publish names that are NOT allowed to have _'s ### The publish file names are then CHARZip ### BUT a really intelligent Co-Ord decided to make ad asset called CHAR_ZIP_RustryPropeller... that broke the code looking for CharZip as now we have more than one ### So we have to be able to; ## Accomodate the following... Char_Zip_hrc Char_Zip_hrc1 Char_Zip_RustryPropellor_hrc #'I:\\bubblebathbay\\assets\\CharacterA\\CHAR_Zip_RustyPropeller\\SRF\\publish\\xml\\CHARZip.v001.xml' #'I:\\bubblebathbay\\assets\\CharacterA\\CHAR_Zip_RustyPropeller\\SRF\\publish\\xml\\CHARZipRustyPropeller.v001.xml' splitPathToAssetName = eachPath.split('\\')[4] #debug(self.app, method = 'processTemplates', message = 'splitPathToAssetName: %s' % splitPathToAssetName, verbose = False) if key.lower() == splitPathToAssetName.lower(): versions.append(eachPath) # debug(self.app, method = 'processTemplates', message = 'versions.... %s' % versions, verbose = False) ## Now if versions has stuff in it.. if versions: if selected: myFinalAssetDict[key] = [max(versions), var[0], var[1]] else: myFinalAssetDict[key] = [max(versions), var] else: debug(self.app, method = 'processTemplates', message = '%s does not have an xml file published.' % key, verbose = False) pass debug(self.app, method = 'processTemplates', message = 'myFinalAssetDict: %s' % myFinalAssetDict, verbose = False) # {u'CHAR_Sydney': ['I:\\bubblebathbay\\assets\\CharacterA\\CHAR_Sydney\\SRF\\publish\\xml\\CHARSydney.v056.xml', u'|ABC_ANIM_CACHES_hrc']} allNodes = {} for key, var in myFinalAssetDict.items(): XMLPath = var[0].replace(os.path.sep, "/") root = xml.parse(XMLPath).getroot() nodes = [each for each in root.getchildren()[0] if each.tag == 'Nodes'][0] shadingEngines = [each for each in root.getchildren()[0] if each.tag == 'ShadingEngine'][0] for each in nodes.getchildren(): allNodes.setdefault(each.tag, []) allNodes[each.tag].append(key) for each in shadingEngines.getchildren(): sgName = each.attrib['value'].split(',')[0] allNodes.setdefault(sgName, []) allNodes[sgName].append(key) ## Create .txt for modelers as reference rebuildShader = 'Continue anyway...' shadingDupeCheck = [dupe for dupe in allNodes.itervalues() if len(dupe) > 1] if shadingDupeCheck: import datetime currentDateTime = datetime.datetime.now().strftime("%Y%m%d.%H%M") _filePath = 'C:/Temp/shadingNodeNameClash.%s.txt' % currentDateTime _file = open(_filePath, 'w') for k, v in allNodes.iteritems(): if len(v) > 1: _file.writelines('%s:\r\n' % k) for dupe in v: _file.writelines('\t%s\r\n' % dupe) _file.writelines('\r\n') _file.close() ## Give warning to the artist that there's shading node name clashes dupeString = 'Shading node name clashes found across multiple assets. Please be advised that this process probably won\'t rebuild 100% as SRF file due to name clashes, a republish of unique shading node name is needed! A Reference .txt of what\'s clashing was compiled at below path.\r\n\r\n' #dupeString += _filePath #rebuildShader = cmds.confirmDialog(title = 'SHADER REBUILD', message = dupeString, button = ['Continue anyway...', 'Cancel'], defaultButton = 'Continue anyway...', cancelButton = 'Cancel', dismissString = 'Cancel') cmds.warning(dupeString) #if rebuildShader == 'Continue anyway...': for key, var in myFinalAssetDict.items(): debug(self.app, method = 'processTemplates', message = 'key %s ...' % key, verbose = False) debug(self.app, method = 'processTemplates', message = 'var[0] %s ...' % var[0], verbose = False) debug(self.app, method = 'processTemplates', message = 'var[1] %s ...' % var[1], verbose = False) if os.path.isfile(var[0].replace(os.path.sep, "/")): debug(self.app, method = 'processTemplates', message = 'Creating shaders for %s now with path %s ...' % (key, var[0].replace(os.path.sep, "/")), verbose = False) debug(self.app, method = 'processTemplates', message = 'parentGrp: %s' % var[1], verbose = False) if selected: shd.createAll(XMLPath = var[0].replace(os.path.sep, "/"), parentGrp = var[1], Namespace = '', Root = 'MaterialNodes', selected = True, selectedOrigHrcName = var[2]) debug(self.app, method = 'processTemplates', message = 'Connecting shaders for %s now with path %s ...' % (key, var[0].replace(os.path.sep, "/")), verbose = False) versionNumber = var[0].replace(os.path.sep, "/").split('.')[-2].split('v')[-1] shd.connectAll(XMLPath = var[0].replace(os.path.sep, "/"), parentGrp= var[1], Namespace = '', Root = 'MaterialNodes', selected = True, selectedOrigHrcName = var[2], xmlVersionNumber = versionNumber) # ## Now add the version tag to the selected _hrc asset group # versionNumber = var[0].replace(os.path.sep, "/").split('.')[-2].split('v')[-1] # debug(self.app, method = 'processTemplates', message = 'JAMES SHD VERS NUMBER!!!! %s' % versionNumber, verbose = False) # self._addVersionTag(var[2], versionNumber) else: shd.createAll(XMLPath = var[0].replace(os.path.sep, "/"), parentGrp = var[1], Namespace = '', Root = 'MaterialNodes') debug(self.app, method = 'processTemplates', message = 'Connecting shaders for %s now with path %s ...' % (key, var[0].replace(os.path.sep, "/")), verbose = False) versionNumber = var[0].replace(os.path.sep, "/").split('.')[-2].split('v')[-1] shd.connectAll(XMLPath = var[0].replace(os.path.sep, "/"), parentGrp= var[1], Namespace = '', Root = 'MaterialNodes', xmlVersionNumber = versionNumber) else: debug(self.app, method = 'processTemplates', message = 'FAILED: No valid published xml file found for %s ...' % (key, var[0].replace(os.path.sep, "/")), verbose = False) pass
def uv_from_element(element): """Return the UV coordinate of given 'element' Supports components, meshes, nurbs. """ supported = ["mesh", "nurbsSurface"] uv = [0.5, 0.5] if "." not in element: type = cmds.nodeType(element) if type == "transform": geometry_shape = cmds.listRelatives(element, shapes=True) if len(geometry_shape) >= 1: geometry_shape = geometry_shape[0] else: return elif type in supported: geometry_shape = element else: cmds.error("Could not do what you wanted..") return else: # If it is indeed a component - get the current Mesh try: parent = element.split(".", 1)[0] # Maya is funny in that when the transform of the shape # of the component elemen has children, the name returned # by that elementection is the shape. Otherwise, it is # the transform. So lets see what type we're dealing with here. if cmds.nodeType(parent) in supported: geometry_shape = parent else: geometry_shape = cmds.listRelatives(parent, shapes=1)[0] if not geometry_shape: cmds.error("Skipping %s: Could not find shape." % element) return if len(cmds.ls(geometry_shape)) > 1: cmds.warning("Multiple shapes with identical " "names found. This might not work") except TypeError as e: cmds.warning("Skipping %s: Didn't find a shape " "for component elementection. %s" % (element, e)) return try: type = cmds.nodeType(geometry_shape) if type == "nurbsSurface": # If a surfacePoint is elementected on a nurbs surface root, u, v = element.rsplit("[", 2) uv = [float(u[:-1]), float(v[:-1])] if type == "mesh": # ----------- # Average the U and V values # =========== uvs = cmds.polyListComponentConversion(element, toUV=1) if not uvs: cmds.warning("Couldn't derive any UV's from " "component, reverting to default U and V") raise TypeError # Flatten list of Uv's as sometimes it returns # neighbors like this [2:3] instead of [2], [3] flattened = [] for uv in uvs: flattened.extend(cmds.ls(uv, flatten=True)) uvs = flattened sumU = 0 sumV = 0 for uv in uvs: try: u, v = cmds.polyEditUV(uv, query=True) except: cmds.warning("Couldn't find any UV coordinated, " "reverting to default U and V") raise TypeError sumU += u sumV += v averagedU = sumU / len(uvs) averagedV = sumV / len(uvs) uv = [averagedU, averagedV] except TypeError: pass return uv
def fetchShadersForSelected(self, tk): """ Function to handle fetching the shaders for selected _hrc groups only. """ inprogressBar = pbui.ProgressBarUI(title = 'Building Shaders For Selected Assets:') inprogressBar.show() inprogressBar.updateProgress(percent = 5, doingWhat = 'Processing scene info...') if self.mcLoaded: ## ASSSIGN DEFAULT LAMBERT AND CLEAN THE HYERPSHADE! for each in cmds.ls(sl = True): try: cmds.sets(each, e = True , forceElement = 'initialShadingGroup') except: cmds.warning('FAILED to set initial Shading group for %s' % each) pass [cmds.lockNode(cp, lock = True) for cp in cmds.ls(type = 'core_renderpass')] ## Lock all the core_renderpasses before deleting unused to preserve... mel.eval("MLdeleteUnused();") scene_path = '%s' % os.path.abspath(cmds.file(query=True, sn= True)) debug(self.app, method = 'fetchShadersForSelected', message = 'scene_path... %s' % scene_path, verbose = False) ## Build an entity type to get some values from. entity = self.app.context.entity ## returns {'type': 'Shot', 'name': 'ep100_sh010', 'id': 1166} debug(self.app, method = 'fetchShadersForSelected', message = 'entity... %s' % entity, verbose = False) ## Filter for the matching ID for the shot sg_filters = [["id", "is", entity["id"]]] debug(self.app, method = 'fetchShadersForSelected', message = 'sg_filters... %s' % sg_filters, verbose = False) ## Build an entity type to get some values from. sg_entity_type = self.app.context.entity["type"] ## returns Shot debug(self.app, method = 'fetchShadersForSelected', message = 'sg_entity_type...\n%s' % sg_entity_type, verbose = False) ## DATA ## NOTES SO HERE WE DON'T NEED TO CALL THE ASSETS FIELD FROM SHOTGUN ## WE CAN JUST GRAB THE LATEST PUBLISH FILE FROM EACH OF THE TEMPLATE STEPS inprogressBar.updateProgress(percent = 10, doingWhat = 'Processing scene info...') shadersTemplate = tk.templates[self.app.get_setting('maya_asset_SHD_XML_template')] debug(self.app, method = 'fetchShadersForSelected', message = 'shadersTemplate...\n%s' % shadersTemplate, verbose = False) texturesTemplate = tk.templates[self.app.get_setting('maya_asset_textures_template')] debug(self.app, method = 'fetchShadersForSelected', message = 'texturesTemplate...\n%s' % texturesTemplate, verbose = False) ## Now get a list of assets in the scene inprogressBar.updateProgress(percent = 15, doingWhat = 'Processing assets...') inprogressBar.updateProgress(percent = 20, doingWhat = 'Processing xml...') assetDict = {} ## key: shotgunName var: inSceneName for grp in cmds.ls(sl= True): if cmds.ls(grp, dag=True, type="mesh"): getParent = cmds.listRelatives(grp, parent = True) if getParent: assetDict[grp.split('_hrc')[0]] = [cmds.listRelatives(grp, parent = True)[0], grp] else: assetDict[grp.split('_hrc')[0]] = ['', grp] ##make the parentGroup nothing so it paths to a root asset in the scene correctly debug(self.app, method = 'fetchShadersForSelected', message = 'Assets... %s' % assetDict, verbose = False) ## Now process XML debug(self.app, method = 'fetchShadersForSelected', message = 'Processing template... %s' % shadersTemplate, verbose = False) self.processSHDTemplate(tk = tk, templateFile = shadersTemplate, assetDict = assetDict, selected = True) self.finalBuildStuff(True, inprogressBar) else: inprogressBar.close() cmds.warning("NO MENTAL CORE FOUND!") pass
def MCR_FrozenTransforms(xmlDefaults, *args): gradeValue = { 'Aplus': int(xmlDefaults.find('gradeValue').find('Aplus').text), 'F': int(xmlDefaults.find('gradeValue').find('F').text), } development = True if development: print 'MCR Frozen Transforms running' gMainProgressBar = maya.mel.eval('$tmp = $gMainProgressBar') cmds.progressBar(gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Checking Transforms', maxValue=100) step = 100 / 7 cmds.progressBar(gMainProgressBar, edit=True, step=step) utils = utilities.utilities() cmds.progressBar(gMainProgressBar, edit=True, step=step) rootNodes = utils.masterGroupTest() cmds.progressBar(gMainProgressBar, edit=True, step=step) collectedNodes = utils.nodeCollector(rootNodes) cmds.progressBar(gMainProgressBar, edit=True, step=step) sortedNodes = utils.sortNodeList(collectedNodes, 'transform') cmds.progressBar(gMainProgressBar, edit=True, step=step) hasTransforms = utils.frozenTransforms(sortedNodes) cleanedNodes = [] if hasTransforms: for node in hasTransforms: # print ('node: {}'.format(node)) try: if cmds.listRelatives(node): # print('listRelatives(node): {}'.format(cmds.listRelatives(node))) f_type = cmds.nodeType( cmds.listRelatives(node, path=True)[0]) if f_type not in ('imagePlane', 'camera'): cleanedNodes.append(node) except RuntimeError: cmds.warning('RuntimeError Occurred - Adding node anyway...') cmds.warning('Problematic node: {}'.format(node)) cleanedNodes.append(node) redFlagNodes = [] for node in cleanedNodes: # print('checking node: {}'.format(node)) # print('Relatives: {}'.format(cmds.listRelatives(node))) if cmds.listRelatives(node) != None: if len(cmds.listRelatives(node)) <= 2: # print('{} has <= 1 relatives'.format(node)) # print('Relatives: {}'.format(cmds.listRelatives(node))) for relative in cmds.listRelatives(node, path=True): if cmds.nodeType(relative) not in ('transform', 'shape'): # print ('Red Flag!: {}'.format(node)) if node not in redFlagNodes: redFlagNodes.append(node) if len(redFlagNodes): # print('red flag nodes!!!\n{}'.format(redFlagNodes)) for node in redFlagNodes: # print('removing node: {}'.format(node)) cleanedNodes.remove(node) if development: print 'cleanedNodes: {}'.format(cleanedNodes) cmds.progressBar(gMainProgressBar, edit=True, step=step) print "Frozen Transforms Automation Successful!" if cleanedNodes: # if development: # print cleanedNodes tempDict = { 'grade_value': gradeValue['F'], 'comment_text': '', 'default_comments_text': 'Object has non frozen transforms.', 'example_comments_text': '' } else: tempDict = { 'grade_value': gradeValue['Aplus'], 'comment_text': '', 'default_comments_text': 'Transforms Frozen! Good job!', 'example_comments_text': '' } cmds.progressBar(gMainProgressBar, edit=True, step=step) cmds.progressBar(gMainProgressBar, edit=True, endProgress=True) return tempDict
def assignLODs(self, *args): """ Creates LOD group based off triangle count of meshes selected Warnings: 'Select more than one mesh to generate LODs' 'Multiple lodGroups are parented to selected Meshes' """ if not self._hasSelection(): return selection = cmds.ls(sl=True, l=True) #Checks if the user has selected at least 2 meshes if len(selection) < 2: cmds.warning('Select more than one mesh to generate LODs') return #Checks for LOD groups lodGroups = [] lodMeshes = [] collisionGroups = [] for selected in selection: selectedShort = selected.split('|')[-1] collisionGroup = '|SM_%s|%s_Collision' % (selectedShort, selectedShort) if cmds.objExists('|SM_%s|%s_Collision' % (selectedShort, selectedShort)): collisionGroups.append(collisionGroup) parent = cmds.listRelatives(selected, f=True, p=True) if parent: cleanParent = parent[0][:parent[0].rfind('|')] if cleanParent: if cmds.nodeType(cleanParent) == 'lodGroup': if parent not in lodGroups: lodGroups.append(cleanParent) if len(lodGroups) > 1: cmds.warning('Multiple LOD groups are parented to selected Meshes') return elif len(collisionGroups) > 1: cmds.warning( 'Multiple collision groups are parented to selected Meshes') return elif len(lodGroups) == 1: cfd = cmds.confirmDialog(title='Confirm', message='Are trying to add LODs to %s?' % lodGroups[0].split('|')[1], button=['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No') if cfd == 'No': return else: #Creates list of lodgroup relatives relatives = cmds.listRelatives('|%s' % lodGroups[0], f=True) for relative in relatives: lod = str(cmds.listRelatives(relative, f=True)) for char in [' ', '[', ']']: lod = lod.replace(char, "") lod = lod.split(',') for mesh in lod: lodMeshes.append(unicode(mesh[2:-1])) #Removes duplicates for lodMesh in lodMeshes: for selected in selection: if selected in lodMesh: selection.remove(selected) #need to research u'n' is in list when item under |lodGroup|lod_#|u'n' when mesh is deleted while 'n' in lodMeshes: lodMeshes.remove('n') elif len(collisionGroups) == 1: cfd = cmds.confirmDialog(title='Confirm', message='Are trying to add LODs to %s?' % collisionGroups[0].split('|')[1], button=['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No') if cfd == 'No': cmds.warning( 'Remove any selections under %s before trying to assign LODs' ) return else: pass lodMeshes = lodMeshes + selection #Gets triangle count of mesh meshesInfo = [] for lodMesh in lodMeshes: cmds.select(lodMesh) meshInfo = {} meshInfo['object'] = lodMesh meshInfo['triangles'] = cmds.polyEvaluate(t=True) meshesInfo.append(meshInfo) cmds.select(cl=True) #Sorts array by triangle count from high to low meshesInfo = sorted(meshesInfo, key=operator.itemgetter('triangles'), reverse=True) #Finds renderMeshName, lodGroup name, location in WS if lodGroups: renderMeshName = lodGroups[0].split('|')[1].replace('SM_', '') elif collisionGroups: renderMeshName = collisionGroups[0].split('|')[1].replace( 'SM_', '') else: renderMeshName = self._checkRenderMeshName( meshesInfo[0]['object'].split('|')[-1]) #shortname lodGroup = renderMeshName + '_LOD' cmds.select(meshesInfo[0]['object']) #Renames and moves meshes to 0,0,0 in world space if cmds.listRelatives(meshesInfo[0]['object'], p=True): meshesInfo[0]['object'] = cmds.parent(meshesInfo[0]['object'], w=True)[0] meshesInfo[0]['object'] = cmds.rename(meshesInfo[0]['object'], renderMeshName) for i, meshInfo in enumerate(meshesInfo[1:]): newName = 'LOD_%s_%02d' % (renderMeshName, i + 1) mesh = cmds.rename(meshInfo['object'], newName) if cmds.listRelatives(mesh, p=True): cmds.parent(mesh, w=True) meshInfo['object'] = newName #Deletes old LOD group if cmds.objExists('|SM_%s|%s' % (renderMeshName, lodGroup)): cmds.delete('|SM_%s|%s' % (renderMeshName, lodGroup)) #Creates lodGroup based on triangle count for meshInfo in meshesInfo: cmds.select('|%s' % meshInfo['object'], add=True) cmds.xform(ws=True, t=(0, 0, 0)) cmds.LevelOfDetailGroup() lodGroup = cmds.rename(lodGroup) for i in range(len(meshesInfo)): cmds.setAttr('%s.displayLevel[%d]' % (lodGroup, i), 1) renderMeshGroup = self.createMainGroup(renderMeshName) cmds.parent(lodGroup, renderMeshGroup) cmds.select(cl=True)
def fetchAllShaders(self, tk): """ Function to handle fetching the shaders """ inprogressBar = pbui.ProgressBarUI(title = 'Building Shaders for All Assets:') inprogressBar.show() if self.mcLoaded: inprogressBar.updateProgress(percent = 5, doingWhat = 'Processing scene info...') scene_path = '%s' % os.path.abspath(cmds.file(query=True, sn= True)) debug(self.app, method = 'fetchAllShaders', message = 'scene_path... %s' % scene_path, verbose = False) ## Build an entity type to get some values from. entity = self.app.context.entity ## returns {'type': 'Shot', 'name': 'ep100_sh010', 'id': 1166} debug(self.app, method = 'fetchAllShaders', message = 'entity... %s' % entity, verbose = False) ## Filter for the matching ID for the shot sg_filters = [["id", "is", entity["id"]]] debug(self.app, method = 'fetchAllShaders', message = 'sg_filters... %s' % sg_filters, verbose = False) ## Build an entity type to get some values from. sg_entity_type = self.app.context.entity["type"] ## returns Shot debug(self.app, method = 'fetchAllShaders', message = 'sg_entity_type...\n%s' % sg_entity_type, verbose = False) ## DATA ## NOTES SO HERE WE DON'T NEED TO CALL THE ASSETS FIELD FROM SHOTGUN ## WE CAN JUST GRAB THE LATEST PUBLISH FILE FROM EACH OF THE TEMPLATE STEPS inprogressBar.updateProgress(percent = 10, doingWhat = 'Processing scene info...') shadersTemplate = tk.templates[self.app.get_setting('maya_asset_SHD_XML_template')] debug(self.app, method = 'fetchAllShaders', message = 'shadersTemplate...\n%s' % shadersTemplate, verbose = False) texturesTemplate = tk.templates[self.app.get_setting('maya_asset_textures_template')] debug(self.app, method = 'fetchAllShaders', message = 'texturesTemplate...\n%s' % texturesTemplate, verbose = False) ## Now get a list of assets in the scene inprogressBar.updateProgress(percent = 15, doingWhat = 'Processing assets...') inprogressBar.updateProgress(percent = 20, doingWhat = 'Processing UV and SHD XML files...') assetDict = {} ## key: shotgunName var: inSceneName dupAssets = {} for parentGrp in cmds.ls(assemblies = True, long = True): if cmds.ls(parentGrp, dag=True, type="mesh"): for each in cmds.listRelatives(parentGrp, children = True): ## Check for duplicate or base assets if not cmds.objExists('%s.dupAsset' % each): assetDict[each.split('_hrc')[0]] = parentGrp #{assetName: parentGrpName} else: # handle the duplicate naming origAssetName = each.split('_hrc')[0] dupAssets[each] = [origAssetName, parentGrp] #{duplicateGrName : [origAssetName, parentGrpName]} debug(self.app, method = 'fetchAllShaders', message = 'DUPLICATE FOUND... origAssetName: %s' % origAssetName, verbose = False) debug(self.app, method = 'fetchAllShaders', message = 'Assets... %s' % assetDict, verbose = False) debug(self.app, method = 'fetchAllShaders', message = 'Duplicate Assets... %s' % dupAssets, verbose = False) ## Now process SHD XML debug(self.app, method = 'fetchAllShaders', message = 'Processing template... %s' % shadersTemplate, verbose = False) self.processSHDTemplate(tk = tk, templateFile = shadersTemplate, assetDict = assetDict, selected = False) self.finalBuildStuff(False, inprogressBar) else: inprogressBar.close() cmds.warning("NO MENTAL CORE FOUND!")