def checkoutLightingFile(): print("checkoutLightingFile") shotPaths = glob.glob(os.path.join(os.environ["SHOTS_DIR"], "*")) selections = [] for sp in shotPaths: selections.append(os.path.basename(sp)) selections.sort() print("Im calling ui") answer = ui.listWindow(selections, wmessage="Select shot file to checkout:") print("Im done calling ui") if answer: answer = answer[0] toCheckout = os.path.join(os.environ["SHOTS_DIR"], selections[answer], "lighting") try: destpath = amu.checkout(toCheckout, True) except Exception as e: if not amu.checkedOutByMe(toCheckout): ui.infoWindow("Can Not Checkout: " + str(e)) return else: destpath = amu.getCheckoutDest(toCheckout) toOpen = os.path.join(destpath, get_filename(toCheckout) + ".hipnc") if os.path.exists(toOpen): hou.hipFile.load(toOpen) else: hou.hipFile.clear() hou.hipFile.save(toOpen)
def checkFiles(files): ''' Checks the list of output files against which files were actually created @param: files - a list of strings representing full paths @return: a list of paths to files that do not exist ''' missingFiles = [] for filename in files: print "CHECKING********** " + filename if not os.path.exists(filename): missingFiles.append(filename) if not len(missingFiles) == 0: errorMessage = "" for f in missingFiles: errorMessage += "MISSING FILE: " + f + "\n" print(errorMessage) errorMessage = str( len(missingFiles)) + " Files Missing:\n\n" + errorMessage #mc.confirmDialog(title="Error exporting files", message=errorMessage) ui.infoWindow(errorMessage, wtitle="Error exporting files", msev=messageSeverity.Error) return missingFiles
def checkin(): """Checks in the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database, and USERNAME must have the lock.""" updateDB() node = getSelectedNode() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add the OTL first") elif info[2]: if not node.isLocked() and info[3] == USERNAME: saveOTL(node) # This save is not strictly necessary since we save again two lines down lockAsset(node, False) saveOTL(node) moveToOtlDir(node, filename) unlockOTL(filename) ui.infoWindow("Checkin Successful!") else: ui.infoWindow(lockedBy(info[3].encode('utf-8'))) else: ui.infoWindow("Already checked in.") else: #ui.infoWindow("Select EXACTLY one node.") checkinLightingFile()
def checkoutLightingFile(): print("checkoutLightingFile") shotPaths = glob.glob(os.path.join(os.environ['SHOTS_DIR'], '*')) selections = [] for sp in shotPaths: selections.append(os.path.basename(sp)) selections.sort() print('Im calling ui') answer = ui.listWindow(selections, wmessage='Select shot file to checkout:') print('Im done calling ui') if answer: answer = answer[0] toCheckout = os.path.join(os.environ['SHOTS_DIR'], selections[answer], 'lighting') try: destpath = amu.checkout(toCheckout, True) except Exception as e: if not amu.checkedOutByMe(toCheckout): ui.infoWindow('Can Not Checkout: '+str(e)) return else: destpath = amu.getCheckoutDest(toCheckout) toOpen = os.path.join(destpath, get_filename(toCheckout)+'.hipnc') if os.path.exists(toOpen): hou.hipFile.load(toOpen) else: hou.hipFile.clear() hou.hipFile.save(toOpen)
def checkout(node): """Checks out the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database.""" updateDB() if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: if node.type().name() == "geometryTemplate": ui.infoWindow("Cannot checkout geometry template node.") return False libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add OTL First.") elif not info[2] or (info[2] and info[3].encode('utf-8') == USERNAME): copyToUsrDir(node, filename) lockAsset(node, True) saveOTL(node) node.allowEditingOfContents() lockOTL(filename) ui.infoWindow("Checkout Successful!", wtitle='Success!') else: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot checkout asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error)
def checkout(): """Checks out the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database.""" updateDB() node = getSelectedNode() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: if node.type().name() == "geometryTemplate": ui.infoWindow("Cannot checkout geometry template node.") return False libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add OTL First.") elif not info[2]: #or (info[2] and info[3] == USERNAME): copyToUsrDir(node, filename) lockAsset(node, True) saveOTL(node) node.allowEditingOfContents() lockOTL(filename) ui.infoWindow("Checkout Successful!", wtitle='Success!') else: ui.infoWindow(lockedBy(info[3].encode('utf-8'))) else: #ui.infoWindow("Select EXACTLY one node.") checkoutLightingFile()
def checkout(node): """Checks out the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database.""" updateDB() if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: if node.type().name() == "geometryTemplate": ui.infoWindow("Cannot checkout geometry template node.") return False libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add OTL First.") elif not info[2] or (info[2] and info[3].encode("utf-8") == USERNAME): copyToUsrDir(node, filename) lockAsset(node, True) saveOTL(node) node.allowEditingOfContents() lockOTL(filename) ui.infoWindow("Checkout Successful!", wtitle="Success!") else: logname, realname = amu.lockedBy(info[3].encode("utf-8")) whoLocked = "User Name: " + logname + "\nReal Name: " + realname + "\n" errstr = "Cannot checkout asset. Locked by: \n\n" + whoLocked ui.infoWindow(errstr, wtitle="Asset Locked", msev=messageSeverity.Error)
def checkoutLightingFile(): shotPaths = glob.glob(os.path.join(os.environ['SHOTS_DIR'], '*')) selections = [] for sp in shotPaths: selections.append(os.path.basename(sp)) selections.sort() answer = ui.listWindow(selections, wmessage='Select shot file to checkout:') if answer: answer = answer[0] toCheckout = os.path.join(os.environ['SHOTS_DIR'], selections[answer], 'lighting') try: destpath = amu.checkout(toCheckout, True) except Exception as e: if not amu.checkedOutByMe(toCheckout): ui.infoWindow('Can Not Checkout: '+str(e)) return else: destpath = amu.getCheckoutDest(toCheckout) toOpen = os.path.join(destpath, get_filename(toCheckout)+'.hipnc') if os.path.exists(toOpen): hou.hipFile.load(toOpen) else: hou.hipFile.clear() hou.hipFile.save(toOpen)
def checkin(node = None): """Checks in the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database, and USERNAME must have the lock.""" updateDB() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add the OTL first") elif info[2]: if not node.isLocked() and info[3] == USERNAME: saveOTL(node) # This save is not strictly necessary since we save again two lines down lockAsset(node, False) saveOTL(node) moveToOtlDir(node, filename) unlockOTL(filename) ui.infoWindow("Checkin Successful!") else: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot checkin asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error) else: ui.infoWindow("Already checked in.") else: #ui.infoWindow("Select EXACTLY one node.") checkinLightingFile()
def newGeo(hpath): templateNode = hou.node(hpath).createNode("geometryTemplate") alist = listContainers() resp = ui.inputWindow("Enter the New Operator Label", wtitle="OTL Label") filename = str() if resp != None and resp.strip() != "": name = formatName(resp) filename = name.replace(" ", "_") templateNode.setName(filename, unique_name=True) answer = ui.listWindow(alist, wmessage="Select Container Asset this belongs to:") if not answer: ui.infoWindow( "Geometry must be associated with a container asset! Geometry asset not created.", msev=messageSeverity.Error, ) templateNode.destroy() return answer = answer[0] sdir = "$JOB/PRODUCTION/assets/" gfile = ui.fileChooser( start_dir=sdir + alist[answer] + "/geo", wtitle="Choose Geometry", mode=fileMode.Read, extensions="*.bjson, *.obj", ) if len(gfile) > 4 and gfile[:4] != "$JOB": ui.infoWindow( "Path must start with '$JOB'. Default geometry used instead.", wtitle="Path Name", msev=messageSeverity.Error, ) templateNode.destroy() elif gfile != "": hou.parm(templateNode.path() + "/read_file/file").set(gfile)
def checkFiles(files): ''' Checks the list of output files against which files were actually created @param: files - a list of strings representing full paths @return: a list of paths to files that do not exist ''' missingFiles = [] for filename in files: print "CHECKING********** " + filename if not os.path.exists(filename): missingFiles.append(filename) if not len(missingFiles) == 0: errorMessage = "" for f in missingFiles: errorMessage += "MISSING FILE: " + f + "\n" print(errorMessage) errorMessage = str(len(missingFiles)) + " Files Missing:\n\n" + errorMessage #mc.confirmDialog(title="Error exporting files", message=errorMessage) ui.infoWindow(errorMessage, wtitle="Error exporting files", msev=messageSeverity.Error) return missingFiles
def newTexture(): # Get a list of assets assetList = glob.glob(os.path.join(os.environ['ASSETS_DIR'], '*')) selections = [] for aL in assetList: # basename takes last folder in path. selections.append(os.path.basename(aL)) # sort alphabetically selections.sort() answer = ui.listWindow(selections, wmessage='Choose an asset to add/update textures for') if answer: answer = answer[0] assetName = selections[answer] assetImageDir = os.path.join(os.environ['ASSETS_DIR'], assetName, 'images') # Direct user to geometry file path and have them choose the correct one sdir = '$JOB/PRODUCTION/assets/'+assetName+'/geo/bjsonFiles' geoPath = ui.fileChooser(start_dir=sdir, wtitle='Choose Asset Geometry for Texture', mode=fileMode.Read, extensions='*.bjson, *.obj') geoName, ext = os.path.splitext(os.path.basename(geoPath)) # Show a list of shading passes shadingPassList = ['diffuse','specular','bump','scalar_displacement','vector_displacement', 'opacity', 'single_SSS', 'multi_SSS', 'other'] answer = ui.listWindow(shadingPassList, wmessage='Which texture will you be creating/updating?') if answer: answer = answer[0] shadingPass = shadingPassList[answer] # Allow user to choose texture map in user local directory userDirectory = os.environ['USER_DIR'] userTextureMap = ui.fileChooser(start_dir=userDirectory, wtitle='Browse to the Texture Map in your User Directory', image=True, extensions='*.jpg,*.jpeg,*.tiff,*.tif,*.png,*.exr') #Allow user to search for texture in any directory userTextureMap = os.path.expandvars(userTextureMap) # Set Variables for texture paths newTexture = '/tmp/newTexture.png' convertedTexture = '/tmp/convertedTexture.png' finalTexture = '/tmp/finalTexture.exr' # Change to 16 bits and convert to png os.system('iconvert -d 16 ' +userTextureMap+ newTexture) # Gamma correct for linear workflow if shadingPass == 'diffuse' or shadingPass == 'specular' or shadingPass == 'single_SSS' or shadingPass == 'multi_SSS' or shadingPass == 'other': os.system('icomposite' +convertedTexture +'= gamma 0.4545454545' +newTexture) # Convert to .exr with otimized settings os.system('iconvert -d half '+convertedTexture+finalTexture+' storage tile 64 tiley 65 compression zip') # Seperate extension from filename and rename texture to production pipeline name finalTextureName, ext = os.path.splitext(os.path.basename(finalTexture)) newTextureName = assetName+'_'+geoName+'_'+shadingPass+ext newfilepath = os.path.join(assetImageDir,newTextureName) shutil.copy(finalTexture,newfilepath) # Output final success message ui.infoWindow('Your texture was saved to: '+newfilepath+' as a .exr image file')
def rollbackOTL(node=None): """Pulls a rollback window for the user to select a version to rollback to. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database. """ print 'RollbackOTL' #Need to check if a particular node is a digital asset first. Rollback is will only work as a DA, with model, rigs and animation. if node != None: if not ham.isDigitalAsset(node): ui.infoWindow('Wait! You can only rollback Digital Assets!') print "NOT A DIGITAL ASSET." else: # First, we need to see if this is checked out or not. If it is checked out, then we can proceed. If not, state so. # For the productions path libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) asset_name, ext = os.path.splitext(filename) #print "asset_name " + asset_name toCheckout = os.path.join(ASSETSDIR, asset_name, 'otl') #print "toCheckout " + toCheckout myCheckout = False myCheckout = amu.isCheckedOut(toCheckout) if myCheckout: #If it has been checked out myCheckout = amu.checkedOutByMe(toCheckout) if myCheckout: #If user was the last to checkout #Here we rollback. versionedFolders = os.path.join(toCheckout, "src") #print "versionedFolders ", versionedFolders versions = glob.glob(os.path.join(versionedFolders, '*')) #print "selections ", versions #Wooohoooo!!! selections = [] selectionInfo = [] nodeInfoDest = toCheckout for vr in versions: selections.append(os.path.basename(vr)) comment = amu.getVersionComment( nodeInfoDest, os.path.basename(vr)) selectionInfo.append(comment) selections.sort() dialog = VersionDialog() dialog.addItems(selections, selectionInfo) dialog.show() dialog.setParams(versionedFolders, asset_name, toCheckout, True) pyqt_houdini.exec_(dialog) else: hou.ui.displayMessage('Already checked out.') return else: hou.ui.displayMessage('Please checkout asset first.') else: print "Node does not exist"
def convert_texture(userTextureMap, assetImageDir, folder_name=''): print userTextureMap if os.path.isdir(userTextureMap): return extensions = ['.jpg','.jpeg','.tiff','.tif','.png','.exr'] userFileName, userExt = os.path.splitext(os.path.basename(userTextureMap)) if userExt not in extensions: return # Set Variables for texture paths convertedTexture = os.path.join('/tmp','intermediate'+userFileName+'.exr') print "convertedTexture:: "+convertedTexture finalTexture = os.path.join('/tmp','finished'+userFileName+'.exr') print "finalTexture:: "+finalTexture # Gamma correct for linear workflow if 'DIFF' in userTextureMap or 'diffuse' in userTextureMap: args = ['icomposite',convertedTexture,'=','gamma',str(1/2.2),userTextureMap] subprocess.check_call(args) didgamma = '\nIt has been gamma corrected.' else: convertedTexture = userTextureMap didgamma = '' # Convert to .exr with otimized settings. Also, setting compatible with RenderMan (in case we need to render there) args = ['txmake','-mode','periodic','-compression','zip'] args += ['-format','openexr','-half',convertedTexture,finalTexture] # Uncomment the following and comment out the previous call if PRMan is not present """ args = 'iconvert -d half ' + convertedTexture + ' ' args += finalTexture + ' storage tile tilex 32 tiley 32 compression zip' subprocess.check_call( args.split() ) """ try: subprocess.check_call(args) except subprocess.CalledProcessError as e: ui.infoWindow('Failed to convert texture. The following error occured:\n' + str(e)) else: # Rename texture and move into production pipeline newTextureName = userFileName + '.exr' newfilepath = os.path.join(assetImageDir, folder_name, newTextureName) print "new file path:: "+newfilepath try: fileutil.move(finalTexture, newfilepath) except Exception as e: os.remove(finalTexture) ui.infoWindow('Failed to move texture. The following error occured:\n' + str(e), msev=messageSeverity.Error) finally: if convertedTexture != userTextureMap: os.remove(convertedTexture)
def rollbackOTL(node = None): """Pulls a rollback window for the user to select a version to rollback to. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database. """ print 'RollbackOTL' #Need to check if a particular node is a digital asset first. Rollback is will only work as a DA, with model, rigs and animation. if node != None: if not ham.isDigitalAsset(node): ui.infoWindow('Wait! You can only rollback Digital Assets!') print "NOT A DIGITAL ASSET." else: # First, we need to see if this is checked out or not. If it is checked out, then we can proceed. If not, state so. # For the productions path libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) asset_name, ext = os.path.splitext(filename) #print "asset_name " + asset_name toCheckout = os.path.join(ASSETSDIR, asset_name, 'otl') #print "toCheckout " + toCheckout myCheckout = False myCheckout = amu.isCheckedOut(toCheckout) if myCheckout: #If it has been checked out myCheckout = amu.checkedOutByMe(toCheckout) if myCheckout: #If user was the last to checkout #Here we rollback. versionedFolders = os.path.join(toCheckout, "src") #print "versionedFolders ", versionedFolders versions = glob.glob(os.path.join(versionedFolders, '*')) #print "selections ", versions #Wooohoooo!!! selections = [] selectionInfo = [] nodeInfoDest = toCheckout for vr in versions: selections.append(os.path.basename(vr)) comment = amu.getVersionComment(nodeInfoDest,os.path.basename(vr)) selectionInfo.append(comment) selections.sort() dialog = VersionDialog() dialog.addItems(selections,selectionInfo) dialog.show() dialog.setParams(versionedFolders,asset_name,toCheckout,True) pyqt_houdini.exec_(dialog) else: hou.ui.displayMessage('Already checked out.') return else: hou.ui.displayMessage('Please checkout asset first.') else: print "Node does not exist"
def checkinLightingFile(): print 'checkin lighting file' filepath = hou.hipFile.path() toCheckin = os.path.join(amu.getUserCheckoutDir(), os.path.basename(os.path.dirname(filepath))) if amu.canCheckin(toCheckin): hou.hipFile.save() hou.hipFile.clear() dest = amu.checkin(toCheckin) else: ui.infoWindow('Checkin Failed')
def unlockOTL1(): """Calls unlockOTL with the selected node""" node = getSelectedNode() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) #TODO save this somewhere unlockOTL(filename)
def checkinLightingFile(): print("checkin lighting file") filepath = hou.hipFile.path() toCheckin = os.path.join(amu.getUserCheckoutDir(), os.path.basename(os.path.dirname(filepath))) if amu.canCheckin(toCheckin): hou.hipFile.save() hou.hipFile.clear() dest = amu.checkin(toCheckin, False) srcFile = amu.getAvailableInstallFiles(dest)[0] amu.install(dest, srcFile) else: ui.infoWindow("Checkin Failed")
def getNodeInfo(node): if node != None and isDigitalAsset(node): updateDB() libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) nodeInfo = getFileInfo(filename) message = "" if nodeInfo[2]: logname, realname = amu.lockedBy(nodeInfo[3].encode("utf-8")) message = "Checked out by " + realname + " (" + logname + ")" else: message = "Not checked out." ui.infoWindow(message, wtitle="Node Info")
def getNodeInfo(node): if isDigitalAsset(node): updateDB() libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) nodeInfo = getFileInfo(filename) message = '' logname, realname = amu.lockedBy(nodeInfo[3].encode('utf-8')) if nodeInfo[2]: message = 'Checked out by '+realname+' ('+logname+')' else: message = 'Not checked out. Last checked in by '+realname+' ('+logname+')' ui.infoWindow(message, wtitle='Node Info')
def unlockOTLbyNode(node = None): """Calls unlockOTL with the selected node""" if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: reply = ui.warningWindow('WARNING! You are unlocking the Database! \n If you are being dumb, please click \n CANCEL!') if reply == 0: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) #TODO save this somewhere unlockOTL(filename) else: ui.infoWindow('Thank you for being safe. \n If you have question please talk to someone in charge.')
def revertChanges(): updateDB() node= getSelectedNode() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("OTL not in globals folder. Can not revert.") elif info[2]: if not node.isLocked() and info[3] == USERNAME: newfilepath = os.path.join(OTLDIR, filename) oldfilepath = os.path.join(USERDIR, filename) switchOPLibraries(oldfilepath, newfilepath) os.remove(oldfilepath) createMe = node.type().name() node.destroy() hou.node('/obj').createNode(createMe) unlockOTL(filename) ui.infoWindow("Revert Successful!") else: ui.infoWindow("Select EXACTLY one node.")
def checkinLightingFile(): print('checkin lighting file') filepath = hou.hipFile.path() toCheckin = os.path.join(amu.getUserCheckoutDir(), os.path.basename(os.path.dirname(filepath))) backups = os.path.join(toCheckin, 'backup') print 'backup = ' + backups if os.path.isdir(backups): os.system('rm -rf '+backups) if amu.canCheckin(toCheckin): hou.hipFile.save() hou.hipFile.clear() dest = amu.checkin(toCheckin, False) srcFile = amu.getAvailableInstallFiles(dest)[0] amu.install(dest, srcFile) else: ui.infoWindow('Checkin Failed')
def new(): updateDB() otb = ("Container", "Geometry", "Cancel") optype = ui.infoWindow("Choose operator type.", wbuttons=otb, wtitle="Asset Type") hpath = determineHPATH() if optype == 0: newContainer(hpath) elif optype == 1: newGeo(hpath)
def new(): updateDB() otb = ('Container', 'Geometry', 'Cancel') optype = ui.infoWindow("Choose operator type.", wbuttons=otb, wtitle='Asset Type') hpath = determineHPATH() if optype == 0: newContainer(hpath) elif optype == 1: newGeo(hpath)
def getInfo(node): if node == None: # code for getting info from the checked out scene file goes here sys.stderr.write('Code for shot info does not yet exist for Houdini!') pass elif isDigitalAsset(node): # code for getting info selected node updateDB() libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) nodeInfo = getFileInfo(filename) message = '' if nodeInfo[2]: logname, realname = amu.lockedBy(nodeInfo[3].encode('utf-8')) message = 'Checked out by '+realname+' ('+logname+')' else: message = 'Not checked out.' ui.infoWindow(message, wtitle='Node Info')
def discardLightingFile(): filepath = hou.hipFile.path() #TODO print(filepath) if ui.infoWindow('YOU ARE ABOUT TO IRREVOKABLY DISCARD ALL CHANGES YOU HAVE MADE. ' 'Please think this through very carefully.\n\nNow that we have ' 'gotten that straightened out, are you sure you want to discard ' 'your changes?' , wbuttons=('Yes','No',) , wdefault_choice=1 , wtitle='Discard Confirmation') == 0: toDiscard = os.path.join(amu.getUserCheckoutDir(), os.path.basename(os.path.dirname(filepath))) if amu.isCheckedOutCopyFolder(toDiscard): hou.hipFile.clear() amu.discard(toDiscard) else: ui.infoWindow('This is not a checked out file. There is nothing to discard', wtitle='Invalid Command') else: ui.infoWindow('Thank you for being responsible.', wtitle='Discard Cancelled')
def newContainer(hpath): templateNode = hou.node(hpath).createNode("containerTemplate") templateNode.hide(True) resp = ui.inputWindow("Enter the New Operator Label", wtitle="OTL Label") if resp != None and resp.strip() != '': name = formatName(resp) filename = name.replace(' ', '_') newfilepath = os.path.join(OTLDIR, filename+'.otl') if not os.path.exists(newfilepath): # create file heirarchy if container asset amu.createNewAssetFolders(ASSETSDIR, filename) templateNode.type().definition().copyToHDAFile(newfilepath, new_name=filename, new_menu_name=name) hou.hda.installFile(newfilepath, change_oplibraries_file=True) newnode = hou.node(hpath).createNode(filename) else: ui.infoWindow("Asset by that name already exists. Cannot create asset.", wtitle='Asset Name', msev=messageSeverity.Error) # clean up templateNode.destroy()
def newTexture(): # Get a list of assets assetList = glob.glob(os.path.join(os.environ["ASSETS_DIR"], "*")) selections = [] for aL in assetList: # basename takes last folder in path. selections.append(os.path.basename(aL)) # sort alphabetically selections.sort() answer = ui.listWindow(selections, wmessage="Choose an asset to add/update textures for") if answer: answer = answer[0] assetName = selections[answer] assetImageDir = os.path.join(os.environ["ASSETS_DIR"], assetName, "images") # Allow user to choose texture map in user local directory userDirectory = os.environ["USER_DIR"] userSelection = ui.fileChooser( start_dir=userDirectory, wtitle="Select texture map, or folder of texture maps", image=True, extensions="*.jpg,*.jpeg,*.tiff,*.tif,*.png,*.exr", ) # Allow user to search for texture in any directory userSelection = os.path.expandvars(userSelection) if os.path.isdir(userSelection): folder_name = os.path.basename(os.path.dirname(userSelection)) texture_paths = glob.glob(os.path.join(userSelection, "*")) newFileDir = os.path.join(assetImageDir, folder_name) os.system("rm -rf " + newFileDir) print "newFileDir:: " + newFileDir os.makedirs(newFileDir) for t in texture_paths: convert_texture(t, assetImageDir, folder_name=folder_name) else: convert_texture(userSelection, assetImageDir) ui.infoWindow("Done.")
def newContainer(hpath): templateNode = hou.node(hpath).createNode("containerTemplate") templateNode.hide(True) resp = ui.inputWindow("Enter the New Operator Label", wtitle="OTL Label") if resp != None and resp.strip() != '': name = formatName(resp) filename = name.replace(' ', '_') newfilepath = os.path.join(OTLDIR, filename+'.otl') if not os.path.exists(newfilepath): # create file heirarchy if container asset amu.createNewAssetFolders(ASSETSDIR, filename) templateNode.type().definition().copyToHDAFile(newfilepath, new_name=filename, new_menu_name=name) hou.hda.installFile(newfilepath, change_oplibraries_file=True) fileutil.clobberPermissions(newfilepath) newnode = hou.node(hpath).createNode(filename) else: ui.infoWindow("Asset by that name already exists. Cannot create asset.", wtitle='Asset Name', msev=messageSeverity.Error) # clean up templateNode.destroy()
def rename(node = None): """Renames the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database. """ updateDB() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: if isContainer(node): oldlibraryPath = node.type().definition().libraryFilePath() oldfilename = os.path.basename(oldlibraryPath) oldAssetName = oldfilename.split('.')[0] assetDirPath = os.path.join(ASSETSDIR, oldAssetName) info = getFileInfo(oldfilename) if not info[2]: if ui.passwordWindow('r3n@m3p@ssw0rd', wmessage='Enter the rename password...'): resp = ui.inputWindow("Enter the New Operator Label", wtitle="Rename OTL") if resp != None and resp.strip() != '': name = formatName(resp) newfilename = name.replace(' ', '_') newfilepath = os.path.join(OTLDIR, newfilename+'.otl') if os.path.exists(newfilepath): ui.infoWindow("Asset by that name already exists. Cannot rename asset.", wtitle='Asset Name', msev=messageSeverity.Error) elif not amu.canRename(assetDirPath, newfilename): ui.infoWindow("Asset checked out in Maya. Cannot rename asset.", wtitle='Asset Name', msev=messageSeverity.Error) else: node.type().definition().copyToHDAFile(newfilepath, new_name=newfilename, new_menu_name=name) hou.hda.installFile(newfilepath, change_oplibraries_file=True) newnode = hou.node(determineHPATH()).createNode(newfilename) node.destroy() hou.hda.uninstallFile(oldlibraryPath, change_oplibraries_file=False) os.system('rm -f '+oldlibraryPath) amu.renameAsset(assetDirPath, newfilename) else: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot checkout asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error) else: ui.infoWindow("Select EXACTLY one node.")
def convert_texture(userTextureMap, assetImageDir, folder_name=""): print userTextureMap if os.path.isdir(userTextureMap): return extensions = [".jpg", ".jpeg", ".tiff", ".tif", ".png", ".exr"] userFileName, userExt = os.path.splitext(os.path.basename(userTextureMap)) if userExt not in extensions: return # Set Variables for texture paths convertedTexture = os.path.join("/tmp", "intermediate" + userFileName + ".exr") print "convertedTexture:: " + convertedTexture finalTexture = os.path.join("/tmp", "finished" + userFileName + ".rat") print "finalTexture:: " + finalTexture # Gamma correct for linear workflow if "DIFF" in userTextureMap or "diffuse" in userTextureMap: args = ["icomposite", convertedTexture, "=", "gamma", str(1 / 2.2), userTextureMap] try: subprocess.check_call(args) except subprocess.CalledProcessError as e: ui.infoWindow("Failed to convert texture. The following error occured:\n" + str(e)) return didgamma = "\nIt has been gamma corrected." else: convertedTexture = userTextureMap didgamma = "" """ # Convert to .exr with optimized settings. Also, setting compatible with RenderMan (in case we need to render there) args = ['txmake','-mode','periodic','-compression','zip'] args += ['-format','openexr','-half',convertedTexture,finalTexture] """ # Uncomment the following and comment out the previous call if PRMan is not present args = ["iconvert", convertedTexture, finalTexture] # subprocess.check_call( args.split() ) try: subprocess.check_call(args) except subprocess.CalledProcessError as e: ui.infoWindow("Failed to convert texture. The following error occured:\n" + str(e)) else: # Rename texture and move into production pipeline newTextureName = userFileName + ".rat" newfilepath = os.path.join(assetImageDir, folder_name, newTextureName) print "new file path:: " + newfilepath try: shutil.move(finalTexture, newfilepath) except Exception as e: os.remove(finalTexture) ui.infoWindow("Failed to move texture. The following error occured:\n" + str(e), msev=messageSeverity.Error) finally: if convertedTexture != userTextureMap: os.remove(convertedTexture)
def newGeo(hpath): templateNode = hou.node(hpath).createNode("geometryTemplate") alist = listContainers() resp = ui.inputWindow("Enter the New Operator Label", wtitle="OTL Label") filename = str() if resp != None and resp.strip() != '': name = formatName(resp) filename = name.replace(' ', '_') templateNode.setName(filename, unique_name=True) answer = ui.listWindow(alist, wmessage='Select Container Asset this belongs to:') if not answer: ui.infoWindow("Geometry must be associated with a container asset! Geometry asset not created.", msev=messageSeverity.Error) templateNode.destroy() return answer = answer[0] sdir = '$JOB/PRODUCTION/assets/' gfile = ui.fileChooser(start_dir=sdir + alist[answer]+'/geo', wtitle='Choose Geometry', mode=fileMode.Read, extensions='*.bjson, *.obj') if len(gfile) > 4 and gfile[:4] != '$JOB': ui.infoWindow("Path must start with '$JOB'. Default geometry used instead.", wtitle='Path Name', msev=messageSeverity.Error) templateNode.destroy() elif gfile != '': hou.parm(templateNode.path() + '/read_file/file').set(gfile)
def unlockLightingFile(): print("unlockLightingFile") shotPaths = glob.glob(os.path.join(os.environ['SHOTS_DIR'], '*')) selections = [] for sp in shotPaths: selections.append(os.path.basename(sp)) selections.sort() answer = ui.listWindow(selections, wmessage='Select shot file to unlock:') if answer: answer = answer[0] toUnlock = os.path.join(os.environ['SHOTS_DIR'], selections[answer], 'lighting') if amu.isLocked(toUnlock): reply = ui.warningWindow('Are you sure you want to unlock this file?') if reply == 0: hou.hipFile.save() hou.hipFile.clear() amu.unlock(toUnlock) ui.infoWindow('Lighting file unlocked') else: ui.infoWindow('Lighting file already unlocked') return
def refresh(): updateDB() node = getSelectedNode() if node == None: ui.infoWindow("Select EXACTLY one node.") return nodeName = getAssetName(node) if isContainer(node): # Get children and change to containerTemplate children = node.children() nameLookup = list(children) for i in range(len(children)): c = children[i] if isContainer(c): assetName = getAssetName(c) print assetName nameLookup[i] = assetName c.changeNodeType('containerTemplate', keep_network_contents=False) print '\n' # Update children and change back children = node.children() for i in range(len(children)): c = children[i] if isContainer(c): name = nameLookup[i] print name c.changeNodeType(name, keep_network_contents=False) # Change the top level node node.changeNodeType('containerTemplate', keep_network_contents=False) node = getSelectedNode() node.changeNodeType(nodeName, keep_network_contents=False) else: ui.infoWindow('Not a container')
def refresh(node=None): updateDB() if node == None: ui.infoWindow("Select EXACTLY one node.") return nodeName = getAssetName(node) if isContainer(node): # Get children and change to containerTemplate children = node.children() nameLookup = list(children) for i in range(len(children)): c = children[i] if isContainer(c): assetName = getAssetName(c) print(assetName) nameLookup[i] = assetName c.changeNodeType("containerTemplate", keep_network_contents=False) print("\n") # Update children and change back children = node.children() for i in range(len(children)): c = children[i] if isContainer(c): name = nameLookup[i] print(name) c.changeNodeType(name, keep_network_contents=False) # Change the top level node if not isSetAsset(node): tempnode = node.changeNodeType("containerTemplate", keep_network_contents=False) tempnode.changeNodeType(nodeName, keep_network_contents=False) else: ui.infoWindow("Not a container")
def newTexture(): # Get a list of assets assetList = glob.glob(os.path.join(os.environ['ASSETS_DIR'], '*')) selections = [] for aL in assetList: # basename takes last folder in path. selections.append(os.path.basename(aL)) # sort alphabetically selections.sort() answer = ui.listWindow(selections, wmessage='Choose an asset to add/update textures for') if answer: answer = answer[0] assetName = selections[answer] assetImageDir = os.path.join(os.environ['ASSETS_DIR'], assetName, 'images') # Allow user to choose texture map in user local directory userDirectory = os.environ['USER_DIR'] userSelection = ui.fileChooser(start_dir=userDirectory, wtitle='Select texture map, or folder of texture maps', image=True, extensions='*.jpg,*.jpeg,*.tiff,*.tif,*.png,*.exr') #Allow user to search for texture in any directory userSelection = os.path.expandvars(userSelection) if os.path.isdir(userSelection): folder_name = os.path.basename(os.path.dirname(userSelection)) texture_paths = glob.glob(os.path.join(userSelection, '*')) newFileDir = os.path.join(assetImageDir, folder_name) os.system('rm -rf '+newFileDir) print 'newFileDir:: '+newFileDir os.makedirs(newFileDir) for t in texture_paths: convert_texture(t, assetImageDir, folder_name=folder_name) else: convert_texture(userSelection, assetImageDir) ui.infoWindow('Done.')
def add(node = None): """Adds the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node CAN NOT already exist in the database.""" updateDB() if node != None: if node.type().definition() is None: ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: saveOTL(node) moveToOtlDir(node, filename) addOTL(filename) ui.infoWindow("Add Successful!") else: ui.infoWindow("Already Added") else: ui.infoWindow("Select EXACTLY one node.")
def discard(node = None): updateDB() if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("OTL not in globals folder. Can not revert.") elif info[2]: if not node.isLocked() and info[3] == USERNAME: newfilepath = os.path.join(OTLDIR, filename) oldfilepath = os.path.join(USERDIR, filename) switchOPLibraries(oldfilepath, newfilepath) os.remove(oldfilepath) createMe = node.type().name() node.destroy() hou.node('/obj').createNode(createMe) unlockOTL(filename) ui.infoWindow("Revert Successful!")
def refresh(node = None): """Only updates transforms of internal nodes of "Editable Assets" Everything else is probably either light linking data, or something else that should always have a local override.""" updateDB() hou.hscript("otrefresh -r") # Refresh all definitions first if node == None or hasattr(node, "__len__"): ui.infoWindow("Select EXACTLY one node.") elif not isEditableAsset(node): ui.infoWindow('Not an "Editable Asset".') else: npath = os.path.dirname(node.path()) dopple = hou.node(npath).createNode(node.type().name()) for c in node.children(): for dc in dopple.children(): if c.name() == dc.name() and isinstance(c, hou.ObjNode): c.setParmTransform(dc.parmTransform()) dopple.destroy() ui.infoWindow('Refresh successful.')
def deleteAsset(node = None): """Deletes the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database. It may not be already checked out in Houdini or in Maya. """ updateDB() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.", wtitle='Non-Asset Node', msev=messageSeverity.Error) return else: if isContainer(node): oldlibraryPath = node.type().definition().libraryFilePath() oldfilename = os.path.basename(oldlibraryPath) oldAssetName = oldfilename.split('.')[0] assetDirPath = os.path.join(ASSETSDIR, oldAssetName) dependents = getAssetDependents(oldAssetName) if dependents: ui.infoWindow('The following assets are depenent on this asset: \n\n'+printList(dependents)+'\nModify these assets first before attempting to delete again!!', wtitle='Can NOT delete!', msev=messageSeverity.Error) return info = getFileInfo(oldfilename) if info[2]: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot delete asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error) return if not amu.canRemove(assetDirPath): ui.infoWindow("Asset currently checked out in Maya. Cannot delete asset.", wtitle='Maya Lock', msev=messageSeverity.Error) return message = "The following paths and files will be deleted:\n" + assetDirPath + "\n" + oldlibraryPath ui.infoWindow(message, wtitle='Asset Deleted', msev=messageSeverity.Message) if ui.passwordWindow('d3l3t3p@ssw0rd', wmessage='Enter the deletion password ...'): node.destroy() hou.hda.uninstallFile(oldlibraryPath, change_oplibraries_file=False) try: amu.removeFolder(assetDirPath) os.remove(oldlibraryPath) except Exception as ex: ui.infoWindow("The following exception occured:\n" + str(ex), wtitle='Exception Occured', msev=messageSeverity.Error) return else: ui.infoWindow("Select EXACTLY one node.") return
def rename(node = None): """Renames the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database. """ updateDB() if node != None: if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: if isContainer(node): oldlibraryPath = node.type().definition().libraryFilePath() oldfilename = os.path.basename(oldlibraryPath) oldAssetName = oldfilename.split('.')[0] assetDirPath = os.path.join(ASSETSDIR, oldAssetName) dependents = getAssetDependents(oldAssetName) if dependents: ui.infoWindow('The following assets are depenent on this asset: \n\n'+printList(dependents)+'\nModify these assets first before attempting to rename again!!', wtitle='Can NOT rename!', msev=messageSeverity.Error) return info = getFileInfo(oldfilename) if not info[2]: if ui.passwordWindow('r3n@m3p@ssw0rd', wmessage='Enter the rename password...'): resp = ui.inputWindow("Enter the New Operator Label", wtitle="Rename OTL") if resp != None and resp.strip() != '': name = formatName(resp) newfilename = name.replace(' ', '_') newfilepath = os.path.join(OTLDIR, newfilename+'.otl') if os.path.exists(newfilepath): ui.infoWindow("Asset by that name already exists. Cannot rename asset.", wtitle='Asset Name', msev=messageSeverity.Error) elif not amu.canRename(assetDirPath, newfilename): ui.infoWindow("Asset checked out in Maya. Cannot rename asset.", wtitle='Asset Name', msev=messageSeverity.Error) else: node.type().definition().copyToHDAFile(newfilepath, new_name=newfilename, new_menu_name=name) hou.hda.installFile(newfilepath, change_oplibraries_file=True) newnode = hou.node(determineHPATH()).createNode(newfilename) node.destroy() hou.hda.uninstallFile(oldlibraryPath, change_oplibraries_file=False) subprocess.check_call( ['rm','-f',oldlibraryPath] ) amu.renameAsset(assetDirPath, newfilename) else: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot checkout asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error) else: ui.infoWindow("Select EXACTLY one node.")
def convert_texture(userTextureMap, assetImageDir, folder_name=''): print userTextureMap if os.path.isdir(userTextureMap): return extensions = ['.jpg','.jpeg','.tiff','.tif','.png','.exr'] userFileName, userExt = os.path.splitext(os.path.basename(userTextureMap)) if userExt not in extensions: return # Set Variables for texture paths convertedTexture = os.path.join('/tmp','intermediate'+userFileName+'.exr') print "convertedTexture:: "+convertedTexture finalTexture = os.path.join('/tmp','finished'+userFileName+'.rat') print "finalTexture:: "+finalTexture # Gamma correct for linear workflow if 'DIFF' in userTextureMap or 'diffuse' in userTextureMap: args = ['icomposite',convertedTexture,'=','gamma',str(1/2.2),userTextureMap] try: subprocess.check_call(args) except subprocess.CalledProcessError as e: ui.infoWindow('Failed to convert texture. The following error occured:\n' + str(e)) return didgamma = '\nIt has been gamma corrected.' else: convertedTexture = userTextureMap didgamma = '' ''' # Convert to .exr with optimized settings. Also, setting compatible with RenderMan (in case we need to render there) args = ['txmake','-mode','periodic','-compression','zip'] args += ['-format','openexr','-half',convertedTexture,finalTexture] ''' # Uncomment the following and comment out the previous call if PRMan is not present args = ['iconvert', convertedTexture, finalTexture] #subprocess.check_call( args.split() ) try: subprocess.check_call(args) except subprocess.CalledProcessError as e: ui.infoWindow('Failed to convert texture. The following error occured:\n' + str(e)) else: # Rename texture and move into production pipeline newTextureName = userFileName + '.rat' newfilepath = os.path.join(assetImageDir, folder_name, newTextureName) print "new file path:: "+newfilepath try: shutil.move(finalTexture, newfilepath) except Exception as e: os.remove(finalTexture) ui.infoWindow('Failed to move texture. The following error occured:\n' + str(e), msev=messageSeverity.Error) finally: if convertedTexture != userTextureMap: os.remove(convertedTexture)
def checkin(node = None): """Checks in the selected node. EXACTLY ONE node may be selected, and it MUST be a digital asset. The node must already exist in the database, and USERNAME must have the lock.""" updateDB() if not isDigitalAsset(node): ui.infoWindow("Not a Digital Asset.") else: libraryPath = node.type().definition().libraryFilePath() filename = os.path.basename(libraryPath) info = getFileInfo(filename) if info == None: ui.infoWindow("Add the OTL first") elif info[2]: if not node.isLocked() and info[3] == USERNAME: saveOTL(node) # This save is not strictly necessary since we save again two lines down lockAsset(node, False) saveOTL(node) moveToOtlDir(node, filename) unlockOTL(filename) if isCameraAsset(node) and ui.infoWindow('Export Alembic?' , wbuttons=('Yes','No',) , wdefault_choice=0 , wtitle='Export Alembic') == 0: writeCamerasToAlembic(node) if isSetAsset(node) and ui.infoWindow('Export Alembic?' , wbuttons=('Yes','No',) , wdefault_choice=0 , wtitle='Export Alembic') == 0: writeSetToAlembic(node) ui.infoWindow("Checkin Successful!") else: logname, realname = amu.lockedBy(info[3].encode('utf-8')) whoLocked = 'User Name: ' + logname + '\nReal Name: ' + realname + '\n' errstr = 'Cannot checkin asset. Locked by: \n\n' + whoLocked ui.infoWindow(errstr, wtitle='Asset Locked', msev=messageSeverity.Error) else: ui.infoWindow("Already checked in.")