From be4cba85bb83501b87a8162b474c4d8f33e3e19e Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 31 Mar 2011 22:23:05 +0200 Subject: [PATCH] plugin reliability improvements --- data/blender/mitsuba/core/__init__.py | 15 +++++------ data/blender/mitsuba/export/__init__.py | 12 ++++++--- data/blender/mitsuba/outputs/__init__.py | 29 +++++++++++++-------- data/blender/mitsuba/properties/material.py | 4 +-- data/blender/mitsuba/properties/texture.py | 2 +- src/films/pngfilm.cpp | 6 ++++- src/libhw/viewer.cpp | 2 ++ 7 files changed, 43 insertions(+), 27 deletions(-) diff --git a/data/blender/mitsuba/core/__init__.py b/data/blender/mitsuba/core/__init__.py index 19fb3908..591bdb94 100644 --- a/data/blender/mitsuba/core/__init__.py +++ b/data/blender/mitsuba/core/__init__.py @@ -20,7 +20,7 @@ import os, time, threading, sys, copy, subprocess # Blender libs -import bpy, bl_ui +import bpy, bl_ui, time # Framework libs from extensions_framework import util as efutil @@ -106,8 +106,6 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine): output_dir = scene_path else: output_dir = os.path.dirname(scene_path) - efutil.export_path = output_dir - os.chdir(output_dir) if scene.render.use_color_management == False: MtsLog('WARNING: Color Management is switched off, render results may look too dark.') @@ -128,10 +126,11 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine): MtsLog("MtsBlend: Launching renderer ..") if scene.mitsuba_engine.render_mode == 'gui': - MtsLaunch(scene.mitsuba_engine.binary_path, ['mtsgui', efutil.export_path]) + MtsLaunch(scene.mitsuba_engine.binary_path, output_dir, + ['mtsgui', efutil.export_path]) elif scene.mitsuba_engine.render_mode == 'cli': output_file = efutil.export_path[:-4] + ".png" - mitsuba_process = MtsLaunch(scene.mitsuba_engine.binary_path, + mitsuba_process = MtsLaunch(scene.mitsuba_engine.binary_path, output_dir, ['mitsuba', '-r', str(scene.mitsuba_engine.refresh_interval), '-o', output_file, efutil.export_path] ) @@ -155,7 +154,6 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine): if mitsuba_process.poll() != None and mitsuba_process.returncode != 0: MtsLog("MtsBlend: Rendering failed -- check the console") - bpy.ops.ef.msg(msg_type='ERROR', msg_text='Rendering failed -- check the console.') else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown() @@ -207,9 +205,10 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine): preview_spp = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_spp', '16')) preview_depth = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_depth', '2')) - mitsuba_process = MtsLaunch(scene.mitsuba_engine.binary_path, + mitsuba_process = MtsLaunch(scene.mitsuba_engine.binary_path, tempdir, ['mitsuba', '-q', '-r%i' % refresh_interval, + '-b16', '-o', output_file, '-Dmatfile=%s' % os.path.join(tempdir, matfile), '-Dwidth=%i' % width, '-Dheight=%i' % height, @@ -219,7 +218,7 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine): framebuffer_thread = MtsFilmDisplay() framebuffer_thread.set_kick_period(refresh_interval) - framebuffer_thread.begin(self, output_file, resolution(scene)) + framebuffer_thread.begin(self, output_file, resolution(scene), preview=True) render_update_timer = None while mitsuba_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) diff --git a/data/blender/mitsuba/export/__init__.py b/data/blender/mitsuba/export/__init__.py index 8d3e58dd..ca948ffe 100644 --- a/data/blender/mitsuba/export/__init__.py +++ b/data/blender/mitsuba/export/__init__.py @@ -211,7 +211,7 @@ def resolution(scene): return xr, yr -def MtsLaunch(mts_path, commandline): +def MtsLaunch(mts_path, path, commandline): env = copy.copy(os.environ) mts_render_libpath = os.path.join(mts_path, "src/librender") mts_core_libpath = os.path.join(mts_path, "src/libcore") @@ -219,7 +219,7 @@ def MtsLaunch(mts_path, commandline): mts_bidir_libpath = os.path.join(mts_path, "src/libbidir") env['LD_LIBRARY_PATH'] = mts_core_libpath + ":" + mts_render_libpath + ":" + mts_hw_libpath + ":" + mts_bidir_libpath commandline[0] = os.path.join(mts_path, commandline[0]) - return subprocess.Popen(commandline, env = env, cwd = mts_path) + return subprocess.Popen(commandline, env = env, cwd = path) class MtsExporter: ''' @@ -245,6 +245,10 @@ class MtsExporter: self.textures = textures if textures != None else bpy.data.textures self.indent = 0 self.stack = [] + if directory[-1] != '/': + directory += '/' + self.output_directory = directory + efutil.export_path = self.xml_filename def writeHeader(self): try: @@ -526,7 +530,6 @@ class MtsExporter: idx = 0 # Force scene update; NB, scene.update() doesn't work scene.frame_set(scene.frame_current) - efutil.export_path = self.xml_filename MtsLog('MtsBlend: Writing adjustments file to "%s"' % self.adj_filename) if not self.writeHeader(): @@ -561,7 +564,8 @@ class MtsExporter: '-n', '-l', 'pngfilm', self.dae_filename, self.xml_filename, self.adj_filename] if scene.mitsuba_integrator.motionblur: command += ['-z'] - process = MtsLaunch(scene.mitsuba_engine.binary_path, command); + process = MtsLaunch(scene.mitsuba_engine.binary_path, + self.output_directory, command); if process.wait() != 0: return False return True diff --git a/data/blender/mitsuba/outputs/__init__.py b/data/blender/mitsuba/outputs/__init__.py index 11a66408..4e8242a0 100644 --- a/data/blender/mitsuba/outputs/__init__.py +++ b/data/blender/mitsuba/outputs/__init__.py @@ -18,28 +18,35 @@ class MtsFilmDisplay(TimerThread): STARTUP_DELAY = 1 - def begin(self, renderer, output_file, resolution): - (xres, yres) = resolution - self.result = renderer.begin_result(0, 0, int(xres), int(yres)) + def begin(self, renderer, output_file, resolution, preview = False): + (self.xres, self.yres) = (int(resolution[0]), int(resolution[1])) self.renderer = renderer self.output_file = output_file self.resolution = resolution + self.preview = preview + if not self.preview: + self.result = self.renderer.begin_result(0, 0, self.xres, self.yres) self.start() def shutdown(self): - self.renderer.end_result(self.result) + if not self.preview: + self.renderer.end_result(self.result) def kick(self, render_end=False): if not bpy.app.background or render_end: - if render_end: - MtsLog('Final render result %ix%i' % self.resolution) - else: - MtsLog('Updating render result %ix%i' % self.resolution) - if os.path.exists(self.output_file): + if render_end: + MtsLog('Final render result %ix%i' % self.resolution) + else: + MtsLog('Updating render result %ix%i' % self.resolution) try: - self.result.layers[0].load_from_file(self.output_file) - self.renderer.update_result(self.result) + if self.preview: + self.result = self.renderer.begin_result(0, 0, self.xres, self.yres) + self.result.layers[0].load_from_file(self.output_file) + self.renderer.end_result(self.result) + else: + self.result.layers[0].load_from_file(self.output_file) + self.renderer.update_result(self.result) except: pass else: diff --git a/data/blender/mitsuba/properties/material.py b/data/blender/mitsuba/properties/material.py index e9c0a2cd..11576e50 100644 --- a/data/blender/mitsuba/properties/material.py +++ b/data/blender/mitsuba/properties/material.py @@ -101,8 +101,8 @@ class mitsuba_material(declarative_property_group): { 'type': 'bool', 'attr': 'is_medium_transition', - 'name': 'Is medium transition?', - 'description': 'Activate this property if the material marks a transition from one participating medium to another.', + 'name': 'Mark as medium transition?', + 'description': 'Activate this property if the material specifies a transition from one participating medium to another.', 'default': False, 'save_in_preset': True } diff --git a/data/blender/mitsuba/properties/texture.py b/data/blender/mitsuba/properties/texture.py index 3efe3569..5296c726 100644 --- a/data/blender/mitsuba/properties/texture.py +++ b/data/blender/mitsuba/properties/texture.py @@ -389,7 +389,7 @@ class mitsuba_tex_ldrtexture(declarative_property_group): def get_params(self): params = ParamSet() - params.add_string('filename', efutil.path_relative_to_export(self.filename) ) \ + params.add_string('filename', efutil.path_relative_to_export(self.filename)) \ .add_string('filterType', self.filterType) \ .add_float('maxAnisotropy', self.maxAnisotropy) \ .add_string('wrapMode', self.wrapMode) \ diff --git a/src/films/pngfilm.cpp b/src/films/pngfilm.cpp index 5a00cca0..7a83eed1 100644 --- a/src/films/pngfilm.cpp +++ b/src/films/pngfilm.cpp @@ -52,6 +52,7 @@ protected: std::string m_toneMappingMethod; Float m_reinhardKey, m_reinhardBurn; int m_compressionRate; + ref m_mutex; public: PNGFilm(const Properties &props) : Film(props) { m_pixels = new Pixel[m_cropSize.x * m_cropSize.y]; @@ -89,6 +90,7 @@ public: Log(EError, "16bpp implies a grayscale image with an alpha channel!"); if (m_bpp != 8 && m_bpp != 16 && m_bpp != 24 && m_bpp != 32) Log(EError, "The PNG film must be set to 8, 16, 24 or 32 bits per pixel!"); + m_mutex = new Mutex(); } PNGFilm(Stream *stream, InstanceManager *manager) @@ -103,6 +105,7 @@ public: m_compressionRate = stream->readInt(); m_gamma = 1.0f / m_gamma; m_pixels = new Pixel[m_cropSize.x * m_cropSize.y]; + m_mutex = new Mutex(); } void serialize(Stream *stream, InstanceManager *manager) const { @@ -212,6 +215,7 @@ public: void develop(const fs::path &destFile) { Log(EDebug, "Developing film .."); + m_mutex->lock(); ref bitmap = new Bitmap(m_cropSize.x, m_cropSize.y, m_bpp); uint8_t *targetPixels = bitmap->getData(); Float r, g, b; @@ -411,8 +415,8 @@ public: ref stream = new FileStream(filename, FileStream::ETruncWrite); bitmap->setGamma(m_gamma); bitmap->save(Bitmap::EPNG, stream, m_compressionRate); - stream->flush(); stream->close(); + m_mutex->unlock(); } bool destinationExists(const fs::path &baseName) const { diff --git a/src/libhw/viewer.cpp b/src/libhw/viewer.cpp index 15c4608d..ee67ab85 100644 --- a/src/libhw/viewer.cpp +++ b/src/libhw/viewer.cpp @@ -105,6 +105,8 @@ bool Viewer::deviceEventOccurred(const DeviceEvent &event) { case Device::EResizeEvent: m_renderer->reconfigure(m_device); windowResized(event); + // no break + case Device::EGainFocusEvent: m_leaveEventLoop = true; break; }