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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/io/netrender')
-rw-r--r--release/io/netrender/__init__.py17
-rw-r--r--release/io/netrender/client.py204
-rw-r--r--release/io/netrender/master.py615
-rw-r--r--release/io/netrender/model.py162
-rw-r--r--release/io/netrender/operators.py236
-rw-r--r--release/io/netrender/slave.py169
-rw-r--r--release/io/netrender/ui.py283
-rw-r--r--release/io/netrender/utils.py61
8 files changed, 0 insertions, 1747 deletions
diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py
deleted file mode 100644
index 1eb91abb938..00000000000
--- a/release/io/netrender/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# This directory is a Python package.
-
-import model
-import operators
-import client
-import slave
-import master
-import utils
-import ui
-
-# store temp data in bpy module
-
-import bpy
-
-bpy.data.netrender_jobs = []
-bpy.data.netrender_slaves = []
-bpy.data.netrender_blacklist = [] \ No newline at end of file
diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py
deleted file mode 100644
index 0c60bd1603c..00000000000
--- a/release/io/netrender/client.py
+++ /dev/null
@@ -1,204 +0,0 @@
-import bpy
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, shutil, time, hashlib
-
-import netrender.slave as slave
-import netrender.master as master
-from netrender.utils import *
-
-
-def clientSendJob(conn, scene, anim = False, chunks = 5):
- netsettings = scene.network_render
- job = netrender.model.RenderJob()
-
- if anim:
- for f in range(scene.start_frame, scene.end_frame + 1):
- job.addFrame(f)
- else:
- job.addFrame(scene.current_frame)
-
- filename = bpy.data.filename
- job.addFile(filename)
-
- job_name = netsettings.job_name
- path, name = os.path.split(filename)
- if job_name == "[default]":
- job_name = name
-
- ###########################
- # LIBRARIES
- ###########################
- for lib in bpy.data.libraries:
- lib_path = lib.filename
-
- if lib_path.startswith("//"):
- lib_path = path + os.sep + lib_path[2:]
-
- job.addFile(lib_path)
-
- ###########################
- # POINT CACHES
- ###########################
-
- root, ext = os.path.splitext(name)
- cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
-
- if os.path.exists(cache_path):
- caches = {}
- pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys")
- for cache_file in sorted(os.listdir(cache_path)):
- match = pattern.match(cache_file)
-
- if match:
- cache_id = match.groups()[0]
- cache_frame = int(match.groups()[1])
-
- cache_files = caches.get(cache_id, [])
- cache_files.append((cache_frame, cache_file))
- caches[cache_id] = cache_files
-
- for cache in caches.values():
- cache.sort()
-
- if len(cache) == 1:
- cache_frame, cache_file = cache[0]
- job.addFile(cache_path + cache_file, cache_frame, cache_frame)
- else:
- for i in range(len(cache)):
- current_item = cache[i]
- next_item = cache[i+1] if i + 1 < len(cache) else None
- previous_item = cache[i - 1] if i > 0 else None
-
- current_frame, current_file = current_item
-
- if not next_item and not previous_item:
- job.addFile(cache_path + current_file, current_frame, current_frame)
- elif next_item and not previous_item:
- next_frame = next_item[0]
- job.addFile(cache_path + current_file, current_frame, next_frame - 1)
- elif not next_item and previous_item:
- previous_frame = previous_item[0]
- job.addFile(cache_path + current_file, previous_frame + 1, current_frame)
- else:
- next_frame = next_item[0]
- previous_frame = previous_item[0]
- job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
-
- ###########################
- # IMAGES
- ###########################
- for image in bpy.data.images:
- if image.source == "FILE" and not image.packed_file:
- job.addFile(image.filename)
-
- # print(job.files)
-
- job.name = job_name
-
- for slave in scene.network_render.slaves_blacklist:
- job.blacklist.append(slave.id)
-
- job.chunks = netsettings.chunks
- job.priority = netsettings.priority
-
- # try to send path first
- conn.request("POST", "job", repr(job.serialize()))
- response = conn.getresponse()
-
- job_id = response.getheader("job-id")
-
- # if not ACCEPTED (but not processed), send files
- if response.status == http.client.ACCEPTED:
- for filepath in job.files:
- f = open(filepath, "rb")
- conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath})
- f.close()
- response = conn.getresponse()
-
- # server will reply with NOT_FOUD until all files are found
-
- return job_id
-
-def clientRequestResult(conn, scene, job_id):
- conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)})
-
-class NetworkRenderEngine(bpy.types.RenderEngine):
- __idname__ = 'NET_RENDER'
- __label__ = "Network Render"
- def render(self, scene):
- if scene.network_render.mode == "RENDER_CLIENT":
- self.render_client(scene)
- elif scene.network_render.mode == "RENDER_SLAVE":
- self.render_slave(scene)
- elif scene.network_render.mode == "RENDER_MASTER":
- self.render_master(scene)
- else:
- print("UNKNOWN OPERATION MODE")
-
- def render_master(self, scene):
- server_address = (scene.network_render.server_address, scene.network_render.server_port)
- httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path)
- httpd.timeout = 1
- httpd.stats = self.update_stats
- while not self.test_break():
- httpd.handle_request()
-
- def render_slave(self, scene):
- slave.render_slave(self, scene)
-
- def render_client(self, scene):
- netsettings = scene.network_render
- self.update_stats("", "Network render client initiation")
-
- conn = clientConnection(scene)
-
- if conn:
- # Sending file
-
- self.update_stats("", "Network render exporting")
-
- job_id = netsettings.job_id
-
- # reading back result
-
- self.update_stats("", "Network render waiting for results")
-
- clientRequestResult(conn, scene, job_id)
- response = conn.getresponse()
-
- if response.status == http.client.NO_CONTENT:
- netsettings.job_id = clientSendJob(conn, scene)
- clientRequestResult(conn, scene, job_id)
-
- while response.status == http.client.ACCEPTED and not self.test_break():
- print("waiting")
- time.sleep(1)
- clientRequestResult(conn, scene, job_id)
- response = conn.getresponse()
-
- if response.status != http.client.OK:
- conn.close()
- return
-
- r = scene.render_data
- x= int(r.resolution_x*r.resolution_percentage*0.01)
- y= int(r.resolution_y*r.resolution_percentage*0.01)
-
- f = open(netsettings.path + "output.exr", "wb")
- buf = response.read(1024)
-
- while buf:
- f.write(buf)
- buf = response.read(1024)
-
- f.close()
-
- result = self.begin_result(0, 0, x, y)
- result.load_from_file(netsettings.path + "output.exr", 0, 0)
- self.end_result(result)
-
- conn.close()
-
-bpy.types.register(NetworkRenderEngine)
-
diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py
deleted file mode 100644
index 78e9243bc9d..00000000000
--- a/release/io/netrender/master.py
+++ /dev/null
@@ -1,615 +0,0 @@
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, shutil, time, hashlib
-
-from netrender.utils import *
-import netrender.model
-
-JOB_WAITING = 0 # before all data has been entered
-JOB_PAUSED = 1 # paused by user
-JOB_QUEUED = 2 # ready to be dispatched
-
-class MRenderFile:
- def __init__(self, filepath, start, end):
- self.filepath = filepath
- self.start = start
- self.end = end
- self.found = False
-
- def test(self):
- self.found = os.path.exists(self.filepath)
- return self.found
-
-
-class MRenderSlave(netrender.model.RenderSlave):
- def __init__(self, name, address, stats):
- super().__init__()
- self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest()
- self.name = name
- self.address = address
- self.stats = stats
- self.last_seen = time.time()
-
- self.job = None
- self.frame = None
-
- netrender.model.RenderSlave._slave_map[self.id] = self
-
- def seen(self):
- self.last_seen = time.time()
-
-# sorting key for jobs
-def groupKey(job):
- return (job.status, job.framesLeft() > 0, job.priority, job.credits)
-
-class MRenderJob(netrender.model.RenderJob):
- def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []):
- super().__init__()
- self.id = job_id
- self.name = name
- self.files = files
- self.frames = []
- self.chunks = chunks
- self.priority = priority
- self.credits = credits
- self.blacklist = blacklist
- self.last_dispatched = time.time()
-
- # special server properties
- self.save_path = ""
- self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files}
- self.status = JOB_WAITING
-
- def save(self):
- if self.save_path:
- f = open(self.save_path + "job.txt", "w")
- f.write(repr(self.serialize()))
- f.close()
-
- def testStart(self):
- for f in self.files_map.values():
- if not f.test():
- return False
-
- self.start()
- return True
-
- def start(self):
- self.status = JOB_QUEUED
-
- def update(self):
- self.credits -= 5 # cost of one frame
- self.credits += (time.time() - self.last_dispatched) / 60
- self.last_dispatched = time.time()
-
- def addFrame(self, frame_number):
- frame = MRenderFrame(frame_number)
- self.frames.append(frame)
- return frame
-
- def framesLeft(self):
- total = 0
- for j in self.frames:
- if j.status == QUEUED:
- total += 1
-
- return total
-
- def reset(self, all):
- for f in self.frames:
- f.reset(all)
-
- def getFrames(self):
- frames = []
- for f in self.frames:
- if f.status == QUEUED:
- self.update()
- frames.append(f)
- if len(frames) >= self.chunks:
- break
-
- return frames
-
-class MRenderFrame(netrender.model.RenderFrame):
- def __init__(self, frame):
- super().__init__()
- self.number = frame
- self.slave = None
- self.time = 0
- self.status = QUEUED
-
- def reset(self, all):
- if all or self.status == ERROR:
- self.slave = None
- self.time = 0
- self.status = QUEUED
-
-
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-class RenderHandler(http.server.BaseHTTPRequestHandler):
- def send_head(self, code = http.client.OK, headers = {}):
- self.send_response(code)
- self.send_header("Content-type", "application/octet-stream")
-
- for key, value in headers.items():
- self.send_header(key, value)
-
- self.end_headers()
-
- def do_HEAD(self):
- print(self.path)
-
- if self.path == "status":
- job_id = self.headers.get('job-id', "")
- job_frame = int(self.headers.get('job-frame', -1))
-
- if job_id:
- print("status:", job_id, "\n")
-
- job = self.server.getJobByID(job_id)
- if job:
- if job_frame != -1:
- frame = job[frame]
-
- if not frame:
- # no such frame
- self.send_heat(http.client.NO_CONTENT)
- return
- else:
- # no such job id
- self.send_head(http.client.NO_CONTENT)
- return
-
- self.send_head()
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- def do_GET(self):
- print(self.path)
-
- if self.path == "version":
- self.send_head()
- self.server.stats("", "New client connection")
- self.wfile.write(VERSION)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "render":
- job_id = self.headers['job-id']
- job_frame = int(self.headers['job-frame'])
- print("render:", job_id, job_frame)
-
- job = self.server.getJobByID(job_id)
-
- if job:
- frame = job[job_frame]
-
- if frame:
- if frame.status in (QUEUED, DISPATCHED):
- self.send_head(http.client.ACCEPTED)
- elif frame.status == DONE:
- self.server.stats("", "Sending result back to client")
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb')
-
- self.send_head()
-
- shutil.copyfileobj(f, self.wfile)
-
- f.close()
- elif frame.status == ERROR:
- self.send_head(http.client.PARTIAL_CONTENT)
- else:
- # no such frame
- self.send_head(http.client.NO_CONTENT)
- else:
- # no such job id
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "log":
- job_id = self.headers['job-id']
- job_frame = int(self.headers['job-frame'])
- print("log:", job_id, job_frame)
-
- job = self.server.getJobByID(job_id)
-
- if job:
- frame = job[job_frame]
-
- if frame:
- if frame.status in (QUEUED, DISPATCHED):
- self.send_head(http.client.PROCESSING)
- else:
- self.server.stats("", "Sending log back to client")
- f = open(job.save_path + "%04d" % job_frame + ".log", 'rb')
-
- self.send_head()
-
- shutil.copyfileobj(f, self.wfile)
-
- f.close()
- else:
- # no such frame
- self.send_head(http.client.NO_CONTENT)
- else:
- # no such job id
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "status":
- job_id = self.headers.get('job-id', "")
- job_frame = int(self.headers.get('job-frame', -1))
-
- if job_id:
- print("status:", job_id, "\n")
-
- job = self.server.getJobByID(job_id)
- if job:
- if job_frame != -1:
- frame = job[frame]
-
- if frame:
- message = frame.serialize()
- else:
- # no such frame
- self.send_heat(http.client.NO_CONTENT)
- return
- else:
- message = job.serialize()
- else:
- # no such job id
- self.send_head(http.client.NO_CONTENT)
- return
- else: # status of all jobs
- message = []
-
- for job in self.server:
- message.append(job.serialize())
-
- self.send_head()
- self.wfile.write(bytes(repr(message), encoding='utf8'))
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "job":
- self.server.update()
-
- slave_id = self.headers['slave-id']
-
- print("slave-id", slave_id)
-
- slave = self.server.updateSlave(slave_id)
-
- if slave: # only if slave id is valid
- job, frames = self.server.getNewJob(slave_id)
-
- if job and frames:
- for f in frames:
- print("dispatch", f.number)
- f.status = DISPATCHED
- f.slave = slave
-
- self.send_head(headers={"job-id": job.id})
-
- message = job.serialize(frames)
-
- self.wfile.write(bytes(repr(message), encoding='utf8'))
-
- self.server.stats("", "Sending job frame to render node")
- else:
- # no job available, return error code
- self.send_head(http.client.ACCEPTED)
- else: # invalid slave id
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "file":
- slave_id = self.headers['slave-id']
-
- slave = self.server.updateSlave(slave_id)
-
- if slave: # only if slave id is valid
- job_id = self.headers['job-id']
- job_file = self.headers['job-file']
- print("job:", job_id, "\n")
- print("file:", job_file, "\n")
-
- job = self.server.getJobByID(job_id)
-
- if job:
- render_file = job.files_map.get(job_file, None)
-
- if render_file:
- self.server.stats("", "Sending file to render node")
- f = open(render_file.path, 'rb')
-
- shutil.copyfileobj(f, self.wfile)
-
- f.close()
- else:
- # no such file
- self.send_head(http.client.NO_CONTENT)
- else:
- # no such job id
- self.send_head(http.client.NO_CONTENT)
- else: # invalid slave id
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "slave":
- message = []
-
- for slave in self.server.slaves:
- message.append(slave.serialize())
-
- self.send_head()
-
- self.wfile.write(bytes(repr(message), encoding='utf8'))
-
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- def do_POST(self):
- print(self.path)
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- if self.path == "job":
- print("posting job info")
- self.server.stats("", "Receiving job")
-
- length = int(self.headers['content-length'])
-
- job_info = netrender.model.RenderJob.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
-
- job_id = self.server.nextJobID()
-
- print(job_info.files)
-
- job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
-
- for frame in job_info.frames:
- frame = job.addFrame(frame.number)
-
- self.server.addJob(job)
-
- headers={"job-id": job_id}
-
- if job.testStart():
- self.send_head(headers=headers)
- else:
- self.send_head(http.client.ACCEPTED, headers=headers)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "cancel":
- job_id = self.headers.get('job-id', "")
- if job_id:
- print("cancel:", job_id, "\n")
- self.server.removeJob(job_id)
- else: # cancel all jobs
- self.server.clear()
-
- self.send_head()
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "reset":
- job_id = self.headers.get('job-id', "")
- job_frame = int(self.headers.get('job-frame', "-1"))
- all = bool(self.headers.get('reset-all', "False"))
-
- job = self.server.getJobByID(job_id)
-
- if job:
- if job_frame != -1:
- job[job_frame].reset(all)
- else:
- job.reset(all)
-
- self.send_head()
- else: # job not found
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "slave":
- length = int(self.headers['content-length'])
- job_frame_string = self.headers['job-frame']
-
- slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
-
- slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats)
-
- self.send_head(headers = {"slave-id": slave_id})
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- def do_PUT(self):
- print(self.path)
-
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- if self.path == "file":
- print("writing blend file")
- self.server.stats("", "Receiving job")
-
- length = int(self.headers['content-length'])
- job_id = self.headers['job-id']
- job_file = self.headers['job-file']
-
- job = self.server.getJobByID(job_id)
-
- if job:
-
- render_file = job.files_map.get(job_file, None)
-
- if render_file:
- main_file = job.files[0]
-
- main_path, main_name = os.path.split(main_file)
-
- if job_file != main_file:
- file_path = prefixPath(job.save_path, job_file, main_path)
- else:
- file_path = job.save_path + main_name
-
- buf = self.rfile.read(length)
-
- # add same temp file + renames as slave
-
- f = open(file_path, "wb")
- f.write(buf)
- f.close()
- del buf
-
- render_file.path = file_path # set the new path
-
- if job.testStart():
- self.send_head(headers=headers)
- else:
- self.send_head(http.client.ACCEPTED, headers=headers)
- else: # invalid file
- self.send_head(http.client.NO_CONTENT)
- else: # job not found
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "render":
- print("writing result file")
- self.server.stats("", "Receiving render result")
-
- slave_id = self.headers['slave-id']
-
- slave = self.server.updateSlave(slave_id)
-
- if slave: # only if slave id is valid
- job_id = self.headers['job-id']
-
- job = self.server.getJobByID(job_id)
-
- if job:
- job_frame = int(self.headers['job-frame'])
- job_result = int(self.headers['job-result'])
- job_time = float(self.headers['job-time'])
-
- frame = job[job_frame]
-
- if job_result == DONE:
- length = int(self.headers['content-length'])
- buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
- f.write(buf)
- f.close()
-
- del buf
- elif job_result == ERROR:
- # blacklist slave on this job on error
- job.blacklist.append(slave.id)
-
- frame.status = job_result
- frame.time = job_time
-
- self.server.updateSlave(self.headers['slave-id'])
-
- self.send_head()
- else: # job not found
- self.send_head(http.client.NO_CONTENT)
- else: # invalid slave id
- self.send_head(http.client.NO_CONTENT)
- # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "log":
- print("writing log file")
- self.server.stats("", "Receiving log file")
-
- job_id = self.headers['job-id']
-
- job = self.server.getJobByID(job_id)
-
- if job:
- length = int(self.headers['content-length'])
- job_frame = int(self.headers['job-frame'])
-
- buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".log", 'wb')
- f.write(buf)
- f.close()
-
- del buf
-
- self.server.updateSlave(self.headers['slave-id'])
-
- self.send_head()
- else: # job not found
- self.send_head(http.client.NO_CONTENT)
-
-class RenderMasterServer(http.server.HTTPServer):
- def __init__(self, address, handler_class, path):
- super().__init__(address, handler_class)
- self.jobs = []
- self.jobs_map = {}
- self.slaves = []
- self.slaves_map = {}
- self.job_id = 0
- self.path = path + "master_" + str(os.getpid()) + os.sep
-
- if not os.path.exists(self.path):
- os.mkdir(self.path)
-
- def nextJobID(self):
- self.job_id += 1
- return str(self.job_id)
-
- def addSlave(self, name, address, stats):
- slave = MRenderSlave(name, address, stats)
- self.slaves.append(slave)
- self.slaves_map[slave.id] = slave
-
- return slave.id
-
- def getSlave(self, slave_id):
- return self.slaves_map.get(slave_id, None)
-
- def updateSlave(self, slave_id):
- slave = self.getSlave(slave_id)
- if slave:
- slave.seen()
-
- return slave
-
- def clear(self):
- self.jobs_map = {}
- self.jobs = []
-
- def update(self):
- self.jobs.sort(key = groupKey)
-
- def removeJob(self, id):
- job = self.jobs_map.pop(id)
-
- if job:
- self.jobs.remove(job)
-
- def addJob(self, job):
- self.jobs.append(job)
- self.jobs_map[job.id] = job
-
- # create job directory
- job.save_path = self.path + "job_" + job.id + os.sep
- if not os.path.exists(job.save_path):
- os.mkdir(job.save_path)
-
- job.save()
-
- def getJobByID(self, id):
- return self.jobs_map.get(id, None)
-
- def __iter__(self):
- for job in self.jobs:
- yield job
-
- def getNewJob(self, slave_id):
- if self.jobs:
- for job in reversed(self.jobs):
- if job.status == JOB_QUEUED and job.framesLeft() > 0 and slave_id not in job.blacklist:
- return job, job.getFrames()
-
- return None, None
diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py
deleted file mode 100644
index 7803ad034a7..00000000000
--- a/release/io/netrender/model.py
+++ /dev/null
@@ -1,162 +0,0 @@
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, shutil, time, hashlib
-
-from netrender.utils import *
-
-class RenderSlave:
- _slave_map = {}
-
- def __init__(self):
- self.id = ""
- self.name = ""
- self.address = (0,0)
- self.stats = ""
- self.total_done = 0
- self.total_error = 0
- self.last_seen = 0.0
-
- def serialize(self):
- return {
- "id": self.id,
- "name": self.name,
- "address": self.address,
- "stats": self.stats,
- "total_done": self.total_done,
- "total_error": self.total_error,
- "last_seen": self.last_seen
- }
-
- @staticmethod
- def materialize(data):
- if not data:
- return None
-
- slave_id = data["id"]
-
- if slave_id in RenderSlave._slave_map:
- return RenderSlave._slave_map[slave_id]
- else:
- slave = RenderSlave()
- slave.id = slave_id
- slave.name = data["name"]
- slave.address = data["address"]
- slave.stats = data["stats"]
- slave.total_done = data["total_done"]
- slave.total_error = data["total_error"]
- slave.last_seen = data["last_seen"]
-
- RenderSlave._slave_map[slave_id] = slave
-
- return slave
-
-class RenderJob:
- def __init__(self):
- self.id = ""
- self.name = ""
- self.files = []
- self.frames = []
- self.chunks = 0
- self.priority = 0
- self.credits = 0
- self.blacklist = []
- self.last_dispatched = 0.0
-
- def addFile(self, file_path, start=-1, end=-1):
- self.files.append((file_path, start, end))
-
- def addFrame(self, frame_number):
- frame = RenderFrame(frame_number)
- self.frames.append(frame)
- return frame
-
- def __len__(self):
- return len(self.frames)
-
- def framesStatus(self):
- results = {
- QUEUED: 0,
- DISPATCHED: 0,
- DONE: 0,
- ERROR: 0
- }
-
- for frame in self.frames:
- results[frame.status] += 1
-
- return results
-
- def __contains__(self, frame_number):
- for f in self.frames:
- if f.number == frame_number:
- return True
- else:
- return False
-
- def __getitem__(self, frame_number):
- for f in self.frames:
- if f.number == frame_number:
- return f
- else:
- return None
-
- def serialize(self, frames = None):
- min_frame = min((f.number for f in frames)) if frames else -1
- max_frame = max((f.number for f in frames)) if frames else -1
- return {
- "id": self.id,
- "name": self.name,
- "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])],
- "frames": [f.serialize() for f in self.frames if not frames or f in frames],
- "chunks": self.chunks,
- "priority": self.priority,
- "credits": self.credits,
- "blacklist": self.blacklist,
- "last_dispatched": self.last_dispatched
- }
-
- @staticmethod
- def materialize(data):
- if not data:
- return None
-
- job = RenderJob()
- job.id = data["id"]
- job.name = data["name"]
- job.files = data["files"]
- job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
- job.chunks = data["chunks"]
- job.priority = data["priority"]
- job.credits = data["credits"]
- job.blacklist = data["blacklist"]
- job.last_dispatched = data["last_dispatched"]
-
- return job
-
-class RenderFrame:
- def __init__(self, number = 0):
- self.number = number
- self.time = 0
- self.status = QUEUED
- self.slave = None
-
- def serialize(self):
- return {
- "number": self.number,
- "time": self.time,
- "status": self.status,
- "slave": None if not self.slave else self.slave.serialize()
- }
-
- @staticmethod
- def materialize(data):
- if not data:
- return None
-
- frame = RenderFrame()
- frame.number = data["number"]
- frame.time = data["time"]
- frame.status = data["status"]
- frame.slave = RenderSlave.materialize(data["slave"])
-
- return frame
diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py
deleted file mode 100644
index 1c6d89c0043..00000000000
--- a/release/io/netrender/operators.py
+++ /dev/null
@@ -1,236 +0,0 @@
-import bpy
-import sys, os
-import http, http.client, http.server, urllib
-
-from netrender.utils import *
-import netrender.client as client
-import netrender.model
-
-class RENDER_OT_netclientsend(bpy.types.Operator):
- '''
- Operator documentation text, will be used for the operator tooltip and python docs.
- '''
- __idname__ = "render.netclientsend"
- __label__ = "Net Render Client Send"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, context):
- return True
-
- def execute(self, context):
- scene = context.scene
-
- conn = clientConnection(scene)
-
- if conn:
- # Sending file
- scene.network_render.job_id = client.clientSendJob(conn, scene, True)
-
- return ('FINISHED',)
-
- def invoke(self, context, event):
- return self.execute(context)
-
-class RENDER_OT_netclientstatus(bpy.types.Operator):
- '''Operator documentation text, will be used for the operator tooltip and python docs.'''
- __idname__ = "render.netclientstatus"
- __label__ = "Net Render Client Status"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, context):
- return True
-
- def execute(self, context):
- netsettings = context.scene.network_render
- conn = clientConnection(context.scene)
-
- if conn:
- conn.request("GET", "status")
-
- response = conn.getresponse()
- print( response.status, response.reason )
-
- jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
-
- while(len(netsettings.jobs) > 0):
- netsettings.jobs.remove(0)
-
- bpy.data.netrender_jobs = []
-
- for j in jobs:
- bpy.data.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.'''
- __idname__ = "render.netclientblacklistslave"
- __label__ = "Net Render Client Blacklist Slave"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, context):
- return True
-
- def execute(self, context):
- netsettings = context.scene.network_render
-
- if netsettings.active_slave_index >= 0:
-
- # deal with data
- slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index)
- bpy.data.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.'''
- __idname__ = "render.netclientwhitelistslave"
- __label__ = "Net Render Client Whitelist Slave"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, context):
- return True
-
- def execute(self, context):
- netsettings = context.scene.network_render
-
- if netsettings.active_blacklisted_slave_index >= 0:
-
- # deal with data
- slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index)
- bpy.data.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):
- '''Operator documentation text, will be used for the operator tooltip and python docs.'''
- __idname__ = "render.netclientslaves"
- __label__ = "Net Render Client Slaves"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, context):
- return True
-
- def execute(self, context):
- netsettings = context.scene.network_render
- conn = clientConnection(context.scene)
-
- if conn:
- conn.request("GET", "slave")
-
- response = conn.getresponse()
- print( response.status, response.reason )
-
- slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
-
- while(len(netsettings.slaves) > 0):
- netsettings.slaves.remove(0)
-
- bpy.data.netrender_slaves = []
-
- for s in slaves:
- for i in range(len(bpy.data.netrender_blacklist)):
- slave = bpy.data.netrender_blacklist[i]
- if slave.id == s.id:
- bpy.data.netrender_blacklist[i] = s
- netsettings.slaves_blacklist[i].name = s.name
- break
- else:
- bpy.data.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):
- '''Operator documentation text, will be used for the operator tooltip and python docs.'''
- __idname__ = "render.netclientcancel"
- __label__ = "Net Render Client Cancel"
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
- __props__ = []
-
- def poll(self, 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(context.scene)
-
- if conn:
- job = bpy.data.netrender_jobs[netsettings.active_job_index]
-
- conn.request("POST", "cancel", headers={"job-id":job.id})
-
- response = conn.getresponse()
- print( response.status, response.reason )
-
- return ('FINISHED',)
-
- def invoke(self, context, event):
- return self.execute(context)
-
-bpy.ops.add(RENDER_OT_netclientsend)
-bpy.ops.add(RENDER_OT_netclientstatus)
-bpy.ops.add(RENDER_OT_netclientslaves)
-bpy.ops.add(RENDER_OT_netclientblacklistslave)
-bpy.ops.add(RENDER_OT_netclientwhitelistslave)
-bpy.ops.add(RENDER_OT_netclientcancel) \ No newline at end of file
diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py
deleted file mode 100644
index c12c846231d..00000000000
--- a/release/io/netrender/slave.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, time
-
-from netrender.utils import *
-import netrender.model
-
-CANCEL_POLL_SPEED = 2
-MAX_TIMEOUT = 10
-INCREMENT_TIMEOUT = 1
-
-def slave_Info():
- sysname, nodename, release, version, machine = os.uname()
- slave = netrender.model.RenderSlave()
- slave.name = nodename
- slave.stats = sysname + " " + release + " " + machine
- return slave
-
-def testCancel(conn, job_id):
- conn.request("HEAD", "status", headers={"job-id":job_id})
- response = conn.getresponse()
-
- # cancelled if job isn't found anymore
- if response.status == http.client.NO_CONTENT:
- return True
- else:
- return False
-
-def testFile(conn, JOB_PREFIX, file_path, main_path = None):
- job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
-
- if not os.path.exists(job_full_path):
- temp_path = JOB_PREFIX + "slave.temp.blend"
- conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path})
- response = conn.getresponse()
-
- if response.status != http.client.OK:
- return None # file for job not returned by server, need to return an error code to server
-
- f = open(temp_path, "wb")
- buf = response.read(1024)
-
- while buf:
- f.write(buf)
- buf = response.read(1024)
-
- f.close()
-
- os.renames(temp_path, job_full_path)
-
- return job_full_path
-
-
-def render_slave(engine, scene):
- netsettings = scene.network_render
- timeout = 1
-
- engine.update_stats("", "Network render node initiation")
-
- conn = clientConnection(scene)
-
- if conn:
- conn.request("POST", "slave", repr(slave_Info().serialize()))
- response = conn.getresponse()
-
- slave_id = response.getheader("slave-id")
-
- NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
- if not os.path.exists(NODE_PREFIX):
- os.mkdir(NODE_PREFIX)
-
- while not engine.test_break():
-
- conn.request("GET", "job", headers={"slave-id":slave_id})
- response = conn.getresponse()
-
- if response.status == http.client.OK:
- timeout = 1 # reset timeout on new job
-
- job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
-
- JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
- if not os.path.exists(JOB_PREFIX):
- os.mkdir(JOB_PREFIX)
-
- job_path = job.files[0][0] # data in files have format (path, start, end)
- main_path, main_file = os.path.split(job_path)
-
- job_full_path = testFile(conn, JOB_PREFIX, job_path)
- print("Fullpath", job_full_path)
- print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
- engine.update_stats("", "Render File", main_file, "for job", job.id)
-
- for file_path, start, end in job.files[1:]:
- print("\t", file_path)
- testFile(conn, JOB_PREFIX, file_path, main_path)
-
- frame_args = []
-
- for frame in job.frames:
- print("frame", frame.number)
- frame_args += ["-f", str(frame.number)]
-
- start_t = time.time()
-
- process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
- cancelled = False
- stdout = bytes()
- run_t = time.time()
- while process.poll() == None and not cancelled:
- stdout += process.stdout.read(32)
- current_t = time.time()
- cancelled = engine.test_break()
- if current_t - run_t > CANCEL_POLL_SPEED:
- if testCancel(conn, job.id):
- cancelled = True
- else:
- run_t = current_t
-
- if cancelled:
- # kill process if needed
- if process.poll() == None:
- process.terminate()
- continue # to next frame
-
- total_t = time.time() - start_t
-
- avg_t = total_t / len(job.frames)
-
- status = process.returncode
-
- print("status", status)
-
- headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
-
- if status == 0: # non zero status is error
- headers["job-result"] = str(DONE)
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send result back to server
- f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
- conn.request("PUT", "render", f, headers=headers)
- f.close()
- response = conn.getresponse()
- else:
- headers["job-result"] = str(ERROR)
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send error result back to server
- conn.request("PUT", "render", headers=headers)
- response = conn.getresponse()
-
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send log in any case
- conn.request("PUT", "log", stdout, headers=headers)
- response = conn.getresponse()
- else:
- if timeout < MAX_TIMEOUT:
- timeout += INCREMENT_TIMEOUT
-
- for i in range(timeout):
- time.sleep(1)
- if engine.test_break():
- conn.close()
- return
-
- conn.close()
diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py
deleted file mode 100644
index 8faabe6ff2d..00000000000
--- a/release/io/netrender/ui.py
+++ /dev/null
@@ -1,283 +0,0 @@
-import bpy
-import sys, os
-import http, http.client, http.server, urllib
-import subprocess, shutil, time, hashlib
-
-import netrender.slave as slave
-import netrender.master as master
-
-from netrender.utils import *
-
-VERSION = b"0.3"
-
-PATH_PREFIX = "/tmp/"
-
-QUEUED = 0
-DISPATCHED = 1
-DONE = 2
-ERROR = 3
-
-class RenderButtonsPanel(bpy.types.Panel):
- __space_type__ = "PROPERTIES"
- __region_type__ = "WINDOW"
- __context__ = "scene"
- # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
-
- def poll(self, context):
- rd = context.scene.render_data
- return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
-
-# Setting panel, use in the scene for now.
-class SCENE_PT_network_settings(RenderButtonsPanel):
- __label__ = "Network Settings"
- COMPAT_ENGINES = set(['NET_RENDER'])
-
- def draw_header(self, context):
- layout = self.layout
- scene = context.scene
-
- def draw(self, context):
- layout = self.layout
- scene = context.scene
- rd = scene.render_data
-
- layout.active = True
-
- split = layout.split()
-
- col = split.column()
-
- col.itemR(scene.network_render, "mode")
- col.itemR(scene.network_render, "server_address")
- col.itemR(scene.network_render, "server_port")
- col.itemR(scene.network_render, "path")
-
- if scene.network_render.mode == "RENDER_CLIENT":
- col.itemR(scene.network_render, "chunks")
- col.itemR(scene.network_render, "priority")
- col.itemR(scene.network_render, "job_name")
- col.itemO("render.netclientsend", text="send job to server")
-bpy.types.register(SCENE_PT_network_settings)
-
-class SCENE_PT_network_slaves(RenderButtonsPanel):
- __label__ = "Slaves Status"
- COMPAT_ENGINES = set(['NET_RENDER'])
-
- def poll(self, context):
- scene = context.scene
- return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT"
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- netsettings = scene.network_render
-
- row = layout.row()
- row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
-
- col = row.column()
-
- subcol = col.column(align=True)
- subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="")
- subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="")
-
- if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0:
- while(len(netsettings.slaves) > 0):
- netsettings.slaves.remove(0)
-
- if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
- layout.itemS()
-
- slave = bpy.data.netrender_slaves[netsettings.active_slave_index]
-
- layout.itemL(text="Name: " + slave.name)
- layout.itemL(text="Address: " + slave.address[0])
- layout.itemL(text="Seen: " + time.ctime(slave.last_seen))
- layout.itemL(text="Stats: " + slave.stats)
-
-bpy.types.register(SCENE_PT_network_slaves)
-
-class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel):
- __label__ = "Slaves Blacklist"
- COMPAT_ENGINES = set(['NET_RENDER'])
-
- def poll(self, context):
- scene = context.scene
- return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT"
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- netsettings = scene.network_render
-
- row = layout.row()
- row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
-
- col = row.column()
-
- subcol = col.column(align=True)
- subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="")
-
- if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
- while(len(netsettings.slaves_blacklist) > 0):
- netsettings.slaves_blacklist.remove(0)
-
- if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
- layout.itemS()
-
- slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index]
-
- layout.itemL(text="Name: " + slave.name)
- layout.itemL(text="Address: " + slave.address[0])
- layout.itemL(text="Seen: " + slave.last_seen)
- layout.itemL(text="Stats: " + time.ctime(slave.stats))
-
-bpy.types.register(SCENE_PT_network_slaves_blacklist)
-
-class SCENE_PT_network_jobs(RenderButtonsPanel):
- __label__ = "Jobs"
- COMPAT_ENGINES = set(['NET_RENDER'])
-
- def poll(self, context):
- scene = context.scene
- return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT"
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- netsettings = scene.network_render
-
- row = layout.row()
- row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
-
- col = row.column()
-
- subcol = col.column(align=True)
- subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="")
- subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="")
-
- if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0:
- while(len(netsettings.jobs) > 0):
- netsettings.jobs.remove(0)
-
- if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
- layout.itemS()
-
- job = bpy.data.netrender_jobs[netsettings.active_job_index]
-
- layout.itemL(text="Name: %s" % job.name)
- layout.itemL(text="Length: %04i" % len(job))
- layout.itemL(text="Done: %04i" % job.results[DONE])
- layout.itemL(text="Error: %04i" % job.results[ERROR])
-
-bpy.types.register(SCENE_PT_network_jobs)
-
-class NetRenderSettings(bpy.types.IDPropertyGroup):
- pass
-
-class NetRenderSlave(bpy.types.IDPropertyGroup):
- pass
-
-class NetRenderJob(bpy.types.IDPropertyGroup):
- pass
-
-bpy.types.register(NetRenderSettings)
-bpy.types.register(NetRenderSlave)
-bpy.types.register(NetRenderJob)
-
-bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
-
-NetRenderSettings.StringProperty( attr="server_address",
- name="Server address",
- description="IP or name of the master render server",
- maxlen = 128,
- default = "127.0.0.1")
-
-NetRenderSettings.IntProperty( attr="server_port",
- name="Server port",
- description="port of the master render server",
- default = 8000,
- min=1,
- max=65535)
-
-NetRenderSettings.StringProperty( attr="path",
- name="Path",
- description="Path for temporary files",
- maxlen = 128,
- default = "/tmp/")
-
-NetRenderSettings.StringProperty( attr="job_name",
- name="Job name",
- description="Name of the job",
- maxlen = 128,
- default = "[default]")
-
-NetRenderSettings.IntProperty( attr="chunks",
- name="Chunks",
- description="Number of frame to dispatch to each slave in one chunk",
- default = 5,
- min=1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="priority",
- name="Priority",
- description="Priority of the job",
- default = 1,
- min=1,
- max=10)
-
-NetRenderSettings.StringProperty( attr="job_id",
- name="Network job id",
- description="id of the last sent render job",
- maxlen = 64,
- default = "")
-
-NetRenderSettings.IntProperty( attr="active_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_job_index",
- name="Index of the active job",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.EnumProperty(attr="mode",
- items=(
- ("RENDER_CLIENT", "Client", "Act as render client"),
- ("RENDER_MASTER", "Master", "Act as render master"),
- ("RENDER_SLAVE", "Slave", "Act as render slave"),
- ),
- name="network mode",
- description="mode of operation of this instance",
- default="RENDER_CLIENT")
-
-NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
-NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
-NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
-
-NetRenderSlave.StringProperty( attr="name",
- name="Name of the slave",
- description="",
- maxlen = 64,
- default = "")
-
-NetRenderJob.StringProperty( attr="name",
- name="Name of the job",
- description="",
- maxlen = 128,
- default = "")
diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py
deleted file mode 100644
index d1b383f7a97..00000000000
--- a/release/io/netrender/utils.py
+++ /dev/null
@@ -1,61 +0,0 @@
-import bpy
-import sys, os
-import re
-import http, http.client, http.server, urllib
-import subprocess, shutil, time, hashlib
-
-import netrender.model
-
-VERSION = b"0.5"
-
-QUEUED = 0
-DISPATCHED = 1
-DONE = 2
-ERROR = 3
-
-def clientConnection(scene):
- netrender = scene.network_render
-
- conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port)
-
- if clientVerifyVersion(conn):
- return conn
- else:
- conn.close()
- return None
-
-def clientVerifyVersion(conn):
- conn.request("GET", "version")
- response = conn.getresponse()
-
- if response.status != http.client.OK:
- conn.close()
- return False
-
- server_version = response.read()
-
- if server_version != VERSION:
- print("Incorrect server version!")
- print("expected", VERSION, "received", server_version)
- return False
-
- return True
-
-def prefixPath(prefix_directory, file_path, prefix_path):
- if os.path.isabs(file_path):
- # if an absolute path, make sure path exists, if it doesn't, use relative local path
- full_path = file_path
- if not os.path.exists(full_path):
- p, n = os.path.split(full_path)
-
- if main_path and p.startswith(main_path):
- directory = prefix_directory + p[len(main_path):]
- full_path = directory + n
- if not os.path.exists(directory):
- os.mkdir(directory)
- else:
- full_path = prefix_directory + n
- else:
- full_path = prefix_directory + file_path
-
- return full_path \ No newline at end of file