mitsuba/data/blender/mitsuba/properties/texture.py

496 lines
12 KiB
Python

# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
from .. import MitsubaAddon
from extensions_framework import declarative_property_group
from extensions_framework import util as efutil
from extensions_framework.validate import Logic_OR as O
from mitsuba.export import ParamSet
#------------------------------------------------------------------------------
# Texture property group construction helpers
#------------------------------------------------------------------------------
class TextureParameterBase(object):
attr = None
name = None
default = (0.8, 0.8, 0.8)
min = 0.0
max = 1.0
texture_collection = 'texture_slots'
controls = None
visibility = None
properties = None
def __init__(self, attr, name, description, default=None, min=None, max=None):
self.attr = attr
self.name = name
self.description = description
if default is not None:
self.default = default
if min is not None:
self.min = min
if max is not None:
self.max = max
self.controls = self.get_controls()
self.visibility = self.get_visibility()
self.properties = self.get_properties()
def texture_collection_finder(self):
return lambda s,c: s.object.material_slots[s.object.active_material_index].material
def texture_slot_set_attr(self):
def set_attr(s,c):
if type(c).__name__ == 'mitsuba_material':
return getattr(c, 'mitsuba_mat_%s'%c.type)
else:
return getattr(c, 'mitsuba_tex_%s'%c.type)
return set_attr
def get_controls(self):
'''
Subclasses can override this for their own needs
'''
return []
def get_visibility(self):
'''
Subclasses can override this for their own needs
'''
return {}
def get_properties(self):
'''
Subclasses can override this for their own needs
'''
return []
def get_extra_controls(self):
'''
Subclasses can override this for their own needs
'''
return []
def get_extra_visibility(self):
'''
Subclasses can override this for their own needs
'''
return {}
def get_extra_properties(self):
'''
Subclasses can override this for their own needs
'''
return []
def get_params(self, context):
'''
Return a Mitsuba ParamSet of the properties
defined in this Texture, getting parameters
from property group 'context'
'''
return ParamSet()
class TextureParameter(TextureParameterBase):
def get_controls(self):
return [
[ 0.9, [0.375,'%s_colorlabel' % self.attr, '%s_color' % self.attr], '%s_usetexture' % self.attr ],
'%s_texture' % self.attr
] + self.get_extra_controls()
def get_visibility(self):
vis = {
'%s_texture' % self.attr: { '%s_usetexture' % self.attr: True },
}
vis.update(self.get_extra_visibility())
return vis
# color for each material type. If the property name is
# not set, then the color won't be changed.
master_color_map = {
'lambertian': 'reflectance',
'difftrans': 'transmittance',
'ward': 'diffuseReflectance',
'phong': 'diffuseReflectance',
'microfacet': 'diffuseReflectance',
'mirror': 'specularReflectance',
'dielectric': 'specularReflectance',
'roughglass': 'specularReflectance',
'roughmetal': 'specularReflectance'
}
def get_properties(self):
return [
{
'attr': self.attr,
'type': 'string',
'default': 'mts_color_texture'
},
{
'attr': '%s_usetexture' % self.attr,
'type': 'bool',
'name': 'T',
'description': 'Textured %s' % self.name,
'default': False,
'toggle': True,
'save_in_preset': True
},
{
'type': 'text',
'attr': '%s_colorlabel' % self.attr,
'name': self.name
},
{
'type': 'float_vector',
'attr': '%s_color' % self.attr,
'name': '', #self.name,
'description': self.description,
'default': self.default,
'min': self.min,
'soft_min': self.min,
'max': self.max,
'soft_max': self.max,
'subtype': 'COLOR',
'save_in_preset': True
},
{
'attr': '%s_texturename' % self.attr,
'type': 'string',
'name': '%s_texturename' % self.attr,
'description': '%s Texture' % self.name,
'save_in_preset': True
},
{
'type': 'prop_search',
'attr': '%s_texture' % self.attr,
'src': self.texture_collection_finder(),
'src_attr': self.texture_collection,
'trg': self.texture_slot_set_attr(),
'trg_attr': '%s_texturename' % self.attr,
'name': self.name
}
] + self.get_extra_properties()
def get_params(self, context):
params = ParamSet()
if hasattr(context, '%s_usetexture' % self.attr) \
and getattr(context, '%s_usetexture' % self.attr):
params.add_reference('texture', self.attr, getattr(context, '%s_texturename' % self.attr))
else:
params.add_color(
self.attr,
getattr(context, '%s_color' % self.attr)
)
return params
@MitsubaAddon.addon_register_class
class mitsuba_texture(declarative_property_group):
'''
Storage class for Mitsuba Texture settings.
This class will be instantiated within a Blender Texture
object.
'''
ef_attach_to = ['Texture']
controls = [
'type'
]
properties = [
{
'attr': 'type',
'name': 'Texture type',
'type': 'enum',
'items': [
('ldrtexture', 'Bitmap', 'Low dynamic-range texture'),
('checkerboard', 'Checkerboard', 'Procedural checkerboard texture'),
('gridtexture', 'Grid texture', 'Procedural grid texture')
],
'default' : 'ldrtexture',
'save_in_preset': True
},
]
def get_params(self):
if hasattr(self, 'mitsuba_tex_%s' % self.type):
mts_texture = getattr(self, 'mitsuba_tex_%s' % self.type)
params = mts_texture.get_params()
params.update(self.mitsuba_tex_mapping.get_params())
return params
else:
return ParamSet()
@MitsubaAddon.addon_register_class
class mitsuba_tex_mapping(declarative_property_group):
ef_attach_to = ['mitsuba_texture']
controls = [
['uscale', 'vscale'],
['uoffset', 'voffset']
]
properties = [
{
'attr': 'uscale',
'type': 'float',
'name': 'U Scale',
'default': 1.0,
'min': -100.0,
'soft_min': -100.0,
'max': 100.0,
'soft_max': 100.0,
'save_in_preset': True
},
{
'attr': 'vscale',
'type': 'float',
'name': 'V Scale',
'default': 1.0,
'min': -100.0,
'soft_min': -100.0,
'max': 100.0,
'soft_max': 100.0,
'save_in_preset': True
},
{
'attr': 'uoffset',
'type': 'float',
'name': 'U Offset',
'default': 0.0,
'min': -100.0,
'soft_min': -100.0,
'max': 100.0,
'soft_max': 100.0,
'save_in_preset': True
},
{
'attr': 'voffset',
'type': 'float',
'name': 'V Offset',
'default': 0.0,
'min': -100.0,
'soft_min': -100.0,
'max': 100.0,
'soft_max': 100.0,
'save_in_preset': True
}
]
def get_params(self):
mapping_params = ParamSet()
mapping_params.add_float('uscale', self.uscale)
mapping_params.add_float('vscale', self.vscale)
mapping_params.add_float('uoffset', self.uoffset)
mapping_params.add_float('voffset', self.voffset)
return mapping_params
@MitsubaAddon.addon_register_class
class mitsuba_tex_ldrtexture(declarative_property_group):
ef_attach_to = ['mitsuba_texture']
controls = [
'filename',
'wrapMode',
'filterType',
'maxAnisotropy',
['srgb', 'gamma']
]
visibility = {
'maxAnisotropy': { 'filterType': 'ewa' },
'gamma': { 'srgb': False }
}
properties = [
{
'type': 'string',
'subtype': 'FILE_PATH',
'attr': 'filename',
'description' : 'Path to a PNG/JPG/TGA/BMP file',
'name': 'File Name',
'save_in_preset': True
},
{
'type': 'enum',
'attr': 'filterType',
'name': 'Filter type',
'description' : 'Specifies the type of texture filtering',
'items': [
('isotropic', 'Isotropic (Trilinear MipMap)', 'isotropic'),
('ewa', 'Anisotropic (EWA Filtering)', 'ewa')
],
'default' : 'ewa',
'save_in_preset': True
},
{
'type': 'bool',
'attr': 'srgb',
'name': 'sRGB',
'description' : 'Is the texture stored in sRGB color space?',
'default': True,
'save_in_preset': True
},
{
'type': 'float',
'attr': 'gamma',
'name': 'Gamma',
'description' : 'Specifies the texture gamma value',
'default': 2.2,
'min': 0.01,
'soft_min': 0.01,
'max': 6.0,
'soft_max': 6.0,
'save_in_preset': True
},
{
'type': 'float',
'description' : 'Maximum allowed anisotropy when using the EWA filter',
'attr': 'maxAnisotropy',
'name': 'Max. Anisotropy',
'default': 8.0,
'save_in_preset': True
},
{
'type': 'enum',
'attr': 'wrapMode',
'name': 'Wrapping',
'description' : 'What should be done when encountering UV coordinates outside of the range [0,1]',
'items': [
('repeat', 'Repeat', 'repeat'),
('black', 'Black outside of [0, 1]', 'black'),
('white', 'White outside of [0, 1]', 'white'),
('clamp', 'Clamp to edges', 'clamp')
],
'save_in_preset': True
}
]
def get_params(self):
params = ParamSet()
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) \
.add_float('gamma', -1 if self.srgb else self.gamma)
return params
@MitsubaAddon.addon_register_class
class mitsuba_tex_checkerboard(declarative_property_group):
ef_attach_to = ['mitsuba_texture']
controls = [
'darkColor',
'brightColor'
]
properties = [
{
'attr': 'darkColor',
'type': 'float_vector',
'subtype': 'COLOR',
'name' : 'Dark color',
'description' : 'Color of the dark patches',
'default' : (0.2, 0.2, 0.2),
'min': 0.0,
'max': 1.0,
'save_in_preset': True
},
{
'attr': 'brightColor',
'type': 'float_vector',
'subtype': 'COLOR',
'description' : 'Color of the bright patches',
'name' : 'Bright color',
'default' : (0.4, 0.4, 0.4),
'min': 0.0,
'max': 1.0,
'save_in_preset': True
}
]
def get_params(self):
params = ParamSet()
params.add_color('darkColor', self.darkColor)
params.add_color('brightColor', self.brightColor)
return params
@MitsubaAddon.addon_register_class
class mitsuba_tex_gridtexture(declarative_property_group):
ef_attach_to = ['mitsuba_texture']
controls = [
'darkColor',
'brightColor',
'lineWidth'
]
properties = [
{
'attr': 'darkColor',
'type': 'float_vector',
'subtype': 'COLOR',
'name' : 'Dark color',
'description' : 'Color of the dark patches',
'default' : (0.2, 0.2, 0.2),
'min': 0.0,
'max': 1.0,
'save_in_preset': True
},
{
'attr': 'brightColor',
'type': 'float_vector',
'subtype': 'COLOR',
'description' : 'Color of the bright patches',
'name' : 'Bright color',
'default' : (0.4, 0.4, 0.4),
'min': 0.0,
'max': 1.0,
'save_in_preset': True
},
{
'attr': 'lineWidth',
'type': 'float',
'description' : 'Size of the grid lines in UV space',
'name' : 'Line width',
'default' : 0.01,
'min': 0.0,
'max': 1.0,
'save_in_preset': True
}
]
def get_params(self):
params = ParamSet()
params.add_color('darkColor', self.darkColor)
params.add_color('brightColor', self.brightColor)
params.add_float('lineWidth', self.lineWidth)
return params