honeybee-radiance 1.66.190__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of honeybee-radiance might be problematic. Click here for more details.

Files changed (152) hide show
  1. honeybee_radiance/__init__.py +11 -0
  2. honeybee_radiance/__main__.py +4 -0
  3. honeybee_radiance/_extend_honeybee.py +93 -0
  4. honeybee_radiance/cli/__init__.py +88 -0
  5. honeybee_radiance/cli/dc.py +400 -0
  6. honeybee_radiance/cli/edit.py +529 -0
  7. honeybee_radiance/cli/glare.py +118 -0
  8. honeybee_radiance/cli/grid.py +859 -0
  9. honeybee_radiance/cli/lib.py +458 -0
  10. honeybee_radiance/cli/modifier.py +133 -0
  11. honeybee_radiance/cli/mtx.py +226 -0
  12. honeybee_radiance/cli/multiphase.py +1034 -0
  13. honeybee_radiance/cli/octree.py +640 -0
  14. honeybee_radiance/cli/postprocess.py +1186 -0
  15. honeybee_radiance/cli/raytrace.py +219 -0
  16. honeybee_radiance/cli/rpict.py +125 -0
  17. honeybee_radiance/cli/schedule.py +56 -0
  18. honeybee_radiance/cli/setconfig.py +63 -0
  19. honeybee_radiance/cli/sky.py +545 -0
  20. honeybee_radiance/cli/study.py +66 -0
  21. honeybee_radiance/cli/sunpath.py +331 -0
  22. honeybee_radiance/cli/threephase.py +255 -0
  23. honeybee_radiance/cli/translate.py +400 -0
  24. honeybee_radiance/cli/util.py +121 -0
  25. honeybee_radiance/cli/view.py +261 -0
  26. honeybee_radiance/cli/viewfactor.py +347 -0
  27. honeybee_radiance/config.json +6 -0
  28. honeybee_radiance/config.py +427 -0
  29. honeybee_radiance/dictutil.py +50 -0
  30. honeybee_radiance/dynamic/__init__.py +5 -0
  31. honeybee_radiance/dynamic/group.py +479 -0
  32. honeybee_radiance/dynamic/multiphase.py +557 -0
  33. honeybee_radiance/dynamic/state.py +718 -0
  34. honeybee_radiance/dynamic/stategeo.py +352 -0
  35. honeybee_radiance/geometry/__init__.py +13 -0
  36. honeybee_radiance/geometry/bubble.py +42 -0
  37. honeybee_radiance/geometry/cone.py +215 -0
  38. honeybee_radiance/geometry/cup.py +54 -0
  39. honeybee_radiance/geometry/cylinder.py +197 -0
  40. honeybee_radiance/geometry/geometrybase.py +37 -0
  41. honeybee_radiance/geometry/instance.py +40 -0
  42. honeybee_radiance/geometry/mesh.py +38 -0
  43. honeybee_radiance/geometry/polygon.py +174 -0
  44. honeybee_radiance/geometry/ring.py +214 -0
  45. honeybee_radiance/geometry/source.py +182 -0
  46. honeybee_radiance/geometry/sphere.py +178 -0
  47. honeybee_radiance/geometry/tube.py +46 -0
  48. honeybee_radiance/lib/__init__.py +1 -0
  49. honeybee_radiance/lib/_loadmodifiers.py +72 -0
  50. honeybee_radiance/lib/_loadmodifiersets.py +69 -0
  51. honeybee_radiance/lib/modifiers.py +58 -0
  52. honeybee_radiance/lib/modifiersets.py +63 -0
  53. honeybee_radiance/lightpath.py +204 -0
  54. honeybee_radiance/lightsource/__init__.py +1 -0
  55. honeybee_radiance/lightsource/_gendaylit.py +479 -0
  56. honeybee_radiance/lightsource/dictutil.py +49 -0
  57. honeybee_radiance/lightsource/ground.py +160 -0
  58. honeybee_radiance/lightsource/sky/__init__.py +7 -0
  59. honeybee_radiance/lightsource/sky/_skybase.py +177 -0
  60. honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
  61. honeybee_radiance/lightsource/sky/cie.py +378 -0
  62. honeybee_radiance/lightsource/sky/climatebased.py +501 -0
  63. honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
  64. honeybee_radiance/lightsource/sky/skydome.py +113 -0
  65. honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
  66. honeybee_radiance/lightsource/sky/strutil.py +34 -0
  67. honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
  68. honeybee_radiance/lightsource/sunpath.py +247 -0
  69. honeybee_radiance/modifier/__init__.py +3 -0
  70. honeybee_radiance/modifier/material/__init__.py +30 -0
  71. honeybee_radiance/modifier/material/absdf.py +477 -0
  72. honeybee_radiance/modifier/material/antimatter.py +54 -0
  73. honeybee_radiance/modifier/material/ashik2.py +51 -0
  74. honeybee_radiance/modifier/material/brtdfunc.py +81 -0
  75. honeybee_radiance/modifier/material/bsdf.py +292 -0
  76. honeybee_radiance/modifier/material/dielectric.py +53 -0
  77. honeybee_radiance/modifier/material/glass.py +431 -0
  78. honeybee_radiance/modifier/material/glow.py +246 -0
  79. honeybee_radiance/modifier/material/illum.py +51 -0
  80. honeybee_radiance/modifier/material/interface.py +49 -0
  81. honeybee_radiance/modifier/material/light.py +206 -0
  82. honeybee_radiance/modifier/material/materialbase.py +36 -0
  83. honeybee_radiance/modifier/material/metal.py +167 -0
  84. honeybee_radiance/modifier/material/metal2.py +41 -0
  85. honeybee_radiance/modifier/material/metdata.py +41 -0
  86. honeybee_radiance/modifier/material/metfunc.py +41 -0
  87. honeybee_radiance/modifier/material/mirror.py +340 -0
  88. honeybee_radiance/modifier/material/mist.py +86 -0
  89. honeybee_radiance/modifier/material/plasdata.py +58 -0
  90. honeybee_radiance/modifier/material/plasfunc.py +59 -0
  91. honeybee_radiance/modifier/material/plastic.py +354 -0
  92. honeybee_radiance/modifier/material/plastic2.py +58 -0
  93. honeybee_radiance/modifier/material/prism1.py +57 -0
  94. honeybee_radiance/modifier/material/prism2.py +48 -0
  95. honeybee_radiance/modifier/material/spotlight.py +50 -0
  96. honeybee_radiance/modifier/material/trans.py +518 -0
  97. honeybee_radiance/modifier/material/trans2.py +49 -0
  98. honeybee_radiance/modifier/material/transdata.py +50 -0
  99. honeybee_radiance/modifier/material/transfunc.py +53 -0
  100. honeybee_radiance/modifier/mixture/__init__.py +6 -0
  101. honeybee_radiance/modifier/mixture/mixdata.py +49 -0
  102. honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
  103. honeybee_radiance/modifier/mixture/mixpict.py +52 -0
  104. honeybee_radiance/modifier/mixture/mixtext.py +66 -0
  105. honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
  106. honeybee_radiance/modifier/modifierbase.py +40 -0
  107. honeybee_radiance/modifier/pattern/__init__.py +9 -0
  108. honeybee_radiance/modifier/pattern/brightdata.py +49 -0
  109. honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
  110. honeybee_radiance/modifier/pattern/brighttext.py +81 -0
  111. honeybee_radiance/modifier/pattern/colordata.py +56 -0
  112. honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
  113. honeybee_radiance/modifier/pattern/colorpict.py +54 -0
  114. honeybee_radiance/modifier/pattern/colortext.py +73 -0
  115. honeybee_radiance/modifier/pattern/patternbase.py +34 -0
  116. honeybee_radiance/modifier/texture/__init__.py +4 -0
  117. honeybee_radiance/modifier/texture/texdata.py +29 -0
  118. honeybee_radiance/modifier/texture/texfunc.py +26 -0
  119. honeybee_radiance/modifier/texture/texturebase.py +27 -0
  120. honeybee_radiance/modifierset.py +1091 -0
  121. honeybee_radiance/mutil.py +60 -0
  122. honeybee_radiance/postprocess/__init__.py +1 -0
  123. honeybee_radiance/postprocess/annual.py +108 -0
  124. honeybee_radiance/postprocess/annualdaylight.py +425 -0
  125. honeybee_radiance/postprocess/annualglare.py +201 -0
  126. honeybee_radiance/postprocess/annualirradiance.py +187 -0
  127. honeybee_radiance/postprocess/electriclight.py +119 -0
  128. honeybee_radiance/postprocess/en17037.py +261 -0
  129. honeybee_radiance/postprocess/leed.py +304 -0
  130. honeybee_radiance/postprocess/solartracking.py +90 -0
  131. honeybee_radiance/primitive.py +554 -0
  132. honeybee_radiance/properties/__init__.py +1 -0
  133. honeybee_radiance/properties/_base.py +390 -0
  134. honeybee_radiance/properties/aperture.py +197 -0
  135. honeybee_radiance/properties/door.py +198 -0
  136. honeybee_radiance/properties/face.py +123 -0
  137. honeybee_radiance/properties/model.py +1291 -0
  138. honeybee_radiance/properties/room.py +490 -0
  139. honeybee_radiance/properties/shade.py +186 -0
  140. honeybee_radiance/properties/shademesh.py +116 -0
  141. honeybee_radiance/putil.py +44 -0
  142. honeybee_radiance/reader.py +214 -0
  143. honeybee_radiance/sensor.py +166 -0
  144. honeybee_radiance/sensorgrid.py +1008 -0
  145. honeybee_radiance/view.py +1101 -0
  146. honeybee_radiance/writer.py +951 -0
  147. honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
  148. honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
  149. honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
  150. honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
  151. honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
  152. honeybee_radiance-1.66.190.dist-info/top_level.txt +1 -0
