material preview support

metadata
Wenzel Jakob 2010-11-17 02:37:59 +01:00
parent 40114792c9
commit ada5d996a3
7 changed files with 148 additions and 8 deletions

View File

@ -49,6 +49,7 @@ protected:
Float m_gamma, m_exposure;
std::string m_toneMappingMethod;
Float m_reinhardKey, m_reinhardBurn;
int m_compressionRate;
public:
PNGFilm(const Properties &props) : Film(props) {
m_pixels = new Pixel[m_cropSize.x * m_cropSize.y];
@ -68,6 +69,8 @@ public:
m_reinhardBurn = props.getFloat("reinhardBurn", 0.0f);
/* Reinhard "key" parameter */
m_reinhardKey = props.getFloat("reinhardKey", 0.18f);
/* Compression rate (1=low, 9=high) */
m_compressionRate = props.getInteger("compressionRate", 1);
if (m_toneMappingMethod != "gamma" && m_toneMappingMethod != "reinhard")
Log(EError, "Unknown tone mapping method specified (must be 'gamma' or 'reinhard')");
@ -95,6 +98,7 @@ public:
m_reinhardKey = stream->readFloat();
m_reinhardBurn = stream->readFloat();
m_exposure = stream->readFloat();
m_compressionRate = stream->readInt();
m_gamma = 1.0f / m_gamma;
m_pixels = new Pixel[m_cropSize.x * m_cropSize.y];
}
@ -109,6 +113,7 @@ public:
stream->writeFloat(m_reinhardKey);
stream->writeFloat(m_reinhardBurn);
stream->writeFloat(m_exposure);
stream->writeInt(m_compressionRate);
}
virtual ~PNGFilm() {
@ -403,7 +408,7 @@ public:
Log(EInfo, "Writing image to \"%s\" ..", filename.leaf().c_str());
ref<FileStream> stream = new FileStream(filename, FileStream::ETruncWrite);
bitmap->setGamma(m_gamma);
bitmap->save(Bitmap::EPNG, stream, 1);
bitmap->save(Bitmap::EPNG, stream, m_compressionRate);
}
bool destinationExists(const fs::path &baseName) const {

View File

@ -16,6 +16,8 @@
#
# ##### END GPL LICENSE BLOCK #####
import os
bl_addon_info = {
"name": "Mitsuba",
"author": "Wenzel Jakob",
@ -30,6 +32,8 @@ bl_addon_info = {
"tracker_url": "https://www.mitsuba-renderer.org/bugtracker/projects/mitsuba",
"category": "Render"}
def plugin_path():
return os.path.dirname(os.path.realpath(__file__))
from .core import RENDERENGINE_mitsuba

View File

@ -27,6 +27,7 @@ from extensions_framework.engine import engine_base
from extensions_framework import util as efutil
# Mitsuba-related classes
from mitsuba import plugin_path
from mitsuba.properties.engine import mitsuba_engine
from mitsuba.properties.lamp import mitsuba_lamp
from mitsuba.properties.texture import mitsuba_texture, \
@ -41,6 +42,7 @@ from mitsuba.properties.material import mitsuba_material, \
from mitsuba.operators import MITSUBA_OT_preset_engine_add, EXPORT_OT_mitsuba
from mitsuba.outputs import MtsLog, MtsFilmDisplay
from mitsuba.export.adjustments import MtsAdjustments
from mitsuba.export import translate_id
from mitsuba.export.film import resolution
from mitsuba.export import get_instance_materials
from mitsuba.ui import render_panels
@ -133,13 +135,61 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine, engine_base):
return
tempdir = efutil.temp_directory()
matpreview_file = os.path.join(tempdir, "matpreview_materials.xml")
matfile = os.path.join(tempdir, "matpreview_materials.xml")
output_file = os.path.join(tempdir, "matpreview.png")
scene_file = os.path.join(os.path.join(plugin_path(),
"matpreview"), "matpreview.xml")
pm = likely_materials[0]
adj = MtsAdjustments(matpreview_file, tempdir,
adj = MtsAdjustments(matfile, tempdir,
bpy.data.materials, bpy.data.textures)
adj.writeHeader()
adj.exportMaterial(pm)
adj.writeFooter()
(mts_path, tail) = os.path.split(bpy.path.abspath(scene.mitsuba_engine.binary_path))
mitsuba_binary = os.path.join(mts_path, "mitsuba")
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")
mts_hw_libpath = os.path.join(mts_path, "src/libhw")
env['LD_LIBRARY_PATH'] = mts_core_libpath + ":" + mts_render_libpath + ":" + mts_hw_libpath
(width, height) = resolution(scene)
refresh_interval = 1
mitsuba_process = subprocess.Popen(
[mitsuba_binary, '-r%i' % refresh_interval,
'-o', output_file, '-Dmatfile=%s' % matfile,
'-Dmatname=%s' % translate_id(pm.name),
'-Dwidth=%i' % width,
'-Dheight=%i' % height,
'-q',
'-o', output_file, scene_file],
env = env,
cwd = tempdir
)
framebuffer_thread = MtsFilmDisplay({
'resolution': resolution(scene),
'RE': self,
'output_file': output_file
})
framebuffer_thread.set_kick_period(refresh_interval)
framebuffer_thread.start()
while mitsuba_process.poll() == None and not self.test_break():
self.render_update_timer = threading.Timer(1, self.process_wait_timer)
self.render_update_timer.start()
if self.render_update_timer.isAlive(): self.render_update_timer.join()
# If we exit the wait loop (user cancelled) and mitsuba is still running, then send SIGINT
if mitsuba_process.poll() == None:
# Use SIGTERM because that's the only one supported on Windows
mitsuba_process.send_signal(subprocess.signal.SIGTERM)
# Stop updating the render result and load the final image
framebuffer_thread.stop()
framebuffer_thread.join()
if mitsuba_process.poll() != None and mitsuba_process.returncode != 0:
MtsLog("MtsBlend: Rendering failed -- check the console")
else:
framebuffer_thread.kick(render_end=True)
def render(self, scene):
@ -196,17 +246,18 @@ class RENDERENGINE_mitsuba(bpy.types.RenderEngine, engine_base):
cwd = self.output_dir
)
elif scene.mitsuba_engine.render_mode == 'cli':
self.output_file = efutil.export_path[:-4] + ".png"
output_file = efutil.export_path[:-4] + ".png"
mitsuba_process = subprocess.Popen(
[mitsuba_binary, '-r', '%d' % scene.mitsuba_engine.refresh_interval,
'-o', self.output_file, efutil.export_path],
'-o', output_file, efutil.export_path],
env = env,
cwd = self.output_dir
)
framebuffer_thread = MtsFilmDisplay({
'resolution': resolution(scene),
'RE': self,
'output_file': output_file
})
framebuffer_thread.set_kick_period(scene.mitsuba_engine.refresh_interval)
framebuffer_thread.start()

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<!--
Automatically converted from COLLADA
-->
<scene>
<integrator id="integrator" type="direct"/>
<include filename="$matfile"/>
<camera id="Camera-camera" type="perspective">
<float name="fov" value="28.8415"/>
<boolean name="mapSmallerSide" value="true"/>
<transform name="toWorld">
<matrix value="0.68588 -0.31737 -0.654862 3.69558 0.727634 0.312469 0.610666 -3.46243 -0.0108168 0.895343 -0.445245 3.25463 0 0 0 1"/>
</transform>
<sampler type="ldsampler">
<integer name="sampleCount" value="16"/>
</sampler>
<film id="film" type="pngfilm">
<integer name="width" value="$width"/>
<integer name="height" value="$height"/>
<boolean name="alpha" value="false"/>
<boolean name="banner" value="false"/>
<rfilter type="gaussian"/>
</film>
</camera>
<luminaire id="Area_002-light" type="envmap">
<string name="filename" value="envmap.exr"/>
<transform name="toWorld">
<matrix value="-0.224951 -0.000001 -0.974370 0.000000 -0.974370 0.000000 0.224951 0.000000 0.000000 1.000000 -0.000001 8.870000 0.000000 0.000000 0.000000 1.000000 "/>
</transform>
<float name="intensityScale" value="1.540006"/>
</luminaire>
<bsdf id="Material_001" type="lambertian">
<rgb name="reflectance" value="0.5 0.5 0.5"/>
</bsdf>
<texture id="Checkerboard_Texture" type="checkerboard">
<rgb name="darkColor" value="0.20000000298 0.20000000298 0.20000000298"/>
<rgb name="brightColor" value="0.40000000596 0.40000000596 0.40000000596"/>
<float name="uscale" value="30.0"/>
<float name="vscale" value="30.0"/>
<float name="uoffset" value="0.0"/>
<float name="voffset" value="0.0"/>
</texture><bsdf id="Plane_Material" type="lambertian">
<ref id="Checkerboard_Texture" name="reflectance"/>
</bsdf><shape id="Interior-mesh_0" type="serialized">
<string name="filename" value="matpreview.Scene.00010.serialized"/>
<integer name="shapeIndex" value="0"/>
<transform name="toWorld">
<matrix value="1 0 0 0 0 1 0 0 0 0 1 0.0252155 0 0 0 1"/>
</transform>
<ref id="Material_001" name="bsdf"/>
</shape>
<shape id="Exterior-mesh_0" type="serialized">
<string name="filename" value="matpreview.Scene.00010.serialized"/>
<integer name="shapeIndex" value="1"/>
<transform name="toWorld">
<matrix value="0.614046 0.614047 0 -1.78814e-07 -0.614047 0.614046 0 2.08616e-07 0 0 0.868393 1.02569 0 0 0 1"/>
</transform>
<ref id="$matname" name="bsdf"/>
</shape>
<shape id="Plane-mesh_0" type="serialized">
<string name="filename" value="matpreview.Scene.00010.serialized"/>
<integer name="shapeIndex" value="2"/>
<transform name="toWorld">
<matrix value="20 0 0 -10 0 20 0 10 0 0 20 0 0 0 0 1"/>
</transform>
<ref id="Plane_Material" name="bsdf"/>
</shape>
</scene>

View File

@ -27,12 +27,12 @@ class MtsFilmDisplay(TimerThread):
MtsLog('Updating render result %ix%i' % (xres,yres))
result = self.LocalStorage['RE'].begin_result(0, 0, int(xres), int(yres))
if os.path.exists(self.LocalStorage['RE'].output_file):
if os.path.exists(self.LocalStorage['output_file']):
bpy.ops.ef.msg(msg_text='Updating RenderResult')
lay = result.layers[0]
lay.load_from_file(self.LocalStorage['RE'].output_file)
lay.load_from_file(self.LocalStorage['output_file'])
else:
err_msg = 'ERROR: Could not load render result from %s' % self.LocalStorage['RE'].output_file
err_msg = 'ERROR: Could not load render result from %s' % self.LocalStorage['output_file']
MtsLog(err_msg)
bpy.ops.ef.msg(msg_type='ERROR', msg_text=err_msg)
self.LocalStorage['RE'].end_result(result)