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:
@@ -83,8 +83,6 @@ class MRenderJob(netrender.model.RenderJob):
|
|||||||
self.save_path = ""
|
self.save_path = ""
|
||||||
self.files = [MRenderFile(rfile.filepath, rfile.index, rfile.start, rfile.end, rfile.signature) for rfile in job_info.files]
|
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):
|
def initInfo(self):
|
||||||
if not self.resolution:
|
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"]))
|
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"]))
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ class RenderJob:
|
|||||||
self.blacklist = []
|
self.blacklist = []
|
||||||
|
|
||||||
self.version_info = None
|
self.version_info = None
|
||||||
|
|
||||||
|
self.resolution = None
|
||||||
|
|
||||||
self.usage = 0.0
|
self.usage = 0.0
|
||||||
self.last_dispatched = 0.0
|
self.last_dispatched = 0.0
|
||||||
@@ -293,7 +295,8 @@ class RenderJob:
|
|||||||
"usage": self.usage,
|
"usage": self.usage,
|
||||||
"blacklist": self.blacklist,
|
"blacklist": self.blacklist,
|
||||||
"last_dispatched": self.last_dispatched,
|
"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
|
@staticmethod
|
||||||
@@ -314,6 +317,7 @@ class RenderJob:
|
|||||||
job.usage = data["usage"]
|
job.usage = data["usage"]
|
||||||
job.blacklist = data["blacklist"]
|
job.blacklist = data["blacklist"]
|
||||||
job.last_dispatched = data["last_dispatched"]
|
job.last_dispatched = data["last_dispatched"]
|
||||||
|
job.resolution = data["resolution"]
|
||||||
|
|
||||||
version_info = data.get("version_info", None)
|
version_info = data.get("version_info", None)
|
||||||
if version_info:
|
if version_info:
|
||||||
|
|||||||
@@ -410,26 +410,71 @@ class netclientdownload(bpy.types.Operator):
|
|||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
if conn:
|
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:
|
for frame in job.frames:
|
||||||
client.requestResult(conn, job.id, frame.number)
|
if frame.status == DONE:
|
||||||
response = conn.getresponse()
|
finished_frames.append(frame.number)
|
||||||
buf = response.read()
|
elif frame.status == ERROR:
|
||||||
|
nb_error += 1
|
||||||
if response.status != http.client.OK:
|
else:
|
||||||
print("missing", frame.number)
|
nb_missing += 1
|
||||||
continue
|
|
||||||
|
if not finished_frames:
|
||||||
print("got back", frame.number)
|
return
|
||||||
|
|
||||||
f = open(os.path.join(bpy.path.abspath(netsettings.path), "%06d.exr" % frame.number), "wb")
|
frame_ranges = []
|
||||||
|
|
||||||
f.write(buf)
|
first = None
|
||||||
|
last = None
|
||||||
f.close()
|
|
||||||
|
for i in range(len(finished_frames)):
|
||||||
conn.close()
|
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'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|||||||
@@ -351,6 +351,18 @@ class RENDER_PT_network_jobs(NeedValidAddress, NetRenderButtonsPanel, bpy.types.
|
|||||||
layout.label(text="Done: %04i" % job.results[DONE])
|
layout.label(text="Done: %04i" % job.results[DONE])
|
||||||
layout.label(text="Error: %04i" % job.results[ERROR])
|
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):
|
class NetRenderSettings(bpy.types.IDPropertyGroup):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ try:
|
|||||||
except:
|
except:
|
||||||
bpy = None
|
bpy = None
|
||||||
|
|
||||||
VERSION = bytes("1.0", encoding='utf8')
|
VERSION = bytes("1.2", encoding='utf8')
|
||||||
|
|
||||||
# Jobs status
|
# Jobs status
|
||||||
JOB_WAITING = 0 # before all data has been entered
|
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
|
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):
|
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()
|
stdout = bytes()
|
||||||
while process.poll() is None:
|
while process.poll() is None:
|
||||||
stdout += process.stdout.read(1024)
|
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("$")]
|
values = [eval(v[1:].strip()) for v in stdout.split("\n") if v.startswith("$")]
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import bpy
|
|
||||||
try:
|
try:
|
||||||
start = sys.argv.index("--") + 1
|
start = sys.argv.index("--") + 1
|
||||||
except ValueError:
|
except ValueError:
|
||||||
start = 0
|
start = 0
|
||||||
for info in sys.argv[start:]:
|
action, *args = sys.argv[start:]
|
||||||
print("$", eval(info))
|
|
||||||
|
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])
|
||||||
|
|||||||
Reference in New Issue
Block a user