First of all, I didn’t expect to get help from the great Bobo himself! When I was first starting out with maxscript, your posts on forums were invaluable, so thanks for that!
As for the code, I’ve created a set of global functions that I can call in all of my scripts (or even the listener, should I want to) that enable the different tools to submit the current scene to deadline. Obviously, I shouldn’t be changing the signature of the function, so I don’t have to open every single tool I’ve made to update it. But I don’t think this will be needed.
I think I will have to go through all the code though, because I’m using batching functionality. I create a queue that holds the maxfile, plugin and jobinfofiles and a boolean to make it dependent on the previous job. I have a SubmitToQueue function that will add this information to an array, and then ultimately I call a FlushQueue function that will output that data to a string and then I use the DeadlineCommandbg.exe -multi flag to submit all those jobs at once. This seemed the most efficient way, as oftentimes we send out large batches of renders and it’s faster this way. Even the simplest of chains (Lightcache pass, irradiance pass, beauty pass, each depending on the previous) benefits from this setup as I don’t have to submit every job by itself just to get the ID to use for dependencies.
I will post the code here anyways, in case I can’t figure it out by the time you see this
[code]global DeadlineJob
struct DeadlineJob
(
sJobFile,
sPluginFile,
sMaxfile,
bDependsOnPrevious = false
)
global aDeadlineQueue = #()
global sDeadlineQueuePath = undefined
global InitDeadlineQueue
global SMTDSettings
global SMTDFunctions
fn InitDeadlineQueue sDescription:unsupplied =
(
theResultFile = getDir #temp + “\_result.txt”
theCommandLine = (“deadlinecommand.exe -getrepositoryroot > “”+theResultFile +”"")
hiddenDosCommand theCommandLine startpath:“C:\Program Files\Thinkbox\Deadline7\bin\”
theFileHandle = openFile theResultFile
theNetworkRoot = readLine theFileHandle
close theFileHandle
remoteScript = theNetworkRoot + "\\submission\\3dsmax\\main\\SubmitMaxToDeadline_Functions.ms"
localScript = getDir #userscripts + "\\SubmitMaxToDeadline_Functions.ms"
if doesFileExist remoteScript do
(
if SMTDFunctions == undefined do
(
deleteFile localScript
copyFile remoteScript localScript
fileIn localScript
)
)
aDate = getlocaltime()
sDate = aDate[1] as string + FormatNumber 2 aDate[2] + FormatNumber 2 aDate[4] + "_" + FormatNumber 2 aDate[5] + FormatNumber 2 aDate[6]
sDeadlineQueuePath = (getdir #temp) + "DeadlineJobInfoFiles\\" + sDate
if sDescription != unsupplied then
(
sDeadlineQueuePath += "_" + sDescription
)
sDeadlineQueuePath += "\\"
makedir sDeadlineQueuePath all:true
aDeadlineQueue = #()
)
– InitDeadlineQueue()
global FlushDeadlineQueue
fn FlushDeadlineQueue bFeedback:false =
(
sCommandFile = (getdir #temp + “\” + sysinfo.username + “.txt”)
oFlags = openfile sCommandFile mode:“w”
sCommand = “DeadlineCommandbg.exe “” + sCommandFile + “””
format " -multi\n" to:oFlags
if bFeedback then
(
format " -notify\n" to:oFlags
)
for job in aDeadlineQueue do
(
format " -job\n" to:oFlags
format "%\n%\n%\n" job.sJobFile job.sPluginFile job.sMaxfile to:oFlags
if job.bDependsOnPrevious then
(
format " -dependsonprevious\n" to:oFlags
)
)
close oFlags
HiddenDOSCommand sCommand startpath:"C:\\Program Files\\Thinkbox\\Deadline7\\bin\\" exitcode:&ExitCode
aDeadlineQueue = #()
)
–This one uses cmd to enable DBR without needing a license, use the other one if possible
global SubmitToDeadlineQueue2
fn SubmitToDeadlineQueue2 iPriority:50 sJobName:unsupplied sComment:unsupplied sDepartment:“AMS” iFPC:1 iMachineLimit:0 bDeleteOnComplete:false bSuspended:false bDependsOnPrevious:false bLimitBatchSize:false iMaxBatchSize:20 bDBR:false iDBRServers:20 =
(
if sDeadlineQueuePath == undefined then
(
messagebox “Init the queue first!”
)
else
(
--Create the job and plugin files
iCounter = (getfiles (sDeadlineQueuePath + "*.job")).count
sJobFile = (sDeadlineQueuePath + "Job" + FormatNumber 4 (iCounter+1) + ".job")
sPluginFile = (sDeadlineQueuePath + "Plugin" + FormatNumber 4 (iCounter+1) + ".job")
if sJobName == unsupplied then
(
if maxfilename == "" then
(
messagebox "Please save your file first!" title:"Davy warns"
return false
)
else
(
sJobName = getfilenamefile maxfilename
)
)
bNameAvailable = false
iCounter = 0
while not bNameAvailable do
(
HiddenDOSCommand ("deadlinecommand -getjobIdsfilter jobname=\"" + sJobName + "\" > c:\\DeadlineJobs.txt") startpath:"C:\\Program Files\\Thinkbox\\Deadline7\\bin\\"
oTemp = openfile "c:\\DeadlineJobs.txt"
sLine = ""
try
(
sLine = readline oTemp
)catch()
try(close oTemp)catch()
if sLine == "" then
(
bNameAvailable = true
)
else
(
if matchpattern sJobName pattern:("*_" + FormatNumber 3 iCounter) then
(
iCounter += 1
sJobName = (substring sJobName 1 (sJobName.count - 3)) + FormatNumber 3 iCounter
)
else
(
iCounter += 1
sJobName = sJobName + "_" + FormatNumber 3 iCounter
)
)
)
savemaxfile (maxfilepath + sJobName + ".max") quiet:true
--JobFile
submitInfoFile = CreateFile sJobFile
if (submitInfoFile != undefined) then
(
format "Plugin=3dsCmd\n" to:submitInfoFile
format "ForceReloadPlugin=false\n" to:submitInfoFile
frames = "0"
if rendtimetype == 1 then
(
frames = (currenttime.frame as integer) as string
)
else if rendtimetype == 2 then
(
frames = (animationrange.start.frame as integer) as string + "-" + (animationrange.end.frame as integer) as string
if rendnthframe >1 then frames+= "step" + rendnthframe as string
)
else if rendtimetype == 3 then
(
frames = (rendstart.frame as integer) as string + "-" + (rendend.frame as integer) as string
if rendnthframe >1 then frames+= "step" + rendnthframe as string
)
else if rendtimetype == 4 then
(
frames = rendpickupFrames
if rendnthframe >1 then frames+= "step" + rendnthframe as string
)
chunkSize = iFPC
if bDBR then
(
frames = "0-" + ((iDBRServers - 1) as string)
chunkSize = 1
)
format "Frames=%\n" frames to:submitInfoFile
format "ChunkSize=%\n" chunkSize to:submitInfoFile
format "Priority=%\n" iPriority to:submitInfoFile
format "Pool=%\n" "ams" to:submitInfoFile
format "SecondaryPool=%\n" "none" to:submitInfoFile
format "Name=%\n" sJobName to:submitInfoFile
if sComment != unsupplied then
(
format "Comment=%\n" sComment to:submitInfoFile
)
format "Department=%\n" sDepartment to:submitInfoFile
--format "DeleteOnComplete=%\n" chk_autoDelete.checked to:submitInfoFile
if bDeleteOnComplete then
(
format "OnJobComplete=%\n" "Delete" to:submitInfoFile
)
if bSuspended then
(
format "InitialStatus=Suspended\n" to:submitInfoFile
)
format "MachineLimit=%\n" iMachineLimit to:submitInfoFile
outputFilenameIndex = 0
-- If an output filename is specified, include it in the submit info file
if rendSaveFile and rendOutputFilename != "" then
(
format "OutputDirectory0=%\n" (getFilenamePath rendOutputFilename) to:submitInfoFile
format "OutputFilename0=%\n" ((getFilenameFile rendOutputFilename) + "####" + (getFilenameType rendOutputFilename)) to:submitInfoFile
outputFilenameIndex = outputFilenameIndex + 1
)
-- Include render elements
reManager = maxOps.GetCurRenderElementMgr()
if reManager.getElementsActive() then
(
reCount = reManager.NumRenderElements()
for i = 0 to reCount - 1 do
(
if classof (reManager.GetRenderElement i) != Missing_Render_Element_Plug_in do --ignore RE's that return as missing in the scene
(
reFilename = reManager.GetRenderElementFilename i
if reFilename != undefined and reFilename != "" do --skip RE's if output file path is undefined or empty
(
format "OutputDirectory%=%\n" outputFilenameIndex (getFilenamePath reFilename) to:submitInfoFile
format "OutputFilename%=%\n" outputFilenameIndex ((getFilenameFile reFilename) + "####" + (getFilenameType reFilename)) to:submitInfoFile
outputFilenameIndex = outputFilenameIndex + 1
)
)
)
)
close submitInfoFile
)
--PluginFile
JobInfoFile = CreateFile sPluginFile
if (JobInfoFile != undefined) then
(
version = ((maxVersion())[1] / 1000)
if maxOps.productAppID == #viz then
(
format "Application=VIZ\n" to:JobInfoFile
version = 2001 + version
)
else
(
format "Application=Max\n" to:JobInfoFile
if version > 9 then
version = 1998 + version
)
format "Version=%\n" version to:JobInfoFile
try
(
VersionInfo = dotnetclass "System.Diagnostics.FileVersionInfo"
MyMax = VersionInfo.GetVersionInfo (pathConfig.appendPath (pathConfig.GetDir #maxroot) "3dsmax.exe")
format "SubmittedFromVersion=%\n" MyMax.FileVersion to:JobInfoFile
)catch()
format "Build=%\n" "64bit" to:JobInfoFile
format "Camera=\n" to:JobInfoFile
format "Camera0=\n" to:JobInfoFile
format "PixelAspect=%\n" renderPixelAspect to:JobInfoFile
format "ImageWidth=%\n" renderWidth to:JobInfoFile
format "ImageHeight=%\n" renderHeight to:JobInfoFile
format "ShowVFB=true\n" to:JobInfoFile
format "ContinueOnError=true\n" to:JobInfoFile
format "GammaCorrection=true\n" to:JobInfoFile
format "GammaInput=%\n" fileingamma to:JobInfoFile
format "GammaOutput=%\n" fileoutgamma to:JobInfoFile
if rendSaveFile and rendOutputFilename != "" then
(
format "OutputFilename=%\n" rendOutputFilename to:JobInfoFile
)
format "SkipRenderedFrames=true\n" to:JobInfoFile
local reMgr = maxOps.GetCurRenderElementMgr()
if reMgr != undefined then
(
if reMgr.GetElementsActive() then
(
format "RenderElements=true\n" to:JobInfoFile
)
else
(
format "RenderElements=false\n" to:JobInfoFile
)
)
if bDBR then
(
format "VRayDBRJob=true\n" to:JobInfoFile
dbrFrame = (currenttime.frame as integer) as string
format "DBRJobFrame=%\n" dbrFrame to:JobInfoFile
format "LocalRendering=false\n" to:JobInfoFile
)
Close JobInfoFile
)
--Append the job to the queue
oJob = DeadlineJob()
oJob.sJobFile = sJobFile
oJob.sPluginFile = sPluginFile
oJob.sMaxfile = maxfilepath + maxfilename
oJob.bDependsOnPrevious = bDependsOnPrevious
append aDeadlineQueue oJob
if bLimitBatchSize then
(
if aDeadlineQueue.count >= iMaxBatchSize then
(
FlushDeadlineQueue()
)
)
)
)
global SubmitToDeadlineQueue
fn SubmitToDeadlineQueue iPriority:50 sJobName:unsupplied sComment:unsupplied sDepartment:“AMS” iFPC:1 iMachineLimit:0 bDeleteOnComplete:false bSuspended:false bDependsOnPrevious:false bLimitBatchSize:false iMaxBatchSize:20 bDBR:false bTileRender:false iDBRServers:20 =
(
if sDeadlineQueuePath == undefined or SMTDFunctions == undefined then
(
messagebox “Init the queue first!”
)
else
(
--Create the job and plugin files
iCounter = (getfiles (sDeadlineQueuePath + "*.job")).count
sJobFile = (sDeadlineQueuePath + "Job" + FormatNumber 4 (iCounter+1) + ".job")
sPluginFile = (sDeadlineQueuePath + "Plugin" + FormatNumber 4 (iCounter+1) + ".job")
if sJobName == unsupplied then
(
if maxfilename == "" then
(
messagebox "Please save your file first!" title:"Davy warns"
return false
)
else
(
sJobName = getfilenamefile maxfilename
)
)
bNameAvailable = false
iCounter = 0
while not bNameAvailable do
(
HiddenDOSCommand ("deadlinecommand -getjobIdsfilter jobname=\"" + sJobName + "\" > c:\\DeadlineJobs.txt") startpath:"C:\\Program Files\\Thinkbox\\Deadline7\\bin\\"
oTemp = openfile "c:\\DeadlineJobs.txt"
sLine = ""
try
(
sLine = readline oTemp
)catch()
try(close oTemp)catch()
if sLine == "" then
(
bNameAvailable = true
)
else
(
if matchpattern sJobName pattern:("*_" + FormatNumber 3 iCounter) then
(
iCounter += 1
sJobName = (substring sJobName 1 (sJobName.count - 3)) + FormatNumber 3 iCounter
)
else
(
iCounter += 1
sJobName = sJobName + "_" + FormatNumber 3 iCounter
)
)
)
savemaxfile (maxfilepath + sJobName + ".max") quiet:true
SMTDFunctions.loadSettings()
SMTDSettings.JobName = sJobName
if sComment != unsupplied then
(
SMTDSettings.Comment = sComment
)
SMTDSettings.Priority = iPriority
SMTDSettings.ChunkSize = iFPC
if iMachineLimit > 0 then
(
SMTDSettings.LimitEnabled = true
SMTDSettings.MachineLimit = iMachineLimit
)
SMTDSettings.SubmitAsSuspended = bSuspended
SMTDSettings.Department = sDepartment
if bDeleteOnComplete then
(
SMTDSettings.OnComplete = "Delete"
)
else
(
SMTDSettings.OnComplete = "Nothing"
)
if bDBR then
(
SMTDSettings.DBR = true
SMTDSettings.DBRServers = iDBRServers
)
else
(
SMTDSettings.DBR = false
SMTDSettings.DBRServers = 1
)
if bTileRender then
(
SMTDSettings.RegionRenderingMode = #singleFrameTiles
SMTDSettings.SingleTileJobDraft = true
SMTDSettings.SingleTileJobCleanup = true
SMTDSettings.SingleTileJobDependent = true
SMTDSettings.TilesInY = iDBRServers
SMTDSettings.TilesInX = iDBRServers
)
else
(
SMTDSettings.RegionRenderingMode = #none
SMTDSettings.SingleTileJobDraft = false
SMTDSettings.SingleTileJobCleanup = false
SMTDSettings.SingleTileJobDependent = false
SMTDSettings.TilesInY = 1
SMTDSettings.TilesInX = 1
)
if bDependsOnPrevious then
(
SMTDSettings.SubmitAsDependent = true
)
else
(
SMTDSettings.SubmitAsDependent = false
)
SMTDFunctions.CreateSubmitInfoFile sJobFile
SMTDFunctions.CreateJobInfoFile sPluginFile
if bDBR then
(
oTempPluginFile = openfile sPluginFile mode:"a"
format "VRayDBRJob=true\nDBRJobFrame=0\n" to:oTempPluginFile
close oTempPluginFile
)
--Append the job to the queue
oJob = DeadlineJob()
oJob.sJobFile = sJobFile
oJob.sPluginFile = sPluginFile
oJob.sMaxfile = maxfilepath + maxfilename
oJob.bDependsOnPrevious = bDependsOnPrevious
append aDeadlineQueue oJob
if bLimitBatchSize then
(
if aDeadlineQueue.count >= iMaxBatchSize then
(
FlushDeadlineQueue()
)
)
)
)[/code]