netrender

Downloading results for jobs from blender now uses the current output settings, it doesn't just download the multilayer exr as it used to.

Render output panel now visible under the jobs panel in client mode.
This commit is contained in:
2011-01-08 19:42:26 +00:00
parent 17e733a4fc
commit c0bae16dad
5 changed files with 126 additions and 27 deletions

View File

@@ -83,8 +83,6 @@ class MRenderJob(netrender.model.RenderJob):
self.save_path = ""
self.files = [MRenderFile(rfile.filepath, rfile.index, rfile.start, rfile.end, rfile.signature) for rfile in job_info.files]
self.resolution = None
def initInfo(self):
if not self.resolution:
self.resolution = tuple(getFileInfo(self.files[0].filepath, ["bpy.context.scene.render.resolution_x", "bpy.context.scene.render.resolution_y", "bpy.context.scene.render.resolution_percentage"]))

View File

@@ -199,6 +199,8 @@ class RenderJob:
self.blacklist = []
self.version_info = None
self.resolution = None
self.usage = 0.0
self.last_dispatched = 0.0
@@ -293,7 +295,8 @@ class RenderJob:
"usage": self.usage,
"blacklist": self.blacklist,
"last_dispatched": self.last_dispatched,
"version_info": self.version_info.serialize() if self.version_info else None
"version_info": self.version_info.serialize() if self.version_info else None,
"resolution": self.resolution
}
@staticmethod
@@ -314,6 +317,7 @@ class RenderJob:
job.usage = data["usage"]
job.blacklist = data["blacklist"]
job.last_dispatched = data["last_dispatched"]
job.resolution = data["resolution"]
version_info = data.get("version_info", None)
if version_info:

View File

@@ -410,26 +410,71 @@ class netclientdownload(bpy.types.Operator):
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
if conn:
job = netrender.jobs[netsettings.active_job_index]
job_id = netrender.jobs[netsettings.active_job_index].id
conn.request("GET", "/status", headers={"job-id":job_id})
response = conn.getresponse()
if response.status != http.client.OK:
self.report('ERROR', "Job ID %i not defined on master" % job_id)
return {'ERROR'}
content = response.read()
job = netrender.model.RenderJob.materialize(json.loads(str(content, encoding='utf8')))
conn.close()
finished_frames = []
nb_error = 0
nb_missing = 0
for frame in job.frames:
client.requestResult(conn, job.id, frame.number)
response = conn.getresponse()
buf = response.read()
if response.status != http.client.OK:
print("missing", frame.number)
continue
print("got back", frame.number)
f = open(os.path.join(bpy.path.abspath(netsettings.path), "%06d.exr" % frame.number), "wb")
f.write(buf)
f.close()
conn.close()
if frame.status == DONE:
finished_frames.append(frame.number)
elif frame.status == ERROR:
nb_error += 1
else:
nb_missing += 1
if not finished_frames:
return
frame_ranges = []
first = None
last = None
for i in range(len(finished_frames)):
current = finished_frames[i]
if not first:
first = current
last = current
elif last + 1 == current:
last = current
if last + 1 < current or i + 1 == len(finished_frames):
if first < last:
frame_ranges.append((first, last))
else:
frame_ranges.append((first,))
first = current
last = current
getResults(netsettings.server_address, netsettings.server_port, job_id, job.resolution[0], job.resolution[1], job.resolution[2], frame_ranges)
if nb_error and nb_missing:
self.report('ERROR', "Results downloaded but skipped %i frames with errors and %i unfinished frames" % (nb_error, nb_missing))
elif nb_error:
self.report('ERROR', "Results downloaded but skipped %i frames with errors" % nb_error)
elif nb_missing:
self.report('WARNING', "Results downloaded but skipped %i unfinished frames" % nb_missing)
else:
self.report('INFO', "All results downloaded")
return {'FINISHED'}

View File

@@ -351,6 +351,18 @@ class RENDER_PT_network_jobs(NeedValidAddress, NetRenderButtonsPanel, bpy.types.
layout.label(text="Done: %04i" % job.results[DONE])
layout.label(text="Error: %04i" % job.results[ERROR])
import properties_render
class RENDER_PT_network_output(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel):
bl_label = "Output"
COMPAT_ENGINES = {'NET_RENDER'}
@classmethod
def poll(cls, context):
netsettings = context.scene.network_render
return super().poll(context) and netsettings.mode == "RENDER_CLIENT"
draw = properties_render.RENDER_PT_output.draw
class NetRenderSettings(bpy.types.IDPropertyGroup):
pass

View File

@@ -28,7 +28,7 @@ try:
except:
bpy = None
VERSION = bytes("1.0", encoding='utf8')
VERSION = bytes("1.2", encoding='utf8')
# Jobs status
JOB_WAITING = 0 # before all data has been entered
@@ -223,8 +223,43 @@ def prefixPath(prefix_directory, file_path, prefix_path, force = False):
return full_path
def getResults(server_address, server_port, job_id, resolution_x, resolution_y, resolution_percentage, frame_ranges):
frame_arguments = []
for r in frame_ranges:
if len(r) == 2:
frame_arguments.extend(["-s", str(r[0]), "-e", str(r[1]), "-a"])
else:
frame_arguments.extend(["-f", str(r[0])])
filepath = os.path.join(bpy.app.tempdir, "netrender_temp.blend")
bpy.ops.wm.save_as_mainfile(filepath=filepath, copy=True, check_existing=False)
process = subprocess.Popen([sys.argv[0], "-b", "-noaudio", filepath, "-P", __file__] + frame_arguments + ["--", "GetResults", server_address, str(server_port), job_id, str(resolution_x), str(resolution_y), str(resolution_percentage)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while process.poll() is None:
process.stdout.read(1024) # empty buffer to be sure
process.stdout.read()
os.remove(filepath)
return
def _getResults(server_address, server_port, job_id, resolution_x, resolution_y, resolution_percentage):
render = bpy.context.scene.render
netsettings = bpy.context.scene.network_render
netsettings.server_address = server_address
netsettings.server_port = int(server_port)
netsettings.job_id = job_id
render.engine = 'NET_RENDER'
render.resolution_x = int(resolution_x)
render.resolution_y = int(resolution_y)
render.resolution_percentage = int(resolution_percentage)
def getFileInfo(filepath, infos):
process = subprocess.Popen([sys.argv[0], "-b", "-noaudio", filepath, "-P", __file__, "--"] + infos, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
process = subprocess.Popen([sys.argv[0], "-b", "-noaudio", filepath, "-P", __file__, "--", "FileInfo"] + infos, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = bytes()
while process.poll() is None:
stdout += process.stdout.read(1024)
@@ -237,12 +272,17 @@ def getFileInfo(filepath, infos):
values = [eval(v[1:].strip()) for v in stdout.split("\n") if v.startswith("$")]
return values
if __name__ == "__main__":
import bpy
try:
start = sys.argv.index("--") + 1
except ValueError:
start = 0
for info in sys.argv[start:]:
print("$", eval(info))
action, *args = sys.argv[start:]
if action == "FileInfo":
for info in args:
print("$", eval(info))
elif action == "GetResults":
_getResults(args[0], args[1], args[2], args[3], args[4], args[5])