def bgMasterShot(fType, variant, variantFolder, newWSFile, destination, currentMaster): """ will use standalone maya to master the ws passed in Args: fType = "anm", "lgt", or "fx" variant = name of the variant variantFolder = full path the variant folder [...shots/SHOT/TYPE/VARIANT] newWSFile = from masterShot func, the full path to latest WS file destination = full path to the proposed incremented past version of the master currentMaster = full path to the name of the master file """ print "MASTERING SHOT IN BACKGROUND" root = os.getenv("MAYA_ROOT") backgroundMaster = cFuncs.fixPath( "{0}/scripts/chrlx_pipe/backgroundMaster.py".format(root)) if os.name == "nt": mayapy = cFuncs.fixPath( os.path.join(os.getenv("MAYA_LOCATION"), "bin", "mayapy.exe")) if os.name != "nt": mayapy = cFuncs.fixPath( os.path.join(os.getenv("MAYA_LOCATION"), "bin", "mayapy")) try: subprocess.Popen([ mayapy, backgroundMaster, fType, variant, variantFolder, newWSFile, destination, currentMaster ]) print "Mastering in BG: {0}".format(variant) except: print "COULD NOT MASTER IN BACKGROUND: {0}\n Please check the 'master log' in the variant folder".format( variant)
def readWinDupe(*args): """gets the info from the win and passes it to dupe execute""" oldAss = cmds.textFieldButtonGrp(widgets["oldTFBG"], q=True, tx=True) newAssBase = cmds.textFieldButtonGrp(widgets["newTFBG"], q=True, tx=True) if cmds.window("dupeWin", exists=True): newType = cmds.radioButtonGrp(widgets["assTypeRBG"], q=True, sl=True) if newType == 1: newType = "characters" if newType == 2: newType = "props" if newType == 3: newType = "sets" name = cmds.textFieldGrp(widgets["nameTFG"], q=True, tx=True) #---------------- get the start job, end job and the asset name # ---------------- check here for info that Paul's dupe needs newAss = cFuncs.fixPath( os.path.join(newAssBase, "3D_assets", newType, name)) if oldAss and newAssBase and name: print "duplicate.readWinDupe: passing\noldAss: {0}\nnewAss: {1}\nnewType: {2}".format( oldAss, newAss, newType) # ---------------- pass Pauls script the correct info here duplicateExecute(cFuncs.fixPath(oldAss), newAss, newType) else: cmds.warning("You have to fill in all of the fields!")
def increment(*args): #get current scene curr = cFuncs.fixPath(cmds.file(q=True, sn=True)) print curr pm = "" #check that we're in schema 2 if curr: try: pm = paths.PathManager(curr) except: warning("Can't get file name or find the project path") if pm: #check that we're in a ws file in correct proj type if isinstance(pm, paths.AssetPath): # if asset asset = pm.name assetFolder = cFuncs.fixPath( os.path.join(pm.assetPath, pm.typ, asset)) fType = pm.stage incrementFile = cFuncs.incrementWS(asset, assetFolder, fType) wsNum = "{0:0>3}".format(pm.version + 1) cmds.file(rename=incrementFile + ".ma") cFuncs.putFileInfo(fType, wsNum, "quick increment") cmds.file(save=True, type="mayaAscii") elif isinstance(pm, paths.ShotPath): # if shot variant = pm.variant fType = pm.shotType varFolder = cFuncs.fixPath( os.path.join(pm.shotPath, fType, variant)) print "quick increment:\nvariant: {0}\nvarFolder: {1}\nfType: {2}".format( variant, varFolder, fType) incrementFile = cFuncs.incrementWS(variant, varFolder, fType) wsNum = "{0:0>3}".format(pm.version + 1) cmds.file(rename=incrementFile + ".ma") cFuncs.putFileInfo(fType, wsNum, "quick increment") cmds.file(save=True, type="mayaAscii") else: cmds.warning( "quickIncrement.increment: I'm not able to recognize the shot you've passed me" ) if cmds.window("assetWin", exists=True): import chrlx_pipe.assetWin as assWin assWin.populateWindow() if cmds.window("shotWin", exists=True): import chrlx_pipe.shotWin as shotWin shotWin.populateWindow() else: cmds.warning( "You're not in a file I can increment (either wrong project schema or not in a workshop)" ) else: cmds.warning( "You seem to be in an unsaved scene! No workshop to increment!")
def fileAction(action="", *args): """ exports the info in the window as fbx """ if action == "fbxexp": pathFld = "pathTFBG" nameFld = "nameTFG" suffix = "fbx" elif action == "mayaexp" or "openMaya": pathFld = "mayaTFBG" nameFld = "animNameTFG" suffix = "ma" elif action == "animFbx": pathFld = "mayaTFBG" nameFld = "animNameTFG" suffix = "fbx" folder = cmds.textFieldButtonGrp(widgets[pathFld], q=True, tx=True) expName = cmds.textFieldGrp(widgets[nameFld], q=True, tx=True) fileName = "{0}.{1}".format(expName, suffix) if folder and expName: path = cFuncs.fixPath(os.path.join(folder, fileName)) if action == "fbxexp": expFbx(path) elif action == "mayaexp": cmds.file(path, force=True, type="mayaAscii", exportSelected=True) elif action == "animFbx": expFbx(path) elif action == "openMaya": cmds.file(path, open=True, force=True) else: cmds.warning("You need to have a location AND a file name")
def initializeRigWS(asset, assetFolder, *args): """will use standalone maya to create the initial rig ws file""" print "INITIALIZING RIG WORKSHOP" root = os.getenv("MAYA_ROOT") initRigFile = cFuncs.fixPath( "{0}/scripts/chrlx_pipe/buildInitialRigFiles.py".format(root)) if os.name == "nt": mayapy = cFuncs.fixPath( os.path.join(os.getenv("MAYA_LOCATION"), "bin", "mayapy.exe")) elif os.name != "nt": mayapy = cFuncs.fixPath( os.path.join(os.getenv("MAYA_LOCATION"), "bin", "mayapy")) try: subprocess.call([mayapy, initRigFile, asset, assetFolder]) print "FINISHED WITH RIG WS CREATION" except Exception, e: print "masterFuncs.InitializeRigWS - error:\n", e print "masterFuncs.InitializeRigWS: DID NOT CREATE RIG WS"
def getPath(pathField, *args): """gets the path that will fill the field group""" path = cmds.fileDialog2(fm=2, dir=currentProj) cmds.textFieldButtonGrp(widgets[pathField], e=True, fi=path[0]) val = cmds.textFieldButtonGrp(widgets["oldTFBG"], q=True, tx=True) if (pathField == "oldTFBG") and (not cmds.textFieldButtonGrp( widgets["newTFBG"], q=True, tx=True)): if val: sel = cmds.radioButtonGrp(widgets["assTypeRBG"], q=True, sl=True) oldPath = PathManager(path[0]) if sel == 1: newDest = cFuncs.fixPath(os.path.join(oldPath.charPath)) if sel == 2: newDest = cFuncs.fixPath(os.path.join(oldPath.propPath)) if sel == 3: newDest = cFuncs.fixPath( os.path.join(os.path.join(oldPath.assetPath, "sets"))) cmds.textFieldButtonGrp(widgets["newTFBG"], e=True, fi=newDest)
def getProjectFolder(*args): cmds.textScrollList(widgets["charTSL"], e=True, ra=True) cmds.textScrollList(widgets["propTSL"], e=True, ra=True) cmds.textScrollList(widgets["setTSL"], e=True, ra=True) folder = cmds.fileDialog2(fileMode=3, dialogStyle=1) if folder: path = utils.PathManager(folder[0]) if path.spotSchema == 2 and (cFuncs.fixPath(path.jobPath) == folder[0]): cmds.textFieldButtonGrp(widgets["asstTFBG"], e=True, tx=folder[0]) pushToImportExportPopulate() else: cmds.warning("That folder is not a job in the new project schema!")
def createWinShotDirs(shotFolder, *args): """ from the window, will create a shot folder structure Args: shotFolder (string): the generic "shots" folder under the job [...SPOT/3d/shots] Return: None """ num = cmds.textFieldGrp(swidgets["num"], q=True, tx=True) myChars = [int(s) for s in num if s.isdigit()] # get list of int digits in num if len(myChars) != 3: # if we don't have 3 digits. . . cmds.warning("You need to enter a 3 digit number for the shot!!") return () shotType = cmds.radioButtonGrp(swidgets["version"], q=True, sl=True) if shotType == 1: sname = "shot" if shotType == 2: sname = "previs" name = "{0}{1}".format(sname, num) #here we compare that list of assets with our proposed name shots = cFuncs.getSpotShotList(shotFolder) if name in shots: cmds.confirmDialog( t="Name Exists!", m="There is already a shot of this name\nin this project! Please enter another." ) return () shotFolderObj = utils.PathManager(shotFolder) #---------------- restore this!! # jobDirectoryCreator.createShot(shotFolderObj.jobDirname, shotFolderObj.spotDirname, name) varName = cmds.textFieldGrp(swidgets["variant"], q=True, tx=True) thisShotFolder = cFuncs.fixPath(os.path.join(shotFolder, name)) createVariantDirs(thisShotFolder, "anm", varName, *args) if cmds.window("createShotWin", exists=True): cmds.deleteUI("createShotWin") # refresh the shot win if cmds.window("shotWin", exists=True): #pth = utils.PathManager(shotFolder) import chrlx_pipe.shotWin as shotWin shotWin.populateWindow()
def pushToImportExportExecute(type, *args): if type == "import": jobFolder = cmds.textFieldButtonGrp(widgets["asstTFBG"], q=True, tx=True) assetFolder = os.path.join(jobFolder, "3D_assets") char = cmds.textScrollList(widgets["charTSL"], q=True, si=True) prop = cmds.textScrollList(widgets["propTSL"], q=True, si=True) set = cmds.textScrollList(widgets["setTSL"], q=True, si=True) name = cmds.textFieldGrp(widgets["nameTFG"], q=True, tx=True) impSavePath = "" if char: impSavePath = cFuncs.fixPath( os.path.join(assetFolder, "characters", char[0], "geo", "import_export", name + ".ma")) if prop: impSavePath = cFuncs.fixPath( os.path.join(assetFolder, "props", prop[0], "geo", "import_export", name + ".ma")) if set: impSavePath = cFuncs.fixPath( os.path.join(assetFolder, "sets", set[0], "geo", "import_export", name + ".ma")) if impSavePath: cmds.file(rename=impSavePath) cmds.file(save=True, force=True) cmds.warning("You're now in: ", impSavePath) else: cmds.warning("You need to select the asset to send the file to!") if type == "wip": print "send to wip" cmds.deleteUI(widgets["win"])
def createVariantDirs(shotFolder, varType, name, *args): """creates variant directories from args -asset folder is path to asset folder under 3D -assType is either "characters", "props", or "sets" -name is string name of the new character """ #do this again (like above) just to make sure we don't repeat a name if we're calling externally cFuncs.createVariantDirectories(shotFolder, varType, name) cmds.warning("Created variant: {0} in {1}".format( name, cFuncs.fixPath(os.path.join(shotFolder, varType)))) if cmds.window("createVarWin", exists=True): cmds.deleteUI("createVarWin") #refresh the shot win if cmds.window("shotWin", exists=True): #pth = utils.PathManager(shotFolder) import chrlx_pipe.shotWin as shotWin shotWin.populateWindow()
def setProject(self, *args): #set project to proper folder!!! project is 3D folder!!! self.job = cmds.textScrollList(self.widgets["jobTSL"], q=True, si=True)[0] self.spot = cmds.textScrollList(self.widgets["spotTSL"], q=True, si=True)[0] if self.job and self.spot: path = os.path.join(self.jobsFolder, self.job, self.spot, "3d") self.cleanPath = funcs.fixPath(path) # - FINAL OUTPUT ATTRIBUTE self.projectPath = self.cleanPath #sets project if arg is True if os.path.isdir(self.cleanPath) and self.set: funcs.setProject(self.cleanPath) cmds.deleteUI("psWin") elif os.path.isdir(self.cleanPath) and not self.set: cmds.warning("The project you've selected is:\n", self.projectPath) cmds.deleteUI("psWin") else: cmds.warning("I can't find the directory you've listed") #reset fileWin or do output thingy based on passed in info if cmds.window("assetWin", exists=True): import chrlx_pipe.assetWin as fileWin fileWin.populateWindow() if cmds.window("shotWin", exists=True): import chrlx_pipe.shotWin as fileWin fileWin.populateWindow() else: cmds.warning("You need to select a job and a spot first!")
def createWinVarDirs(shotFolder, varType, *args): """folder is the shot folder (shot folder). Proj is project folder""" name = cmds.textFieldGrp(vwidgets["name"], q=True, tx=True) varFold = cFuncs.fixPath(os.path.join(shotFolder, varType)) variants = cFuncs.getShotVariantList(varFold) if variants and (name in variants): cmds.confirmDialog( t="Name Exists!", m="There is already a shot of this name\nin this spot! Please enter another." ) return () createVariantDirs(shotFolder, varType, name) if cmds.window("createVarWin", exists=True): cmds.delete("createVarWin") # refresh the shot win if cmds.window("shotWin", exists=True): #pth = utils.PathManager(shotFolder) import chrlx_pipe.shotWin as shotWin shotWin.populateWindow()
def masterShot(var, varFolder, fType, batch=False, BG=False, importRefs=True, *args): """ gets latest version of past_versions Args: varName (string): variantName (ie. "defaultVariant") varFolder (string): the folder for the variant (i.e. rig folder, lgt var folder, etc) fType (string): the type of shot abbreviation ('lgt', 'anm', 'fx'), batch (bool): for batch mode (no UI) BG (bool): render in background? importRefs (bool): should we import the references when mastering? Return: string: returns message for the confirm dialog in shot win """ note = "mastering shot!" #clash check clash = cClash.clash(0) if clash: fix = cmds.confirmDialog( title="Clash Fix?", message= "Name clashes have been detected!\nSee script editor for details\nHow should we fix?", button=("Fix Automatically", "Fix Manually"), defaultButton="Fix Automatically", dismissString="Fix Manually", cancelButton="Fix Automatically") if fix == "Fix Manually": cClash.clash(0) return ("clash") else: cClash.clash(1) # below UI has "dict" attr that will grab a dictionary from masterWin ("note":str, "cam":bool, "shd":bool, "rig":bool). use these vals to turn on funcs if not batch: options = mstWin.masterShotUI() shotOptions["note"] = options.dict["note"] shotOptions["shd"] = options.dict["shd"] # - ------- add frame range, resolution, FPS? note = shotOptions['note'] if note == "__CANCEL__": return "__CANCEL__" pm = utils.PathManager(varFolder) shotmst = pm.getMaster() masterFile = os.path.basename(shotmst)[:-3] latestMasterVersion = cFuncs.getLatestVarMaster( var, varFolder, fType) #check if there's a master #---------------- HERE: GET two WS FILES. THE SECOND WILL BE THE ONE WE SAVE, THEN EXTERNALLY COPY AND MASTER THE FIRST latestWorkshop = cFuncs.getLatestVarWS( varFolder) #check the lastest workshop # get the number on the end of te if latestMasterVersion and (latestMasterVersion != "Abort"): num = int( os.path.basename(latestMasterVersion).rstrip(".ma").rpartition( "_v")[2]) incrNum = "{:0>3d}".format(num + 1) elif latestMasterVersion == "Abort": cmds.warning( "masterFuncs.masterShot: There was some kind of issue with the paths to get the latest master for backup" ) return elif latestMasterVersion == None: incrNum = "001" #create file name and full path # newPastVersion = "{0}/past_versions/{1}_v{2}.ma".format(varFolder, masterFile, incrNum) newPastVersion = cFuncs.fixPath(pm.getNextVersion()) # does this line up with the ws file structure? check = cFuncs.checkCurrentMasterMatch(masterFile, fType) if not check: #here we bail out if current scene isn't workshop of the scene you're trying to master (from window) cmds.confirmDialog( t="SCENE MISMATCH", m="Your current scene doesn't line up\nwith the asset you've selected\nin the asset window. . . \n\nMake sure you're in a workshop file\nfor the asset you want to master!" ) return "FILE MISMATCH - NO MASTER CREATED!" #copy current master to past masters and rename to new num currentMaster = "{0}/{1}.ma".format(varFolder, masterFile) destination = "{0}".format(newPastVersion) currentWS = cmds.file(q=True, sceneName=True) #increment ws file from current newWSFile = "{0}.ma".format(cFuncs.incrementWS(var, varFolder, fType)) correctWSnum = "{:0>3d}".format(int(latestWorkshop[-6:-3])) # -------------- add more data to the shot master fileInfo cFuncs.putFileInfo(fType, correctWSnum, note) # increment ws cmds.file(rename=newWSFile) cmds.file(save=True, type="mayaAscii") #do the mastering stuff to the current file, if we bail at any stage, reopen the ws and don't save master # depending on type of master we want to do, finish up the mastering process. . . . if BG == False and importRefs == True: # regular master print "\n-------------------\nDOING IMPORT MASTER SHOT STUFF HERE!\n-------------------" clean = cleanShotScene(fType, BG, importRefs) if clean == "Abort": print "trying to return you to latest workshop file: {0}".format( newWSFile) cmds.file(newWSFile, open=True, force=True) return ( "Failed mastering at cleanup phase. Try again after fixing problems" ) cmds.file(rename=currentMaster) if os.path.isfile( currentMaster ): #check if there is a master file currently. If so, move it to the past versions os.rename(currentMaster, destination) print "masterFuncs.masterShot:\n------ moving: {0} \n------ to: {1}".format( currentMaster, destination) cmds.file(save=True, type="mayaAscii") # save as master cmds.file(newFile=True, force=True) if BG == False and importRefs == False: # referenced master print "\n-------------------\nDOING REFERENCE MASTER SHOT STUFF HERE!\n-------------------" clean = cleanShotScene(fType, BG, importRefs) if clean == "Abort": print "trying to return you to latest ws file: {0}".format( newWSFile) cmds.file(newWSFile, open=True, force=True) return ( "Failed mastering at cleanup phase. Try again after fixing problems" ) cmds.file(rename=currentMaster) if os.path.isfile( currentMaster ): #check if there is a master file currently. If so, move it to the past versions os.rename(currentMaster, destination) print "masterFuncs.masterShot:\n------ moving: {0} \n------ to: {1}".format( currentMaster, destination) cmds.file(save=True, type="mayaAscii") # save as master #rename to increment ws secondWSFile = "{0}".format(cFuncs.incrementWS(var, varFolder, fType)) cmds.file(rename=secondWSFile) cmds.file(save=True, type="mayaAscii") if BG == True and importRefs == True: # BG master # call to function to master shot on current ws print "---------- kicking out to BG Master function ------------" bgMasterShot(fType, var, varFolder, newWSFile, destination, currentMaster) # increment again and open variant ws #---------------- maybe DON'T re-increment this here? Just open old ws? reincr = "{0}".format(cFuncs.incrementWS(var, varFolder, fType)) cmds.file(rename=reincr) cmds.file(save=True, type="mayaAscii") #refresh the info in the shot win if cmds.window("shotWin", exists=True): import chrlx_pipe.shotWin as shotWin shotWin.populateWindow() if BG == True: return "Mastering in background process: {0}".format(currentMaster) if BG == False: return "Master created successfully: {0}".format(currentMaster)
def duplicateExecute(oldAss=None, newAss=None, newType=None, *args): """given an old asset name (full path, [. . ./3d/assets/TYPE/NAME]) and a new asset name (...3d/assets/TYPE/NAME), newType is either [characters, props or sets]""" #create objs that we can get info from the utils function oldAss = cFuncs.fixPath(oldAss) newAssRaw = cFuncs.fixPath(newAss) #replace type with newType newAss = cFuncs.fixPath( os.path.join( os.path.join(os.path.dirname(os.path.dirname(newAssRaw)), newType), os.path.basename(newAss))) oldAssNew = cFuncs.fixPath( os.path.join( os.path.join(os.path.dirname(os.path.dirname(oldAss)), newType), os.path.basename(oldAss))) print "oldAssNew:", oldAssNew oldPath = PathManager(oldAss) newPath = PathManager(newAss) oldAssName = os.path.basename(oldAss) newAssName = os.path.basename(newAss) # print "oldassname:", oldAssName # print "newAssName:", newAssName #create an asset structure for the new name createAssDirs(newPath.assetPath, newType, newAssName) #geo latest ws - rename, replace references oldGeoWS = cFuncs.getLatestAssetWS(oldAssName, oldAss, "geo") newGeoWS = "" if oldGeoWS: newGeoWS = "{0}/geo/workshops/{1}".format( newAss, os.path.basename(oldGeoWS).replace( oldAssName.partition("_")[0], newAssName)) print newGeoWS copyfile(oldGeoWS, newGeoWS) #geo master if exists - rename oldGeoMst = cFuncs.getAssetMaster(oldAssName, oldAss, "geo") newGeoMst = "" if oldGeoMst: newGeoMst = "{0}/geo/{1}".format( newAss, os.path.basename(oldGeoMst).replace( oldAssName.partition("_")[0], newAssName)) copyfile(oldGeoMst, newGeoMst) #rig latest ws if exists - rename, replace references oldRigWS = cFuncs.getLatestAssetWS(oldAssName, oldAss, "rig") newRigWS = "" if oldRigWS: newRigWS = "{0}/rig/workshops/{1}".format( newAss, os.path.basename(oldRigWS).replace( oldAssName.partition("_")[0], newAssName)) copyfile(oldRigWS, newRigWS) #get rig master and copy oldRigMst = cFuncs.getAssetMaster(oldAssName, oldAss, "rig") newRigMst = "" if oldRigMst: newRigMst = "{0}/rig/{1}".format( newAss, os.path.basename(oldRigMst).replace( oldAssName.partition("_")[0], newAssName)) copyfile(oldRigMst, newRigMst) ######## copy mtl and shader files. . . . replaceFiles = [] # copy contents of source images for fl in cFuncs.getFilesInPath(os.path.join(oldAss, "sourceImages")): if fl: copyfile( fl, "{0}/sourceImages/{1}".format( newAss, os.path.basename(fl).replace(oldAssName, newAssName))) #replaceFiles.append(fl) ############ - now we have to find the refs to the geoWS folder and replace it with the new one, same with source images in all files # files to search for: oldGeoMst, sourceImage list #replaceFiles.append(oldGeoMst) ########## -- add mtl file to this . . . filesToSearch = [newRigWS] for doc in filesToSearch: cFuncs.replaceTextInFile(doc, oldGeoMst, newGeoMst) if cmds.window("dupeWin", exists=True): cmds.deleteUI("dupeWin")
def buttonsToLayout(layout="", dictionary={}, width=50, height=20, color=(.5, .5, .5), *args): """ takes info from the given dictionary and creates buttons in the given layout to execute and display scripts Args: dict (dictionary): dictionary of button attrs (list) in the form --> key(which is used as label): [type ("py" or "mel"), command, annotation] width (int): the width of each button created height (int): the height of each button created color (float array3): a 3-array of 0-1 floats layout (string): the layout widget that is the parent widget of the buttons we will create example dictionary: example = {"buttonLabel_1":["py", "from myFolder import myModule; reload myModule; myModule.myFunc()", "this function does something"] "buttonLabel_2":["mel", "myMelScript.mel", "this function does something else"]} note: this assumes the call will correctly place the button in the layout Return: None """ iconPath = cFuncs.fixPath( os.path.join(os.getenv("MAYA_ROOT"), "scripts", "chrlx_icons")) font = "tinyBoldLabelFont" melIconDefault = "commandButton.png" pyIconDefault = "pythonFamily.png" if layout and dictionary: rKeys = dictionary.keys() sKeys = [] for sk in rKeys: strKey = str(sk) sKeys.append(strKey) keys = sorted(sKeys, key=lambda s: s.lower()) for key in keys: if dictionary[key][0] == "py": c = dictionary[key][1] icon = pyIconDefault if dictionary[key][0] == "mel": c = "mel.eval('{0}')".format(dictionary[key][1]) icon = melIconDefault a = dictionary[key][2] if len(dictionary[key]) > 3: icon = cFuncs.fixPath( os.path.join(iconPath, dictionary[key][3])) # change style to iconAndTextVertical, if you want thisButton = cmds.iconTextButton(label=key, parent=layout, w=width, h=height, backgroundColor=color, command=c, annotation=a, image=icon, style="iconAndTextHorizontal", font=font)
def getLoc(field, *args): """ get location, put it in the tfbg """ path = cFuncs.fixPath(cmds.fileDialog2(fileMode=2, ds=1)[0]) cmds.textFieldButtonGrp(widgets[field], e=True, tx=path)