plugin reliability improvements
parent
c9cb0dc56f
commit
be4cba85bb
|
@ -20,7 +20,7 @@
|
||||||
import os, time, threading, sys, copy, subprocess
|
import os, time, threading, sys, copy, subprocess
|
||||||
|
|
||||||
# Blender libs
|
# Blender libs
|
||||||
import bpy, bl_ui
|
import bpy, bl_ui, time
|
||||||
|
|
||||||
# Framework libs
|
# Framework libs
|
||||||
from extensions_framework import util as efutil
|
from extensions_framework import util as efutil
|
||||||
|
@ -106,8 +106,6 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine):
|
||||||
output_dir = scene_path
|
output_dir = scene_path
|
||||||
else:
|
else:
|
||||||
output_dir = os.path.dirname(scene_path)
|
output_dir = os.path.dirname(scene_path)
|
||||||
efutil.export_path = output_dir
|
|
||||||
os.chdir(output_dir)
|
|
||||||
|
|
||||||
if scene.render.use_color_management == False:
|
if scene.render.use_color_management == False:
|
||||||
MtsLog('WARNING: Color Management is switched off, render results may look too dark.')
|
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 ..")
|
MtsLog("MtsBlend: Launching renderer ..")
|
||||||
if scene.mitsuba_engine.render_mode == 'gui':
|
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':
|
elif scene.mitsuba_engine.render_mode == 'cli':
|
||||||
output_file = efutil.export_path[:-4] + ".png"
|
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),
|
['mitsuba', '-r', str(scene.mitsuba_engine.refresh_interval),
|
||||||
'-o', output_file, efutil.export_path]
|
'-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:
|
if mitsuba_process.poll() != None and mitsuba_process.returncode != 0:
|
||||||
MtsLog("MtsBlend: Rendering failed -- check the console")
|
MtsLog("MtsBlend: Rendering failed -- check the console")
|
||||||
bpy.ops.ef.msg(msg_type='ERROR', msg_text='Rendering failed -- check the console.')
|
|
||||||
else:
|
else:
|
||||||
framebuffer_thread.kick(render_end=True)
|
framebuffer_thread.kick(render_end=True)
|
||||||
framebuffer_thread.shutdown()
|
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_spp = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_spp', '16'))
|
||||||
preview_depth = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_depth', '2'))
|
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',
|
['mitsuba', '-q',
|
||||||
'-r%i' % refresh_interval,
|
'-r%i' % refresh_interval,
|
||||||
|
'-b16',
|
||||||
'-o', output_file, '-Dmatfile=%s' % os.path.join(tempdir, matfile),
|
'-o', output_file, '-Dmatfile=%s' % os.path.join(tempdir, matfile),
|
||||||
'-Dwidth=%i' % width,
|
'-Dwidth=%i' % width,
|
||||||
'-Dheight=%i' % height,
|
'-Dheight=%i' % height,
|
||||||
|
@ -219,7 +218,7 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine):
|
||||||
|
|
||||||
framebuffer_thread = MtsFilmDisplay()
|
framebuffer_thread = MtsFilmDisplay()
|
||||||
framebuffer_thread.set_kick_period(refresh_interval)
|
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
|
render_update_timer = None
|
||||||
while mitsuba_process.poll() == None and not self.test_break():
|
while mitsuba_process.poll() == None and not self.test_break():
|
||||||
render_update_timer = threading.Timer(1, self.process_wait_timer)
|
render_update_timer = threading.Timer(1, self.process_wait_timer)
|
||||||
|
|
|
@ -211,7 +211,7 @@ def resolution(scene):
|
||||||
|
|
||||||
return xr, yr
|
return xr, yr
|
||||||
|
|
||||||
def MtsLaunch(mts_path, commandline):
|
def MtsLaunch(mts_path, path, commandline):
|
||||||
env = copy.copy(os.environ)
|
env = copy.copy(os.environ)
|
||||||
mts_render_libpath = os.path.join(mts_path, "src/librender")
|
mts_render_libpath = os.path.join(mts_path, "src/librender")
|
||||||
mts_core_libpath = os.path.join(mts_path, "src/libcore")
|
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")
|
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
|
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])
|
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:
|
class MtsExporter:
|
||||||
'''
|
'''
|
||||||
|
@ -245,6 +245,10 @@ class MtsExporter:
|
||||||
self.textures = textures if textures != None else bpy.data.textures
|
self.textures = textures if textures != None else bpy.data.textures
|
||||||
self.indent = 0
|
self.indent = 0
|
||||||
self.stack = []
|
self.stack = []
|
||||||
|
if directory[-1] != '/':
|
||||||
|
directory += '/'
|
||||||
|
self.output_directory = directory
|
||||||
|
efutil.export_path = self.xml_filename
|
||||||
|
|
||||||
def writeHeader(self):
|
def writeHeader(self):
|
||||||
try:
|
try:
|
||||||
|
@ -526,7 +530,6 @@ class MtsExporter:
|
||||||
idx = 0
|
idx = 0
|
||||||
# Force scene update; NB, scene.update() doesn't work
|
# Force scene update; NB, scene.update() doesn't work
|
||||||
scene.frame_set(scene.frame_current)
|
scene.frame_set(scene.frame_current)
|
||||||
efutil.export_path = self.xml_filename
|
|
||||||
|
|
||||||
MtsLog('MtsBlend: Writing adjustments file to "%s"' % self.adj_filename)
|
MtsLog('MtsBlend: Writing adjustments file to "%s"' % self.adj_filename)
|
||||||
if not self.writeHeader():
|
if not self.writeHeader():
|
||||||
|
@ -561,7 +564,8 @@ class MtsExporter:
|
||||||
'-n', '-l', 'pngfilm', self.dae_filename, self.xml_filename, self.adj_filename]
|
'-n', '-l', 'pngfilm', self.dae_filename, self.xml_filename, self.adj_filename]
|
||||||
if scene.mitsuba_integrator.motionblur:
|
if scene.mitsuba_integrator.motionblur:
|
||||||
command += ['-z']
|
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:
|
if process.wait() != 0:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -18,26 +18,33 @@ class MtsFilmDisplay(TimerThread):
|
||||||
|
|
||||||
STARTUP_DELAY = 1
|
STARTUP_DELAY = 1
|
||||||
|
|
||||||
def begin(self, renderer, output_file, resolution):
|
def begin(self, renderer, output_file, resolution, preview = False):
|
||||||
(xres, yres) = resolution
|
(self.xres, self.yres) = (int(resolution[0]), int(resolution[1]))
|
||||||
self.result = renderer.begin_result(0, 0, int(xres), int(yres))
|
|
||||||
self.renderer = renderer
|
self.renderer = renderer
|
||||||
self.output_file = output_file
|
self.output_file = output_file
|
||||||
self.resolution = resolution
|
self.resolution = resolution
|
||||||
|
self.preview = preview
|
||||||
|
if not self.preview:
|
||||||
|
self.result = self.renderer.begin_result(0, 0, self.xres, self.yres)
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
|
if not self.preview:
|
||||||
self.renderer.end_result(self.result)
|
self.renderer.end_result(self.result)
|
||||||
|
|
||||||
def kick(self, render_end=False):
|
def kick(self, render_end=False):
|
||||||
if not bpy.app.background or render_end:
|
if not bpy.app.background or render_end:
|
||||||
|
if os.path.exists(self.output_file):
|
||||||
if render_end:
|
if render_end:
|
||||||
MtsLog('Final render result %ix%i' % self.resolution)
|
MtsLog('Final render result %ix%i' % self.resolution)
|
||||||
else:
|
else:
|
||||||
MtsLog('Updating render result %ix%i' % self.resolution)
|
MtsLog('Updating render result %ix%i' % self.resolution)
|
||||||
|
|
||||||
if os.path.exists(self.output_file):
|
|
||||||
try:
|
try:
|
||||||
|
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.result.layers[0].load_from_file(self.output_file)
|
||||||
self.renderer.update_result(self.result)
|
self.renderer.update_result(self.result)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -101,8 +101,8 @@ class mitsuba_material(declarative_property_group):
|
||||||
{
|
{
|
||||||
'type': 'bool',
|
'type': 'bool',
|
||||||
'attr': 'is_medium_transition',
|
'attr': 'is_medium_transition',
|
||||||
'name': 'Is medium transition?',
|
'name': 'Mark as medium transition?',
|
||||||
'description': 'Activate this property if the material marks a transition from one participating medium to another.',
|
'description': 'Activate this property if the material specifies a transition from one participating medium to another.',
|
||||||
'default': False,
|
'default': False,
|
||||||
'save_in_preset': True
|
'save_in_preset': True
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,7 +389,7 @@ class mitsuba_tex_ldrtexture(declarative_property_group):
|
||||||
def get_params(self):
|
def get_params(self):
|
||||||
params = ParamSet()
|
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_string('filterType', self.filterType) \
|
||||||
.add_float('maxAnisotropy', self.maxAnisotropy) \
|
.add_float('maxAnisotropy', self.maxAnisotropy) \
|
||||||
.add_string('wrapMode', self.wrapMode) \
|
.add_string('wrapMode', self.wrapMode) \
|
||||||
|
|
|
@ -52,6 +52,7 @@ protected:
|
||||||
std::string m_toneMappingMethod;
|
std::string m_toneMappingMethod;
|
||||||
Float m_reinhardKey, m_reinhardBurn;
|
Float m_reinhardKey, m_reinhardBurn;
|
||||||
int m_compressionRate;
|
int m_compressionRate;
|
||||||
|
ref<Mutex> m_mutex;
|
||||||
public:
|
public:
|
||||||
PNGFilm(const Properties &props) : Film(props) {
|
PNGFilm(const Properties &props) : Film(props) {
|
||||||
m_pixels = new Pixel[m_cropSize.x * m_cropSize.y];
|
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!");
|
Log(EError, "16bpp implies a grayscale image with an alpha channel!");
|
||||||
if (m_bpp != 8 && m_bpp != 16 && m_bpp != 24 && m_bpp != 32)
|
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!");
|
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)
|
PNGFilm(Stream *stream, InstanceManager *manager)
|
||||||
|
@ -103,6 +105,7 @@ public:
|
||||||
m_compressionRate = stream->readInt();
|
m_compressionRate = stream->readInt();
|
||||||
m_gamma = 1.0f / m_gamma;
|
m_gamma = 1.0f / m_gamma;
|
||||||
m_pixels = new Pixel[m_cropSize.x * m_cropSize.y];
|
m_pixels = new Pixel[m_cropSize.x * m_cropSize.y];
|
||||||
|
m_mutex = new Mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
|
@ -212,6 +215,7 @@ public:
|
||||||
|
|
||||||
void develop(const fs::path &destFile) {
|
void develop(const fs::path &destFile) {
|
||||||
Log(EDebug, "Developing film ..");
|
Log(EDebug, "Developing film ..");
|
||||||
|
m_mutex->lock();
|
||||||
ref<Bitmap> bitmap = new Bitmap(m_cropSize.x, m_cropSize.y, m_bpp);
|
ref<Bitmap> bitmap = new Bitmap(m_cropSize.x, m_cropSize.y, m_bpp);
|
||||||
uint8_t *targetPixels = bitmap->getData();
|
uint8_t *targetPixels = bitmap->getData();
|
||||||
Float r, g, b;
|
Float r, g, b;
|
||||||
|
@ -411,8 +415,8 @@ public:
|
||||||
ref<FileStream> stream = new FileStream(filename, FileStream::ETruncWrite);
|
ref<FileStream> stream = new FileStream(filename, FileStream::ETruncWrite);
|
||||||
bitmap->setGamma(m_gamma);
|
bitmap->setGamma(m_gamma);
|
||||||
bitmap->save(Bitmap::EPNG, stream, m_compressionRate);
|
bitmap->save(Bitmap::EPNG, stream, m_compressionRate);
|
||||||
stream->flush();
|
|
||||||
stream->close();
|
stream->close();
|
||||||
|
m_mutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool destinationExists(const fs::path &baseName) const {
|
bool destinationExists(const fs::path &baseName) const {
|
||||||
|
|
|
@ -105,6 +105,8 @@ bool Viewer::deviceEventOccurred(const DeviceEvent &event) {
|
||||||
case Device::EResizeEvent:
|
case Device::EResizeEvent:
|
||||||
m_renderer->reconfigure(m_device);
|
m_renderer->reconfigure(m_device);
|
||||||
windowResized(event);
|
windowResized(event);
|
||||||
|
// no break
|
||||||
|
case Device::EGainFocusEvent:
|
||||||
m_leaveEventLoop = true;
|
m_leaveEventLoop = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue