A script to send your render as a render job to Autodesk Backburner on windows.
I’ve had some problems with the blender netrender, and flamenco is near impossible to install on windows, so i found an old script by Matt Ebb and made it work with blender 2.76.
I havent had time to test it very much, but in all cases i’ve tried it works great.
Credit goes to Matt Ebb who did most of the work in his old Blender 2.5 script
It should work fine with the free Autodesk backburner:
https://knowledge.autodesk.com/support/3ds-max/downloads/caas/downloads/content/backburner-2015-windows-version-for-3ds-max3ds-max-design-2015.html
Please let me know your results, and if you have any thoughts on improving it ( although i suck and scripting )
bl_info = {
"name": "Backburner",
"author": "Matt Ebb + Blaize",
"version": (1, 0),
"blender": (2, 72, 1),
"location": "Properties > Render",
"description": "Network and Queue with Autodesk Backburner",
"warning": "",
"wiki_url": "",
"category": "Render"}
import bpy, os, subprocess
from subprocess import Popen, PIPE
from bpy.props import PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty, CollectionProperty
default_backburner_path = 'C:\\Program Files (x86)\\Autodesk\\Backburner\\cmdjob.exe'
default_blender_path = 'C:\\Program Files\\Blender Foundation\\Blender\\blender.exe'
#def rnaType(rna_type):
# if bpy: bpy.types.register(rna_type)
# return rna_type
#@rnaType
class BackburnerSettings(bpy.types.PropertyGroup):
pass
bpy.utils.register_class(BackburnerSettings)
# entry point for settings collection
bpy.types.Scene.backburner = PointerProperty(
type=BackburnerSettings, name='Backburner Submission', description='Backburner Submission Settings')
# fill the new struct
BackburnerSettings.job_name = StringProperty(
name='Job Name', description='Name of the job to be shown in Backburner', maxlen=256, default='')
BackburnerSettings.frames_per_task = IntProperty(
name='Frames per Task', description='Number of frames to give each render node', min=1, max=1000, soft_min=1, soft_max=64, default=1)
BackburnerSettings.timeout = IntProperty(
name='Timeout', description='Timeout per task', min=1, max=1000, soft_min=1, soft_max=64, default=120)
BackburnerSettings.priority = IntProperty(name='Priority', description='Priority of this job', min=1, max=1000, soft_min=1, soft_max=64, default=50)
BackburnerSettings.override_frame_range = BoolProperty(
name='Override Frame Range', description='Override scene start and end frames', default=False)
BackburnerSettings.frame_start = IntProperty(
name='Start Frame', description='Start frame of animation sequence to render', min=1, max=1000, soft_min=1, soft_max=64, default=1)
BackburnerSettings.frame_end = IntProperty(
name='End Frame', description='End frame of animation sequence to render', min=1, max=1000, soft_min=1, soft_max=64, default=250)
#BackburnerSettings.group = StringProperty(
#name='Group', description='Render this job only with the servers in this group', maxlen=400, default='Localhost')
BackburnerSettings.servers = StringProperty(
name='Servers', description='Render this job only with the servers specified (semi-colon separated list - ignored if group is used)', maxlen=400, default='')
BackburnerSettings.path_backburner = StringProperty(
name='Backburner Path', description='Path to Backburner cmdjob.exe', maxlen=400, default=default_backburner_path, subtype='FILE_PATH')
BackburnerSettings.path_blender = StringProperty(
name='Blender Path', description='Path to blender.exe', maxlen=400, default=default_blender_path, subtype='FILE_PATH')
class RENDER_PT_Backburner(bpy.types.Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
bl_label = 'Backburner'
bl_default_closed = True
def draw(self, context):
layout = self.layout
scene = context.scene
bb = scene.backburner
layout.operator('render.submit_to_backburner', icon='RENDER_ANIMATION')
layout.separator()
layout.prop(bb, 'job_name')
layout.prop(bb, 'frames_per_task')
row = layout.row()
row.prop(bb, 'timeout')
row.prop(bb, 'priority')
layout.separator()
#layout.prop(bb, 'override_frame_range')
row = layout.row()
row.enabled = bb.override_frame_range
#row.prop(bb, 'frame_start')
#row.prop(bb, 'frame_end')
layout.prop(bb, 'group')
layout.prop(bb, 'servers')
layout.prop(bb, 'path_backburner')
layout.prop(bb, 'path_blender')
def write_tasklist(step, sframe, eframe, filename):
dir = os.path.dirname(filename)
# if we need a unique ID?
# id = str(time.time())[:-3]
# tasklist_path = dir + '\\submit_temp_' + id + '.txt'
tasklist_path = dir + '\\submit_temp.txt'
try:
file = open(tasklist_path, 'w')
except:
print("couldn't open " + tasklist_path + " for writing")
curframe = sframe
while(curframe <= eframe):
seq_sta = curframe
seq_end = curframe + (step-1)
if seq_end > eframe: seq_end = eframe
curframe = seq_end + 1
task = 'Frame ' + str(seq_sta)
if seq_sta != seq_end:
task += ' - ' + str(seq_end)
task += ' '
task += str(seq_sta) + ' ' + str(seq_end) + '
'
file.write(task)
file.close()
return tasklist_path
def submit(scene):
bb = scene.backburner
filename = bpy.data.filepath
blenderdir = os.path.dirname(bb.path_blender)
print('--- Submitting: ')
manager = 'localhost'
description = 'Rendering_to_' + scene.render.filepath
tasklist_path = write_tasklist(bb.frames_per_task, bb.frame_start, bb.frame_end, filename)
cmd = '"' + bb.path_backburner + '"'
cmd += ' -jobName:' + bb.job_name
cmd += ' -description:' + description
cmd += ' -manager:' + manager
cmd += ' -priority:' + str(bb.priority)
cmd += ' -timeout:' + str(bb.timeout)
#cmd += ' -manager:' + bb.group
if bb.servers != '':
cmd += ' -servers:' + bb.servers
cmd += ' -workPath:' + blenderdir
cmd += ' -taskList:' + tasklist_path
cmd += ' -taskName: 1'
cmd += ' "' + bb.path_blender + '" --background '
cmd += filename
cmd += ' --frame-start %tp2 --frame-end %tp3 --render-anim'
print(cmd)
result = subprocess.call(cmd)
if result != 0:
print('Submit Failed for: ' + filename)
submit_status = "FAILED"
else:
print('Submit Suceeded for: ' + filename)
submit_status = "OK"
os.remove(tasklist_path)
return {'FINISHED'}
class SubmitToBackburner(bpy.types.Operator):
''''''
bl_idname = "render.submit_to_backburner"
bl_label = "Submit to Backburner"
@classmethod
def poll(cls, context):
return context.scene != None
def invoke(self, context, event):
bb = context.scene.backburner
if bb.path_blender == '':
self.report({'ERROR'}, "Network path to Blender hasn't been set")
return {'CANCELLED'}
if bb.path_backburner == '':
self.report({'ERROR'}, "Path to Backburner cmdjob.exe hasn't been set")
return {'CANCELLED'}
submit(context.scene)
return {'FINISHED'}
def execute(self, context):
submit(context.scene)
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()