def get_invalid(cls, instance): from maya import cmds import reveries.maya.xgen.legacy as xgen invalid = list() cmds.filePathEditor(refresh=True) missing = (cmds.filePathEditor(query=True, listFiles="", withAttribute=True, byType="xgmDescription", unresolved=True) or [])[1::2] for map_attr in missing: path, parents = xgen.parse_map_path(map_attr) palette, description, obj, attr, index = parents if description in instance.data["xgenDescriptions"]: if obj in xgen.list_fx_modules(description, activated=False): # Ignore if not active continue if xgen.is_modifier_under_bake_manager(palette, description, obj): # Ignore if obj is a modifier and is under an active bake # groom manager cls.log.warning("Map missing but baked, ignored.") cls.log.warning(path) continue invalid.append((parents, path)) return invalid
def parse_description_maps(description): """Get all path of maps and attributes which used them by description Args: description (str): XGen Legacy description name Returns: list: A list of tuple of file path and attribute objects """ cmds.filePathEditor(refresh=True) resloved = (cmds.filePathEditor(query=True, listFiles="", withAttribute=True, byType="xgmDescription", unresolved=False) or []) desc_shape_long = get_description_long_name(description, shape=True) for map_attr, fname in zip(resloved[1::2], resloved[0::2]): desc_shape = map_attr.split(".", 1)[0] if desc_shape_long not in cmds.ls(desc_shape, type="xgmDescription", long=True): continue path, parents = parse_map_path(map_attr) if not (path.endswith(".ptx") or path.endswith(".abc")): sep = "" if path.endswith("/") else "/" path += sep + fname yield path, parents
def list_referenced_files(): results = [] links = cmds.filePathEditor(query=True, listDirectories="") for link in links: pairs = cmds.filePathEditor(query=True, listFiles=link, withAttribute=True, status=True) ''' paris: list of strings ["file_name node status ...", "file_name node status ...",...] we need to make this large list of ugly strings (good inforamtion seperated by white space) into a dictionry we can use ''' l = len(pairs) items = l / 3 order = {} index = 0 ''' order: dict of {node: [file_name, status],...} ''' for i in range(0, items): order[pairs[index + 1]] = [ os.path.join(link, pairs[index]), pairs[index + 1], pairs[index + 2] ] index = index + 3 for key in order: # for each item in the dict, if the status is 0, repath it if order[key][2] == "1": results.append([order[key][0], cmds.nodeType(order[key][1])]) return results
def relink_pathes(project_path = None): results = [] links = cmds.filePathEditor(query=True, listDirectories="") for link in links: pairs = cmds.filePathEditor(query=True, listFiles=link, withAttribute=True, status=True) ''' paris: list of strings ["file_name node status ...", "file_name node status ...",...] we need to make this large list of ugly strings (good inforamtion seperated by white space) into a dictionry we can use ''' l = len(pairs) items = l/3 order = {} index = 0 ''' order: dict of {node: [file_name, status],...} ''' for i in range(0,items): order[pairs[index+1]] = [pairs[index],pairs[index+2]] index = index + 3 for key in order: # for each item in the dict, if the status is 0, repath it if order[key][1] == "0": if repath(key,order[key][0],project_path): results.append(key) return results
def list_referenced_files(): results = [] links = cmds.filePathEditor(query=True, listDirectories="") for link in links: pairs = cmds.filePathEditor(query=True, listFiles=link, withAttribute=True, status=True) ''' paris: list of strings ["file_name node status ...", "file_name node status ...",...] we need to make this large list of ugly strings (good inforamtion seperated by white space) into a dictionry we can use ''' l = len(pairs) items = l/3 order = {} index = 0 ''' order: dict of {node: [file_name, status],...} ''' for i in range(0,items): order[pairs[index+1]] = [os.path.join(link,pairs[index]),pairs[index+1],pairs[index+2]] index = index + 3 for key in order: # for each item in the dict, if the status is 0, repath it if order[key][2] == "1": results.append([order[key][0],cmds.nodeType(order[key][1])]) return results
def cleanTexturePaths(): fileNodes = cmds.ls(type='file') #project folder workspace = cmds.workspace(q=True, directory=True, rd=True) #texture folder textureFolder = cmds.workspace(fre='sourceImages') #full path fullPath = os.path.realpath('%s%s' % (workspace, textureFolder)) for f in fileNodes: imgPath = cmds.getAttr('%s.fileTextureName' % f) parentFolder, remainingPath = getParentFolder() relativePath = '%s/%s' % (remainingPath, imgPath.split('/')[-1]) #check if the file exists if os.path.isfile('%s/%s' % (fullPath, relativePath)): #change path cmds.filePathEditor('%s.fileTextureName' % f, repath=relativePath.rsplit('/', 1)[0], f=True) #check if file exists in wrong place elif os.path.isfile(imgPath): copyfile(imgPath, '%s/%s' % (fullPath, relativePath)) #update path cmds.filePathEditor('%s.fileTextureName' % f, repath=relativePath.rsplit('/', 1)[0], f=True)
def relink_pathes(project_path=None): results = [] links = cmds.filePathEditor(query=True, listDirectories="") for link in links: pairs = cmds.filePathEditor(query=True, listFiles=link, withAttribute=True, status=True) ''' paris: list of strings ["file_name node status ...", "file_name node status ...",...] we need to make this large list of ugly strings (good inforamtion seperated by white space) into a dictionry we can use ''' l = len(pairs) items = l / 3 order = {} index = 0 ''' order: dict of {node: [file_name, status],...} ''' for i in range(0, items): order[pairs[index + 1]] = [pairs[index], pairs[index + 2]] index = index + 3 for key in order: # for each item in the dict, if the status is 0, repath it if order[key][1] == "0": if repath(key, order[key][0], project_path): results.append(key) return results
def validateFiles(): logging('Repath scene') # TODO: repath from folder with group unresolved_files = cmds.filePathEditor(query=True, listFiles='', unresolved=True, attributeOnly=True) if unresolved_files: for item in unresolved_files: cmds.filePathEditor(item, repath=RES_PATH, recursive=True, ra=1)
def textName(self, evt): filelist = self.filelist empty_name = [] or_ = cmds.textFieldGrp('obj1', query=True, tx=True) ch_ = cmds.textFieldGrp('obj2', query=True, tx=True) cmds.filePathEditor(refresh=True) for i in filelist: fPath = cmds.getAttr(i + ".fileTextureName") print fPath, i + ".fileTextureName" setName = cmds.filePathEditor(i + ".fileTextureName", replaceField="nameOnly", replaceString=(or_, ch_), replaceAll=True) self.texReload return setName
def RepathTextureFiles(targetDir): fileNodeAttrList = cmds.filePathEditor(query=True, listFiles="", attributeOnly=True) if fileNodeAttrList: validTexFileNodeAttrList = [] for curAttr in fileNodeAttrList: if re.search("\.", curAttr): fileNode = re.sub("\.[^.]+$", "", curAttr) if not cmds.referenceQuery( fileNode, isNodeReferenced=True) and cmds.objectType( fileNode) in mlNodeDef.textureNode: validTexFileNodeAttrList.append(curAttr) if len(validTexFileNodeAttrList) > 0: cmds.filePathEditor(validTexFileNodeAttrList, repath=targetDir, force=True)
def get_invalid(cls, instance): from maya import cmds invalid = list() cmds.filePathEditor(refresh=True) unresloved = (cmds.filePathEditor(query=True, listFiles="", withAttribute=True, byType="file", unresolved=True) or []) for map_attr in unresloved[1::2]: file_node = map_attr.split(".", 1)[0] if file_node in instance: invalid.append(file_node) return invalid
def nodes(withAttribute = True, ignoreReference = True): """ 获取file节点 :rtype: list """ _list = [] cmds.filePathEditor(rf = 1) item = cmds.filePathEditor(query=True, listFiles="", unresolved=False, withAttribute=True) if item: files = item[0::2] nodes = item[1::2] for _file,_node_attr in zip(files,nodes): _node = _node_attr.split(".")[0] if os.path.splitext(_file)[-1].lower() in TEX_SUFFIX: _is_reference = cmds.referenceQuery(_node, isNodeReferenced = True) if _is_reference and ignoreReference: continue if withAttribute: _list.append(_node_attr) else: _list.append(_node) return _list
def repath(node, file, project_path): matches = [] for root, dirnames, filenames in os.walk(project_path): for x in filenames: if x == file: matches.append([root,os.path.join(root, x)]) elif x.split(".")[0] == file.split(".")[0]: #---> this second option is used when a file is useing ##### padding, we can match by name only x_ext = x.split(".")[len(x.split("."))-1] file_ext = file.split(".")[len(file.split("."))-1] if x_ext == file_ext: matches.append([root,os.path.join(root, x)]) if len(matches)>0: return cmds.filePathEditor(node, repath=matches[0][0]) return None
def repath(node, file, project_path): matches = [] for root, dirnames, filenames in os.walk(project_path): for x in filenames: if x == file: matches.append([root, os.path.join(root, x)]) elif x.split(".")[0] == file.split(".")[ 0]: # ---> this second option is used when a file is useing ##### padding, we can match by name only x_ext = x.split(".")[len(x.split(".")) - 1] file_ext = file.split(".")[len(file.split(".")) - 1] if x_ext == file_ext: matches.append([root, os.path.join(root, x)]) if len(matches) > 0: return cmds.filePathEditor(node, repath=matches[0][0]) return None
def CopyAndRepathTextureFiles(targetDir, progressBar): MakeSureDirExists(targetDir) fileNodeAttrList = cmds.filePathEditor(query=True, listFiles="", attributeOnly=True) if fileNodeAttrList: perStepValue = 100 / len(fileNodeAttrList) for curAttr in fileNodeAttrList: if re.search("\.", curAttr): fileNode = re.sub("\.[^.]+$", "", curAttr) if ObjExists(fileNode): if not cmds.referenceQuery( fileNode, isNodeReferenced=True ) and cmds.objectType(fileNode) in mlNodeDef.textureNode: srcImagePathName = cmds.getAttr(curAttr) if FileExists(srcImagePathName): imageFilePath = FilePathFromName(srcImagePathName) print imageFilePath, targetDir if imageFilePath != targetDir: if cmds.attributeQuery('uvTilingMode', node=fileNode, exists=True): uvTilingModeAttr = "%s.uvTilingMode" % fileNode uvTilingMode = cmds.getAttr( uvTilingModeAttr) if uvTilingMode == 3: CopyUdimTexFiles( srcImagePathName, targetDir) elif uvTilingMode == 2: Copy1BasedTexFiles( srcImagePathName, targetDir) else: copyFile(srcImagePathName, targetDir) else: copyFile(srcImagePathName, targetDir) progressBar.setValue(progressBar.value() + perStepValue) progressBar.setValue(100) RepathTextureFiles(targetDir)
output_type = "mayaAscii" import maya.standalone maya.standalone.initialize() import maya.cmds as cmds cmds.file(filename, open=True) workspace = cmds.workspace(q=True, rd=True) downloaded = 0 failed = 0 reused = 0 for d in cmds.filePathEditor(query=True, listDirectories="", unresolved=True): files = cmds.filePathEditor(query=True, listFiles=d, unresolved=True, withAttribute=True) if not files: print("no missing files to resolve in", d) continue for (f, n) in zip(*[iter(files)] * 2): target_path = os.path.join(d, f) try: missing_file = os.path.relpath(target_path, start=workspace) except ValueError: print("can't resolve", target_path) failed += 1
elif not exist: nonExistLocal.append(i) #如果文件路径不存在sourceImages文件夹则放入nonExistSourceiamges elif not ('sourceimages' in fileTexturePath): nonExistSourceiamges.append(i) findExistTexMessage(undefinedPathSel, '此节点丢失贴图:') findExistTexMessage(nonExistLocal, '此节点贴图不存在:') findExistTexMessage(nonExistSourceiamges, '此节点贴图不存在sourceimage路径下:') #如果都没有节点,证明材质贴图没有问题 if len(undefinedPathSel) != 0 and len(nonExistLocal) != 0 and len( nonExistSourceiamges) != 0: print '检查完毕,该文件材质贴图状态正常' #打印查找信息 def findExistTexMessage(sel, sen): if len(sel) > 0: for i in sel: print sen, i findExistTextrue() #查询节点外部文件夹路径,如果listDirectories属性为“”,默认返回全部文件路径 listDirectories = cmds.filePathEditor(query=True, listDirectories="") #查询节点外部文件路径,如果listFiles属性为“”,默认返回全部文件路径 listFiles = cmds.filePathEditor(query=True, listFiles="", byType="file") print listDirectories print listFiles
def listFilePathEditor(): listFullPathEditor = (cmds.filePathEditor(query=True, listFiles="", listDirectories="")) return (listFullPathEditor)
def buildButton( self, *args ): #get artist name artistName = cmds.textField( self.widgets[ "artistTextField" ], query=True, text=True ) #get current project currentProject = cmds.optionMenu( self.widgets[ "ProjectOptionWidget" ], q=True, v=True ) #get curent asset currentAsset = cmds.optionMenu( self.widgets[ "AssetOptionWidget" ], q=True, v=True ) #get curent job currentJob = cmds.optionMenu( self.widgets[ "assetJobMenu" ], q=True, v=True ) #get curent version currentVersion = cmds.optionMenu( self.widgets[ "versionMenu" ], q=True, v=True ) #export Directory exportDir = ripleyPath+currentProject+"/09_CG_RnD/CG_Assets/"+str(currentAsset)+"/"+str(currentJob)+"/"+str(currentVersion)+"/exports" #texture directory textureDir = ripleyPath+currentProject+"/09_CG_RnD/CG_Assets/"+str(currentAsset)+"/"+str(currentJob)+"/"+str(currentVersion)+"/textures" #mayaPath directory mayaDir = ripleyPath+currentProject+"/09_CG_RnD/CG_Assets/"+str(currentAsset)+"/"+str(currentJob)+"/"+str(currentVersion)+"/maya_files" #notes directory notesDir = ripleyPath+currentProject+"/09_CG_RnD/CG_Assets/"+str(currentAsset)+"/"+str(currentJob)+"/"+str(currentVersion)+"/notes" #get list of all geometry in scene geoList = cmds.ls( type='mesh') geoLength = len( geoList ) #get list of all textures in scene textureList = cmds.ls( type='file' ) textureLength = len( textureList ) #full length of export list exportLength = textureLength + geoLength #export all and save scene artist = cmds.textField( self.widgets[ "artistTextField" ], query=True, text=True ) if artist != "": #-----------------------------------------------# # SCENE SAVE # #-----------------------------------------------# i=1 cmds.progressBar( self.widgets[ "progressBar" ], edit=True, maxValue=10000 ) for i in range(1, 10000): cmds.text( self.widgets[ "progressBarText" ], edit=True, label="Saving Scene File." ) cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=i ) i=i+1 cmds.file( rename=mayaDir+"/"+currentJob+"_"+currentVersion+".mb" ) cmds.file( save=True, type='mayaBinary' ) cmds.text( self.widgets[ "progressBarText" ], edit=True, label="" ) cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=0 ) #-----------------------------------------------# # GEO EXPORT # #-----------------------------------------------# g=1 if geoLength > 0: try: cmds.progressBar( self.widgets[ "progressBar" ], edit=True, maxValue=geoLength ) cmds.select( geoList ) for geo in geoList: if cmds.file( exportDir+"/"+geo+'.obj', query=True, exists=True ): pass else: cmds.text( self.widgets[ "progressBarText" ], edit=True, label="Exporting Geo " + str(g) + " of " + str(geoLength) + "." ) g= g+1 cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=g ) cmds.file( exportDir+"/"+geo+'.obj', exportSelected=True, type='OBJexport', force=True ) cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=0 ) cmds.text( self.widgets[ "progressBarText" ], edit=True, label="" ) #kill all .mtl files OBJList = os.listdir( exportDir ) for mtl in OBJList: if mtl.endswith( ".mtl" ): os.remove( exportDir+"/"+mtl ) except: raise else: cmds.warning( "There is no geometry in the scene." ) #-----------------------------------------------# # TEXTURE EXPORT # #-----------------------------------------------# t=1 tFiles = [] cmds.filePathEditor( refresh=True ) if textureLength > 0: try: cmds.select( textureList ) cmds.progressBar( self.widgets[ "progressBar" ], edit=True, maxValue=textureLength ) directories = cmds.filePathEditor( query=True, listDirectories="" ) for d in directories: fileName = cmds.filePathEditor( query=True, listFiles=d ) for f in fileName: fullTexturePath = str(d+"/"+f) tFiles.append(fullTexturePath) #copy files from previous folder to correct destination for tex in tFiles: cmds.text( self.widgets[ "progressBarText" ], edit=True, label="Exporting Texture " + str(t) + " of " + str(textureLength) + "." ) cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=t ) if os.path.exists(tex): shutil.copy( tex, textureDir+"/") t=t+1 #reload textures from current assset folder for t in textureList: cmds.filePathEditor( t+".fileTextureName", repath=textureDir+"/", force=True ) except: raise else: cmds.warning("Therer are no textures in your scene.") cmds.progressBar( self.widgets[ "progressBar" ], edit=True, progress=0 ) cmds.text( self.widgets[ "progressBarText" ], edit=True, label="" ) #-----------------------------------------------# # NOTES # #-----------------------------------------------# textureExport = os.listdir( textureDir ) textureExportLength = len(textureExport) notesFile = open( notesDir+"/"+currentJob+"_"+currentVersion+".rtf", 'w' ) notes = [] notes.append( "Date: "+str(datetime.date.today())+"\n" ) notes.append( "\n" ) notes.append( "Time: "+str(datetime.datetime.now().time())+"\n" ) notes.append( "\n" ) notes.append( "Artist: "+artistName+"\n" ) notes.append( "\n" ) notes.append( "Number of meshes exported to OBJ format = "+ str(geoLength)+":\n" ) for geo in geoList: notes.append( geo+"\n" ) notes.append( "\n" ) notes.append( "\n" ) notes.append( "\n" ) notes.append( "Number of textures exported from scene = "+str(textureExportLength)+":\n" ) for t in textureExport: notes.append( t+"\n" ) notes.append( "\n" ) notesFile.writelines( notes ) notesFile.close(); #update version list self.populateVersions() #if no name is entered in to the artist field else: cmds.warning( "Please enter your name in the artist field." )
import maya.cmds as cmds #返回Maya场景中外部文件的目录。 cmds.filePathEditor(query=True, listDirectories="") #Return the directories of the external files that are saved at the target location. #返回目标位置保存的外部文件的目录。 cmds.filePathEditor(query=True, listDirectories="c:/textures/", status=True) #Return the files present in the specified directory, but not including the #files in the sub directories.If no specified directory, search all external #files in the scene. # #Use "withAttribute" to return the associated plugs. # #Use "status" to return whether the file exists. # #Use "unresolved" to return the broken files only. # #Use "attributeOnly" to return node and attribute name only. # #Use "byType" to specify the node and attribute type. # #For example, if "stone.jpg" exists and it is used by the plug #"node1.imageName", then the returned result will be an ordered pair: #"stone.jpg node1.imageName 1". # cmds.filePathEditor(query=True, listFiles="c:/textures/", withAttribute=True, status=True)
def bt_findMissingTextures(): selectedAll = [] selectedMeshes = [] selectedShaders = [] selectedFileNodes = [] shaders = [] fileNodes = [] successCount = 0 failureCount = 0 #get current project path currentProject = cmds.workspace(q=1,fn=1) #get current selections selectedAll = cmds.ls(sl=1) selectedMeshes = cmds.ls(cmds.filterExpand(sm=12)) selectedShaders = cmds.ls(sl=1,mat=1) selectedFileNodes = cmds.ls(sl=1,type='file') if ((len(selectedMeshes) == 0) and (len(selectedShaders) == 0) and (len(selectedFileNodes) == 0)): response = (cmds.confirmDialog( title='Confirm', message=' No meshes, shaders or textures were selected.\n\nDo you want to search the current project for all missing textures in this scene? ', button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )) if (response == 'No'): cmds.warning('Select a mesh, shader or texture and try again') sys.exit() else: selectedFileNodes = cmds.ls(type='file') if (len(selectedMeshes) != 0): #get any connected shaders cmds.select(selectedMeshes,r=1) connectedShaders = cmds.ls(cmds.listConnections(cmds.listConnections(cmds.ls(sl=True, o=True, dag=True, s=True), t='shadingEngine')), mat=True) shaders = selectedShaders + connectedShaders; else: shaders = selectedShaders if (len(shaders) != 0): #get any connected file nodes connectedFileNodes = cmds.ls(cmds.listConnections(shaders, type='file'), r=1) #also check for thing like Secondary/normal maps connectedSecondaryNodes = cmds.ls(cmds.listConnections(shaders), r=1) connectedSecondaryFileNodes = cmds.ls(cmds.listConnections(connectedSecondaryNodes, type='file'), r=1) fileNodes = selectedFileNodes + connectedFileNodes + connectedSecondaryFileNodes else: fileNodes = selectedFileNodes #remove duplicates fileNodes = list(set(fileNodes)) #print fileNodes fileCount = len(fileNodes) print ('\n##########################################################################\n') print ('Checking ' + str(fileCount) + ' nodes for associated texture/image files\n') if (len(fileNodes) == 0): print('No file nodes found') else: for fileNode in fileNodes: print ('Checking file node -> ' + fileNode + '.fileTextureName') #get file names pathFileName = (cmds.getAttr(fileNode + '.fileTextureName')) if (os.path.isfile(pathFileName) == 0): fileName = os.path.basename(pathFileName) print ('File does not exist at currently specified path : ' + pathFileName) print ('Searching project for : ' + fileName) cmds.filePathEditor ((fileNode + '.fileTextureName'),repath=currentProject,recursive=1) pathFileName = (cmds.getAttr(fileNode + '.fileTextureName')) if (os.path.isfile(pathFileName) == 1): print ('SUCCESS: File relocated at: ' + pathFileName + '\n') successCount += 1 else: print ('FAILURE: File can not be found in current project: ' + fileName + '\n') failureCount += 1 else: print ('File found at existing path: ' + pathFileName + '\n') if (len(selectedAll) != 0): cmds.select(selectedAll, r=1) if (successCount > 0): print ('SUCCESS: Relocated ' + str(successCount) + ' missing texture/image files. (See Script Editor for details)') if ((successCount == 0) and (failureCount == 0)): cmds.warning ('No changes were made. (See Script Editor for details)') if (failureCount > 0): cmds.warning ('Could not locate ' + str(failureCount) + ' texture/image files. (See Script Editor for details)')