''' Muster 8 Generic script template class ''' ''' Import Muster base modules ''' import MClientAPI import MTemplateAPI ''' Import Python base lib modules ''' import os.path import re ''' Get the template manager singleton ''' manager = MTemplateAPI.MManager.getUniqueClass() ''' Define a new class derived from MTemplateAPI.MTemplate base class , override required methods ''' class ShellTemplate(MTemplateAPI.MTemplate): def __init__(self): MTemplateAPI.MTemplate.__init__(self) self.setID(2008) self.setName("Denoise_Noice") self.setDescription("Denoise with Noice") self.setTemplateLogic(MTemplateAPI.kTemplateMultiframe) self.setDefaultPriority(1) self.setDefaultPools("arnold_16thread") self.setDefaultExcludedPools("") self.setMaximumLicenses(0) self.setEnableAdditionalFlagsField(1) ''' Submission form items allocation ''' NoiceBin = MTemplateAPI.MTemplateItemFolder("NOICEBIN", "Noice Bin Path", "Specifies the Noice bin Path", "", 0, 1, 1) patchRadius = MTemplateAPI.MTemplateItemInteger("PATCHRADIUS", "PatchRadius", "Specify the patch radius", 3, 0, 0, 1) searchRadius = MTemplateAPI.MTemplateItemInteger("SEARCHRADIUS", "PatchRadius", "Specify the patch radius", 9, 0, 0, 1) variance = MTemplateAPI.MTemplateItemDouble("VARIANCE", "Variance", "Specifies the variance", 0.25, 0, 0, 1) lightAovString = MTemplateAPI.MTemplateItemString("LIGHTAOVSTRING", "Light AOV String", "Specifies the AOVs to be denoised. Syntax: -aov aovname1 -aov aovname2 -aov aovname3", "-aov rgba", 0, 0, 1) temporalFrames = MTemplateAPI.MTemplateItemInteger("TEMPORALFRAMES", "Temporal Frames", "Specifies the temporal frames", 0, 0, 0, 1) denoiseThreads = MTemplateAPI.MTemplateItemInteger("DENOISETHREADS", "Threads", "Specify the denoise threads", -2, 1, 0, 1) startFrame = MTemplateAPI.MTemplateItemInteger("NOICESTARTFRAME", "Start frame", "Specifies the starting frame for the rendering job", 1001, 0, 0, 1) endFrame = MTemplateAPI.MTemplateItemInteger("NOICEENDFRAME", "End frame", "Specifies the ending frame for the rendering job", 1010, 0, 0, 1) inputFile = MTemplateAPI.MTemplateItemFile("INPUTFILE", "Input File", "Specifies the File to be denoised", "", 0, 1, 1, "*.exr") outputFile = MTemplateAPI.MTemplateItemFile("OUTPUTFILE", "Output File", "Specifies the output File", "", 0, 1, 1, "*.exr") self.addSubmissionItem(NoiceBin) self.addSubmissionItem(patchRadius) self.addSubmissionItem(searchRadius) self.addSubmissionItem(variance) self.addSubmissionItem(lightAovString) self.addSubmissionItem(temporalFrames) self.addSubmissionItem(denoiseThreads) self.addSubmissionItem(startFrame) self.addSubmissionItem(endFrame) self.addSubmissionItem(inputFile) self.addSubmissionItem(outputFile) ''' items mapping to Muster default tags ''' self.addMapping("INPUTFILE", "job_file") self.addMapping("NOICESTARTFRAME", "start_frame") self.addMapping("NOICEENDFRAME", "end_frame") ''' Windows support ''' self.platformWindows.setPlatformEnabled(1) self.platformWindows.setEnableErrorCheck(1) self.platformWindows.setEnabledByDefault(1) self.platformWindows.setDetectionLogic(MTemplateAPI.kProcessChild) #self.platformWindows.setDetectionLogic(MTemplateAPI.kProcessDirect) self.platformWindows.setDetectionLogicProcessName("noice.exe") ''' OSX support ''' self.platformOSX.setPlatformEnabled(0) self.platformOSX.setEnableErrorCheck(1) self.platformOSX.setEnabledByDefault(1) self.platformOSX.setDetectionLogic(MTemplateAPI.kProcessDirect) applicationPath = MTemplateAPI.MTemplateItemFile("SHELLCMD", "Script interpreter executable", "Specifies the OS X script executable", "/bin/sh", 0, 0, 1, "*.exe") self.platformOSX.addClientConfigurationItem(applicationPath) ''' Linux support ''' self.platformLinux.setPlatformEnabled(0) self.platformLinux.setEnableErrorCheck(1) self.platformLinux.setEnabledByDefault(1) self.platformLinux.setDetectionLogic(MTemplateAPI.kProcessDirect) applicationPath = MTemplateAPI.MTemplateItemFile("SHELLCMD", "Script interpreter executable", "Specifies the Linux script executable", "/bin/sh", 0, 0, 1, "*.exe") self.platformLinux.addClientConfigurationItem(applicationPath) ''' virtual functions overrides ''' def onBuildCommandLine(self, platform, job, chunk, clientTemplatePreferences, instanceNum): # sequence with sequence string bla.1001.exr fileIn = job.attributeGetString(manager.resolveMappingToJob(self.getID(), "INPUTFILE")) fileOut = job.attributeGetString(manager.resolveMappingToJob(self.getID(), "OUTPUTFILE")) # regex patternSeq = re.compile(r'\.\d\d\d+\.') # extract frame substring frame = patternSeq.findall(fileIn) # if there are more matches due to non-conform naming frame = frame[-1] chunkFrame = "." + str(int(chunk.getStartFrame())) + "." # replace padding with the startFrame of the chunk fileIn = fileIn.replace(frame, chunkFrame) fileOut = fileOut.replace(frame, chunkFrame) renderCmd = "" if platform == MClientAPI.kPlatformWindows: renderCmd += "/c " renderCmd += "\"" renderCmd += job.attributeGetString("NOICEBIN") + "noice.exe" renderCmd += " -patchradius %s" % job.attributeGetInt("PATCHRADIUS") renderCmd += " -searchradius %s" % job.attributeGetInt("SEARCHRADIUS") renderCmd += " -variance %s" % job.attributeGetFloat("VARIANCE") renderCmd += " " + job.attributeGetString("LIGHTAOVSTRING") # '-aov aovname1 -aov aovname2' renderCmd += " -i " + fileIn renderCmd += " -t " + job.attributeGetString("DENOISETHREADS") renderCmd += " -ef %s" % job.attributeGetInt("TEMPORALFRAMES") renderCmd += " -output " + fileOut renderCmd += "\"" addFlags = job.attributeGetString("ADD_FLAGS") if len(addFlags) > 0: renderCmd += " " + addFlags return renderCmd def onCheckLog(self, job, chunk, clientTemplatePreferences, log, warnings, errors, silencedWarnings, silencedErrors): ## WARNINGS noWarnings = [] foundset = [] for line in log.splitlines(): if line.lower().find("warning") != -1: foundset.append(line) # remove no warning strings result = [x for x in foundset if not any(y in x for y in noWarnings)] if len(result) != 0: return MTemplateAPI.MTemplateError(2, "Warning keyword found", MTemplateAPI.MTemplateError.kTemplateErrorTypeWarning) ## ERRORS if log.lower().find("error") != -1: return MTemplateAPI.MTemplateError(1, "Error keyword found", MTemplateAPI.MTemplateError.kTemplateErrorTypeError) if log.lower().find("no licenses could be found to run this application") != -1: return MTemplateAPI.MTemplateError(1, "No license available", MTemplateAPI.MTemplateError.kTemplateErrorTypeError) return MTemplateAPI.MTemplateError() def onCheckLogLine(self, job, chunk, clientTemplatePreferences, line, lineNum, warnings, errors, silencedWarnings, silencedErrors): return MTemplateAPI.MTemplateError() def onBuildEnvironment(this, job, chunk, clientTemplatePreferences, existingEnvironment): return existingEnvironment def onGetApplicationPath(self, job, chunk, clientTemplatePreferences, pathOut): platform = MClientAPI.GetPlatform() if platform == MClientAPI.kPlatformWindows: pathOut.setString("cmd.exe") else: pathOut.setString("/bin/sh") return MTemplateAPI.MTemplateError() def onGetApplicationStartingFolder(self, job, chunk, clientTemplatePreferences, pathOut): pathStart = "c:\\Windows\\System32" platform = MClientAPI.GetPlatform() if platform == MClientAPI.kPlatformWindows: #pathOut.setString(job.attributeGetString("NOICEBIN")) pathOut.setString(pathStart) else: pass return MTemplateAPI.MTemplateError() def onCheckForSubframeAdvancingString(self, job, chunk, line): return 0 def onCheckForSubframeProgress(self, job, chunk, line, progressOut): return 0 def onCheckExitCode(self, job, chunk, clientTemplatePreferences, exitCode): if exitCode != 0: return MTemplateAPI.MTemplateError(exitCode, "%d Exit code different from expected 0 value" % exitCode, MTemplateAPI.MTemplateError.kTemplateErrorTypeWarning) return MTemplateAPI.MTemplateError() def onApplicationFinder(self, moduleRegExp, moduleTag): return MTemplateAPI.kTemplateScanNone def onFindApplication(self, basePath, clientTemplatePreferences): pass ''' Create an instance of the template class and install it into the template manager context ''' template = ShellTemplate() manager.installPyTemplate(template)