diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py index 2fc9e78c097..6c4ed4119fc 100644 --- a/release/scripts/io/netrender/__init__.py +++ b/release/scripts/io/netrender/__init__.py @@ -56,6 +56,12 @@ init_data = True def register(): ui.addProperties() + + import bpy + scene = bpy.context.scene + if scene: + netsettings = scene.network_render + ui.init_data(netsettings) def unregister(): diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py index 95f345249f2..dde3ad53084 100644 --- a/release/scripts/io/netrender/balancing.py +++ b/release/scripts/io/netrender/balancing.py @@ -25,6 +25,9 @@ class RatingRule: def __init__(self): self.enabled = True + def id(self): + return str(id(self)) + def rate(self, job): return 0 @@ -32,6 +35,9 @@ class ExclusionRule: def __init__(self): self.enabled = True + def id(self): + return str(id(self)) + def test(self, job): return False @@ -39,6 +45,9 @@ class PriorityRule: def __init__(self): self.enabled = True + def id(self): + return str(id(self)) + def test(self, job): return False @@ -50,13 +59,13 @@ class Balancer: def ruleByID(self, rule_id): for rule in self.rules: - if id(rule) == rule_id: + if rule.id() == rule_id: return rule for rule in self.priorities: - if id(rule) == rule_id: + if rule.id() == rule_id: return rule for rule in self.exceptions: - if id(rule) == rule_id: + if rule.id() == rule_id: return rule return None diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py index 93f2baf4a36..1d4ab3699ae 100644 --- a/release/scripts/io/netrender/master.py +++ b/release/scripts/io/netrender/master.py @@ -27,6 +27,7 @@ from netrender.utils import * import netrender.model import netrender.balancing import netrender.master_html +import netrender.thumbnail as thumbnail class MRenderFile(netrender.model.RenderFile): def __init__(self, filepath, index, start, end, signature): @@ -203,6 +204,15 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # is extremely slow due to some timeout.. sys.stderr.write("[%s] %s\n" % (self.log_date_time_string(), format%args)) + def getInfoMap(self): + length = int(self.headers['content-length']) + + if length > 0: + msg = str(self.rfile.read(length), encoding='utf8') + return json.loads(msg) + else: + return {} + def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): self.send_response(code) self.send_header("Content-type", content) @@ -299,7 +309,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): elif frame.status == DONE: filename = os.path.join(job.save_path, "%06d.exr" % frame_number) - thumbname = thumbnail(filename) + thumbname = thumbnail.generate(filename) if thumbname: f = open(thumbname, 'rb') @@ -518,8 +528,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job = self.server.getJobID(job_id) if job: - length = int(self.headers['content-length']) - info_map = eval(str(self.rfile.read(length), encoding='utf8')) + info_map = self.getInfoMap() job.edit(info_map) self.send_head() @@ -531,8 +540,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/balance_limit": - length = int(self.headers['content-length']) - info_map = eval(str(self.rfile.read(length), encoding='utf8')) + info_map = self.getInfoMap() for rule_id, limit in info_map.items(): try: rule = self.server.balancer.ruleByID(rule_id) @@ -544,8 +552,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head() # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/balance_enable": - length = int(self.headers['content-length']) - info_map = eval(str(self.rfile.read(length), encoding='utf8')) + info_map = self.getInfoMap() for rule_id, enabled in info_map.items(): rule = self.server.balancer.ruleByID(rule_id) if rule: @@ -557,13 +564,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): match = cancel_pattern.match(self.path) if match: - length = int(self.headers['content-length']) - - if length > 0: - info_map = eval(str(self.rfile.read(length), encoding='utf8')) - clear = info_map.get("clear", False) - else: - clear = False + info_map = self.getInfoMap() + clear = info_map.get("clear", False) job_id = match.groups()[0] @@ -584,13 +586,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): match = pause_pattern.match(self.path) if match: - length = int(self.headers['content-length']) - - if length > 0: - info_map = eval(str(self.rfile.read(length), encoding='utf8')) - status = info_map.get("status", None) - else: - status = None + info_map = self.getInfoMap() + status = info_map.get("status", None) job_id = match.groups()[0] @@ -609,13 +606,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/clear": # cancel all jobs - length = int(self.headers['content-length']) - - if length > 0: - info_map = eval(str(self.rfile.read(length), encoding='utf8')) - clear = info_map.get("clear", False) - else: - clear = False + info_map = self.getInfoMap() + clear = info_map.get("clear", False) self.server.stats("", "Clearing jobs") self.server.clear(clear) diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py index 0e14905a86b..877273207a8 100644 --- a/release/scripts/io/netrender/master_html.py +++ b/release/scripts/io/netrender/master_html.py @@ -183,28 +183,28 @@ def get(handler): for rule in handler.server.balancer.rules: rowTable( "rating", - checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + checkbox("", rule.enabled, "balance_enable('%s', '%s')" % (rule.id(), str(not rule.enabled).lower())), rule, rule.str_limit() + - """""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + """""" % (rule.id(), str(rule.limit)) if hasattr(rule, "limit") else " " ) for rule in handler.server.balancer.priorities: rowTable( "priority", - checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + checkbox("", rule.enabled, "balance_enable('%s', '%s')" % (rule.id(), str(not rule.enabled).lower())), rule, rule.str_limit() + - """""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + """""" % (rule.id(), str(rule.limit)) if hasattr(rule, "limit") else " " ) for rule in handler.server.balancer.exceptions: rowTable( "exception", - checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + checkbox("", rule.enabled, "balance_enable('%s', '%s')" % (rule.id(), str(not rule.enabled).lower())), rule, rule.str_limit() + - """""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + """""" % (rule.id(), str(rule.limit)) if hasattr(rule, "limit") else " " ) endTable() diff --git a/release/scripts/io/netrender/netrender.js b/release/scripts/io/netrender/netrender.js index 041a39a3ebc..1024a169571 100644 --- a/release/scripts/io/netrender/netrender.js +++ b/release/scripts/io/netrender/netrender.js @@ -20,9 +20,9 @@ function clear_jobs() var r=confirm("Also delete files on master?"); if (r==true) { - request('/clear', "{'clear':True}"); + request('/clear', '{"clear":true}'); } else { - request('/clear', "{'clear':False}"); + request('/clear', '{"clear":false}'); } } @@ -31,9 +31,9 @@ function cancel_job(id) var r=confirm("Also delete files on master?"); if (r==true) { - request('/cancel_' + id, "{'clear':True}"); + request('/cancel_' + id, '{"clear":true}'); } else { - request('/cancel_' + id, "{'clear':False}"); + request('/cancel_' + id, '{"clear":false}'); } } @@ -41,13 +41,13 @@ function balance_edit(id, old_value) { var new_value = prompt("New limit", old_value); if (new_value != null && new_value != "") { - request("/balance_limit", "{" + id + ":'" + new_value + "'}"); + request("/balance_limit", '{"' + id + '":"' + new_value + '"}'); } } function balance_enable(id, value) { - request("/balance_enable", "{" + id + ":" + value + "}"); + request("/balance_enable", '{"' + id + '":' + value + "}"); } function showThumb(job, frame) diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py index fe82011d706..2bfbc491ac2 100644 --- a/release/scripts/io/netrender/operators.py +++ b/release/scripts/io/netrender/operators.py @@ -62,12 +62,9 @@ class RENDER_OT_netslave_bake(bpy.types.Operator): modifier.point_cache.use_disk_cache = True modifier.point_cache.use_external = False elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN": - modifier.domain_settings.point_cache_low.use_step = 1 - modifier.domain_settings.point_cache_low.use_disk_cache = True - modifier.domain_settings.point_cache_low.use_external = False - modifier.domain_settings.point_cache_high.use_step = 1 - modifier.domain_settings.point_cache_high.use_disk_cache = True - modifier.domain_settings.point_cache_high.use_external = False + modifier.domain_settings.point_cache.use_step = 1 + modifier.domain_settings.point_cache.use_disk_cache = True + modifier.domain_settings.point_cache.use_external = False # particles modifier are stupid and don't contain data # we have to go through the object property @@ -355,7 +352,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): if conn: job = netrender.jobs[netsettings.active_job_index] - conn.request("POST", cancelURL(job.id)) + conn.request("POST", cancelURL(job.id), json.dumps({'clear':False})) response = conn.getresponse() response.read() @@ -382,7 +379,7 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator): conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report) if conn: - conn.request("POST", "/clear") + conn.request("POST", "/clear", json.dumps({'clear':False})) response = conn.getresponse() response.read() diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py index 12f8fdbf986..378871566a8 100644 --- a/release/scripts/io/netrender/slave.py +++ b/release/scripts/io/netrender/slave.py @@ -26,6 +26,7 @@ import bpy from netrender.utils import * import netrender.model import netrender.repath +import netrender.thumbnail as thumbnail BLENDER_PATH = sys.argv[0] @@ -304,7 +305,7 @@ def render_slave(engine, netsettings, threads): # thumbnail first if netsettings.use_slave_thumb: - thumbname = thumbnail(filename) + thumbname = thumbnail.generate(filename) if thumbname: f = open(thumbname, 'rb') diff --git a/release/scripts/io/netrender/thumbnail.py b/release/scripts/io/netrender/thumbnail.py new file mode 100755 index 00000000000..2ead6e82745 --- /dev/null +++ b/release/scripts/io/netrender/thumbnail.py @@ -0,0 +1,81 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +import sys, os +import subprocess + +import bpy + +def generate(filename, external=True): + if external: + process = subprocess.Popen([sys.argv[0], "-b", "-noaudio", "-P", __file__, "--", filename], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + while process.poll() is None: + process.stdout.read(1024) # empty buffer to be sure + process.stdout.read() + + return _thumbname(filename) + else: + return _internal(filename) + +def _thumbname(filename): + root = os.path.splitext(filename)[0] + return root + ".jpg" + +def _internal(filename): + imagename = os.path.split(filename)[1] + thumbname = _thumbname(filename) + + if os.path.exists(thumbname): + return thumbname + + if bpy: + scene = bpy.data.scenes[0] # FIXME, this is dodgy! + scene.render.file_format = "JPEG" + scene.render.file_quality = 90 + + # remove existing image, if there's a leftover (otherwise open changes the name) + if imagename in bpy.data.images: + img = bpy.data.images[imagename] + bpy.data.images.remove(img) + + bpy.ops.image.open(filepath=filename) + img = bpy.data.images[imagename] + + img.save_render(thumbname, scene=scene) + + img.user_clear() + bpy.data.images.remove(img) + + try: + process = subprocess.Popen(["convert", thumbname, "-resize", "300x300", thumbname]) + process.wait() + return thumbname + except Exception as exp: + print("Error while generating thumbnail") + print(exp) + + return None + +if __name__ == "__main__": + import bpy + try: + start = sys.argv.index("--") + 1 + except ValueError: + start = 0 + for filename in sys.argv[start:]: + generate(filename, external=False) diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index 49aba80580e..46da06d9eb9 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -276,8 +276,6 @@ class RENDER_PT_network_slaves(NeedValidAddress, NetRenderButtonsPanel, bpy.type sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="") sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="") - init_data(netsettings) - if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0: layout.separator() @@ -309,8 +307,6 @@ class RENDER_PT_network_slaves_blacklist(NeedValidAddress, NetRenderButtonsPanel sub = row.column(align=True) sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="") - init_data(netsettings) - if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0: layout.separator() @@ -345,8 +341,6 @@ class RENDER_PT_network_jobs(NeedValidAddress, NetRenderButtonsPanel, bpy.types. sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="") sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="") - init_data(netsettings) - if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0: layout.separator() diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py index 6c5c313f4a4..7496675f592 100644 --- a/release/scripts/io/netrender/utils.py +++ b/release/scripts/io/netrender/utils.py @@ -238,43 +238,11 @@ def getFileInfo(filepath, infos): return values -def thumbnail(filename): - root = os.path.splitext(filename)[0] - imagename = os.path.split(filename)[1] - thumbname = root + ".jpg" - - if os.path.exists(thumbname): - return thumbname - - if bpy: - scene = bpy.data.scenes[0] # FIXME, this is dodgy! - scene.render.file_format = "JPEG" - scene.render.file_quality = 90 - - # remove existing image, if there's a leftover (otherwise open changes the name) - if imagename in bpy.data.images: - img = bpy.data.images[imagename] - bpy.data.images.remove(img) - - bpy.ops.image.open(filepath=filename) - img = bpy.data.images[imagename] - - img.save_render(thumbname, scene=scene) - - img.user_clear() - bpy.data.images.remove(img) - - try: - process = subprocess.Popen(["convert", thumbname, "-resize", "300x300", thumbname]) - process.wait() - return thumbname - except Exception as exp: - print("Error while generating thumbnail") - print(exp) - - return None - if __name__ == "__main__": import bpy - for info in sys.argv[7:]: + try: + start = sys.argv.index("--") + 1 + except ValueError: + start = 0 + for info in sys.argv[start:]: print("$", eval(info))