Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'netrender/operators.py')
-rw-r--r--netrender/operators.py570
1 files changed, 570 insertions, 0 deletions
diff --git a/netrender/operators.py b/netrender/operators.py
new file mode 100644
index 00000000..563da1c5
--- /dev/null
+++ b/netrender/operators.py
@@ -0,0 +1,570 @@
+# ##### 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 bpy
+import sys, os
+import http, http.client, http.server, urllib, socket
+import webbrowser
+import json
+
+import netrender
+from netrender.utils import *
+import netrender.client as client
+import netrender.model
+import netrender.versioning as versioning
+
+class RENDER_OT_netslave_bake(bpy.types.Operator):
+ '''NEED DESCRIPTION'''
+ bl_idname = "render.netslavebake"
+ bl_label = "Bake all in file"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+ netsettings = scene.network_render
+
+ filename = bpy.data.filepath
+ path, name = os.path.split(filename)
+ root, ext = os.path.splitext(name)
+ default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
+ relative_path = os.sep + os.sep + "blendcache_" + root + os.sep
+
+ # Force all point cache next to the blend file
+ for object in bpy.data.objects:
+ for modifier in object.modifiers:
+ if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
+ modifier.settings.path = relative_path
+ bpy.ops.fluid.bake({"active_object": object, "scene": scene})
+ elif modifier.type == "CLOTH":
+ modifier.point_cache.frame_step = 1
+ modifier.point_cache.use_disk_cache = True
+ modifier.point_cache.use_external = False
+ elif modifier.type == "SOFT_BODY":
+ modifier.point_cache.frame_step = 1
+ 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.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
+ for psys in object.particle_systems:
+ psys.point_cache.use_step = 1
+ psys.point_cache.use_disk_cache = True
+ psys.point_cache.use_external = False
+ psys.point_cache.filepath = relative_path
+
+ bpy.ops.ptcache.bake_all()
+
+ #bpy.ops.wm.save_mainfile(filepath = path + os.sep + root + "_baked.blend")
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientanim(bpy.types.Operator):
+ '''Start rendering an animation on network'''
+ bl_idname = "render.netclientanim"
+ bl_label = "Animation on network"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+ netsettings = scene.network_render
+
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ # Sending file
+ scene.network_render.job_id = client.clientSendJob(conn, scene, True)
+ conn.close()
+
+ bpy.ops.render.render('INVOKE_AREA', animation=True)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientrun(bpy.types.Operator):
+ '''Start network rendering service'''
+ bl_idname = "render.netclientstart"
+ bl_label = "Start Service"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ bpy.ops.render.render('INVOKE_AREA', animation=True)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientsend(bpy.types.Operator):
+ '''Send Render Job to the Network'''
+ bl_idname = "render.netclientsend"
+ bl_label = "Send job"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+ netsettings = scene.network_render
+
+ try:
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ # Sending file
+ scene.network_render.job_id = client.clientSendJob(conn, scene, True)
+ conn.close()
+ self.report('INFO', "Job sent to master")
+ except Exception as err:
+ self.report('ERROR', str(err))
+
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientsendframe(bpy.types.Operator):
+ '''Send Render Job with current frame to the Network'''
+ bl_idname = "render.netclientsendframe"
+ bl_label = "Send current frame job"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ scene = context.scene
+ netsettings = scene.network_render
+
+ try:
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ # Sending file
+ scene.network_render.job_id = client.clientSendJob(conn, scene, False)
+ conn.close()
+ self.report('INFO', "Job sent to master")
+ except Exception as err:
+ self.report('ERROR', str(err))
+
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientstatus(bpy.types.Operator):
+ '''Refresh the status of the current jobs'''
+ bl_idname = "render.netclientstatus"
+ bl_label = "Client Status"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ conn.request("GET", "/status")
+
+ response = conn.getresponse()
+ content = response.read()
+ print( response.status, response.reason )
+
+ jobs = (netrender.model.RenderJob.materialize(j) for j in json.loads(str(content, encoding='utf8')))
+
+ while(len(netsettings.jobs) > 0):
+ netsettings.jobs.remove(0)
+
+ netrender.jobs = []
+
+ for j in jobs:
+ netrender.jobs.append(j)
+ netsettings.jobs.add()
+ job = netsettings.jobs[-1]
+
+ j.results = j.framesStatus() # cache frame status
+
+ job.name = j.name
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ bl_idname = "render.netclientblacklistslave"
+ bl_label = "Client Blacklist Slave"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+ if netsettings.active_slave_index >= 0:
+
+ # deal with data
+ slave = netrender.slaves.pop(netsettings.active_slave_index)
+ netrender.blacklist.append(slave)
+
+ # deal with rna
+ netsettings.slaves_blacklist.add()
+ netsettings.slaves_blacklist[-1].name = slave.name
+
+ netsettings.slaves.remove(netsettings.active_slave_index)
+ netsettings.active_slave_index = -1
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ bl_idname = "render.netclientwhitelistslave"
+ bl_label = "Client Whitelist Slave"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+ if netsettings.active_blacklisted_slave_index >= 0:
+
+ # deal with data
+ slave = netrender.blacklist.pop(netsettings.active_blacklisted_slave_index)
+ netrender.slaves.append(slave)
+
+ # deal with rna
+ netsettings.slaves.add()
+ netsettings.slaves[-1].name = slave.name
+
+ netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index)
+ netsettings.active_blacklisted_slave_index = -1
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+class RENDER_OT_netclientslaves(bpy.types.Operator):
+ '''Refresh status about available Render slaves'''
+ bl_idname = "render.netclientslaves"
+ bl_label = "Client Slaves"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ conn.request("GET", "/slaves")
+
+ response = conn.getresponse()
+ content = response.read()
+ print( response.status, response.reason )
+
+ slaves = (netrender.model.RenderSlave.materialize(s) for s in json.loads(str(content, encoding='utf8')))
+
+ while(len(netsettings.slaves_blacklist) > 0):
+ netsettings.slaves_blacklist.remove(0)
+
+ while(len(netsettings.slaves) > 0):
+ netsettings.slaves.remove(0)
+
+ netrender.slaves = []
+
+ for s in slaves:
+ for i in range(len(netrender.blacklist)):
+ slave = netrender.blacklist[i]
+ if slave.id == s.id:
+ netrender.blacklist[i] = s
+ netsettings.slaves_blacklist.add()
+ slave = netsettings.slaves_blacklist[-1]
+ slave.name = s.name
+ break
+ else:
+ netrender.slaves.append(s)
+
+ netsettings.slaves.add()
+ slave = netsettings.slaves[-1]
+ slave.name = s.name
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientcancel(bpy.types.Operator):
+ '''Cancel the selected network rendering job.'''
+ bl_idname = "render.netclientcancel"
+ bl_label = "Client Cancel"
+
+ @classmethod
+ def poll(cls, context):
+ netsettings = context.scene.network_render
+ return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ job = netrender.jobs[netsettings.active_job_index]
+
+ conn.request("POST", cancelURL(job.id), json.dumps({'clear':False}))
+
+ response = conn.getresponse()
+ response.read()
+ print( response.status, response.reason )
+
+ netsettings.jobs.remove(netsettings.active_job_index)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class RENDER_OT_netclientcancelall(bpy.types.Operator):
+ '''Cancel all running network rendering jobs.'''
+ bl_idname = "render.netclientcancelall"
+ bl_label = "Client Cancel All"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ conn.request("POST", "/clear", json.dumps({'clear':False}))
+
+ response = conn.getresponse()
+ response.read()
+ print( response.status, response.reason )
+
+ while(len(netsettings.jobs) > 0):
+ netsettings.jobs.remove(0)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class netclientdownload(bpy.types.Operator):
+ '''Download render results from the network'''
+ bl_idname = "render.netclientdownload"
+ bl_label = "Client Download"
+
+ @classmethod
+ def poll(cls, context):
+ netsettings = context.scene.network_render
+ return netsettings.active_job_index >= 0 and len(netsettings.jobs) > netsettings.active_job_index
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+ rd = context.scene.render
+
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ 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:
+ 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'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class netclientscan(bpy.types.Operator):
+ '''Listen on network for master server broadcasting its address and port.'''
+ bl_idname = "render.netclientscan"
+ bl_label = "Client Scan"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ address, port = clientScan(self.report)
+
+ if address:
+ scene = context.scene
+ netsettings = scene.network_render
+ netsettings.server_address = address
+ netsettings.server_port = port
+ netrender.valid_address = True
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+class netclientvcsguess(bpy.types.Operator):
+ '''Guess VCS setting for the current file'''
+ bl_idname = "render.netclientvcsguess"
+ bl_label = "VCS Guess"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+ system = versioning.SYSTEMS.get(netsettings.vcs_system, None)
+
+ if system:
+ wpath, name = os.path.split(os.path.abspath(bpy.data.filepath))
+
+ rpath = system.path(wpath)
+ revision = system.revision(wpath)
+
+ netsettings.vcs_wpath = wpath
+ netsettings.vcs_rpath = rpath
+ netsettings.vcs_revision = revision
+
+
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+class netclientweb(bpy.types.Operator):
+ '''Open new window with information about running rendering jobs'''
+ bl_idname = "render.netclientweb"
+ bl_label = "Open Master Monitor"
+
+ @classmethod
+ def poll(cls, context):
+ netsettings = context.scene.network_render
+ return netsettings.server_address != "[default]"
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+
+ # open connection to make sure server exists
+ conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
+
+ if conn:
+ conn.close()
+
+ webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return self.execute(context)