Source code for honeybee_plus.radiance.material.trans

"""Radiance Trans Material.

http://radsite.lbl.gov/radiance/refer/ray.html#Trans
https://radiance-online.org//community/workshops/2010-freiburg/PDF/DavidMead.pdf
"""
from .materialbase import RadianceMaterial
from ..datatype import RadianceNumber


[docs]class Trans(RadianceMaterial): """Radiance translucent material.""" r_reflectance = RadianceNumber('r_reflectance', num_type=float, valid_range=(0, 1)) g_reflectance = RadianceNumber('g_reflectance', num_type=float, valid_range=(0, 1)) b_reflectance = RadianceNumber('b_reflectance', num_type=float, valid_range=(0, 1)) specularity = RadianceNumber('specularity', num_type=float, valid_range=(0, 1)) roughness = RadianceNumber('roughness', num_type=float, valid_range=(0, 1)) transmitted_diff = \ RadianceNumber('transmitted_diff', num_type=float, valid_range=(0, 1)) transmitted_spec = \ RadianceNumber('transmitted_spec', num_type=float, valid_range=(0, 1)) def __init__(self, name, r_reflectance=0.0, g_reflectance=0.0, b_reflectance=0.0, specularity=0.0, roughness=0.0, transmitted_diff=0.0, transmitted_spec=0.0, modifier="void"): """Create trans material. Attributes: name: Material name as a string. Do not use white space and special character. r_reflectance: Reflectance for red. The value should be between 0 and 1 (Default: 0). g_reflectance: Reflectance for green. The value should be between 0 and 1 (Default: 0). b_reflectance: Reflectance for blue. The value should be between 0 and 1 (Default: 0). specularity: Fraction of specularity. Specularity fractions greater than 0.1 are not realistic (Default: 0). roughness: Roughness is specified as the rms slope of surface facets. A value of 0 corresponds to a perfectly smooth surface, and a value of 1 would be a very rough surface. Roughness values greater than 0.2 are not very realistic. (Default: 0). transmitted_diff: The transmitted diffuse component is the fraction of transmitted light that is transmitted diffusely in as scattering fashion. transmitted_spec: The transmitted specular component is the fraction of transmitted light that is not diffusely scattered. modifier: Material modifier (Default: "void"). """ RadianceMaterial.__init__(self, name, modifier=modifier) self.r_reflectance = r_reflectance """Reflectance for red. The value should be between 0 and 1 (Default: 0).""" self.g_reflectance = g_reflectance """Reflectance for green. The value should be between 0 and 1 (Default: 0).""" self.b_reflectance = b_reflectance """Reflectance for blue. The value should be between 0 and 1 (Default: 0).""" self.specularity = specularity """Fraction of specularity. Specularity fractions greater than 0.1 are not realistic (Default: 0).""" self.roughness = roughness """Roughness is specified as the rms slope of surface facets. A value of 0 corresponds to a perfectly smooth surface, and a value of 1 would be a very rough surface. Roughness values greater than 0.2 are not very realistic. (Default: 0).""" self.transmitted_diff = transmitted_diff self.transmitted_spec = transmitted_spec self._update_values()
[docs] @classmethod def from_reflected_spacularity( cls, name, r_reflectance=0.0, g_reflectance=0.0, b_reflectance=0.0, reflected_spacularity=0.0, roughness=0.0, transmitted_diff=0.0, transmitted_spec=0.0, modifier="void"): """Create trans material from reflected spacularityself. See: https://radiance-online.org//community/workshops/2010-freiburg/PDF/DavidMead.pdf Attributes: name: Material name as a string. Do not use white space and special character. r_reflectance: Reflectance for red. The value should be between 0 and 1 (Default: 0). g_reflectance: Reflectance for green. The value should be between 0 and 1 (Default: 0). b_reflectance: Reflectance for blue. The value should be between 0 and 1 (Default: 0). reflected_spacularity: Fraction of reflected spacular. The reflected specularity of common uncoated glass is around .06, Matte = min 0, Satin = suggested max 0.07 (Default: 0). roughness: Roughness is specified as the rms slope of surface facets. A value of 0 corresponds to a perfectly smooth surface, and a value of 1 would be a very rough surface. Roughness values greater than 0.2 are not very realistic. (Default: 0). transmitted_diff: The transmitted diffuse component is the fraction of transmitted light that is transmitted diffusely in as scattering fashion. transmitted_spec: The transmitted specular component is the fraction of transmitted light that is not diffusely scattered. modifier: Material modifier (Default: "void"). """ cr, cg, cb, rs, roughness, td, ts = \ r_reflectance, g_reflectance, b_reflectance, reflected_spacularity, \ roughness, transmitted_diff, transmitted_spec rd = (0.265 * cr + 0.670 * cg + 0.065 * cb) absorb = 1 - td - ts - rd - rs if absorb < 0: summ = td + ts + rd + rs msg = 'Sum of Diffuse Transmission (%.3f), Specular Transmission (%.3f),' \ 'Specular Reflection (%.3f) and Diffuse Reflection (%.3f) cannot be ' \ 'more than 1 (%.3f).' % (td, ts, rs, rd, summ) raise ValueError(msg) # calculate the material try: a7 = ts / (td + ts) except ZeroDivisionError: a7 = 0 try: a6 = (td + ts) / (rd + td + ts) except ZeroDivisionError: a6 = 0 a5 = roughness a4 = rs a3 = cb / ((1 - rs) * (1 - a6)) a2 = cg / ((1 - rs) * (1 - a6)) a1 = cr / ((1 - rs) * (1 - a6)) if a3 > 1 or a2 > 1 or a1 > 1: raise ValueError( 'This material is physically impossible to create!\n' 'You need to adjust the inputs for diffuse reflectance values.') return cls(name, a1, a2, a3, a4, a5, a6, a7, modifier)
[docs] @classmethod def from_string(cls, material_string, modifier=None): """Create a Radiance material from a string. If the material has a modifier the modifier material should also be partof the string or should be provided using modifier argument. """ modifier, name, base_material_data = cls._analyze_string_input( cls.__name__.lower(), material_string, modifier) _, _, _, r_reflectance, g_reflectance, b_reflectance, specularity, \ roughness, transmitted_diff, transmitted_spec = base_material_data return cls(name, r_reflectance, g_reflectance, b_reflectance, specularity, roughness, transmitted_diff, transmitted_spec, modifier)
[docs] @classmethod def from_json(cls, rec_json): """Make radiance material from json { "modifier": {} or void, // Material modifier "type": "trans", // Material type "name": "", // Material Name "r_reflectance": float, // Reflectance for red "g_reflectance": float, // Reflectance for green "b_reflectance": float, // Reflectance for blue "specularity": float, // Material specularity "roughness": float, // Material roughness "transmitted_diff": float, "transmitted_spec": float } """ modifier = cls._analyze_json_input(cls.__name__.lower(), rec_json) return cls(name=rec_json["name"], r_reflectance=rec_json["r_reflectance"], g_reflectance=rec_json["g_reflectance"], b_reflectance=rec_json["b_reflectance"], specularity=rec_json["specularity"], roughness=rec_json["roughness"], transmitted_diff=rec_json["transmitted_diff"], transmitted_spec=rec_json["transmitted_spec"], modifier=modifier)
[docs] @classmethod def by_single_reflect_value(cls, name, rgb_reflectance=0.0, specularity=0.0, roughness=0.0, transmitted_diff=0.0, transmitted_spec=0.0, modifier="void"): """Create trans material with single reflectance value. Attributes: name: Material name as a string. Do not use white space and special character rgb_reflectance: Reflectance for red, green and blue. The value should be between 0 and 1 (Default: 0). specularity: Fraction of specularity. Specularity fractions greater than 0.1 are not realistic (Default: 0). roughness: Roughness is specified as the rms slope of surface facets. A value of 0 corresponds to a perfectly smooth surface, and a value of 1 would be a very rough surface. Roughness values greater than 0.2 are not very realistic. (Default: 0). transmitted_diff: The transmitted diffuse component is the fraction of transmitted light that is transmitted diffusely in as scattering fashion. transmitted_spec: The transmitted specular component is the fraction of transmitted light that is not diffusely scattered. modifier: Material modifier (Default: "void"). Usage: wallMaterial = trans.by_single_reflect_value("generic wall", .55) print(wallMaterial) """ return cls(name, r_reflectance=rgb_reflectance, g_reflectance=rgb_reflectance, b_reflectance=rgb_reflectance, specularity=specularity, roughness=roughness, transmitted_diff=transmitted_diff, transmitted_spec=transmitted_spec, modifier=modifier)
@property def average_reflectance(self): """Calculate average reflectance of trans material.""" return (0.265 * self.r_reflectance + 0.670 * self.g_reflectance + 0.065 * self.b_reflectance) * (1 - self.specularity) + self.specularity @property def specular_sampling_threshold(self): """Specular sampling threshold (-st).""" return self.transmitted_diff * self.transmitted_spec * \ (1 - (0.265 * self.r_reflectance + 0.670 * self.g_reflectance + 0.065 * self.b_reflectance)) * self.specularity def _update_values(self): "update value dictionaries." self._values[2] = [ self.r_reflectance, self.g_reflectance, self.b_reflectance, self.specularity, self.roughness, self.transmitted_diff, self.transmitted_spec ]
[docs] def to_json(self): """Translate radiance material to json { "type": "trans", // Material type "name": "", // Material Name "r_reflectance": float, // Reflectance for red "g_reflectance": float, // Reflectance for green "b_reflectance": float, // Reflectance for blue "specularity": float, // Material specularity "roughness": float, // Material roughness "transmitted_diff": float, "transmitted_spec": float } """ return { "modifier": self.modifier.to_json(), "type": "trans", "name": self.name, "r_reflectance": self.r_reflectance, "g_reflectance": self.g_reflectance, "b_reflectance": self.b_reflectance, "specularity": self.specularity, "roughness": self.roughness, "transmitted_diff": self.transmitted_diff, "transmitted_spec": self.transmitted_spec }