honeybee-grasshopper-radiance 1.35.1__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.
- honeybee_grasshopper_radiance/__init__.py +7 -0
- honeybee_grasshopper_radiance/src/HB Adjust HDR.py +107 -0
- honeybee_grasshopper_radiance/src/HB Ambient Resolution.py +63 -0
- honeybee_grasshopper_radiance/src/HB Annual Average Values.py +205 -0
- honeybee_grasshopper_radiance/src/HB Annual Cumulative Values.py +191 -0
- honeybee_grasshopper_radiance/src/HB Annual Daylight Metrics.py +209 -0
- honeybee_grasshopper_radiance/src/HB Annual Daylight.py +153 -0
- honeybee_grasshopper_radiance/src/HB Annual Glare Metrics.py +137 -0
- honeybee_grasshopper_radiance/src/HB Annual Irradiance.py +112 -0
- honeybee_grasshopper_radiance/src/HB Annual Peak Values.py +224 -0
- honeybee_grasshopper_radiance/src/HB Annual Results to Data.py +246 -0
- honeybee_grasshopper_radiance/src/HB Annual Sunlight Exposure.py +147 -0
- honeybee_grasshopper_radiance/src/HB Aperture Group Schedule.py +69 -0
- honeybee_grasshopper_radiance/src/HB Apply Face Modifier.py +107 -0
- honeybee_grasshopper_radiance/src/HB Apply ModifierSet.py +71 -0
- honeybee_grasshopper_radiance/src/HB Apply Shade Modifier.py +110 -0
- honeybee_grasshopper_radiance/src/HB Apply Window Modifier.py +120 -0
- honeybee_grasshopper_radiance/src/HB Assign Grids and Views.py +58 -0
- honeybee_grasshopper_radiance/src/HB Automatic Aperture Group.py +100 -0
- honeybee_grasshopper_radiance/src/HB BSDF Modifier.py +78 -0
- honeybee_grasshopper_radiance/src/HB CIE Standard Sky.py +75 -0
- honeybee_grasshopper_radiance/src/HB Certain Illuminance.py +41 -0
- honeybee_grasshopper_radiance/src/HB Check Scene.py +208 -0
- honeybee_grasshopper_radiance/src/HB Climatebased Sky.py +75 -0
- honeybee_grasshopper_radiance/src/HB Cumulative Radiation.py +98 -0
- honeybee_grasshopper_radiance/src/HB Custom Sky.py +74 -0
- honeybee_grasshopper_radiance/src/HB Daylight Control Schedule.py +211 -0
- honeybee_grasshopper_radiance/src/HB Daylight Factor.py +82 -0
- honeybee_grasshopper_radiance/src/HB Deconstruct Modifier.py +47 -0
- honeybee_grasshopper_radiance/src/HB Deconstruct ModifierSet Interior.py +67 -0
- honeybee_grasshopper_radiance/src/HB Deconstruct ModifierSet.py +80 -0
- honeybee_grasshopper_radiance/src/HB Deconstruct Wea.py +44 -0
- honeybee_grasshopper_radiance/src/HB Direct Sun Hours.py +88 -0
- honeybee_grasshopper_radiance/src/HB Dynamic Aperture Group.py +90 -0
- honeybee_grasshopper_radiance/src/HB Dynamic Shade Group.py +95 -0
- honeybee_grasshopper_radiance/src/HB Dynamic State Geometry.py +68 -0
- honeybee_grasshopper_radiance/src/HB Dynamic State.py +44 -0
- honeybee_grasshopper_radiance/src/HB Exterior Modifier Subset.py +68 -0
- honeybee_grasshopper_radiance/src/HB Extract HDR.py +225 -0
- honeybee_grasshopper_radiance/src/HB False Color.py +246 -0
- honeybee_grasshopper_radiance/src/HB Get Dynamic Groups.py +57 -0
- honeybee_grasshopper_radiance/src/HB Get Grids and Views.py +82 -0
- honeybee_grasshopper_radiance/src/HB Glare Postprocess.py +225 -0
- honeybee_grasshopper_radiance/src/HB Glass Modifier 3.py +62 -0
- honeybee_grasshopper_radiance/src/HB Glass Modifier.py +58 -0
- honeybee_grasshopper_radiance/src/HB HDR to GIF.py +72 -0
- honeybee_grasshopper_radiance/src/HB Imageless Annual Glare.py +108 -0
- honeybee_grasshopper_radiance/src/HB Interior Modifier Subset.py +83 -0
- honeybee_grasshopper_radiance/src/HB Metal Modifier 3.py +70 -0
- honeybee_grasshopper_radiance/src/HB Metal Modifier.py +68 -0
- honeybee_grasshopper_radiance/src/HB Mirror Modifier 3.py +56 -0
- honeybee_grasshopper_radiance/src/HB Mirror Modifier.py +55 -0
- honeybee_grasshopper_radiance/src/HB Model to Rad Folder.py +75 -0
- honeybee_grasshopper_radiance/src/HB ModifierSet.py +127 -0
- honeybee_grasshopper_radiance/src/HB Opaque Modifier 3.py +68 -0
- honeybee_grasshopper_radiance/src/HB Opaque Modifier.py +67 -0
- honeybee_grasshopper_radiance/src/HB Point-In-Time Grid-Based.py +93 -0
- honeybee_grasshopper_radiance/src/HB Point-In-Time View-Based.py +127 -0
- honeybee_grasshopper_radiance/src/HB Radial Grid from Rooms.py +160 -0
- honeybee_grasshopper_radiance/src/HB Radial Sensor Grid.py +99 -0
- honeybee_grasshopper_radiance/src/HB Radiance Parameter.py +163 -0
- honeybee_grasshopper_radiance/src/HB Search Modifier Sets.py +58 -0
- honeybee_grasshopper_radiance/src/HB Search Modifiers.py +58 -0
- honeybee_grasshopper_radiance/src/HB Section Plane View.py +69 -0
- honeybee_grasshopper_radiance/src/HB Sensor Grid from Apertures.py +153 -0
- honeybee_grasshopper_radiance/src/HB Sensor Grid from Faces.py +147 -0
- honeybee_grasshopper_radiance/src/HB Sensor Grid from Rooms.py +210 -0
- honeybee_grasshopper_radiance/src/HB Sensor Grid.py +82 -0
- honeybee_grasshopper_radiance/src/HB Shade Modifier Subset.py +62 -0
- honeybee_grasshopper_radiance/src/HB Sky View.py +86 -0
- honeybee_grasshopper_radiance/src/HB Spatial Daylight Autonomy.py +86 -0
- honeybee_grasshopper_radiance/src/HB Subface Modifier Subset.py +90 -0
- honeybee_grasshopper_radiance/src/HB Translucent Modifier 3.py +77 -0
- honeybee_grasshopper_radiance/src/HB Translucent Modifier.py +77 -0
- honeybee_grasshopper_radiance/src/HB View from Viewport.py +85 -0
- honeybee_grasshopper_radiance/src/HB View.py +96 -0
- honeybee_grasshopper_radiance/src/HB Visualize Sky.py +141 -0
- honeybee_grasshopper_radiance/src/HB Wea From Clear Sky.py +61 -0
- honeybee_grasshopper_radiance/src/HB Wea From EPW.py +50 -0
- honeybee_grasshopper_radiance/src/HB Wea From Tau Clear Sky.py +56 -0
- honeybee_grasshopper_radiance/src/HB Wea from Zhang-Huang.py +63 -0
- honeybee_grasshopper_radiance/src/__init__.py +1 -0
- honeybee_grasshopper_radiance/user_objects/HB Adjust HDR.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Ambient Resolution.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Average Values.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Cumulative Values.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Daylight Metrics.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Daylight.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Glare Metrics.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Irradiance.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Peak Values.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Results to Data.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Annual Sunlight Exposure.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Aperture Group Schedule.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Apply Face Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Apply ModifierSet.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Apply Shade Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Apply Window Modifier.ghuser +0 -0
- Views.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Automatic Aperture Group.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB BSDF Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB CIE Standard Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Certain Illuminance.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Check Scene.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Climatebased Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Cumulative Radiation.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Custom Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Daylight Control Schedule.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Daylight Factor.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Deconstruct Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Deconstruct ModifierSet Interior.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Deconstruct ModifierSet.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Deconstruct Wea.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Direct Sun Hours.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Dynamic Aperture Group.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Dynamic Shade Group.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Dynamic State Geometry.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Dynamic State.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Exterior Modifier Subset.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Face Radiance Attributes.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB False Color.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Get Dynamic Groups.ghuser +0 -0
- Views.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Glare Postprocess.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Glass Modifier 3.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Glass Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB HDR to GIF.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Imageless Annual Glare.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Interior Modifier Subset.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Metal Modifier 3.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Metal Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Mirror Modifier 3.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Mirror Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Model to Rad Folder.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB ModifierSet.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Opaque Modifier 3.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Opaque Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Point-In-Time Grid-Based.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Point-In-Time View-Based.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Radial Grid from Rooms.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Radial Sensor Grid.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Radiance Parameter.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Room Radiance Attributes.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Search Modifier Sets.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Search Modifiers.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Section Plane View.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Apertures.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Faces.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Rooms.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Sensor Grid.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Shade Modifier Subset.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Sky View.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Spatial Daylight Autonomy.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Subface Modifier Subset.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Translucent Modifier 3.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Translucent Modifier.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB View from Viewport.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB View.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Visualize Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Wea From Clear Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Wea From EPW.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Wea From Tau Clear Sky.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/HB Wea from Zhang-Huang.ghuser +0 -0
- honeybee_grasshopper_radiance/user_objects/__init__.py +1 -0
- honeybee_grasshopper_radiance-1.35.1.dist-info/METADATA +64 -0
- honeybee_grasshopper_radiance-1.35.1.dist-info/RECORD +170 -0
- honeybee_grasshopper_radiance-1.35.1.dist-info/WHEEL +5 -0
- honeybee_grasshopper_radiance-1.35.1.dist-info/licenses/LICENSE +661 -0
- honeybee_grasshopper_radiance-1.35.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# This file is part of Honeybee.
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025, Ladybug Tools.
|
|
4
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
5
|
+
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
|
|
6
|
+
#
|
|
7
|
+
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
Convert a High Dynamic Range (HDR) image file into a falsecolor version of itself.
|
|
11
|
+
-
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
_hdr: Path to a High Dynamic Range (HDR) image file.
|
|
15
|
+
max_: A number to set the upper boundary of the legend. The default is
|
|
16
|
+
dictated based on the legend_unit_.
|
|
17
|
+
seg_count_: An interger representing the number of steps between the
|
|
18
|
+
high and low boundary of the legend. The default is set to 10
|
|
19
|
+
and any custom values input in here should always be greater
|
|
20
|
+
than or equal to 2.
|
|
21
|
+
legend_height_: An integer for the height of the legend in pixels. Set to 0
|
|
22
|
+
to completely remove the legend from the output. (Default: 200).
|
|
23
|
+
legend_width_: An integer for the width of the legend in pixels. Set to 0
|
|
24
|
+
to completely remove the legend from the output. (Default: 100).
|
|
25
|
+
legend_unit_: Text for the unit of the legend. If unspecified, an attempt will
|
|
26
|
+
be made to sense the metric from the input image file. Typical examples
|
|
27
|
+
include lux, W/m2, cd/m2, w/sr-m2.
|
|
28
|
+
conversion_: Number for the conversion factor (aka. multiplier) for the results.
|
|
29
|
+
The default is either 1 or 179 depending on whether the image is for
|
|
30
|
+
radiance or irradiance to luminance or illuminance, respectively.
|
|
31
|
+
contour_lines_: Set to True ro render the image with colored contour lines.
|
|
32
|
+
logarithmic_: Number of decades to use with a logarithmic legend scale.
|
|
33
|
+
Decades are the number of intervals of 10 below the maximum scale. If
|
|
34
|
+
unspecified, a linear scale is used.
|
|
35
|
+
extrema_: Set to True to cause extrema points to be printed on the brightest
|
|
36
|
+
and darkest pixels of the input picture.
|
|
37
|
+
mask_: A boolen to note whether pixels with a value of zero should be masked in
|
|
38
|
+
black. (Default: False).
|
|
39
|
+
color_palette_: Optional interger or text to change the color palette.
|
|
40
|
+
Choose from the following.
|
|
41
|
+
* 0 = def - default colors
|
|
42
|
+
* 1 = pm3d - a variation of the default colors
|
|
43
|
+
* 2 = spec - the old spectral mapping
|
|
44
|
+
* 3 = hot - a thermal scale
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
hdr: Path to the resulting falsecolor HDR file. This can be plugged into the
|
|
48
|
+
Ladybug "Image Viewer" component to preview the image. It can also
|
|
49
|
+
be plugged into the "HB HDR to GIF" component to get a GIF image
|
|
50
|
+
that is more portable and easily previewed by different software.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
ghenv.Component.Name = 'HB False Color'
|
|
54
|
+
ghenv.Component.NickName = 'FalseColor'
|
|
55
|
+
ghenv.Component.Message = '1.9.0'
|
|
56
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
57
|
+
ghenv.Component.SubCategory = '4 :: Results'
|
|
58
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '3'
|
|
59
|
+
|
|
60
|
+
import os
|
|
61
|
+
import subprocess
|
|
62
|
+
import re
|
|
63
|
+
|
|
64
|
+
try: # import honeybee_radiance_command dependencies
|
|
65
|
+
from honeybee_radiance_command.falsecolor import Falsecolor
|
|
66
|
+
from honeybee_radiance_command.pcomb import Pcomb
|
|
67
|
+
except ImportError as e:
|
|
68
|
+
raise ImportError('\nFailed to import honeybee_radiance_command:\n\t{}'.format(e))
|
|
69
|
+
|
|
70
|
+
try: # import honeybee_radiance dependencies
|
|
71
|
+
from honeybee_radiance.config import folders as rad_folders
|
|
72
|
+
except ImportError as e:
|
|
73
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
74
|
+
|
|
75
|
+
try: # import ladybug_rhino dependencies
|
|
76
|
+
from ladybug_rhino.grasshopper import all_required_inputs
|
|
77
|
+
except ImportError as e:
|
|
78
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
79
|
+
|
|
80
|
+
# check the Radiance date of the installed radiance
|
|
81
|
+
try: # import lbt_recipes dependencies
|
|
82
|
+
from lbt_recipes.version import check_radiance_date
|
|
83
|
+
except ImportError as e:
|
|
84
|
+
raise ImportError('\nFailed to import lbt_recipes:\n\t{}'.format(e))
|
|
85
|
+
check_radiance_date()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def sense_metric_from_hdr(hdr_path):
|
|
89
|
+
"""Sense the metric/units of a given HDR file from its properties.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
hdr_path: The path to an HDR image file
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Text for the units of the file (either 'lux', 'W/m2', 'cd/m2', 'W/sr-m2')
|
|
96
|
+
"""
|
|
97
|
+
with open(hdr_path, 'r') as hdr_file:
|
|
98
|
+
for lineCount, line in enumerate(hdr_file):
|
|
99
|
+
if lineCount < 10:
|
|
100
|
+
low_line = line.strip().lower()
|
|
101
|
+
if low_line.startswith('oconv') and low_line.endswith('.sky'):
|
|
102
|
+
return 'W/sr-m2' # this is an image of a sky
|
|
103
|
+
if low_line.startswith('rpict'):
|
|
104
|
+
if line.find('_irradiance.vf') > -1:
|
|
105
|
+
return 'W/m2'
|
|
106
|
+
if line.find('_radiance.vf') > -1:
|
|
107
|
+
return 'W/sr-m2'
|
|
108
|
+
if line.find('-i') > -1 and not line.find('-i-') > -1:
|
|
109
|
+
return 'lux'
|
|
110
|
+
else: # we have passed the header of the file
|
|
111
|
+
return 'cd/m2' # luminance
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def is_fisheye(hdr_path):
|
|
115
|
+
"""Sense whether a given HDR file is a fisheye.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
hdr_path: The path to an HDR image file
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Text for the units of the file (either 'lux', 'W/m2', 'cd/m2', 'W/sr-m2')
|
|
122
|
+
"""
|
|
123
|
+
with open(hdr_path, 'r') as hdr_file:
|
|
124
|
+
for lineCount, line in enumerate(hdr_file):
|
|
125
|
+
if lineCount < 10:
|
|
126
|
+
if '-vth' in line:
|
|
127
|
+
return True
|
|
128
|
+
else:
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
def get_dimensions(img_dim):
|
|
132
|
+
"""Get integers for the dimensions of an image from the pcomb stdout.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
img_dim: Text string that is returned from the pcomb function
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Two integers for the dimensions of the HDR image
|
|
139
|
+
"""
|
|
140
|
+
dimensions = []
|
|
141
|
+
for d in ['+X', '-Y']:
|
|
142
|
+
regex = r'\%s\s+(\d+)' % d
|
|
143
|
+
matches = re.finditer(regex, img_dim, re.MULTILINE)
|
|
144
|
+
try:
|
|
145
|
+
dim = next(matches).groups()[0]
|
|
146
|
+
dimensions.append(int(dim))
|
|
147
|
+
except Exception:
|
|
148
|
+
pass
|
|
149
|
+
if len(dimensions) == 1: # it is likely a sky-generated image
|
|
150
|
+
dimensions.append(int(dim))
|
|
151
|
+
|
|
152
|
+
return dimensions
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
if all_required_inputs(ghenv.Component):
|
|
156
|
+
# set up the paths for the various files used in translation
|
|
157
|
+
img_dir = os.path.dirname(_hdr)
|
|
158
|
+
input_image = os.path.basename(_hdr)
|
|
159
|
+
new_image = input_image.lower().replace('.hdr', '_falsecolor.HDR')
|
|
160
|
+
hdr = os.path.join(img_dir, new_image)
|
|
161
|
+
|
|
162
|
+
# set default properties
|
|
163
|
+
seg_count_ = seg_count_ if seg_count_ is not None else 10
|
|
164
|
+
if legend_unit_ is None:
|
|
165
|
+
legend_unit_ = sense_metric_from_hdr(_hdr)
|
|
166
|
+
if conversion_ is None:
|
|
167
|
+
if legend_unit_ in ('W/sr-m2', 'W/m2'):
|
|
168
|
+
conversion_ = 1
|
|
169
|
+
else:
|
|
170
|
+
conversion_ = 179
|
|
171
|
+
if max_ is None: # get the max value by running pextrem
|
|
172
|
+
pextrem_exe = os.path.join(rad_folders.radbin_path, 'pextrem.exe') if \
|
|
173
|
+
os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'pextrem')
|
|
174
|
+
use_shell = True if os.name == 'nt' else False
|
|
175
|
+
cmds = [pextrem_exe, '-o', _hdr]
|
|
176
|
+
process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)
|
|
177
|
+
stdout = process.communicate()
|
|
178
|
+
max_rgb = stdout[0].split('\n')[1]
|
|
179
|
+
max_ = (sum([float(x) for x in max_rgb.split(' ')[2:]]) / 3) * conversion_
|
|
180
|
+
if legend_unit_ == 'W/sr-m2' and max_ > 200: # sun pixel overpowering image
|
|
181
|
+
max_ = max_ / 50000
|
|
182
|
+
max_ = str(round(max_, 1)) if max_ >= 0.1 else str(max_)
|
|
183
|
+
|
|
184
|
+
# create the command to run falsecolor
|
|
185
|
+
mask = True if mask_ and is_fisheye(_hdr) else False
|
|
186
|
+
out_img = new_image if not mask else input_image.lower().replace('.hdr', '_fc_temp.HDR')
|
|
187
|
+
falsecolor = Falsecolor(input=input_image, output=out_img)
|
|
188
|
+
falsecolor.options.s = max_
|
|
189
|
+
falsecolor.options.n = seg_count_
|
|
190
|
+
falsecolor.options.l = legend_unit_
|
|
191
|
+
falsecolor.options.m = conversion_
|
|
192
|
+
if contour_lines_:
|
|
193
|
+
falsecolor.options.cl = True
|
|
194
|
+
falsecolor.options.p = input_image
|
|
195
|
+
if extrema_:
|
|
196
|
+
falsecolor.options.e = True
|
|
197
|
+
if logarithmic_:
|
|
198
|
+
falsecolor.options.log = logarithmic_
|
|
199
|
+
if legend_height_ is not None:
|
|
200
|
+
falsecolor.options.lh = legend_height_
|
|
201
|
+
if legend_width_ is not None:
|
|
202
|
+
falsecolor.options.lw = legend_width_
|
|
203
|
+
if color_palette_:
|
|
204
|
+
PALETTE_DICT = {
|
|
205
|
+
'0': 'def',
|
|
206
|
+
'1': 'pm3d',
|
|
207
|
+
'2': 'spec',
|
|
208
|
+
'3': 'hot',
|
|
209
|
+
'def': 'def',
|
|
210
|
+
'pm3d': 'pm3d',
|
|
211
|
+
'spec': 'spec',
|
|
212
|
+
'hot': 'hot'
|
|
213
|
+
}
|
|
214
|
+
falsecolor.options.pal = PALETTE_DICT[color_palette_]
|
|
215
|
+
|
|
216
|
+
# run the falsecolor command
|
|
217
|
+
env = None
|
|
218
|
+
if rad_folders.env != {}:
|
|
219
|
+
env = rad_folders.env
|
|
220
|
+
env = dict(os.environ, **env) if env else None
|
|
221
|
+
falsecolor.run(env, cwd=img_dir)
|
|
222
|
+
|
|
223
|
+
# if we should maske, then run an additional pcomb command
|
|
224
|
+
if mask:
|
|
225
|
+
# get the dimensions of the image
|
|
226
|
+
getinfo_exe = os.path.join(rad_folders.radbin_path, 'getinfo.exe') if \
|
|
227
|
+
os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'getinfo')
|
|
228
|
+
cmds = [getinfo_exe, '-d', _hdr]
|
|
229
|
+
use_shell = True if os.name == 'nt' else False
|
|
230
|
+
process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)
|
|
231
|
+
stdout = process.communicate()
|
|
232
|
+
img_dim = stdout[0]
|
|
233
|
+
x, y = get_dimensions(img_dim)
|
|
234
|
+
|
|
235
|
+
# mask the image
|
|
236
|
+
xw = legend_width_ if legend_width_ is not None else 100
|
|
237
|
+
lh = int(legend_height_ * 1.17) if legend_height_ is not None else (200 * 1.17)
|
|
238
|
+
yw = lh - y if lh - y > 0 else 0
|
|
239
|
+
expression = 's(x):x*x;' \
|
|
240
|
+
'm=if((xmax-{0})*(ymax-{1})/4-s(x-{0}-(xmax-{0})/2)-s(y-(ymax-{1})/2),1,if({0}-x,1,0));' \
|
|
241
|
+
'ro=m*ri(1);' \
|
|
242
|
+
'go=m*gi(1);' \
|
|
243
|
+
'bo=m*bi(1)'.format(xw, yw)
|
|
244
|
+
pcomb = Pcomb(input=out_img, output=new_image)
|
|
245
|
+
pcomb.options.e = '"{}"'.format(expression)
|
|
246
|
+
pcomb.run(env, cwd=img_dir)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Honeybee: A Plugin for Environmental Analysis (GPL)
|
|
2
|
+
# This file is part of Honeybee.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2025, Ladybug Tools.
|
|
5
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
6
|
+
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
|
|
7
|
+
#
|
|
8
|
+
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
Get all of the Dynamic Radiance Groups assigned to a Model.
|
|
12
|
+
-
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
_model: A Honeybee Model for which dynamic groups will be output.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
group_ids: The identifiers of the dynamic groups assigned to the Model.
|
|
19
|
+
group_aps: A data tree of Dynamic Apertures in the Model. Each branch of the
|
|
20
|
+
tree represents a different Dynamic Aperture Group and corresponds to
|
|
21
|
+
the group_ids above. The data tree can be exploded with the native
|
|
22
|
+
Grasshopper "Explod Tree" component to assign schedules to each
|
|
23
|
+
Dynamic Group for postprocessing.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
ghenv.Component.Name = 'HB Get Dynamic Groups'
|
|
27
|
+
ghenv.Component.NickName = 'GetDyn'
|
|
28
|
+
ghenv.Component.Message = '1.9.0'
|
|
29
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
30
|
+
ghenv.Component.SubCategory = '0 :: Basic Properties'
|
|
31
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '0'
|
|
32
|
+
|
|
33
|
+
try: # import core honeybee dependencies
|
|
34
|
+
from honeybee.model import Model
|
|
35
|
+
except ImportError as e:
|
|
36
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
37
|
+
|
|
38
|
+
try: # import ladybug_rhino dependencies
|
|
39
|
+
from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if all_required_inputs(ghenv.Component):
|
|
45
|
+
assert isinstance(_model, Model), \
|
|
46
|
+
'Expected Honeybee Model. Got {}.'.format(type(_model))
|
|
47
|
+
# get the dynamic group objects
|
|
48
|
+
groups = _model.properties.radiance.dynamic_subface_groups
|
|
49
|
+
groups.sort(key=lambda x: x.identifier)
|
|
50
|
+
|
|
51
|
+
# get the group attributes
|
|
52
|
+
group_ids, group_aps = [], []
|
|
53
|
+
for group in groups:
|
|
54
|
+
group_ids.append([group.identifier])
|
|
55
|
+
group_aps.append(group.dynamic_objects)
|
|
56
|
+
group_ids = list_to_data_tree(group_ids)
|
|
57
|
+
group_aps = list_to_data_tree(group_aps)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Honeybee: A Plugin for Environmental Analysis (GPL)
|
|
2
|
+
# This file is part of Honeybee.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2025, Ladybug Tools.
|
|
5
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
6
|
+
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
|
|
7
|
+
#
|
|
8
|
+
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
Get Radiance Sensor Grids and/or Views from a Honeybee Model and visualize them
|
|
12
|
+
in the Rhino scene.
|
|
13
|
+
-
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
_model: A Honeybee Model for which grids and views will be output.
|
|
17
|
+
view_filter_: Text for a view identifer or a pattern to filter the views of the
|
|
18
|
+
model that are output. For instance, `first_floor_*` will simulate
|
|
19
|
+
only the views that have an identifier that starts with `first_floor_`.
|
|
20
|
+
By default, all views in the model will be output.
|
|
21
|
+
grid_filter_: Text for a grid identifer or a pattern to filter the sensor grids of
|
|
22
|
+
the model that are output. For instance, first_floor_* will simulate
|
|
23
|
+
only the sensor grids that have an identifier that starts with
|
|
24
|
+
first_floor_. By default, all grids in the model will be output.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
views: A list of Honeybee-Radiance Views that are assigned to the
|
|
28
|
+
input _model.
|
|
29
|
+
grids: A list of Honeybee-Radiance SensorGrids that are assigned to
|
|
30
|
+
the input _model.
|
|
31
|
+
points: The points that are at the center of each grid cell.
|
|
32
|
+
meshes: Mesh for each sensor grid, which can be passed to the "LB Spatial
|
|
33
|
+
Heatmap" component.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
ghenv.Component.Name = 'HB Get Grids and Views'
|
|
37
|
+
ghenv.Component.NickName = 'GetGridsViews'
|
|
38
|
+
ghenv.Component.Message = '1.9.0'
|
|
39
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
40
|
+
ghenv.Component.SubCategory = '0 :: Basic Properties'
|
|
41
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '5'
|
|
42
|
+
|
|
43
|
+
try: # import core ladybug_geometry dependencies
|
|
44
|
+
from ladybug_geometry.geometry3d.pointvector import Point3D
|
|
45
|
+
except ImportError as e:
|
|
46
|
+
raise ImportError('\nFailed to import ladybug_geometry:\n\t{}'.format(e))
|
|
47
|
+
|
|
48
|
+
try: # import core honeybee dependencies
|
|
49
|
+
from honeybee.model import Model
|
|
50
|
+
except ImportError as e:
|
|
51
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
52
|
+
|
|
53
|
+
try: # import honeybee_radiance dependencies
|
|
54
|
+
from honeybee_radiance.writer import _filter_by_pattern
|
|
55
|
+
except ImportError as e:
|
|
56
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
57
|
+
|
|
58
|
+
try: # import ladybug_rhino dependencies
|
|
59
|
+
from ladybug_rhino.fromgeometry import from_point3d, from_mesh3d
|
|
60
|
+
from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree
|
|
61
|
+
except ImportError as e:
|
|
62
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if all_required_inputs(ghenv.Component):
|
|
66
|
+
assert isinstance(_model, Model), \
|
|
67
|
+
'Expected Honeybee Model. Got {}.'.format(type(_model))
|
|
68
|
+
# get the honeybee-radiance objects
|
|
69
|
+
views = _model.properties.radiance.views
|
|
70
|
+
if view_filter_ is not None:
|
|
71
|
+
views = _filter_by_pattern(views, view_filter_)
|
|
72
|
+
grids = _model.properties.radiance.sensor_grids
|
|
73
|
+
if grid_filter_ is not None:
|
|
74
|
+
grids = _filter_by_pattern(grids, grid_filter_)
|
|
75
|
+
|
|
76
|
+
# get the visualizable attributes
|
|
77
|
+
points = [[from_point3d(Point3D.from_array(s.pos)) for s in sg] for sg in grids]
|
|
78
|
+
points = list_to_data_tree(points)
|
|
79
|
+
meshes = []
|
|
80
|
+
for grid in grids:
|
|
81
|
+
if grid.mesh is not None:
|
|
82
|
+
meshes.append(from_mesh3d(grid.mesh))
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# This file is part of Honeybee.
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025, Ladybug Tools.
|
|
4
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
5
|
+
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
|
|
6
|
+
#
|
|
7
|
+
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
Perform glare post-processing on a hemisphical fisheye HDR image file.
|
|
11
|
+
_
|
|
12
|
+
Glare post-processing includes calcuating Daylight Glare Probability (DGP) as
|
|
13
|
+
well as other glare indexes (DGI, UGR, VCP, CGI, UDP).
|
|
14
|
+
_
|
|
15
|
+
This component is using the `evalglare` function for glare calculations., which
|
|
16
|
+
is developed by J. Wienold at Fraunhofer ISE. More information on evalglare
|
|
17
|
+
can be found here:
|
|
18
|
+
https://www.radiance-online.org/learning/documentation/manual-pages/pdfs/evalglare.pdf/view
|
|
19
|
+
_
|
|
20
|
+
For more information about the metrics used to evaluate glare, see here:
|
|
21
|
+
http://web.mit.edu/tito_/www/Projects/Glare/GlareRecommendationsForPractice.html
|
|
22
|
+
|
|
23
|
+
-
|
|
24
|
+
Args:
|
|
25
|
+
_hdr: Path to a hemisphical fisheye High Dynamic Range (HDR) image file. This can be
|
|
26
|
+
obtained from the "HB Point-In-Time View-Based" recipe component. Due
|
|
27
|
+
to runtime reasons of the evalglare code, the input HDR image should
|
|
28
|
+
be smaller than 1500 x 1500 pixels. The recommended size is 1000 x 1000
|
|
29
|
+
pixels, the minimum recommended size is 800 x 800 pixels.
|
|
30
|
+
task_pos_: An optional task position as a 2D point or string formatted as "X, Y".
|
|
31
|
+
The X and Y coordinates of this point must be numbers between 0 and 1
|
|
32
|
+
and correspond to fraction of the image width and height where the
|
|
33
|
+
task position lies. If no task position is provided, the glare will
|
|
34
|
+
be valuated for the entire scene of the image.
|
|
35
|
+
task_angle_: An number between 0 and 180 for the task position opening angle
|
|
36
|
+
in degrees. This angle indicates how widely the peripheral vision
|
|
37
|
+
is engaged for the task. (Default: 30).
|
|
38
|
+
hide_task_: Boolean to note whether the task area should be hidden in the
|
|
39
|
+
output check_hdr.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
DGP: Daylight Glare Probability (DGP) as a number between 0 and 1. The DGP
|
|
43
|
+
describes the fraction of persons disturbed by glare, where 0 is no
|
|
44
|
+
one disturbed and 1 is everyone. Values lower than 0.2 are out of the
|
|
45
|
+
range of the user assessment tests, where the program is based on and
|
|
46
|
+
should be interpreted carefully.
|
|
47
|
+
category: Text for the category of glare discomfort. It will be one of the
|
|
48
|
+
following.
|
|
49
|
+
* Imperceptible Glare [0.35 > DGP]
|
|
50
|
+
* Perceptible Glare [0.4 > DGP >= 0.35]
|
|
51
|
+
* Disturbing Glare [0.45 > DGP >= 0.4]
|
|
52
|
+
* Intolerable Glare [DGP >= 0.45]
|
|
53
|
+
glare_indices: A list of various glare indices ordered as follows.
|
|
54
|
+
* Daylight Glare Index (DGI)
|
|
55
|
+
* Unified Glare Rating (UGR)
|
|
56
|
+
* Visual Comfort Probability (VCP)
|
|
57
|
+
* CIE Glare Index (CGI)
|
|
58
|
+
* Veiling Luminance (Lveil)
|
|
59
|
+
check_hdr: Path to a HDR image produced from the glare study. The image will
|
|
60
|
+
use randomly-assigned colors to indicate different sources of glare
|
|
61
|
+
in the image. It will also show a circular region for the task area
|
|
62
|
+
unless hide_task_ has been set to True.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
ghenv.Component.Name = 'HB Glare Postprocess'
|
|
66
|
+
ghenv.Component.NickName = 'Glare'
|
|
67
|
+
ghenv.Component.Message = '1.9.0'
|
|
68
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
69
|
+
ghenv.Component.SubCategory = '4 :: Results'
|
|
70
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '3'
|
|
71
|
+
|
|
72
|
+
import os
|
|
73
|
+
import subprocess
|
|
74
|
+
import math
|
|
75
|
+
import re
|
|
76
|
+
|
|
77
|
+
try: # import honeybee_radiance dependencies
|
|
78
|
+
from honeybee_radiance.config import folders as rad_folders
|
|
79
|
+
except ImportError as e:
|
|
80
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
81
|
+
|
|
82
|
+
try: # import ladybug_rhino dependencies
|
|
83
|
+
from ladybug_rhino.grasshopper import all_required_inputs, give_warning
|
|
84
|
+
except ImportError as e:
|
|
85
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
86
|
+
|
|
87
|
+
# check the Radiance date of the installed radiance
|
|
88
|
+
try: # import lbt_recipes dependencies
|
|
89
|
+
from lbt_recipes.version import check_radiance_date
|
|
90
|
+
except ImportError as e:
|
|
91
|
+
raise ImportError('\nFailed to import lbt_recipes:\n\t{}'.format(e))
|
|
92
|
+
check_radiance_date()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def check_hdr_luminance_and_fisheye(hdr_path):
|
|
96
|
+
"""Check that a given HDR file is a fisheye image for visible luminance.
|
|
97
|
+
|
|
98
|
+
A ValueError is raised if the image is not for luminance or if the image is
|
|
99
|
+
not clearly a hemispheical fisheye.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
hdr_path: The path to an HDR image file.
|
|
103
|
+
"""
|
|
104
|
+
msg = 'Connected _hdr image must be for luminance. Got "{}".'
|
|
105
|
+
projection = '-vth'
|
|
106
|
+
with open(hdr_path, 'r') as hdr_file:
|
|
107
|
+
for lineCount, line in enumerate(hdr_file):
|
|
108
|
+
if lineCount < 200:
|
|
109
|
+
low_line = line.strip().lower()
|
|
110
|
+
if low_line.startswith('rpict'):
|
|
111
|
+
if line.find('_irradiance.vf') > -1:
|
|
112
|
+
raise ValueError(msg.format('irradiance'))
|
|
113
|
+
if line.find('_radiance.vf') > -1:
|
|
114
|
+
raise ValueError(msg.format('radiance'))
|
|
115
|
+
if line.find('-i') > -1 and not line.find('-i-') > -1:
|
|
116
|
+
raise ValueError(msg.format('illuminance'))
|
|
117
|
+
elif low_line.startswith('view='):
|
|
118
|
+
if line.find('-vth') > -1:
|
|
119
|
+
projection = '-vth'
|
|
120
|
+
elif line.find('-vta') > -1:
|
|
121
|
+
projection = '-vta'
|
|
122
|
+
else:
|
|
123
|
+
raise ValueError(
|
|
124
|
+
'Connected _hdr image is not a fisheye projection.\n'
|
|
125
|
+
'Make sure the view type of the image is 1(h) or 4(a).')
|
|
126
|
+
elif 'pcond -h' in low_line:
|
|
127
|
+
raise ValueError(
|
|
128
|
+
'Connected _hdr image has had the exposure adjusted on it.\n'
|
|
129
|
+
'Make sure adj_expos_ has been set to False in previous steps.')
|
|
130
|
+
else: # no need to check the rest of the document
|
|
131
|
+
break
|
|
132
|
+
return projection
|
|
133
|
+
|
|
134
|
+
def check_hdr_dimensions(hdr_path):
|
|
135
|
+
"""Check that a given HDR file has dimensions suitable for evalglare.
|
|
136
|
+
|
|
137
|
+
A warning is raised if the image is not 1000x1000 pixels and a ValueError is
|
|
138
|
+
raised if the image is completely outside the accptable ragne from 800x800
|
|
139
|
+
to 1500x1500 pixels.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
hdr_path: The path to an HDR image file.
|
|
143
|
+
"""
|
|
144
|
+
# get the path the the getinfo command
|
|
145
|
+
getinfo_exe = os.path.join(rad_folders.radbin_path, 'getinfo.exe') if \
|
|
146
|
+
os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'getinfo')
|
|
147
|
+
|
|
148
|
+
# run the getinfo command in a manner that lets us obtain the result
|
|
149
|
+
cmds = [getinfo_exe, '-d', hdr_path]
|
|
150
|
+
use_shell = True if os.name == 'nt' else False
|
|
151
|
+
process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)
|
|
152
|
+
stdout = process.communicate()
|
|
153
|
+
img_dim = stdout[0]
|
|
154
|
+
|
|
155
|
+
def get_dimensions(img_dim):
|
|
156
|
+
dimensions = []
|
|
157
|
+
for d in ['+X', '-Y']:
|
|
158
|
+
regex = r'\%s\s+(\d+)' % d
|
|
159
|
+
matches = re.finditer(regex, img_dim, re.MULTILINE)
|
|
160
|
+
dim = next(matches).groups()[0]
|
|
161
|
+
dimensions.append(int(dim))
|
|
162
|
+
return dimensions
|
|
163
|
+
# check the X and Y dimensions of the image
|
|
164
|
+
x, y = get_dimensions(img_dim)
|
|
165
|
+
|
|
166
|
+
msg = 'Recommended _hdr image dimensions for glare analysis should be \n' \
|
|
167
|
+
'{} {} x {} pixels. Got {} x {}.'
|
|
168
|
+
if x < 800 or y < 800:
|
|
169
|
+
give_warning(ghenv.Component, msg.format('at least', 800, 800, x, y))
|
|
170
|
+
elif x > 1500 or y > 1500:
|
|
171
|
+
give_warning(ghenv.Component, msg.format('no greater than', 1500, 1500, x, y))
|
|
172
|
+
return x, y
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def dgp_comfort_category(dgp):
|
|
176
|
+
"""Get text for the glare comfort category given a DGP value."""
|
|
177
|
+
if dgp < 0.35:
|
|
178
|
+
return 'Imperceptible Glare'
|
|
179
|
+
elif dgp < 0.40:
|
|
180
|
+
return 'Perceptible Glare'
|
|
181
|
+
elif dgp < 0.45:
|
|
182
|
+
return 'Disturbing Glare'
|
|
183
|
+
else:
|
|
184
|
+
return 'Intolerable Glare'
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
if all_required_inputs(ghenv.Component):
|
|
188
|
+
# check the input image to ensure it meets the criteria
|
|
189
|
+
projection = check_hdr_luminance_and_fisheye(_hdr)
|
|
190
|
+
width, height = check_hdr_dimensions(_hdr)
|
|
191
|
+
|
|
192
|
+
# get the path the the evalglare command and setup the check image argument
|
|
193
|
+
evalglare_exe = os.path.join(rad_folders.radbin_path, 'evalglare.exe') if \
|
|
194
|
+
os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'evalglare')
|
|
195
|
+
img_dir = os.path.dirname(_hdr)
|
|
196
|
+
input_image = os.path.basename(_hdr)
|
|
197
|
+
new_image = input_image.lower().replace('.hdr', '_check.HDR')
|
|
198
|
+
check_hdr = os.path.join(img_dir, new_image)
|
|
199
|
+
cmds = [evalglare_exe, '-c', check_hdr]
|
|
200
|
+
|
|
201
|
+
# since pcomp is used to merge images, the input usually doesn't have view information
|
|
202
|
+
# add default view information for hemispheical fish-eye camera
|
|
203
|
+
cmds.extend([projection, '-vv', '180', '-vh', '180'])
|
|
204
|
+
|
|
205
|
+
# process the task position and add the input HDR
|
|
206
|
+
if task_pos_:
|
|
207
|
+
uv_pt = [float(val) for val in task_pos_.split(',')]
|
|
208
|
+
assert 0 <= uv_pt[0] <= 1 and 0 <= uv_pt[1] <= 1, 'Task position X and Y ' \
|
|
209
|
+
'coordinates must be between 0 and 1.'
|
|
210
|
+
angle = math.radians(task_angle_) if task_angle_ is not None else math.radians(30)
|
|
211
|
+
task_opt = '-t' if hide_task_ else '-T'
|
|
212
|
+
cmds.extend(
|
|
213
|
+
[task_opt, str(int(uv_pt[0] * width)), str(int(uv_pt[1] * height)), str(angle)])
|
|
214
|
+
cmds.append(_hdr)
|
|
215
|
+
|
|
216
|
+
# run the evalglare command in a manner that lets us obtain the stdout result
|
|
217
|
+
use_shell = True if os.name == 'nt' else False
|
|
218
|
+
process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)
|
|
219
|
+
stdout = process.communicate()
|
|
220
|
+
|
|
221
|
+
# process the stdout result into the component outputs
|
|
222
|
+
glare_result = stdout[0].split(':')[-1].strip()
|
|
223
|
+
glare_indices = [float(val) for val in glare_result.split(' ')]
|
|
224
|
+
DGP = glare_indices.pop(0)
|
|
225
|
+
category = dgp_comfort_category(DGP)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Honeybee: A Plugin for Environmental Analysis (GPL)
|
|
2
|
+
# This file is part of Honeybee.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2025, Ladybug Tools.
|
|
5
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
6
|
+
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
|
|
7
|
+
#
|
|
8
|
+
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
Create an glass radiance modifier from a red, green, and blue transmittances
|
|
12
|
+
-
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
_name_: Text to set the name for the modifier and to be incorporated into
|
|
16
|
+
a unique modifier identifier.
|
|
17
|
+
_r_trans: A number between 0 and 1 for the transmittance of the red
|
|
18
|
+
channel. (Default: 0).
|
|
19
|
+
_g_trans: A number between 0 and 1 for the transmittance of the green
|
|
20
|
+
channel. (Default: 0).
|
|
21
|
+
_b_trans: A number between 0 and 1 for the transmittance of the blue
|
|
22
|
+
channel. (Default: 0).
|
|
23
|
+
_refract_: Index of refraction. Typical values are 1.52 for float
|
|
24
|
+
glass and 1.4 for ETFE. If None, Radiance will default to using 1.52
|
|
25
|
+
for glass (Default: None).
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
modifier: A glass modifier that can be assigned to a Honeybee geometry or
|
|
29
|
+
Modifier Sets.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
ghenv.Component.Name = 'HB Glass Modifier 3'
|
|
33
|
+
ghenv.Component.NickName = 'GlassMod3'
|
|
34
|
+
ghenv.Component.Message = '1.9.0'
|
|
35
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
36
|
+
ghenv.Component.SubCategory = '1 :: Modifiers'
|
|
37
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '0'
|
|
38
|
+
|
|
39
|
+
try: # import the core honeybee dependencies
|
|
40
|
+
from honeybee.typing import clean_rad_string, clean_and_id_rad_string
|
|
41
|
+
except ImportError as e:
|
|
42
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
43
|
+
|
|
44
|
+
try: # import the honeybee-radiance dependencies
|
|
45
|
+
from honeybee_radiance.modifier.material import Glass
|
|
46
|
+
except ImportError as e:
|
|
47
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
48
|
+
|
|
49
|
+
try: # import ladybug_rhino dependencies
|
|
50
|
+
from ladybug_rhino.grasshopper import all_required_inputs
|
|
51
|
+
except ImportError as e:
|
|
52
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if all_required_inputs(ghenv.Component):
|
|
56
|
+
name = clean_and_id_rad_string('GlassMaterial') if _name_ is None else \
|
|
57
|
+
clean_rad_string(_name_)
|
|
58
|
+
|
|
59
|
+
# create the modifier
|
|
60
|
+
modifier = Glass.from_transmittance(name, _r_trans, _g_trans, _b_trans, _refract_)
|
|
61
|
+
if _name_ is not None:
|
|
62
|
+
modifier.display_name = _name_
|