medium-related bugfixes
parent
6fe9cb7b6b
commit
5560e70033
|
@ -52,7 +52,7 @@ from ..ui.materials import (
|
||||||
from .. import operators
|
from .. import operators
|
||||||
|
|
||||||
def compatible(mod):
|
def compatible(mod):
|
||||||
mod = __import__('bl_ui.' + mod)
|
mod = getattr(bl_ui, mod)
|
||||||
for subclass in mod.__dict__.values():
|
for subclass in mod.__dict__.values():
|
||||||
try:
|
try:
|
||||||
subclass.COMPAT_ENGINES.add(MitsubaAddon.BL_IDNAME)
|
subclass.COMPAT_ENGINES.add(MitsubaAddon.BL_IDNAME)
|
||||||
|
@ -67,12 +67,13 @@ bl_ui.properties_render.RENDER_PT_output.COMPAT_ENGINES.add(MitsubaAddon.BL_IDNA
|
||||||
|
|
||||||
compatible("properties_data_mesh")
|
compatible("properties_data_mesh")
|
||||||
compatible("properties_data_camera")
|
compatible("properties_data_camera")
|
||||||
|
compatible("properties_particle")
|
||||||
|
|
||||||
@MitsubaAddon.addon_register_class
|
@MitsubaAddon.addon_register_class
|
||||||
class RENDERENGINE_mitsuba(bpy.types.RenderEngine):
|
class RENDERENGINE_mitsuba(bpy.types.RenderEngine):
|
||||||
bl_idname = MitsubaAddon.BL_IDNAME
|
bl_idname = MitsubaAddon.BL_IDNAME
|
||||||
bl_label = 'Mitsuba'
|
bl_label = 'Mitsuba'
|
||||||
bl_use_preview = True
|
bl_use_preview = False
|
||||||
|
|
||||||
render_lock = threading.Lock()
|
render_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
import bpy, os, copy, subprocess
|
import bpy, os, copy, subprocess, math, mathutils
|
||||||
from extensions_framework import util as efutil
|
from extensions_framework import util as efutil
|
||||||
from ..outputs import MtsLog
|
from ..outputs import MtsLog
|
||||||
|
|
||||||
|
@ -246,44 +246,75 @@ class MtsExporter:
|
||||||
self.exported_textures = []
|
self.exported_textures = []
|
||||||
self.materials = materials if materials != None else bpy.data.materials
|
self.materials = materials if materials != None else bpy.data.materials
|
||||||
self.textures = textures if textures != None else bpy.data.textures
|
self.textures = textures if textures != None else bpy.data.textures
|
||||||
|
self.indent = 0
|
||||||
|
self.stack = []
|
||||||
|
|
||||||
|
def parameter(self, paramType, paramName, attributes = {}):
|
||||||
|
self.out.write('\t' * self.indent + '<%s name="%s"' % (paramType, paramName))
|
||||||
|
for (k, v) in attributes.items():
|
||||||
|
self.out.write(' %s=\"%s\"' % (k, v))
|
||||||
|
self.out.write('/>\n')
|
||||||
|
|
||||||
|
def element(self, name, attributes = {}):
|
||||||
|
self.out.write('\t' * self.indent + '<%s' % name)
|
||||||
|
for (k, v) in attributes.items():
|
||||||
|
self.out.write(' %s=\"%s\"' % (k, v))
|
||||||
|
self.out.write('/>\n')
|
||||||
|
|
||||||
|
def openElement(self, name, attributes = {}):
|
||||||
|
self.out.write('\t' * self.indent + '<%s' % name)
|
||||||
|
for (k, v) in attributes.items():
|
||||||
|
self.out.write(' %s=\"%s\"' % (k, v))
|
||||||
|
self.out.write('>\n')
|
||||||
|
self.indent = self.indent+1
|
||||||
|
self.stack.append(name)
|
||||||
|
|
||||||
|
def closeElement(self):
|
||||||
|
self.indent = self.indent-1
|
||||||
|
name = self.stack.pop()
|
||||||
|
self.out.write('\t' * self.indent + '</%s>\n' % name)
|
||||||
|
|
||||||
def exportWorldTrafo(self, trafo):
|
def exportWorldTrafo(self, trafo):
|
||||||
self.out.write('\t\t<transform name="toWorld">\n')
|
self.openElement('transform', {'name' : 'toWorld'})
|
||||||
self.out.write('\t\t\t<matrix value="')
|
value = ""
|
||||||
for j in range(0,4):
|
for j in range(0,4):
|
||||||
for i in range(0,4):
|
for i in range(0,4):
|
||||||
self.out.write("%f " % trafo[i][j])
|
value += "%f " % trafo[i][j]
|
||||||
self.out.write('"/>\n\t\t</transform>\n')
|
self.element('matrix', {'value' : value})
|
||||||
|
self.closeElement()
|
||||||
|
|
||||||
def exportLamp(self, lamp, idx):
|
def exportLamp(self, lamp, idx):
|
||||||
ltype = lamp.data.mitsuba_lamp.type
|
ltype = lamp.data.type
|
||||||
name = translate_id(lamp.data.name)
|
name = translate_id(lamp.data.name)
|
||||||
|
mult = lamp.data.mitsuba_lamp.intensity
|
||||||
if ltype == 'POINT':
|
if ltype == 'POINT':
|
||||||
self.out.write('\t<luminaire id="%s-light" type="point">\n' % name)
|
self.openElement('luminaire', { 'type' : 'point', 'id' : '%s-light' % name })
|
||||||
mult = lamp.data.mitsuba_lamp.intensity
|
|
||||||
self.exportWorldTrafo(lamp.matrix_world)
|
self.exportWorldTrafo(lamp.matrix_world)
|
||||||
self.out.write('\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', {'value' :
|
||||||
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult))
|
"%f %f %f" % (lamp.data.color.r*mult, lamp.data.color.g*mult,
|
||||||
self.out.write('\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.data.mitsuba_lamp.samplingWeight)
|
lamp.data.color.b*mult)})
|
||||||
self.out.write('\t</luminaire>\n')
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
|
||||||
|
self.closeElement()
|
||||||
elif ltype == 'AREA':
|
elif ltype == 'AREA':
|
||||||
self.out.write('\t<remove id="%s-light"/>\n' % name)
|
self.element('remove', { 'id' : '%s-light' % name})
|
||||||
self.out.write('\t<shape type="obj">\n')
|
self.openElement('shape', { 'type' : 'obj'} )
|
||||||
size_x = lamp.data.size
|
(size_x, size_y) = (lamp.data.size, lamp.data.size)
|
||||||
size_y = lamp.data.size
|
|
||||||
if lamp.data.shape == 'RECTANGLE':
|
if lamp.data.shape == 'RECTANGLE':
|
||||||
size_y = lamp.data.size_y
|
size_y = lamp.data.size_y
|
||||||
|
mult = mult / (2 * size_x * size_y)
|
||||||
filename = "area_luminaire_%d.obj" % idx
|
filename = "area_luminaire_%d.obj" % idx
|
||||||
|
|
||||||
self.out.write('\t\t<string name="filename" value="meshes/%s"/>\n' % filename)
|
self.parameter('string', 'filename', { 'value' : 'meshes/%s' % filename})
|
||||||
self.exportWorldTrafo(lamp.matrix_world)
|
self.exportWorldTrafo(lamp.matrix_world)
|
||||||
self.out.write('\n\t\t<luminaire id="%s-arealight" type="area">\n' % name)
|
|
||||||
mult = lamp.data.mitsuba_lamp.intensity / (2 * size_x * size_y)
|
self.openElement('luminaire', { 'id' : '%s-arealight' % name, 'type' : 'area'})
|
||||||
self.out.write('\t\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', { 'value' : "%f %f %f"
|
||||||
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult))
|
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult)})
|
||||||
self.out.write('\t\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.data.mitsuba_lamp.samplingWeight)
|
self.closeElement()
|
||||||
self.out.write('\t\t</luminaire>\n')
|
self.openElement('bsdf', { 'type' : 'lambertian'})
|
||||||
self.out.write('\t</shape>\n')
|
self.parameter('spectrum', 'reflectance', {'value' : '0'})
|
||||||
|
self.closeElement()
|
||||||
|
self.closeElement()
|
||||||
path = os.path.join(self.meshes_dir, filename)
|
path = os.path.join(self.meshes_dir, filename)
|
||||||
objFile = open(path, 'w')
|
objFile = open(path, 'w')
|
||||||
objFile.write('v %f %f 0\n' % (-size_x/2, -size_y/2))
|
objFile.write('v %f %f 0\n' % (-size_x/2, -size_y/2))
|
||||||
|
@ -293,47 +324,45 @@ class MtsExporter:
|
||||||
objFile.write('f 4 3 2 1\n')
|
objFile.write('f 4 3 2 1\n')
|
||||||
objFile.close()
|
objFile.close()
|
||||||
elif ltype == 'SUN':
|
elif ltype == 'SUN':
|
||||||
self.out.write('\t<luminaire id="%s-light" type="directional">\n' % name)
|
self.openElement('luminaire', { 'id' : '%s-light' % name, 'type' : 'directional'})
|
||||||
mult = lamp.data.mitsuba_lamp.intensity
|
|
||||||
scale = mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1]))
|
scale = mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1]))
|
||||||
self.exportWorldTrafo(lamp.matrix_world * mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1])))
|
self.exportWorldTrafo(lamp.matrix_world * mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1])))
|
||||||
self.out.write('\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', { 'value' : "%f %f %f"
|
||||||
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult))
|
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult)})
|
||||||
self.out.write('\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.data.mitsuba_lamp.samplingWeight)
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
|
||||||
self.out.write('\t</luminaire>\n')
|
self.closeElement()
|
||||||
elif ltype == 'SPOT':
|
elif ltype == 'SPOT':
|
||||||
self.out.write('\t<luminaire id="%s-light" type="spot">\n' % name)
|
self.openElement('luminaire', { 'id' : '%s-light' % name, 'type' : 'spot'})
|
||||||
mult = lamp.data.mitsuba_lamp.intensity
|
|
||||||
self.exportWorldTrafo(lamp.matrix_world * mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1])))
|
self.exportWorldTrafo(lamp.matrix_world * mathutils.Matrix.Scale(-1, 4, mathutils.Vector([0, 0, 1])))
|
||||||
self.out.write('\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', { 'value' : "%f %f %f"
|
||||||
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult))
|
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult)})
|
||||||
self.out.write('\t\t<float name="cutoffAngle" value="%f"/>\n' % (lamp.data.spot_size * 180 / (math.pi * 2)))
|
self.parameter('float', 'cutoffAngle', {'value' : '%f' % (lamp.data.spot_size * 180 / (math.pi * 2))})
|
||||||
self.out.write('\t\t<float name="beamWidth" value="%f"/>\n' % (lamp.data.spot_blend * lamp.data.spot_size * 180 / (math.pi * 2)))
|
self.parameter('float', 'beamWidth', {'value' : '%f' % (lamp.data.spot_blend * lamp.data.spot_size * 180 / (math.pi * 2))})
|
||||||
self.out.write('\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.data.mitsuba_lamp.samplingWeight)
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
|
||||||
self.out.write('\t</luminaire>\n')
|
self.closeElement()
|
||||||
elif ltype == 'ENV':
|
elif ltype == 'HEMI':
|
||||||
if lamp.data.mitsuba_lamp.envmap_type == 'constant':
|
if lamp.data.mitsuba_lamp.envmap_type == 'constant':
|
||||||
self.out.write('\t<luminaire id="%s-light" type="constant">\n' % name)
|
self.openElement('luminaire', { 'id' : '%s-light' % name, 'type' : 'constant'})
|
||||||
mult = lamp.data.mitsuba_lamp.intensity
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
|
||||||
self.out.write('\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', { 'value' : "%f %f %f"
|
||||||
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult))
|
% (lamp.data.color.r*mult, lamp.data.color.g*mult, lamp.data.color.b*mult)})
|
||||||
self.out.write('\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.data.mitsuba_lamp.samplingWeight)
|
self.closeElement()
|
||||||
self.out.write('\t</luminaire>\n')
|
|
||||||
elif lamp.data.mitsuba_lamp.envmap_type == 'envmap':
|
elif lamp.data.mitsuba_lamp.envmap_type == 'envmap':
|
||||||
self.out.write('\t<luminaire id="%s-light" type="envmap">\n' % name)
|
self.openElement('luminaire', { 'id' : '%s-light' % name, 'type' : 'envmap'})
|
||||||
self.out.write('\t\t<string name="filename" value="%s"/>\n' % efutil.filesystem_path(lamp.data.mitsuba_lamp.envmap_file))
|
self.parameter('string', 'filename', {'value' : efutil.filesystem_path(lamp.data.mitsuba_lamp.envmap_file)})
|
||||||
self.exportWorldTrafo(lamp.matrix_world)
|
self.exportWorldTrafo(lamp.matrix_world)
|
||||||
self.out.write('\t\t<float name="intensityScale" value="%f"/>\n' % lamp.data.mitsuba_lamp.intensity)
|
self.parameter('float', 'intensityScale', {'value' : '%f' % lamp.data.mitsuba_lamp.intensity})
|
||||||
self.out.write('\t</luminaire>\n')
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
|
||||||
|
self.closeElement()
|
||||||
|
|
||||||
def exportIntegrator(self, integrator):
|
def exportIntegrator(self, integrator):
|
||||||
self.out.write('\t<integrator id="integrator" type="%s">\n' % integrator.type)
|
self.openElement('integrator', { 'id' : 'integrator', 'type' : integrator.type})
|
||||||
self.out.write('\t</integrator>\n')
|
self.closeElement()
|
||||||
|
|
||||||
def exportSampler(self, sampler):
|
def exportSampler(self, sampler):
|
||||||
self.out.write('\t<sampler id="sampler" type="%s">\n' % sampler.type)
|
self.openElement('sampler', { 'id' : 'sampler', 'type' : sampler.type})
|
||||||
self.out.write('\t\t<integer name="sampleCount" value="%i"/>\n' % sampler.sampleCount)
|
self.parameter('integer', 'sampleCount', { 'value' : '%i' % sampler.sampleCount})
|
||||||
self.out.write('\t</sampler>\n')
|
self.closeElement()
|
||||||
|
|
||||||
def findTexture(self, name):
|
def findTexture(self, name):
|
||||||
if name in self.textures:
|
if name in self.textures:
|
||||||
|
@ -382,23 +411,24 @@ class MtsExporter:
|
||||||
self.out.write('\t</bsdf>\n')
|
self.out.write('\t</bsdf>\n')
|
||||||
|
|
||||||
def exportEmission(self, obj):
|
def exportEmission(self, obj):
|
||||||
|
mult = lamp.intensity
|
||||||
lamp = obj.data.materials[0].mitsuba_emission
|
lamp = obj.data.materials[0].mitsuba_emission
|
||||||
name = translate_id(obj.data.name)
|
name = translate_id(obj.data.name)
|
||||||
self.out.write('\t<append id="%s-mesh_0">\n' % name)
|
self.openElement('append', { 'id' : '%s-mesh_0' % name})
|
||||||
self.out.write('\t\t<luminaire id="%s-emission" type="area">\n' % name)
|
self.openElement('luminaire', { 'id' : '%s-emission' % name, 'type' : 'area'})
|
||||||
mult = lamp.intensity
|
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.samplingWeight})
|
||||||
self.out.write('\t\t\t<rgb name="intensity" value="%f %f %f"/>\n'
|
self.parameter('rgb', 'intensity', { 'value' : "%f %f %f"
|
||||||
% (lamp.color.r*mult, lamp.color.g*mult, lamp.color.b*mult))
|
% (lamp.color.r*mult, lamp.color.g*mult, lamp.color.b*mult)})
|
||||||
self.out.write('\t\t\t<float name="samplingWeight" value="%f"/>\n' % lamp.samplingWeight)
|
self.closeElement()
|
||||||
self.out.write('\t\t</luminaire>\n')
|
self.closeElement()
|
||||||
self.out.write('\t</append>\n')
|
|
||||||
|
|
||||||
def writeHeader(self):
|
def writeHeader(self):
|
||||||
self.out = open(self.adj_filename, 'w')
|
self.out = open(self.adj_filename, 'w')
|
||||||
self.out.write('<scene>\n');
|
self.out.write('<?xml version="1.0" encoding="utf-8"?>\n');
|
||||||
|
self.openElement('scene')
|
||||||
|
|
||||||
def writeFooter(self):
|
def writeFooter(self):
|
||||||
self.out.write('</scene>\n');
|
self.closeElement()
|
||||||
self.out.close()
|
self.out.close()
|
||||||
|
|
||||||
def exportPreviewMesh(self, material):
|
def exportPreviewMesh(self, material):
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# System Libs
|
# System Libs
|
||||||
import os, sys, subprocess, traceback, string
|
import os, sys, subprocess, traceback, string, math
|
||||||
|
|
||||||
# Blender Libs
|
# Blender Libs
|
||||||
import bpy, bl_operators
|
import bpy, bl_operators
|
||||||
|
@ -207,3 +207,54 @@ class MITSUBA_OT_material_add(bpy.types.Operator):
|
||||||
obj.data.materials.append(mat)
|
obj.data.materials.append(mat)
|
||||||
obj.active_material_index = len(obj.data.materials)-1
|
obj.active_material_index = len(obj.data.materials)-1
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def material_converter(report, scene, blender_mat):
|
||||||
|
try:
|
||||||
|
mitsuba_mat = blender_mat.mitsuba_material
|
||||||
|
|
||||||
|
mitsuba_mat.type = 'microfacet'
|
||||||
|
mitsuba_mat.mitsuba_mat_microfacet.diffuseReflectance_color = [blender_mat.diffuse_intensity*i for i in blender_mat.diffuse_color]
|
||||||
|
mitsuba_mat.mitsuba_mat_microfacet.specularAmount = 1.0
|
||||||
|
mitsuba_mat.mitsuba_mat_microfacet.diffuseAmount = 1.0
|
||||||
|
|
||||||
|
logHardness = math.log(blender_mat.specular_hardness)
|
||||||
|
specular_scale = 2.0 * max(0.0128415*logHardness**2 - 0.171266*logHardness + 0.575631, 0.0)
|
||||||
|
mitsuba_mat.mitsuba_mat_microfacet.specularReflectance_color = [specular_scale * blender_mat.specular_intensity*i for i in blender_mat.specular_color]
|
||||||
|
mitsuba_mat.mitsuba_mat_microfacet.alphaB = min(max(0.757198 - 0.120395*logHardness, 0.0), 1.0)
|
||||||
|
|
||||||
|
report({'INFO'}, 'Converted blender material "%s"' % blender_mat.name)
|
||||||
|
return {'FINISHED'}
|
||||||
|
except Exception as err:
|
||||||
|
report({'ERROR'}, 'Cannot convert material: %s' % err)
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
@MitsubaAddon.addon_register_class
|
||||||
|
class MITSUBA_OT_convert_all_materials(bpy.types.Operator):
|
||||||
|
bl_idname = 'mitsuba.convert_all_materials'
|
||||||
|
bl_label = 'Convert all Blender materials'
|
||||||
|
|
||||||
|
def report_log(self, level, msg):
|
||||||
|
MtsLog('Material conversion %s: %s' % (level, msg))
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
for blender_mat in bpy.data.materials:
|
||||||
|
# Don't convert materials from linked-in files
|
||||||
|
if blender_mat.library == None:
|
||||||
|
material_converter(self.report_log, context.scene, blender_mat)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
@MitsubaAddon.addon_register_class
|
||||||
|
class MITSUBA_OT_convert_material(bpy.types.Operator):
|
||||||
|
bl_idname = 'mitsuba.convert_material'
|
||||||
|
bl_label = 'Convert selected Blender material'
|
||||||
|
|
||||||
|
material_name = bpy.props.StringProperty(default='')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if self.properties.material_name == '':
|
||||||
|
blender_mat = context.material
|
||||||
|
else:
|
||||||
|
blender_mat = bpy.data.materials[self.properties.material_name]
|
||||||
|
|
||||||
|
material_converter(self.report, context.scene, blender_mat)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
|
@ -28,8 +28,7 @@ class MtsFilmDisplay(TimerThread):
|
||||||
|
|
||||||
result = self.LocalStorage['RE'].begin_result(0, 0, int(xres), int(yres))
|
result = self.LocalStorage['RE'].begin_result(0, 0, int(xres), int(yres))
|
||||||
if os.path.exists(self.LocalStorage['output_file']):
|
if os.path.exists(self.LocalStorage['output_file']):
|
||||||
lay = result.layers[0]
|
result.layers[0].load_from_file(self.LocalStorage['output_file'])
|
||||||
lay.load_from_file(self.LocalStorage['output_file'])
|
|
||||||
else:
|
else:
|
||||||
err_msg = 'ERROR: Could not load render result from %s' % self.LocalStorage['output_file']
|
err_msg = 'ERROR: Could not load render result from %s' % self.LocalStorage['output_file']
|
||||||
MtsLog(err_msg)
|
MtsLog(err_msg)
|
||||||
|
|
|
@ -36,21 +36,6 @@ class mitsuba_lamp(declarative_property_group):
|
||||||
}
|
}
|
||||||
|
|
||||||
properties = [
|
properties = [
|
||||||
{
|
|
||||||
'type': 'enum',
|
|
||||||
'attr': 'type',
|
|
||||||
'name': 'Light source type',
|
|
||||||
'description': 'Specifies the behavior of the light source',
|
|
||||||
'default': 'POINT',
|
|
||||||
'items': [
|
|
||||||
('POINT', 'Point', 'Omnidirectional spot light source'),
|
|
||||||
('SUN', 'Dir', 'Constant direction parallel light source'),
|
|
||||||
('SPOT', 'Spot', 'Directional cone light source'),
|
|
||||||
('ENV', 'Env', 'Environment map light source'),
|
|
||||||
('AREA', 'Area', 'Diffuse area light source')
|
|
||||||
],
|
|
||||||
'save_in_preset': True
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'type': 'float',
|
'type': 'float',
|
||||||
'attr': 'samplingWeight',
|
'attr': 'samplingWeight',
|
||||||
|
|
|
@ -23,7 +23,7 @@ from .. import MitsubaAddon
|
||||||
|
|
||||||
from extensions_framework import declarative_property_group
|
from extensions_framework import declarative_property_group
|
||||||
from extensions_framework import util as efutil
|
from extensions_framework import util as efutil
|
||||||
from extensions_framework.validate import Logic_Operator
|
from extensions_framework.validate import Logic_Operator, Logic_OR as O
|
||||||
from ..properties.texture import TextureParameter
|
from ..properties.texture import TextureParameter
|
||||||
from ..export import ParamSet
|
from ..export import ParamSet
|
||||||
|
|
||||||
|
@ -53,14 +53,19 @@ class mitsuba_material(declarative_property_group):
|
||||||
|
|
||||||
controls = [
|
controls = [
|
||||||
'type',
|
'type',
|
||||||
]
|
'twosided'
|
||||||
|
]
|
||||||
|
|
||||||
|
visibility = {
|
||||||
|
'twosided' : { 'type' : O(['lambertian', 'phong', 'ward', 'mirror', 'roughmetal', 'microfacet', 'composite'])}
|
||||||
|
}
|
||||||
|
|
||||||
properties = [
|
properties = [
|
||||||
# Material Type Select
|
# Material Type Select
|
||||||
{
|
{
|
||||||
'type': 'enum',
|
'type': 'enum',
|
||||||
'attr': 'type',
|
'attr': 'type',
|
||||||
'name': 'Type',
|
'name': 'Material Type',
|
||||||
'description': 'Mitsuba material type',
|
'description': 'Mitsuba material type',
|
||||||
'default': 'lambertian',
|
'default': 'lambertian',
|
||||||
'items': [
|
'items': [
|
||||||
|
@ -76,6 +81,14 @@ class mitsuba_material(declarative_property_group):
|
||||||
('composite', 'Composite material', 'Allows creating mixtures of different materials')
|
('composite', 'Composite material', 'Allows creating mixtures of different materials')
|
||||||
],
|
],
|
||||||
'save_in_preset': True
|
'save_in_preset': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'bool',
|
||||||
|
'attr': 'twosided',
|
||||||
|
'name': 'Use two-sided shading',
|
||||||
|
'description': 'Use two-sided shading for this material? This only makes sense for non-transparent/translucent materials.',
|
||||||
|
'default': False,
|
||||||
|
'save_in_preset': True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ class TextureParameter(TextureParameterBase):
|
||||||
vis.update(self.get_extra_visibility())
|
vis.update(self.get_extra_visibility())
|
||||||
return vis
|
return vis
|
||||||
|
|
||||||
# colour for each material type. If the property name is
|
# color for each material type. If the property name is
|
||||||
# not set, then the color won't be changed.
|
# not set, then the color won't be changed.
|
||||||
master_color_map = {
|
master_color_map = {
|
||||||
'lambertian': 'reflectance',
|
'lambertian': 'reflectance',
|
||||||
|
|
|
@ -27,8 +27,8 @@ narrowui = 180
|
||||||
@MitsubaAddon.addon_register_class
|
@MitsubaAddon.addon_register_class
|
||||||
class lamps(bl_ui.properties_data_lamp.DataButtonsPanel, property_group_renderer, bpy.types.Panel):
|
class lamps(bl_ui.properties_data_lamp.DataButtonsPanel, property_group_renderer, bpy.types.Panel):
|
||||||
bl_label = 'Mitsuba Lamps'
|
bl_label = 'Mitsuba Lamps'
|
||||||
COMPAT_ENGINES = {'mitsuba'}
|
COMPAT_ENGINES = { MitsubaAddon.BL_IDNAME }
|
||||||
|
|
||||||
display_property_groups = [
|
display_property_groups = [
|
||||||
( ('lamp',), 'mitsuba_lamp' )
|
( ('lamp',), 'mitsuba_lamp' )
|
||||||
]
|
]
|
||||||
|
@ -41,14 +41,9 @@ class lamps(bl_ui.properties_data_lamp.DataButtonsPanel, property_group_renderer
|
||||||
wide_ui = context.region.width > narrowui
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
layout.prop(lamp.mitsuba_lamp, "type", expand=True)
|
layout.prop(lamp, "type", expand=True)
|
||||||
else:
|
else:
|
||||||
layout.prop(lamp.mitsuba_lamp, "type", text="")
|
layout.prop(lamp, "type", text="")
|
||||||
|
|
||||||
if lamp.mitsuba_lamp.type == 'ENV':
|
|
||||||
lamp.type = 'HEMI'
|
|
||||||
else:
|
|
||||||
lamp.type = lamp.mitsuba_lamp.type
|
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
|
|
|
@ -37,5 +37,10 @@ class main(mitsuba_material_base, bpy.types.Panel):
|
||||||
row.menu("MITSUBA_MT_presets_material", text=bpy.types.MITSUBA_MT_presets_material.bl_label)
|
row.menu("MITSUBA_MT_presets_material", text=bpy.types.MITSUBA_MT_presets_material.bl_label)
|
||||||
row.operator("mitsuba.preset_material_add", text="", icon="ZOOMIN")
|
row.operator("mitsuba.preset_material_add", text="", icon="ZOOMIN")
|
||||||
row.operator("mitsuba.preset_material_add", text="", icon="ZOOMOUT").remove_active = True
|
row.operator("mitsuba.preset_material_add", text="", icon="ZOOMOUT").remove_active = True
|
||||||
|
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.operator("mitsuba.convert_all_materials", icon='WORLD_DATA')
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.operator("mitsuba.convert_material", icon='MATERIAL_DATA')
|
||||||
|
|
||||||
super().draw(context)
|
super().draw(context)
|
||||||
|
|
|
@ -80,6 +80,14 @@ public:
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Possibly include emitted radiance if requested */
|
||||||
|
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
||||||
|
Li += its.Le(-ray.d);
|
||||||
|
|
||||||
|
/* Include radiance from a subsurface integrator if requested */
|
||||||
|
if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
|
||||||
|
Li += its.LoSub(scene, -ray.d);
|
||||||
|
|
||||||
const BSDF *bsdf = its.getBSDF(ray);
|
const BSDF *bsdf = its.getBSDF(ray);
|
||||||
|
|
||||||
if (EXPECT_NOT_TAKEN(!bsdf)) {
|
if (EXPECT_NOT_TAKEN(!bsdf)) {
|
||||||
|
@ -89,14 +97,6 @@ public:
|
||||||
return Li;
|
return Li;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Possibly include emitted radiance if requested */
|
|
||||||
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
|
||||||
Li += its.Le(-ray.d);
|
|
||||||
|
|
||||||
/* Include radiance from a subsurface integrator if requested */
|
|
||||||
if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
|
|
||||||
Li += its.LoSub(scene, -ray.d);
|
|
||||||
|
|
||||||
/* Leave here if direct illumination was not requested */
|
/* Leave here if direct illumination was not requested */
|
||||||
if (!(rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance))
|
if (!(rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance))
|
||||||
return Li;
|
return Li;
|
||||||
|
|
|
@ -179,16 +179,6 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BSDF *bsdf = its.getBSDF(ray);
|
|
||||||
if (!bsdf) {
|
|
||||||
/* Pass right through the surface (there is no BSDF) */
|
|
||||||
if (its.isMediumTransition())
|
|
||||||
rRec.medium = its.getTargetMedium(ray.d);
|
|
||||||
ray.setOrigin(its.p);
|
|
||||||
scene->rayIntersect(ray, its);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Possibly include emitted radiance if requested */
|
/* Possibly include emitted radiance if requested */
|
||||||
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
||||||
Li += pathThroughput * its.Le(-ray.d);
|
Li += pathThroughput * its.Le(-ray.d);
|
||||||
|
@ -200,6 +190,16 @@ public:
|
||||||
if (rRec.depth == m_maxDepth && m_maxDepth > 0)
|
if (rRec.depth == m_maxDepth && m_maxDepth > 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
const BSDF *bsdf = its.getBSDF(ray);
|
||||||
|
if (!bsdf) {
|
||||||
|
/* Pass right through the surface (there is no BSDF) */
|
||||||
|
if (its.isMediumTransition())
|
||||||
|
rRec.medium = its.getTargetMedium(ray.d);
|
||||||
|
ray.setOrigin(its.p);
|
||||||
|
scene->rayIntersect(ray, its);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
/* Luminaire sampling */
|
/* Luminaire sampling */
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
|
@ -134,6 +134,14 @@ public:
|
||||||
|
|
||||||
computeIntersection = true;
|
computeIntersection = true;
|
||||||
|
|
||||||
|
/* Possibly include emitted radiance if requested */
|
||||||
|
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
||||||
|
Li += pathThroughput * its.Le(-ray.d);
|
||||||
|
|
||||||
|
/* Include radiance from a subsurface integrator if requested */
|
||||||
|
if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
|
||||||
|
Li += pathThroughput * its.LoSub(rRec.scene, -ray.d);
|
||||||
|
|
||||||
const BSDF *bsdf = its.getBSDF(ray);
|
const BSDF *bsdf = its.getBSDF(ray);
|
||||||
|
|
||||||
if (!bsdf) {
|
if (!bsdf) {
|
||||||
|
@ -144,14 +152,6 @@ public:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Possibly include emitted radiance if requested */
|
|
||||||
if (its.isLuminaire() && (rRec.type & RadianceQueryRecord::EEmittedRadiance))
|
|
||||||
Li += pathThroughput * its.Le(-ray.d);
|
|
||||||
|
|
||||||
/* Include radiance from a subsurface integrator if requested */
|
|
||||||
if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
|
|
||||||
Li += pathThroughput * its.LoSub(rRec.scene, -ray.d);
|
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
/* Luminaire sampling */
|
/* Luminaire sampling */
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
Loading…
Reference in New Issue