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,147 @@
|
|
|
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
|
+
Generate SensorGrid objects from exterior Faces (Walls, Roofs, and Floors).
|
|
12
|
+
_
|
|
13
|
+
These SensorGrids can be used in any grid-based recipe and are particularly useful
|
|
14
|
+
for radiation studies of roofs for photovoltaic potential or solar gain studies
|
|
15
|
+
of walls.
|
|
16
|
+
-
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
_hb_objs: A list of honeybee Faces or Rooms for which sensor grids will be
|
|
20
|
+
generated. This can also be an entire Honeybee Model.
|
|
21
|
+
_grid_size: Number for the size of the grid cells.
|
|
22
|
+
_offset_: Number for the distance to move points from the base geometry.
|
|
23
|
+
The default is 0.1 meters.
|
|
24
|
+
_face_type_: Text or an integer to specify the type of face that will be used to
|
|
25
|
+
generate grids. Note that only Faces with Outdoors boundary conditions
|
|
26
|
+
will be used, meaning that most Floors will typically be
|
|
27
|
+
excluded unless they represent the underside of a cantilever.
|
|
28
|
+
Choose from the following. (Default: Wall).
|
|
29
|
+
* 1 - Wall
|
|
30
|
+
* 2 - Roof
|
|
31
|
+
* 3 - Floor
|
|
32
|
+
* 4 - All
|
|
33
|
+
punched_: Boolean to note whether the punched_geometry of the faces
|
|
34
|
+
should be used (True) with the areas of sub-faces removed from the grid
|
|
35
|
+
or the full geometry should be used (False). (Default:False).
|
|
36
|
+
quad_only_: Boolean to note whether meshing should be done using Rhino's
|
|
37
|
+
defaults (False), which fills the entire face geometry to the edges
|
|
38
|
+
with both quad and tringulated faces, or a mesh with only quad
|
|
39
|
+
faces should be generated. (Default: False).
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
grid: A SensorGrid object that can be used in a grid-based recipe.
|
|
43
|
+
points: The points that are at the center of each grid cell.
|
|
44
|
+
mesh: Analysis mesh that can be passed to the 'Spatial Heatmap' component.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
ghenv.Component.Name = 'HB Sensor Grid from Faces'
|
|
48
|
+
ghenv.Component.NickName = 'GridFaces'
|
|
49
|
+
ghenv.Component.Message = '1.9.0'
|
|
50
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
51
|
+
ghenv.Component.SubCategory = '0 :: Basic Properties'
|
|
52
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '0'
|
|
53
|
+
|
|
54
|
+
try: # import the ladybug_geometry dependencies
|
|
55
|
+
from ladybug_geometry.geometry3d.mesh import Mesh3D
|
|
56
|
+
except ImportError as e:
|
|
57
|
+
raise ImportError('\nFailed to import ladybug_geometry:\n\t{}'.format(e))
|
|
58
|
+
|
|
59
|
+
try: # import the core honeybee dependencies
|
|
60
|
+
from honeybee.model import Model
|
|
61
|
+
from honeybee.room import Room
|
|
62
|
+
from honeybee.face import Face
|
|
63
|
+
from honeybee.boundarycondition import Outdoors
|
|
64
|
+
from honeybee.facetype import Floor, Wall, RoofCeiling
|
|
65
|
+
from honeybee.typing import clean_rad_string, clean_and_id_rad_string
|
|
66
|
+
except ImportError as e:
|
|
67
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
68
|
+
|
|
69
|
+
try: # import the honeybee-radiance dependencies
|
|
70
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
71
|
+
except ImportError as e:
|
|
72
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
73
|
+
|
|
74
|
+
try: # import ladybug_rhino dependencies
|
|
75
|
+
from ladybug_rhino.config import conversion_to_meters
|
|
76
|
+
from ladybug_rhino.togeometry import to_joined_gridded_mesh3d
|
|
77
|
+
from ladybug_rhino.fromgeometry import from_mesh3d, from_point3d, from_face3d
|
|
78
|
+
from ladybug_rhino.grasshopper import all_required_inputs
|
|
79
|
+
except ImportError as e:
|
|
80
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
FACE_TYPES = {
|
|
84
|
+
'1': Wall,
|
|
85
|
+
'2': RoofCeiling,
|
|
86
|
+
'3': Floor,
|
|
87
|
+
'4': (Wall, RoofCeiling, Floor),
|
|
88
|
+
'Wall': Wall,
|
|
89
|
+
'Roof': RoofCeiling,
|
|
90
|
+
'RoofCeiling': RoofCeiling,
|
|
91
|
+
'Floor': Floor,
|
|
92
|
+
'All': (Wall, RoofCeiling, Floor)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if all_required_inputs(ghenv.Component):
|
|
97
|
+
# set defaults for any blank inputs
|
|
98
|
+
_offset_ = 0.1 / conversion_to_meters() if _offset_ is None else _offset_
|
|
99
|
+
ft = FACE_TYPES[_face_type_.title()] if _face_type_ is not None else Wall
|
|
100
|
+
|
|
101
|
+
# collect all of the relevant faces
|
|
102
|
+
faces = []
|
|
103
|
+
for obj in _hb_objs:
|
|
104
|
+
if isinstance(obj, (Model, Room)):
|
|
105
|
+
for face in obj.faces:
|
|
106
|
+
if isinstance(face.boundary_condition, Outdoors) and isinstance(face.type, ft):
|
|
107
|
+
faces.append(face)
|
|
108
|
+
elif isinstance(obj, Face):
|
|
109
|
+
if isinstance(obj.boundary_condition, Outdoors) and isinstance(obj.type, ft):
|
|
110
|
+
faces.append(obj)
|
|
111
|
+
else:
|
|
112
|
+
raise TypeError('Expected Honeybee Face, Room or Model. Got {}.'.format(type(obj)))
|
|
113
|
+
|
|
114
|
+
# greneate the meshes and grids from the faces
|
|
115
|
+
if len(faces) != 0:
|
|
116
|
+
# create the gridded ladybug Mesh3D
|
|
117
|
+
f_geos = [face.punched_geometry for face in faces] if punched_ else \
|
|
118
|
+
[face.geometry for face in faces]
|
|
119
|
+
if quad_only_: # use Ladybug's built-in meshing methods
|
|
120
|
+
lb_meshes = []
|
|
121
|
+
for geo in f_geos:
|
|
122
|
+
try:
|
|
123
|
+
lb_meshes.append(geo.mesh_grid(_grid_size, offset=_offset_))
|
|
124
|
+
except AssertionError:
|
|
125
|
+
continue
|
|
126
|
+
if len(lb_meshes) == 0:
|
|
127
|
+
lb_mesh = None
|
|
128
|
+
else:
|
|
129
|
+
lb_mesh = lb_meshes[0] if len(lb_meshes) == 1 else \
|
|
130
|
+
Mesh3D.join_meshes(lb_meshes)
|
|
131
|
+
else: # use Rhino's default meshing
|
|
132
|
+
rh_faces = [from_face3d(face) for face in f_geos]
|
|
133
|
+
lb_mesh = to_joined_gridded_mesh3d(rh_faces, _grid_size, _offset_)
|
|
134
|
+
|
|
135
|
+
if lb_mesh is not None:
|
|
136
|
+
# extract positions and directions from the mesh
|
|
137
|
+
mesh = from_mesh3d(lb_mesh)
|
|
138
|
+
points = [from_point3d(pt) for pt in lb_mesh.face_centroids]
|
|
139
|
+
base_poss = [(pt.x, pt.y, pt.z) for pt in lb_mesh.face_centroids]
|
|
140
|
+
base_dirs = [(vec.x, vec.y, vec.z) for vec in lb_mesh.face_normals]
|
|
141
|
+
|
|
142
|
+
# create the sensor grid
|
|
143
|
+
f_nm = 'Faces' if isinstance(ft, tuple) else ft.__name__
|
|
144
|
+
g_name = clean_rad_string('{}_Exterior{}'.format(_hb_objs[0].display_name, f_nm)) \
|
|
145
|
+
if len(_hb_objs) == 1 else clean_and_id_rad_string('Exterior{}'.format(f_nm))
|
|
146
|
+
grid = SensorGrid.from_position_and_direction(g_name, base_poss, base_dirs)
|
|
147
|
+
grid.mesh = lb_mesh
|
|
@@ -0,0 +1,210 @@
|
|
|
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
|
+
Generate SensorGrid objects from the floors of honeybee Rooms.
|
|
12
|
+
These SensorGrids can be used in a grid-based recipe.
|
|
13
|
+
-
|
|
14
|
+
The names of the grids will be the same as the rooms that they came from.
|
|
15
|
+
-
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
_rooms: A list of honeybee Rooms for which sensor grids will be generated.
|
|
19
|
+
This can also be an entire Honeybee Model from which Rooms will
|
|
20
|
+
be extracted.
|
|
21
|
+
_grid_size: Number for the size of the grid cells.
|
|
22
|
+
_dist_floor_: Number for the distance to move points from the floors of
|
|
23
|
+
the input rooms. The default is 0.8 meters.
|
|
24
|
+
quad_only_: Boolean to note whether meshing should be done using Rhino's
|
|
25
|
+
defaults (False), which fills the entire floor geometry to the edges
|
|
26
|
+
with both quad and tringulated faces, or a mesh with only quad
|
|
27
|
+
faces should be generated.
|
|
28
|
+
_
|
|
29
|
+
FOR ADVANCED USERS: This input can also be a vector object that will
|
|
30
|
+
be used to set the orientation of the quad-only grid. Note that,
|
|
31
|
+
if a vector is input here that is not aligned with the plane of
|
|
32
|
+
the room's floors, an error will be raised.
|
|
33
|
+
remove_out_: Boolean to note whether an extra check should be run to remove
|
|
34
|
+
sensor points that lie outside the Room volume. Note that this can
|
|
35
|
+
add significantly to the component's run time and this check is
|
|
36
|
+
usually not necessary in the case that all walls are vertical
|
|
37
|
+
and all floors are horizontal (Default: False).
|
|
38
|
+
wall_offset_: A number for the distance at which sensors close to walls
|
|
39
|
+
should be removed.
|
|
40
|
+
by_zone_: Set to "True" to have the component generate one sensor grid per zone
|
|
41
|
+
across the input rooms rather than one sensor grid per room. This
|
|
42
|
+
option is useful for getting a more consolidated set of Radiance
|
|
43
|
+
results by zone. (Default: False).
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
grid: A SensorGrid object that can be used in a grid-based recipe.
|
|
47
|
+
points: The points that are at the center of each grid cell.
|
|
48
|
+
mesh: Analysis mesh that can be passed to the 'Spatial Heatmap' component.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
ghenv.Component.Name = 'HB Sensor Grid from Rooms'
|
|
52
|
+
ghenv.Component.NickName = 'GridRooms'
|
|
53
|
+
ghenv.Component.Message = '1.9.1'
|
|
54
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
55
|
+
ghenv.Component.SubCategory = '0 :: Basic Properties'
|
|
56
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '4'
|
|
57
|
+
|
|
58
|
+
import math
|
|
59
|
+
from collections import OrderedDict
|
|
60
|
+
|
|
61
|
+
try: # import the ladybug_geometry dependencies
|
|
62
|
+
from ladybug_geometry.geometry3d.plane import Plane
|
|
63
|
+
from ladybug_geometry.geometry3d.face import Face3D
|
|
64
|
+
from ladybug_geometry.geometry3d.mesh import Mesh3D
|
|
65
|
+
except ImportError as e:
|
|
66
|
+
raise ImportError('\nFailed to import ladybug_geometry:\n\t{}'.format(e))
|
|
67
|
+
|
|
68
|
+
try: # import the core honeybee dependencies
|
|
69
|
+
from honeybee.model import Model
|
|
70
|
+
from honeybee.room import Room
|
|
71
|
+
from honeybee.facetype import Floor, Wall
|
|
72
|
+
from honeybee.typing import clean_rad_string
|
|
73
|
+
except ImportError as e:
|
|
74
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
75
|
+
|
|
76
|
+
try: # import the honeybee-radiance dependencies
|
|
77
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
78
|
+
except ImportError as e:
|
|
79
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
80
|
+
|
|
81
|
+
try: # import ladybug_rhino dependencies
|
|
82
|
+
from ladybug_rhino.config import conversion_to_meters, tolerance
|
|
83
|
+
from ladybug_rhino.togeometry import to_joined_gridded_mesh3d, to_vector3d
|
|
84
|
+
from ladybug_rhino.fromgeometry import from_mesh3d, from_point3d, from_face3d
|
|
85
|
+
from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree
|
|
86
|
+
except ImportError as e:
|
|
87
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if all_required_inputs(ghenv.Component):
|
|
91
|
+
# set defaults for any blank inputs and process the quad_only_
|
|
92
|
+
_dist_floor_ = 0.8 / conversion_to_meters() if _dist_floor_ is None else _dist_floor_
|
|
93
|
+
try:
|
|
94
|
+
x_axis = to_vector3d(quad_only_)
|
|
95
|
+
except AttributeError:
|
|
96
|
+
x_axis = None
|
|
97
|
+
|
|
98
|
+
# create lists to be filled with content
|
|
99
|
+
grid = []
|
|
100
|
+
points = []
|
|
101
|
+
mesh = []
|
|
102
|
+
rooms = []
|
|
103
|
+
for obj in _rooms:
|
|
104
|
+
if isinstance(obj, Model):
|
|
105
|
+
rooms.extend(obj.rooms)
|
|
106
|
+
elif isinstance(obj, Room):
|
|
107
|
+
rooms.append(obj)
|
|
108
|
+
else:
|
|
109
|
+
raise TypeError('Expected Honeybee Room or Model. Got {}.'.format(type(obj)))
|
|
110
|
+
|
|
111
|
+
# group the rooms by zone if requested
|
|
112
|
+
if by_zone_:
|
|
113
|
+
room_groups = OrderedDict()
|
|
114
|
+
for room in rooms:
|
|
115
|
+
try:
|
|
116
|
+
room_groups[room.zone].append(room)
|
|
117
|
+
except KeyError: # first room to be found in the zone
|
|
118
|
+
room_groups[room.zone] = [room]
|
|
119
|
+
else:
|
|
120
|
+
room_groups = OrderedDict([(room.identifier, [room]) for room in rooms])
|
|
121
|
+
|
|
122
|
+
for zone_id, room_group in room_groups.items():
|
|
123
|
+
# get all of the floor faces of the room
|
|
124
|
+
lb_floors = []
|
|
125
|
+
for room in room_group:
|
|
126
|
+
lb_floors.extend([floor.geometry.flip() for floor in room.floors])
|
|
127
|
+
|
|
128
|
+
if len(lb_floors) != 0:
|
|
129
|
+
# create the gridded ladybug Mesh3D
|
|
130
|
+
if quad_only_: # use Ladybug's built-in meshing methods
|
|
131
|
+
if x_axis:
|
|
132
|
+
lb_floors = [Face3D(f.boundary, Plane(f.normal, f[0], x_axis), f.holes)
|
|
133
|
+
for f in lb_floors]
|
|
134
|
+
lb_meshes = []
|
|
135
|
+
for geo in lb_floors:
|
|
136
|
+
try:
|
|
137
|
+
lb_meshes.append(geo.mesh_grid(_grid_size, offset=_dist_floor_))
|
|
138
|
+
except AssertionError:
|
|
139
|
+
continue
|
|
140
|
+
if len(lb_meshes) == 0:
|
|
141
|
+
lb_mesh = None
|
|
142
|
+
else:
|
|
143
|
+
lb_mesh = lb_meshes[0] if len(lb_meshes) == 1 else \
|
|
144
|
+
Mesh3D.join_meshes(lb_meshes)
|
|
145
|
+
else: # use Rhino's default meshing
|
|
146
|
+
floor_faces = [from_face3d(face) for face in lb_floors]
|
|
147
|
+
lb_mesh = to_joined_gridded_mesh3d(floor_faces, _grid_size, _dist_floor_)
|
|
148
|
+
|
|
149
|
+
# remove points outside of the room volume if requested
|
|
150
|
+
if remove_out_ and lb_mesh is not None:
|
|
151
|
+
pattern = []
|
|
152
|
+
for pt in lb_mesh.face_centroids:
|
|
153
|
+
for room in room_group:
|
|
154
|
+
if room.geometry.is_point_inside(pt):
|
|
155
|
+
pattern.append(True)
|
|
156
|
+
break
|
|
157
|
+
else:
|
|
158
|
+
pattern.append(False)
|
|
159
|
+
try:
|
|
160
|
+
lb_mesh, vertex_pattern = lb_mesh.remove_faces(pattern)
|
|
161
|
+
except AssertionError: # the grid lies completely outside of the room
|
|
162
|
+
lb_mesh = None
|
|
163
|
+
|
|
164
|
+
# remove any sensors within a certain distance of the walls, if requested
|
|
165
|
+
if wall_offset_ is not None and lb_mesh is not None:
|
|
166
|
+
wall_geos = []
|
|
167
|
+
for room in room_group:
|
|
168
|
+
wall_geos.extend([wall.geometry for wall in room.walls])
|
|
169
|
+
pattern = []
|
|
170
|
+
for pt in lb_mesh.face_centroids:
|
|
171
|
+
for wg in wall_geos:
|
|
172
|
+
close_pt = wg.plane.closest_point(pt)
|
|
173
|
+
p_dist = pt.distance_to_point(close_pt)
|
|
174
|
+
if p_dist <= wall_offset_:
|
|
175
|
+
close_pt_2d = wg.plane.xyz_to_xy(close_pt)
|
|
176
|
+
g_dist = wg.polygon2d.distance_to_point(close_pt_2d)
|
|
177
|
+
f_dist = math.sqrt(p_dist ** 2 + g_dist ** 2)
|
|
178
|
+
if f_dist <= wall_offset_:
|
|
179
|
+
pattern.append(False)
|
|
180
|
+
break
|
|
181
|
+
else:
|
|
182
|
+
pattern.append(True)
|
|
183
|
+
try:
|
|
184
|
+
lb_mesh, vertex_pattern = lb_mesh.remove_faces(pattern)
|
|
185
|
+
except AssertionError: # the grid lies completely outside of the room
|
|
186
|
+
lb_mesh = None
|
|
187
|
+
|
|
188
|
+
if lb_mesh is not None:
|
|
189
|
+
# extract positions and directions from the mesh
|
|
190
|
+
base_points = [from_point3d(pt) for pt in lb_mesh.face_centroids]
|
|
191
|
+
base_poss = [(pt.x, pt.y, pt.z) for pt in lb_mesh.face_centroids]
|
|
192
|
+
base_dirs = [(vec.x, vec.y, vec.z) for vec in lb_mesh.face_normals]
|
|
193
|
+
|
|
194
|
+
# create the sensor grid
|
|
195
|
+
grid_name = room.display_name if not by_zone_ else zone_id
|
|
196
|
+
s_grid = SensorGrid.from_position_and_direction(
|
|
197
|
+
clean_rad_string(grid_name), base_poss, base_dirs)
|
|
198
|
+
s_grid.display_name = grid_name
|
|
199
|
+
s_grid.room_identifier = room_group[0].identifier
|
|
200
|
+
s_grid.mesh = lb_mesh
|
|
201
|
+
s_grid.base_geometry = \
|
|
202
|
+
tuple(f.move(f.normal * _dist_floor_) for f in lb_floors)
|
|
203
|
+
|
|
204
|
+
# append everything to the lists
|
|
205
|
+
grid.append(s_grid)
|
|
206
|
+
points.append(base_points)
|
|
207
|
+
mesh.append(from_mesh3d(lb_mesh))
|
|
208
|
+
|
|
209
|
+
# convert the lists of points to data trees
|
|
210
|
+
points = list_to_data_tree(points)
|
|
@@ -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
|
+
Create a Sensor Grid object that can be used in a grid-based recipe.
|
|
12
|
+
-
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
_name_: A name for this sensor grid.
|
|
16
|
+
_positions: A list or a datatree of points with one point for the position
|
|
17
|
+
of each sensor. Each branch of the datatree will be considered as a
|
|
18
|
+
separate sensor grid.
|
|
19
|
+
_directions_: A list or a datatree of vectors with one vector for the
|
|
20
|
+
direction of each sensor. The input here MUST therefor align with
|
|
21
|
+
the input _positions. If no value is provided (0, 0, 1) will be
|
|
22
|
+
assigned for all the sensors.
|
|
23
|
+
mesh_: An optional mesh that aligns with the sensors. This is useful for
|
|
24
|
+
generating visualizations of the sensor grid beyond the sensor
|
|
25
|
+
positions. Note that the number of sensors in the grid must match
|
|
26
|
+
the number of faces or the number vertices within the mesh.
|
|
27
|
+
base_geo_: An optional Brep for the geometry used to make the grid. There are
|
|
28
|
+
no restrictions on how this brep relates to the sensors and it is
|
|
29
|
+
provided only to assist with the display of the grid when the number
|
|
30
|
+
of sensors or the mesh is too large to be practically visualized.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
grid: An SensorGrid object that can be used in a grid-based recipe.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
ghenv.Component.Name = 'HB Sensor Grid'
|
|
37
|
+
ghenv.Component.NickName = 'SensorGrid'
|
|
38
|
+
ghenv.Component.Message = '1.9.0'
|
|
39
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
40
|
+
ghenv.Component.SubCategory = '0 :: Basic Properties'
|
|
41
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '4'
|
|
42
|
+
|
|
43
|
+
try: # import the core honeybee dependencies
|
|
44
|
+
from honeybee.typing import clean_and_id_rad_string, clean_rad_string
|
|
45
|
+
except ImportError as e:
|
|
46
|
+
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
|
|
47
|
+
|
|
48
|
+
try: # import the honeybee-radiance dependencies
|
|
49
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
50
|
+
except ImportError as e:
|
|
51
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
52
|
+
|
|
53
|
+
try: # import ladybug_rhino dependencies
|
|
54
|
+
from ladybug_rhino.grasshopper import all_required_inputs
|
|
55
|
+
from ladybug_rhino.togeometry import to_mesh3d, to_face3d
|
|
56
|
+
except ImportError as e:
|
|
57
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if all_required_inputs(ghenv.Component):
|
|
61
|
+
# set the default name and process the points to tuples
|
|
62
|
+
name = clean_and_id_rad_string('SensorGrid') if _name_ is None else _name_
|
|
63
|
+
pts = [(pt.X, pt.Y, pt.Z) for pt in _positions]
|
|
64
|
+
|
|
65
|
+
# create the sensor grid object
|
|
66
|
+
id = clean_rad_string(name) if '/' not in name else clean_rad_string(name.split('/')[0])
|
|
67
|
+
if len(_directions_) == 0:
|
|
68
|
+
grid = SensorGrid.from_planar_positions(id, pts, (0, 0, 1))
|
|
69
|
+
else:
|
|
70
|
+
vecs = [(vec.X, vec.Y, vec.Z) for vec in _directions_]
|
|
71
|
+
grid = SensorGrid.from_position_and_direction(id, pts, vecs)
|
|
72
|
+
|
|
73
|
+
# set the display name
|
|
74
|
+
if _name_ is not None:
|
|
75
|
+
grid.display_name = _name_
|
|
76
|
+
if '/' in name:
|
|
77
|
+
grid.group_identifier = \
|
|
78
|
+
'/'.join(clean_rad_string(key) for key in name.split('/')[1:])
|
|
79
|
+
if mesh_ is not None:
|
|
80
|
+
grid.mesh = to_mesh3d(mesh_)
|
|
81
|
+
if base_geo_ is not None:
|
|
82
|
+
grid.base_geometry = to_face3d(base_geo_)
|
|
@@ -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 a list of modifiers that can be used to edit or create a ModifierSet object.
|
|
12
|
+
-
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
_exterior_shade_: A modifier object for exterior shades (or text for
|
|
16
|
+
the identifier of the modifier within the library).
|
|
17
|
+
_interior_shade_: A modifier object for interior shades (or text for
|
|
18
|
+
the identifier of the modifier within the library).
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
shade_set: A list of shade modifiers that can be used to edit or create
|
|
22
|
+
a ModifierSet object.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
ghenv.Component.Name = 'HB Shade Modifier Subset'
|
|
26
|
+
ghenv.Component.NickName = 'ShadeSubset'
|
|
27
|
+
ghenv.Component.Message = '1.9.0'
|
|
28
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
29
|
+
ghenv.Component.SubCategory = '1 :: Modifiers'
|
|
30
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '4'
|
|
31
|
+
|
|
32
|
+
try: # import honeybee_radiance dependencies
|
|
33
|
+
from honeybee_radiance.modifier import Modifier
|
|
34
|
+
from honeybee_radiance.lib.modifiers import modifier_by_identifier
|
|
35
|
+
except ImportError as e:
|
|
36
|
+
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
from ladybug_rhino.grasshopper import turn_off_old_tag
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
42
|
+
turn_off_old_tag(ghenv.Component)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def check_mod(mod, input_name):
|
|
46
|
+
"""Get an Modifier from the library if it's a string."""
|
|
47
|
+
if isinstance(mod, str):
|
|
48
|
+
return modifier_by_identifier(mod)
|
|
49
|
+
else:
|
|
50
|
+
assert isinstance(mod, Modifier), \
|
|
51
|
+
'Expected Modifier for {}. Got {}'.format(input_name, type(mod))
|
|
52
|
+
return mod
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# go through each input modifier
|
|
56
|
+
if _exterior_shade_ is not None:
|
|
57
|
+
_exterior_shade_ = check_mod(_exterior_shade_, '_exterior_shade_')
|
|
58
|
+
if _interior_shade_ is not None:
|
|
59
|
+
_interior_shade_ = check_mod(_interior_shade_, '_interior_shade_')
|
|
60
|
+
|
|
61
|
+
# return the final list from the component
|
|
62
|
+
shade_set = [_exterior_shade_, _interior_shade_]
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
Run a Sky View (SV) study for a Honeybee model.
|
|
12
|
+
_
|
|
13
|
+
Sky View is defined as the percent of the sky dome seen by a surface. These can
|
|
14
|
+
be computed either using a uniform (default) sky or a cloudy sky.
|
|
15
|
+
_
|
|
16
|
+
Note that computing cloudy Sky View for a vertically-oriented geometry (horizontal
|
|
17
|
+
sensor direction) will yield Vertical Sky Component (VSC) as described by the UK
|
|
18
|
+
Building Research Establishment (BRE). VSC is defined as the ratio of cloudy sky
|
|
19
|
+
illuminance falling on a vertical wall to the simultaneous horizontal illuminance
|
|
20
|
+
under an unobstructed sky [Littlefair, 1991].
|
|
21
|
+
_
|
|
22
|
+
Also note that this recipe still respects the transparency of objects, reducing
|
|
23
|
+
the percentage of the sky visible through a certain geometry by the transmittance
|
|
24
|
+
of that geometry.
|
|
25
|
+
|
|
26
|
+
-
|
|
27
|
+
Args:
|
|
28
|
+
_model: A Honeybee Model for which Sky View or Wky Exposure will be simulated.
|
|
29
|
+
Note that this model should have grids assigned to it in order
|
|
30
|
+
to produce meaningful results.
|
|
31
|
+
cloudy_sky_: A boolean to note whether a uniform sky should be used (False) or
|
|
32
|
+
a cloudy overcast sky (True). (Default: False).
|
|
33
|
+
grid_filter_: Text for a grid identifer or a pattern to filter the sensor grids of
|
|
34
|
+
the model that are simulated. For instance, `first_floor_*` will simulate
|
|
35
|
+
only the sensor grids that have an identifier that starts with
|
|
36
|
+
`first_floor_`. By default, all grids in the model will be simulated.
|
|
37
|
+
radiance_par_: Text for the radiance parameters to be used for ray
|
|
38
|
+
tracing. (Default: -ab 2 -aa 0.1 -ad 2048 -ar 64).
|
|
39
|
+
run_settings_: Settings from the "HB Recipe Settings" component that specify
|
|
40
|
+
how the recipe should be run. This can also be a text string of
|
|
41
|
+
recipe settings.
|
|
42
|
+
_run: Set to True to run the recipe and get results.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
report: Reports, errors, warnings, etc.
|
|
46
|
+
results: Numbers for the sky view or sky exposure at each sensor. These can be plugged
|
|
47
|
+
into the "LB Spatial Heatmap" component along with meshes of the
|
|
48
|
+
sensor grids to visualize results. Values are in percent (between 0
|
|
49
|
+
and 100).
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
ghenv.Component.Name = 'HB Sky View'
|
|
53
|
+
ghenv.Component.NickName = 'SkyView'
|
|
54
|
+
ghenv.Component.Message = '1.9.0'
|
|
55
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
56
|
+
ghenv.Component.SubCategory = '3 :: Recipes'
|
|
57
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '3'
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
from lbt_recipes.recipe import Recipe
|
|
61
|
+
except ImportError as e:
|
|
62
|
+
raise ImportError('\nFailed to import lbt_recipes:\n\t{}'.format(e))
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
from ladybug_rhino.grasshopper import all_required_inputs, recipe_result
|
|
66
|
+
except ImportError as e:
|
|
67
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if all_required_inputs(ghenv.Component) and _run:
|
|
71
|
+
# create the recipe and set the input arguments
|
|
72
|
+
recipe = Recipe('sky-view')
|
|
73
|
+
recipe.input_value_by_name('model', _model)
|
|
74
|
+
recipe.input_value_by_name('grid-filter', grid_filter_)
|
|
75
|
+
recipe.input_value_by_name('cloudy-sky', cloudy_sky_)
|
|
76
|
+
recipe.input_value_by_name('radiance-parameters', radiance_par_)
|
|
77
|
+
|
|
78
|
+
# run the recipe
|
|
79
|
+
silent = True if _run > 1 else False
|
|
80
|
+
project_folder = recipe.run(run_settings_, radiance_check=True, silent=silent)
|
|
81
|
+
|
|
82
|
+
# load the results
|
|
83
|
+
try:
|
|
84
|
+
results = recipe_result(recipe.output_value_by_name('results', project_folder))
|
|
85
|
+
except Exception:
|
|
86
|
+
raise Exception(recipe.failure_message(project_folder))
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
Calculate Spatial Daylight Autonomy (sDA) from lists of daylight autonomy values.
|
|
11
|
+
_
|
|
12
|
+
As per IES-LM-83-12 Spatial Daylight Autonomy (sDA) is a metric describing
|
|
13
|
+
annual sufficiency of ambient daylight levels in interior environments.
|
|
14
|
+
It is defined as the percent of an analysis area (the area where calcuations
|
|
15
|
+
are performed -typically across an entire space) that meets a minimum
|
|
16
|
+
daylight illuminance level for a specified fraction of the operating hours
|
|
17
|
+
per year. The sDA value is expressed as a percentage of area.
|
|
18
|
+
_
|
|
19
|
+
Note: This component will only output a LEED compliant sDA if you've run the
|
|
20
|
+
simulation with dynamic blinds and blind schedules as per the IES-LM-83-12
|
|
21
|
+
standard. If you are not using dynamic blinds, then this output is NOT LEED
|
|
22
|
+
compliant.
|
|
23
|
+
|
|
24
|
+
-
|
|
25
|
+
Args:
|
|
26
|
+
_DA: A data tree of daylight autonomy values output from the "HB Annual Dalyight"
|
|
27
|
+
recipe or the "HB Annual Daylight Metrics" component. Note that,
|
|
28
|
+
unless these DA values follow LM83 dynamic blinds setup, the resulting
|
|
29
|
+
sDA is not LEED compliant.
|
|
30
|
+
mesh_: An optional list of Meshes that align with the _DA data tree above, which
|
|
31
|
+
will be used to assign an area to each sensor. If no mesh is connected
|
|
32
|
+
here, it will be assumed that each sensor represents an equal area
|
|
33
|
+
to all of the others.
|
|
34
|
+
_target_time_: A minimum threshold of occupied time (eg. 50% of the time), above
|
|
35
|
+
which a given sensor passes and contributes to the spatial daylight
|
|
36
|
+
autonomy. (Default: 50%).
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
report: Reports, errors, warnings, etc.
|
|
40
|
+
sDA: Spatial daylight autonomy as percentage of area for each analysis grid.
|
|
41
|
+
pass_fail: A data tree of zeros and ones, which indicate whether a given senor
|
|
42
|
+
passes the criteria for being daylit (1) or fails the criteria (0).
|
|
43
|
+
Each value is for a different sensor of the grid. These can be plugged
|
|
44
|
+
into the "LB Spatial Heatmap" component along with meshes of the
|
|
45
|
+
sensor grids to visualize results.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
ghenv.Component.Name = 'HB Spatial Daylight Autonomy'
|
|
49
|
+
ghenv.Component.NickName = 'sDA'
|
|
50
|
+
ghenv.Component.Message = '1.9.0'
|
|
51
|
+
ghenv.Component.Category = 'HB-Radiance'
|
|
52
|
+
ghenv.Component.SubCategory = '4 :: Results'
|
|
53
|
+
ghenv.Component.AdditionalHelpFromDocStrings = '1'
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
from ladybug_rhino.togeometry import to_mesh3d
|
|
57
|
+
except ImportError as e:
|
|
58
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree, \
|
|
62
|
+
data_tree_to_list
|
|
63
|
+
except ImportError as e:
|
|
64
|
+
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if all_required_inputs(ghenv.Component):
|
|
68
|
+
# process the input values into a rokable format
|
|
69
|
+
da_mtx = [item[-1] for item in data_tree_to_list(_DA)]
|
|
70
|
+
_target_time_ = 50 if _target_time_ is None else _target_time_
|
|
71
|
+
lb_meshes = [to_mesh3d(mesh) for mesh in mesh_]
|
|
72
|
+
|
|
73
|
+
# determine whether each point passes or fails
|
|
74
|
+
pass_fail = [[int(val > _target_time_) for val in grid] for grid in da_mtx]
|
|
75
|
+
|
|
76
|
+
# compute spatial daylight autonomy from the pass/fail results
|
|
77
|
+
if len(lb_meshes) == 0: # all sensors represent the same area
|
|
78
|
+
sDA = [sum(pf_list) / len(pf_list) for pf_list in pass_fail]
|
|
79
|
+
else: # weight the sensors based on the area of mesh faces
|
|
80
|
+
sDA = []
|
|
81
|
+
for i, mesh in enumerate(lb_meshes):
|
|
82
|
+
m_area = mesh.area
|
|
83
|
+
weights = [fa / m_area for fa in mesh.face_areas]
|
|
84
|
+
sDA.append(sum(v * w for v, w in zip(pass_fail[i], weights)))
|
|
85
|
+
|
|
86
|
+
pass_fail = list_to_data_tree(pass_fail) # convert matrix to data tree
|