class InternalBufferDisplay(RenderListener): ''' Class to monitor rendering and update blender render result ''' def __init__(self, render_ctx): super(InternalBufferDisplay, self).__init__() self.ctx = render_ctx self.film = self.ctx.scene.getFilm() self.size = self.film.getSize() self.bitmap = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, self.size) self.bitmap.clear() self.buffer = None self.fast_buffer = True self.do_cancel = False self.time = 0 self.delay = .5 self.ctx.queue.registerListener(self) def get_offset_size(self, wu): offset = wu.getOffset() size = wu.getSize() end = offset + size offset.x = max(0, offset.x) offset.y = max(0, offset.y) end.x = min(self.size.x, end.x) end.y = min(self.size.y, end.y) size = end - offset return offset, size def workBeginEvent(self, job, wu, thr): offset, size = self.get_offset_size(wu) self.bitmap.drawWorkUnit(offset, size, thr) self.timed_update_result() def workEndEvent(self, job, wr, cancelled): offset, size = self.get_offset_size(wr) self.film.develop(offset, size, offset, self.bitmap) self.timed_update_result() def refreshEvent(self, job): self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap) self.update_result() def finishJobEvent(self, job, cancelled): MtsLog('Render Job Finished') self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap) self.update_result(render_end=True) def get_bitmap_buffer(self, passes=1): bitmap_clone = self.bitmap.clone() bitmap_clone.flipVertically() if passes == 1: return bitmap_clone.buffer() if self.buffer is None: self.buffer = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, Vector2i(self.size[0], self.size[1] * passes)) self.buffer.clear() self.buffer.copyFrom(bitmap_clone) return self.buffer.buffer() def get_bitmap_list(self): self.delay = 1.5 bitmap_list = numpy.ndarray((self.size[0] * self.size[1], 4), buffer=self.get_bitmap_buffer(), dtype='float32') # .tolist() return bitmap_list def timed_update_result(self): now = time.time() if now - self.time > self.delay: self.time = now self.update_result() def update_result(self, render_end=False): if self.ctx.test_break(): return try: render_result = self.ctx.render_engine.begin_result(0, 0, self.size[0], self.size[1]) if render_result is None: err_msg = 'ERROR: Cannot not load render result: begin_result() returned None.' self.do_cancel = True raise Exception(err_msg) if self.fast_buffer: passes = len(render_result.layers[0].passes) bitmap_buffer = self.get_bitmap_buffer(passes) render_result.layers[0].passes.foreach_set('rect', bitmap_buffer) else: bitmap_buffer = self.get_bitmap_list() render_result.layers[0].passes[0].rect = bitmap_buffer self.ctx.render_engine.end_result(render_result, 0) except Exception as err: MtsLog('%s' % err) if self.fast_buffer: self.fast_buffer = False else: self.do_cancel = True if self.do_cancel: self.ctx.render_cancel()
class InternalBufferDisplay(RenderListener): ''' Class to monitor rendering and update blender render result ''' def __init__(self, render_ctx): super(InternalBufferDisplay, self).__init__() self.ctx = render_ctx self.film = self.ctx.scene.getFilm() self.size = self.film.getSize() self.bitmap = Bitmap(Bitmap.ERGBA, Bitmap.EFloat32, self.size) self.bitmap.clear() self.buffer = None self.fast_buffer = True self.do_cancel = False self.time = 0 self.delay = .5 self.ctx.queue.registerListener(self) def get_offset_size(self, wu): offset = wu.getOffset() size = wu.getSize() end = offset + size offset.x = max(0, offset.x) offset.y = max(0, offset.y) end.x = min(self.size.x, end.x) end.y = min(self.size.y, end.y) size = end - offset return offset, size def workBeginEvent(self, job, wu, thr): offset, size = self.get_offset_size(wu) self.bitmap.drawWorkUnit(offset, size, thr) self.timed_update_result() def workEndEvent(self, job, wr, cancelled): offset, size = self.get_offset_size(wr) self.film.develop(offset, size, offset, self.bitmap) self.timed_update_result() def refreshEvent(self, job): self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap) self.update_result() def finishJobEvent(self, job, cancelled): MtsLog('Render Job Finished') self.film.develop(Point2i(0), self.size, Point2i(0), self.bitmap) self.update_result(render_end=True) def get_bitmap_buffer(self, passes=1): bitmap_clone = self.bitmap.clone() bitmap_clone.flipVertically() if passes == 1: return bitmap_clone.buffer() if self.buffer is None: self.buffer = Bitmap( Bitmap.ERGBA, Bitmap.EFloat32, Vector2i(self.size[0], self.size[1] * passes)) self.buffer.clear() self.buffer.copyFrom(bitmap_clone) return self.buffer.buffer() def get_bitmap_list(self): self.delay = 1.5 bitmap_list = numpy.ndarray((self.size[0] * self.size[1], 4), buffer=self.get_bitmap_buffer(), dtype='float32') # .tolist() return bitmap_list def timed_update_result(self): now = time.time() if now - self.time > self.delay: self.time = now self.update_result() def update_result(self, render_end=False): if self.ctx.test_break(): return try: render_result = self.ctx.render_engine.begin_result( 0, 0, self.size[0], self.size[1]) if render_result is None: err_msg = 'ERROR: Cannot not load render result: begin_result() returned None.' self.do_cancel = True raise Exception(err_msg) if self.fast_buffer: passes = len(render_result.layers[0].passes) bitmap_buffer = self.get_bitmap_buffer(passes) render_result.layers[0].passes.foreach_set( 'rect', bitmap_buffer) else: bitmap_buffer = self.get_bitmap_list() render_result.layers[0].passes[0].rect = bitmap_buffer self.ctx.render_engine.end_result(render_result, 0) except Exception as err: MtsLog('%s' % err) if self.fast_buffer: self.fast_buffer = False else: self.do_cancel = True if self.do_cancel: self.ctx.render_cancel()