@@ -0,0 +1,477 @@
1
+ """Radiance aBSDF Material.
2
+
3
+ https://floyd.lbl.gov/radiance/refer/ray.html#BSDF
4
+ """
5
+ from __future__ import division
6
+
7
+ import os
8
+ from .materialbase import Material
9
+ import honeybee.typing as typing
10
+ from honeybee.config import folders
11
+ import ladybug_geometry.geometry3d.pointvector as pv
12
+
13
+
14
+ class aBSDF(Material):
15
+ """Radiance aBSDF material.
16
+
17
+ From source code: https://github.com/LBNL-ETA/Radiance/blob/master/src/rt/m_bsdf.c
18
+ "For the MAT_ABSDF type, we check for a strong "through" component. Such a component
19
+ will cause direct rays to pass through unscattered. A separate test prevents
20
+ over-counting by dropping samples that are too close to this "through" direction.
21
+ BSDFs with such a through direction will also have a view component, meaning they are
22
+ somewhat see-through. A MAT_BSDF type with zero thickness behaves the same as a
23
+ MAT_ABSDF type with no strong through component."
24
+
25
+ .. code-block:: shell
26
+
27
+ mod aBSDF id
28
+ 5+ BSDFfile ux uy uz funcfile transform
29
+ 0
30
+ 0|3|6|9
31
+ rfdif gfdif bfdif
32
+ rbdif gbdif bbdif
33
+ rtdif gtdif btdif
34
+
35
+ The __init__ method sets additional diffuse reflectance for front and back as well
36
+ as additional diffuse transmittance to 0. You can setup these values by using their
37
+ respective property.
38
+
39
+ Args:
40
+ bsdf_file: Path to an xml file. Data will NOT be cached in memory.
41
+ identifier: Text string for a unique Material ID. Must not contain spaces
42
+ or special characters. This will be used to identify the object across
43
+ a model and in the exported Radiance files. If None, the identifier
44
+ will be derived from the bsdf_file name. (Default: None)
45
+ up_orientation: (x, y ,z) vector that sets the hemisphere that the
46
+ BSDF material faces. For materials that are symmetrical about
47
+ the face plane (like non-angled venetian blinds), this can be
48
+ any vector that is not perfectly normal to the face. For
49
+ asymmetrical materials like angled venetian blinds, this variable
50
+ should be coordinated with the direction the face are facing.
51
+ The default is set to (0.01, 0.01, 1.00), which should hopefully
52
+ not be perpendicular to any typical face.
53
+ modifier: Material modifier (Default: None).
54
+ function_file: Optional input for function file (Default: .).
55
+ transform: Optional transform input to to scale the thickness and reorient
56
+ the up vector (default: None).
57
+ angle_basis: BSDF file angle basis. If not provided by user honeybee tries to
58
+ find it by parsing BSDF file itself.
59
+ dependencies: A list of primitives that this primitive depends on. This
60
+ argument is only useful for defining advanced primitives where the
61
+ primitive is defined based on other primitives. (Default: [])
62
+
63
+
64
+ Properties:
65
+ * identifier
66
+ * display_name
67
+ * bsdf_file
68
+ * up_orientation
69
+ * function_file
70
+ * transform
71
+ * angle_basis
72
+ * front_diffuse_reflectance
73
+ * back_diffuse_reflectance
74
+ * diffuse_transmittance
75
+ * dependencies
76
+ * values
77
+ * modifier
78
+ * dependencies
79
+ * is_modifier
80
+ * is_material
81
+ """
82
+
83
+ __slots__ = ('_bsdf_file', '_up_orientation', '_function_file',
84
+ '_transform', '_angle_basis', '_front_diffuse_reflectance',
85
+ '_back_diffuse_reflectance', '_diffuse_transmittance')
86
+
87
+ # TODO(): compress file content: https://stackoverflow.com/a/15529390/4394669
88
+ def __init__(self, bsdf_file, identifier=None, up_orientation=None, modifier=None,
89
+ function_file='.', transform=None, angle_basis=None, dependencies=None):
90
+ """Create aBSDF material."""
91
+ identifier = identifier or \
92
+ '_'.join('.'.join(os.path.split(bsdf_file)[-1].split('.')[:-1]).split(' '))
93
+
94
+ Material.__init__(self, identifier, modifier=modifier,
95
+ dependencies=dependencies)
96
+
97
+ self.bsdf_file = bsdf_file
98
+ self.angle_basis = angle_basis
99
+ self.up_orientation = up_orientation
100
+ self.function_file = function_file
101
+ self.transform = transform
102
+ self._front_diffuse_reflectance = None
103
+ self._back_diffuse_reflectance = None
104
+ self._diffuse_transmittance = None
105
+
106
+ self._update_values()
107
+
108
+ def _update_values(self):
109
+ "update value dictionaries."
110
+ n_path = os.path.normpath(self.bsdf_file).replace('\\', '/')
111
+ f_path = n_path if os.path.isabs(n_path) else './{}'.format(n_path)
112
+ self._values[0] = [
113
+ '"{}"'.format(f_path),
114
+ self.up_orientation.x,
115
+ self.up_orientation.y,
116
+ self.up_orientation.z,
117
+ self.function_file
118
+ ]
119
+ if self.transform:
120
+ self.values[0].append(self.transform)
121
+
122
+ if self.front_diffuse_reflectance is not None:
123
+ self._values[2] = list(self.front_diffuse_reflectance)
124
+
125
+ if self.back_diffuse_reflectance is not None:
126
+ for v in self.back_diffuse_reflectance:
127
+ self._values[2].append(v)
128
+
129
+ if self.diffuse_transmittance is not None:
130
+ for v in self.diffuse_transmittance:
131
+ self._values[2].append(v)
132
+
133
+ @property
134
+ def bsdf_file(self):
135
+ """Path to BSDF file."""
136
+ return self._bsdf_file
137
+
138
+ @bsdf_file.setter
139
+ def bsdf_file(self, bsdf_file):
140
+ assert os.path.isfile(
141
+ bsdf_file), 'No such file at: {}'.format(bsdf_file)
142
+ assert bsdf_file.lower().endswith('.xml'), \
143
+ 'BSDF file must be an xml file: {}'.format(bsdf_file)
144
+ self._bsdf_file = os.path.normpath(bsdf_file).replace('\\', '/')
145
+ if not hasattr(self, '_angle_basis'):
146
+ # first time that file is assigned
147
+ pass
148
+ else:
149
+ self.find_angle_basis(bsdf_file)
150
+
151
+ @property
152
+ def up_orientation(self):
153
+ """Get or set the up normal vector.
154
+
155
+ (x, y ,z) vector that sets the hemisphere that the
156
+ BSDF material faces. For materials that are symmetrical about
157
+ the face plane (like non-angled venetian blinds), this can be
158
+ any vector that is not perfectly normal to the face. For
159
+ asymmetrical materials like angled venetian blinds, this variable
160
+ should be coordinated with the direction the face are facing.
161
+ The default is set to (0.01, 0.01, 1.00), which should hopefully
162
+ not be perpendicular to any typical face.
163
+ """
164
+ return self._up_orientation
165
+
166
+ @up_orientation.setter
167
+ def up_orientation(self, vector):
168
+ if vector:
169
+ up_vector = pv.Vector3D(*[float(v) for v in vector])
170
+ else:
171
+ up_vector = pv.Vector3D(0.01, 0.01, 1.00)
172
+
173
+ self._up_orientation = up_vector
174
+
175
+ @property
176
+ def function_file(self):
177
+ """Get or set the path to function file."""
178
+ return self._function_file
179
+
180
+ @function_file.setter
181
+ def function_file(self, value):
182
+ self._function_file = value or '.'
183
+
184
+ @property
185
+ def transform(self):
186
+ """Get or set the transform.
187
+
188
+ This is optional and is used to scale the thickness and reorient the
189
+ up vector. (Default: None).
190
+ """
191
+ return self._transform
192
+
193
+ @transform.setter
194
+ def transform(self, value):
195
+ self._transform = value
196
+
197
+ @property
198
+ def angle_basis(self):
199
+ """Get or set a string for the BSDF file angle basis.
200
+
201
+ Valid values are Klems Full, Klems Half, Klems Quarter and TensorTree
202
+ """
203
+ return self._angle_basis
204
+
205
+ @angle_basis.setter
206
+ def angle_basis(self, value):
207
+ if value:
208
+ assert value in (
209
+ 'Klems Full', 'Klems Half',
210
+ 'Klems Quarter', 'TensorTree'), '{} is not a valid angle basis.'
211
+ self._angle_basis = value
212
+ else:
213
+ self._angle_basis = self.find_angle_basis(self.bsdf_file)
214
+
215
+ @property
216
+ def sampling_type(self):
217
+ """Return rfluxmtx parameters sampling type based on the angle basis.
218
+
219
+ Values are:
220
+
221
+ * kf for klems full.
222
+ * kh for klems half.
223
+ * kq for klems quarter.
224
+
225
+ For other angle basis a None value will be returned.
226
+ """
227
+ _mapper = {
228
+ 'Klems Full': 'kf', 'Klems Half': 'kh', 'Klems Quarter': 'kq'
229
+ }
230
+
231
+ try:
232
+ sampling = _mapper[self.angle_basis]
233
+ except KeyError:
234
+ sampling = None
235
+
236
+ return sampling
237
+
238
+ @property
239
+ def front_diffuse_reflectance(self):
240
+ """Get or set the additional front diffuse reflectance."""
241
+ return self._front_diffuse_reflectance
242
+
243
+ @front_diffuse_reflectance.setter
244
+ def front_diffuse_reflectance(self, value):
245
+ if value is not None:
246
+ value = typing.tuple_with_length(value, 3)
247
+
248
+ self._front_diffuse_reflectance = value
249
+
250
+ @property
251
+ def back_diffuse_reflectance(self):
252
+ """Get or set the additional back diffuse reflectance."""
253
+ return self._back_diffuse_reflectance
254
+
255
+ @back_diffuse_reflectance.setter
256
+ def back_diffuse_reflectance(self, value):
257
+ if value is not None:
258
+ value = typing.tuple_with_length(value, 3)
259
+
260
+ self._back_diffuse_reflectance = value
261
+
262
+ @property
263
+ def diffuse_transmittance(self):
264
+ """Get or set the additional diffuse transmittance."""
265
+ return self._diffuse_transmittance
266
+
267
+ @diffuse_transmittance.setter
268
+ def diffuse_transmittance(self, value):
269
+ if value is not None:
270
+ value = typing.tuple_with_length(value, 3)
271
+
272
+ self._diffuse_transmittance = value
273
+
274
+ @classmethod
275
+ def from_primitive_dict(cls, primitive_dict):
276
+ """Initialize a aBSDF from a primitive dict.
277
+
278
+ Args:
279
+ data: A dictionary in the format below.
280
+
281
+ .. code-block:: python
282
+
283
+ {
284
+ "modifier": {}, # primitive modifier (Default: None)
285
+ "type": "aBSDF", # primitive type
286
+ "identifier": "", # primitive identifier
287
+ "display_name": "", # primitive display name
288
+ "values": [] # values,
289
+ "dependencies": []
290
+ }
291
+
292
+ """
293
+ cls._dict_type_check(cls.__name__, primitive_dict)
294
+ modifier, dependencies = cls.filter_dict_input(primitive_dict)
295
+ values = primitive_dict['values'][0]
296
+ extra_values = primitive_dict['values'][2]
297
+
298
+ cls_ = cls(
299
+ bsdf_file=values[0],
300
+ identifier=primitive_dict['identifier'],
301
+ up_orientation=values[1:4],
302
+ modifier=modifier,
303
+ function_file=values[4],
304
+ transform=values[5] if len(values) == 6 else None,
305
+ angle_basis=None,
306
+ dependencies=dependencies
307
+ )
308
+ if 'display_name' in primitive_dict and \
309
+ primitive_dict['display_name'] is not None:
310
+ cls_.display_name = primitive_dict['display_name']
311
+
312
+ # this might look redundant but it is NOT. see glass for explanation.
313
+ cls_.values = primitive_dict['values']
314
+
315
+ if not extra_values:
316
+ return cls_
317
+
318
+ values_length = len(extra_values)
319
+ assert values_length in (3, 6, 9), \
320
+ 'Length of real values should be 3, 6 or 9 not %d.' % values_length
321
+
322
+ if values_length == 3:
323
+ cls_.front_diffuse_reflectance = extra_values
324
+ elif values_length == 6:
325
+ cls_.front_diffuse_reflectance = extra_values[:3]
326
+ cls_.back_diffuse_reflectance = extra_values[3:]
327
+ else:
328
+ cls_.front_diffuse_reflectance = extra_values[:3]
329
+ cls_.back_diffuse_reflectance = extra_values[3:6]
330
+ cls_.diffuse_transmittance = extra_values[6:]
331
+
332
+ return cls_
333
+
334
+ @classmethod
335
+ def from_dict(cls, data, folder=None):
336
+ """Initialize a aBSDF from a dictionary.
337
+
338
+ Args:
339
+ data: A dictionary in the format below.
340
+ folder: Path to a destination folder to save the bsdf file.
341
+
342
+ .. code-block:: python
343
+
344
+ {
345
+ "modifier": {}, # material modifier (Default: None)
346
+ "type": "aBSDF", # Material type
347
+ "identifier": "", # Material identifer
348
+ "display_name": "" # Material display name
349
+ "up_orientation": [number, number, number],
350
+ "function_file": string, # default: '.'
351
+ "transform": string, # default: None
352
+ "bsdf_data": string, # bsdf file data as string
353
+ "front_diffuse_reflectance": [number, number, number], # optional
354
+ "back_diffuse_reflectance": [number, number, number], # optional
355
+ "diffuse_transmittance": [number, number, number] # optional
356
+ }
357
+ """
358
+ cls._dict_type_check(cls.__name__, data)
359
+ modifier, dependencies = cls.filter_dict_input(data)
360
+
361
+ # check folder and create it if it does not exist
362
+ folder = os.path.join(folders.default_simulation_folder, 'BSDF') \
363
+ if folder is None else folder
364
+ if not os.path.isdir(folder):
365
+ os.makedirs(folder)
366
+
367
+ fp = os.path.join(folder, '%s.xml' % data['identifier'])
368
+ # write to xml file
369
+ cls.decompress_to_file(data['bsdf_data'], fp)
370
+
371
+ cls_ = cls(
372
+ bsdf_file=fp,
373
+ identifier=data['identifier'],
374
+ up_orientation=data['up_orientation'],
375
+ modifier=modifier,
376
+ dependencies=dependencies
377
+ )
378
+ if 'display_name' in data and data['display_name'] is not None:
379
+ cls_.display_name = data['display_name']
380
+
381
+ if 'front_diffuse_reflectance' in data:
382
+ cls_.front_diffuse_reflectance = data['front_diffuse_reflectance']
383
+ if 'back_diffuse_reflectance' in data:
384
+ cls_.back_diffuse_reflectance = data['back_diffuse_reflectance']
385
+ if 'diffuse_transmittance' in data:
386
+ cls_.diffuse_transmittance = data['diffuse_transmittance']
387
+
388
+ return cls_
389
+
390
+ def to_dict(self):
391
+ """Convert aBSDF material to a dictionary."""
392
+ bsdf_data = self.compress_file(self.bsdf_file)
393
+
394
+ absdf_dict = {
395
+ 'modifier': self.modifier.to_dict(),
396
+ 'type': 'aBSDF',
397
+ 'identifier': self.identifier,
398
+ 'up_orientation': self.up_orientation.to_array(),
399
+ 'function_file': self.function_file,
400
+ 'transform': self.transform,
401
+ 'bsdf_data': bsdf_data,
402
+ 'dependencies': [dep.to_dict() for dep in self.dependencies]
403
+ }
404
+ if self._display_name is not None:
405
+ absdf_dict['display_name'] = self.display_name
406
+
407
+ if self.front_diffuse_reflectance:
408
+ absdf_dict['front_diffuse_reflectance'] = self.front_diffuse_reflectance
409
+ if self.back_diffuse_reflectance:
410
+ absdf_dict['back_diffuse_reflectance'] = self.back_diffuse_reflectance
411
+ if self.diffuse_transmittance:
412
+ absdf_dict['diffuse_transmittance'] = self.diffuse_transmittance
413
+
414
+ return absdf_dict
415
+
416
+ @staticmethod
417
+ def find_angle_basis(bsdf_file, max_ln_count=2000):
418
+ """Find angle basis in an xml file."""
419
+ # find data structure first
420
+ with open(bsdf_file, 'r') as inf:
421
+ for count, line in enumerate(inf):
422
+ if line.strip().startswith('<IncidentDataStructure>'):
423
+ # get data structure
424
+ data_structure = line.replace('<IncidentDataStructure>', '') \
425
+ .replace('</IncidentDataStructure>', '').strip()
426
+ break
427
+ assert count < max_ln_count, \
428
+ 'Failed to find IncidentDataStructure in first %d lines. ' \
429
+ 'You can check the file by opening the file in a text editor ' \
430
+ 'and search for <IncidentDataStructure>' % max_ln_count
431
+
432
+ # now find the angle basis
433
+ if data_structure.startswith('TensorTree'):
434
+ return 'TensorTree'
435
+ elif data_structure.lower() == 'columns':
436
+ # look for AngleBasisName
437
+ with open(bsdf_file, 'r') as inf:
438
+ for i in range(count):
439
+ next(inf)
440
+ for count, line in enumerate(inf):
441
+ if line.strip().startswith('<AngleBasisName>'):
442
+ angle_basis = line.replace('<AngleBasisName>', '') \
443
+ .replace('</AngleBasisName>', '').replace('LBNL/', '') \
444
+ .strip()
445
+ return angle_basis
446
+ assert count < max_ln_count, \
447
+ 'Failed to find AngleBasisName in first %d lines. ' \
448
+ 'You can check the file by opening the file in a text editor ' \
449
+ 'and search for <AngleBasisName>' % max_ln_count
450
+ else:
451
+ raise ValueError(
452
+ 'Unknown IncidentDataStructure: {}'.format(data_structure))
453
+
454
+ @staticmethod
455
+ def compress_file(filepath):
456
+ """Compress bsdf data in an XML file to a string."""
457
+ # TODO: Research better ways to compress the file
458
+ with open(filepath, 'r') as input_file:
459
+ content = input_file.read()
460
+ return content
461
+
462
+ @staticmethod
463
+ def decompress_to_file(value, filepath):
464
+ """Write bsdf data string to a file."""
465
+ with open(filepath, 'w') as output_file:
466
+ output_file.write(value)
467
+
468
+ def __copy__(self):
469
+ mod, depend = self._dup_mod_and_depend()
470
+ new_absdf = self.__class__(
471
+ self.bsdf_file, self.identifier, self.up_orientation, mod,
472
+ self.function_file, self.transform, self.angle_basis, depend)
473
+ new_absdf._front_diffuse_reflectance = self._front_diffuse_reflectance
474
+ new_absdf._back_diffuse_reflectance = self._back_diffuse_reflectance
475
+ new_absdf._diffuse_transmittance = self._diffuse_transmittance
476
+ new_absdf._display_name = self._display_name
477
+ return new_absdf
@@ -0,0 +1,54 @@
1
+ """Radiance Antimatter Material.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Antimatter
4
+ """
5
+ from .materialbase import Material
6
+
7
+
8
+ # TODO: Implement the class. It's currently only a generic Radiance Primitive
9
+ class Antimatter(Material):
10
+ """Radiance Antimatter Material.
11
+
12
+ Antimatter is a material that can \'subtract\' volumes from other volumes. A ray
13
+ passing into an antimatter object becomes blind to all the specified modifiers:
14
+
15
+ .. code-block:: shell
16
+
17
+ mod antimatter id
18
+ N mod1 mod2 .. modN
19
+ 0
20
+ 0
21
+
22
+ The first modifier will also be used to shade the area leaving the antimatter volume
23
+ and entering the regular volume. If mod1 is void, the antimatter volume is completely
24
+ invisible. Antimatter does not work properly with the material type "trans", and
25
+ multiple antimatter surfaces should be disjoint. The viewpoint must be outside all
26
+ volumes concerned for a correct rendering.
27
+
28
+ Args:
29
+ identifier: Text string for a unique Material ID. Must not contain spaces
30
+ or special characters. This will be used to identify the object across
31
+ a model and in the exported Radiance files.
32
+ modifier: Modifier. It can be primitive, mixture, texture or pattern.
33
+ (Default: None).
34
+ values: An array 3 arrays for primitive data. Each of the 3 sub-arrays
35
+ refer to a line number in the radiance primitive definitions and the
36
+ values in each array correspond to values occurring within each line.
37
+ is_opaque: A boolean to indicate whether this primitive is opaque.
38
+ dependencies: A list of primitives that this primitive depends on. This
39
+ argument is only useful for defining advanced primitives that are
40
+ defined based on other primitives. (Default: []).
41
+
42
+ Properties:
43
+ * identifier
44
+ * display_name
45
+ * values
46
+ * modifier
47
+ * dependencies
48
+ * is_modifier
49
+ * is_material
50
+ * is_opaque
51
+ """
52
+ __slots__ = ()
53
+
54
+ pass
@@ -0,0 +1,51 @@
1
+ """Radiance Ashik2 Material.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Ashik2
4
+ """
5
+ from .materialbase import Material
6
+
7
+
8
+ # TODO: Implement the class. It's currently only a generic Radiance Primitive
9
+ class Ashik2(Material):
10
+ """Radiance Ashik2 Material.
11
+
12
+ Ashik2 is the anisotropic reflectance model by Ashikhmin & Shirley. The string
13
+ arguments are the same as for plastic2, but the real arguments have additional
14
+ flexibility to specify the specular color. Also, rather than roughness, specular
15
+ power is used, which has no physical meaning other than larger numbers are equivalent
16
+ to a smoother surface.
17
+
18
+ .. code-block:: shell
19
+
20
+ mod ashik2 id
21
+ 4+ ux uy uz funcfile transform
22
+ 0
23
+ 8 dred dgrn dblu sred sgrn sblu u-power v-power
24
+
25
+ Args:
26
+ identifier: Text string for a unique Material ID. Must not contain spaces
27
+ or special characters. This will be used to identify the object across
28
+ a model and in the exported Radiance files.
29
+ modifier: Modifier. It can be primitive, mixture, texture or pattern.
30
+ (Default: None).
31
+ values: An array 3 arrays for primitive data. Each of the 3 sub-arrays
32
+ refer to a line number in the radiance primitive definitions and the
33
+ values in each array correspond to values occurring within each line.
34
+ is_opaque: A boolean to indicate whether this primitive is opaque.
35
+ dependencies: A list of primitives that this primitive depends on. This
36
+ argument is only useful for defining advanced primitives that are
37
+ defined based on other primitives. (Default: []).
38
+
39
+ Properties:
40
+ * identifier
41
+ * display_name
42
+ * values
43
+ * modifier
44
+ * dependencies
45
+ * is_modifier
46
+ * is_material
47
+ * is_opaque
48
+ """
49
+ __slots__ = ()
50
+
51
+ pass
@@ -0,0 +1,81 @@
1
+ """Radiance BRTDfunc Material.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#BRTDfunc
4
+ """
5
+ from .materialbase import Material
6
+
7
+
8
+ # TODO: Implement the class. It's currently only a generic Radiance Primitive
9
+ class BRTDfunc(Material):
10
+ """Radiance BRTDfunc Material.
11
+
12
+ The material BRTDfunc gives the maximum flexibility over surface reflectance and
13
+ transmittance, providing for spectrally-dependent specular rays and reflectance and
14
+ transmittance distribution functions.
15
+
16
+ .. code-block:: shell
17
+
18
+ mod BRTDfunc id
19
+ 10+ rrefl grefl brefl
20
+ rtrns gtrns btrns
21
+ rbrtd gbrtd bbrtd
22
+ funcfile transform
23
+ 0
24
+ 9+ rfdif gfdif bfdif
25
+ rbdif gbdif bbdif
26
+ rtdif gtdif btdif
27
+ A10 ..
28
+
29
+ The variables rrefl, grefl and brefl specify the color coefficients for the ideal
30
+ specular (mirror) reflection of the surface. The variables rtrns, gtrns and btrns
31
+ specify the color coefficients for the ideal specular transmission. The functions
32
+ rbrtd, gbrtd and bbrtd take the direction to the incident light (and its solid angle)
33
+ and compute the color coefficients for the directional diffuse part of reflection and
34
+ transmission. As a special case, three identical values of '0' may be given in place
35
+ of these function names to indicate no directional diffuse component.
36
+
37
+ Unlike most other material types, the surface normal is not altered to face the
38
+ incoming ray. Thus, functions and variables must pay attention to the orientation of
39
+ the surface and make adjustments appropriately. However, the special variables for
40
+ the perturbed dot product and surface normal, RdotP, NxP, NyP and NzP are reoriented
41
+ as if the ray hit the front surface for convenience.
42
+
43
+ A diffuse reflection component may be given for the front side with rfdif, gfdif and
44
+ bfdif for the front side of the surface or rbdif, gbdif and bbdif for the back side.
45
+ The diffuse transmittance (must be the same for both sides by physical law) is given
46
+ by rtdif, gtdif and btdif. A pattern will modify these diffuse scattering values, and
47
+ will be available through the special variables CrP, CgP and CbP.
48
+
49
+ Care must be taken when using this material type to produce a physically valid
50
+ reflection model. The reflectance functions should be bidirectional, and under no
51
+ circumstances should the sum of reflected diffuse, transmitted diffuse, reflected
52
+ specular, transmitted specular and the integrated directional diffuse component be
53
+ greater than one.
54
+
55
+ Args:
56
+ identifier: Text string for a unique Material ID. Must not contain spaces
57
+ or special characters. This will be used to identify the object across
58
+ a model and in the exported Radiance files.
59
+ modifier: Modifier. It can be primitive, mixture, texture or pattern.
60
+ (Default: None).
61
+ values: An array 3 arrays for primitive data. Each of the 3 sub-arrays
62
+ refer to a line number in the radiance primitive definitions and the
63
+ values in each array correspond to values occurring within each line.
64
+ is_opaque: A boolean to indicate whether this primitive is opaque.
65
+ dependencies: A list of primitives that this primitive depends on. This
66
+ argument is only useful for defining advanced primitives that are
67
+ defined based on other primitives. (Default: []).
68
+
69
+ Properties:
70
+ * identifier
71
+ * display_name
72
+ * values
73
+ * modifier
74
+ * dependencies
75
+ * is_modifier
76
+ * is_material
77
+ * is_opaque
78
+ """
79
+ __slots__ = ()
80
+
81
+ pass