# coding=utf-8
from ._commandbase import RadianceCommand
from ..datatype import RadiancePath, RadianceBoolFlag, RadianceValue
from ..parameters.genBsdf import GenbsdfParameters
from ..parameters.rtrace import RtraceParameters
from .getbbox import Getbbox
from .xform import Xform
import tempfile
import os
# TODO: 30thNov2016:
[docs]class GenBSDF(RadianceCommand):
output_file = RadiancePath(
'output_file',
'output BSDF file in XML format',
extension='.xml')
normal_orientation = RadianceValue(
'normal_orientation',
'the orientation of the normal for the BSDF geometry',
accepted_inputs=('+X', '+Y', '+Z', '-X', '-Y', '-Z',
'+x', '+y', '+z', '-x', '-y', '-z'))
prepare_geometry = RadianceBoolFlag('prepare_geometry',
'prepare geometry for BSDF')
def __init__(self, input_geometry=None, gen_bsdf_parameters=None,
grid_based_parameters=None, output_file=None, normal_orientation=None,
prepare_geometry=True):
RadianceCommand.__init__(self, executable_name='genBSDF.pl')
self.grid_based_parameters = grid_based_parameters
"""The input for this attribute must be an instance of Grid based parameters"""
self.gen_bsdf_parameters = gen_bsdf_parameters
"""These are parameters specific to genBsdf such as sampling, geometry dimensions
etc."""
self.input_geometry = input_geometry
"""Rad or mgf files that are inputs for genBSDF"""
self.output_file = output_file
"""Path name for the XML file created by genBSDF"""
self.normal_orientation = normal_orientation
"""Direction of the normal surface for the overall input geometry"""
self.prepare_geometry = prepare_geometry
"""A boolean value to decide if the input geometry needs to be translated and
rotated before being sent as input to genBSDf"""
@property
def input_geometry(self):
"""Get and set scene files."""
return self.__input_geometry
@input_geometry.setter
def input_geometry(self, files):
if files:
self.__input_geometry = [os.path.normpath(f) for f in files]
else:
self.__input_geometry = None
@property
def gen_bsdf_parameters(self):
"""Get and set gen_bsdf_parameters."""
return self.__gen_bsdf_parameters
@gen_bsdf_parameters.setter
def gen_bsdf_parameters(self, gen_bsdf_param):
self.__gen_bsdf_parameters = gen_bsdf_param if gen_bsdf_param is not None \
else GenbsdfParameters()
assert hasattr(self.gen_bsdf_parameters, "isRadianceParameters"), \
"input gen_bsdf_parameters is not a valid parameters type."
@property
def grid_based_parameters(self):
return self.__grid_based_parameters
@grid_based_parameters.setter
def grid_based_parameters(self, grid_based_parameters):
if grid_based_parameters:
assert isinstance(grid_based_parameters, RtraceParameters),\
'The input for rcontribOptions should be an instance of '\
'Gridbased parameters'
self.__grid_based_parameters = grid_based_parameters
else:
self.__grid_based_parameters = None
[docs] def prepare_geometry_for_bsdf(self):
"""A method that will translate and rotate the model properly for genBSDF.
"""
assert self.input_geometry,\
'The files required for input_geometry have not been specified'
assert self.normal_orientation._value, \
'The input required for normal_orientation has not been specified'
temp_for_getbox = tempfile.mktemp(prefix='getb')
get_b = Getbbox()
get_b.rad_files = self.input_geometry
get_b.output_file = temp_for_getbox
get_b.header_suppress = True
get_b.execute()
with open(temp_for_getbox) as get_box_data:
get_box_value = get_box_data.read().strip().split()
xMin, xMax, yMin, yMax, zMin, zMax = map(float, get_box_value)
os.remove(temp_for_getbox)
temp_for_xform = tempfile.mktemp(prefix='xform')
xTr, yTr, zTr = 0 - xMin, 0 - yMin, 0 - zMin
zTr += -0.001
rotation_dict = {'+x': '-ry -90', '-x': '-ry 90',
'+y': '-rx 90', '-y': '-rx -90',
'+z': '', '-z': ''}
rotation_normal = self.normal_orientation._value.lower()
rot_tr = rotation_dict[rotation_normal]
xfr = Xform()
xfr.rad_file = [os.path.abspath(geo) for geo in self.input_geometry]
xfr.transforms = "-t %s %s %s %s" % (xTr, yTr, zTr, rot_tr)
xfr.output_file = temp_for_xform
xfr.execute()
return temp_for_xform
[docs] def to_rad_string(self, relative_path=False):
exe_name = 'genBSDF.pl' if os.name == 'nt' else 'genBSDF'
cmd_path = self.normspace(os.path.join(self.radbin_path, exe_name))
perl_path = self.normspace(self.perl_exe_path) if os.name == 'nt' else ''
if os.name == 'nt':
if not perl_path:
raise IOError('Failed to find perl installation.\n'
'genBSDF.pl needs perl to run successfully.')
else:
cmd_path = "%s %s" % (perl_path, cmd_path)
if self.grid_based_parameters:
if os.name == 'nt':
grid_based = '-r "%s"' % self.grid_based_parameters.to_rad_string()
else:
grid_based = "-r '%s'" % self.grid_based_parameters.to_rad_string()
else:
grid_based = ''
if self.gen_bsdf_parameters:
gen_bsdf_para = self.gen_bsdf_parameters.to_rad_string()
else:
gen_bsdf_para = ''
if self.output_file and self.output_file._value:
output_file = "> %s" % self.output_file.to_rad_string()
else:
output_file = ''
file_path = " ".join(self.normspace(f) for f in self.input_geometry)
command_string = "%s %s %s %s %s" % (cmd_path, gen_bsdf_para,
grid_based, file_path, output_file)
return command_string
@property
def input_files(self):
return self.input_geometry
[docs] def execute(self):
if self.prepare_geometry._value:
self.input_geometry = [self.prepare_geometry_for_bsdf()]
RadianceCommand.execute(self)