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.
Files changed (170) hide show
  1. honeybee_grasshopper_radiance/__init__.py +7 -0
  2. honeybee_grasshopper_radiance/src/HB Adjust HDR.py +107 -0
  3. honeybee_grasshopper_radiance/src/HB Ambient Resolution.py +63 -0
  4. honeybee_grasshopper_radiance/src/HB Annual Average Values.py +205 -0
  5. honeybee_grasshopper_radiance/src/HB Annual Cumulative Values.py +191 -0
  6. honeybee_grasshopper_radiance/src/HB Annual Daylight Metrics.py +209 -0
  7. honeybee_grasshopper_radiance/src/HB Annual Daylight.py +153 -0
  8. honeybee_grasshopper_radiance/src/HB Annual Glare Metrics.py +137 -0
  9. honeybee_grasshopper_radiance/src/HB Annual Irradiance.py +112 -0
  10. honeybee_grasshopper_radiance/src/HB Annual Peak Values.py +224 -0
  11. honeybee_grasshopper_radiance/src/HB Annual Results to Data.py +246 -0
  12. honeybee_grasshopper_radiance/src/HB Annual Sunlight Exposure.py +147 -0
  13. honeybee_grasshopper_radiance/src/HB Aperture Group Schedule.py +69 -0
  14. honeybee_grasshopper_radiance/src/HB Apply Face Modifier.py +107 -0
  15. honeybee_grasshopper_radiance/src/HB Apply ModifierSet.py +71 -0
  16. honeybee_grasshopper_radiance/src/HB Apply Shade Modifier.py +110 -0
  17. honeybee_grasshopper_radiance/src/HB Apply Window Modifier.py +120 -0
  18. honeybee_grasshopper_radiance/src/HB Assign Grids and Views.py +58 -0
  19. honeybee_grasshopper_radiance/src/HB Automatic Aperture Group.py +100 -0
  20. honeybee_grasshopper_radiance/src/HB BSDF Modifier.py +78 -0
  21. honeybee_grasshopper_radiance/src/HB CIE Standard Sky.py +75 -0
  22. honeybee_grasshopper_radiance/src/HB Certain Illuminance.py +41 -0
  23. honeybee_grasshopper_radiance/src/HB Check Scene.py +208 -0
  24. honeybee_grasshopper_radiance/src/HB Climatebased Sky.py +75 -0
  25. honeybee_grasshopper_radiance/src/HB Cumulative Radiation.py +98 -0
  26. honeybee_grasshopper_radiance/src/HB Custom Sky.py +74 -0
  27. honeybee_grasshopper_radiance/src/HB Daylight Control Schedule.py +211 -0
  28. honeybee_grasshopper_radiance/src/HB Daylight Factor.py +82 -0
  29. honeybee_grasshopper_radiance/src/HB Deconstruct Modifier.py +47 -0
  30. honeybee_grasshopper_radiance/src/HB Deconstruct ModifierSet Interior.py +67 -0
  31. honeybee_grasshopper_radiance/src/HB Deconstruct ModifierSet.py +80 -0
  32. honeybee_grasshopper_radiance/src/HB Deconstruct Wea.py +44 -0
  33. honeybee_grasshopper_radiance/src/HB Direct Sun Hours.py +88 -0
  34. honeybee_grasshopper_radiance/src/HB Dynamic Aperture Group.py +90 -0
  35. honeybee_grasshopper_radiance/src/HB Dynamic Shade Group.py +95 -0
  36. honeybee_grasshopper_radiance/src/HB Dynamic State Geometry.py +68 -0
  37. honeybee_grasshopper_radiance/src/HB Dynamic State.py +44 -0
  38. honeybee_grasshopper_radiance/src/HB Exterior Modifier Subset.py +68 -0
  39. honeybee_grasshopper_radiance/src/HB Extract HDR.py +225 -0
  40. honeybee_grasshopper_radiance/src/HB False Color.py +246 -0
  41. honeybee_grasshopper_radiance/src/HB Get Dynamic Groups.py +57 -0
  42. honeybee_grasshopper_radiance/src/HB Get Grids and Views.py +82 -0
  43. honeybee_grasshopper_radiance/src/HB Glare Postprocess.py +225 -0
  44. honeybee_grasshopper_radiance/src/HB Glass Modifier 3.py +62 -0
  45. honeybee_grasshopper_radiance/src/HB Glass Modifier.py +58 -0
  46. honeybee_grasshopper_radiance/src/HB HDR to GIF.py +72 -0
  47. honeybee_grasshopper_radiance/src/HB Imageless Annual Glare.py +108 -0
  48. honeybee_grasshopper_radiance/src/HB Interior Modifier Subset.py +83 -0
  49. honeybee_grasshopper_radiance/src/HB Metal Modifier 3.py +70 -0
  50. honeybee_grasshopper_radiance/src/HB Metal Modifier.py +68 -0
  51. honeybee_grasshopper_radiance/src/HB Mirror Modifier 3.py +56 -0
  52. honeybee_grasshopper_radiance/src/HB Mirror Modifier.py +55 -0
  53. honeybee_grasshopper_radiance/src/HB Model to Rad Folder.py +75 -0
  54. honeybee_grasshopper_radiance/src/HB ModifierSet.py +127 -0
  55. honeybee_grasshopper_radiance/src/HB Opaque Modifier 3.py +68 -0
  56. honeybee_grasshopper_radiance/src/HB Opaque Modifier.py +67 -0
  57. honeybee_grasshopper_radiance/src/HB Point-In-Time Grid-Based.py +93 -0
  58. honeybee_grasshopper_radiance/src/HB Point-In-Time View-Based.py +127 -0
  59. honeybee_grasshopper_radiance/src/HB Radial Grid from Rooms.py +160 -0
  60. honeybee_grasshopper_radiance/src/HB Radial Sensor Grid.py +99 -0
  61. honeybee_grasshopper_radiance/src/HB Radiance Parameter.py +163 -0
  62. honeybee_grasshopper_radiance/src/HB Search Modifier Sets.py +58 -0
  63. honeybee_grasshopper_radiance/src/HB Search Modifiers.py +58 -0
  64. honeybee_grasshopper_radiance/src/HB Section Plane View.py +69 -0
  65. honeybee_grasshopper_radiance/src/HB Sensor Grid from Apertures.py +153 -0
  66. honeybee_grasshopper_radiance/src/HB Sensor Grid from Faces.py +147 -0
  67. honeybee_grasshopper_radiance/src/HB Sensor Grid from Rooms.py +210 -0
  68. honeybee_grasshopper_radiance/src/HB Sensor Grid.py +82 -0
  69. honeybee_grasshopper_radiance/src/HB Shade Modifier Subset.py +62 -0
  70. honeybee_grasshopper_radiance/src/HB Sky View.py +86 -0
  71. honeybee_grasshopper_radiance/src/HB Spatial Daylight Autonomy.py +86 -0
  72. honeybee_grasshopper_radiance/src/HB Subface Modifier Subset.py +90 -0
  73. honeybee_grasshopper_radiance/src/HB Translucent Modifier 3.py +77 -0
  74. honeybee_grasshopper_radiance/src/HB Translucent Modifier.py +77 -0
  75. honeybee_grasshopper_radiance/src/HB View from Viewport.py +85 -0
  76. honeybee_grasshopper_radiance/src/HB View.py +96 -0
  77. honeybee_grasshopper_radiance/src/HB Visualize Sky.py +141 -0
  78. honeybee_grasshopper_radiance/src/HB Wea From Clear Sky.py +61 -0
  79. honeybee_grasshopper_radiance/src/HB Wea From EPW.py +50 -0
  80. honeybee_grasshopper_radiance/src/HB Wea From Tau Clear Sky.py +56 -0
  81. honeybee_grasshopper_radiance/src/HB Wea from Zhang-Huang.py +63 -0
  82. honeybee_grasshopper_radiance/src/__init__.py +1 -0
  83. honeybee_grasshopper_radiance/user_objects/HB Adjust HDR.ghuser +0 -0
  84. honeybee_grasshopper_radiance/user_objects/HB Ambient Resolution.ghuser +0 -0
  85. honeybee_grasshopper_radiance/user_objects/HB Annual Average Values.ghuser +0 -0
  86. honeybee_grasshopper_radiance/user_objects/HB Annual Cumulative Values.ghuser +0 -0
  87. honeybee_grasshopper_radiance/user_objects/HB Annual Daylight Metrics.ghuser +0 -0
  88. honeybee_grasshopper_radiance/user_objects/HB Annual Daylight.ghuser +0 -0
  89. honeybee_grasshopper_radiance/user_objects/HB Annual Glare Metrics.ghuser +0 -0
  90. honeybee_grasshopper_radiance/user_objects/HB Annual Irradiance.ghuser +0 -0
  91. honeybee_grasshopper_radiance/user_objects/HB Annual Peak Values.ghuser +0 -0
  92. honeybee_grasshopper_radiance/user_objects/HB Annual Results to Data.ghuser +0 -0
  93. honeybee_grasshopper_radiance/user_objects/HB Annual Sunlight Exposure.ghuser +0 -0
  94. honeybee_grasshopper_radiance/user_objects/HB Aperture Group Schedule.ghuser +0 -0
  95. honeybee_grasshopper_radiance/user_objects/HB Apply Face Modifier.ghuser +0 -0
  96. honeybee_grasshopper_radiance/user_objects/HB Apply ModifierSet.ghuser +0 -0
  97. honeybee_grasshopper_radiance/user_objects/HB Apply Shade Modifier.ghuser +0 -0
  98. honeybee_grasshopper_radiance/user_objects/HB Apply Window Modifier.ghuser +0 -0
  99. Views.ghuser +0 -0
  100. honeybee_grasshopper_radiance/user_objects/HB Automatic Aperture Group.ghuser +0 -0
  101. honeybee_grasshopper_radiance/user_objects/HB BSDF Modifier.ghuser +0 -0
  102. honeybee_grasshopper_radiance/user_objects/HB CIE Standard Sky.ghuser +0 -0
  103. honeybee_grasshopper_radiance/user_objects/HB Certain Illuminance.ghuser +0 -0
  104. honeybee_grasshopper_radiance/user_objects/HB Check Scene.ghuser +0 -0
  105. honeybee_grasshopper_radiance/user_objects/HB Climatebased Sky.ghuser +0 -0
  106. honeybee_grasshopper_radiance/user_objects/HB Cumulative Radiation.ghuser +0 -0
  107. honeybee_grasshopper_radiance/user_objects/HB Custom Sky.ghuser +0 -0
  108. honeybee_grasshopper_radiance/user_objects/HB Daylight Control Schedule.ghuser +0 -0
  109. honeybee_grasshopper_radiance/user_objects/HB Daylight Factor.ghuser +0 -0
  110. honeybee_grasshopper_radiance/user_objects/HB Deconstruct Modifier.ghuser +0 -0
  111. honeybee_grasshopper_radiance/user_objects/HB Deconstruct ModifierSet Interior.ghuser +0 -0
  112. honeybee_grasshopper_radiance/user_objects/HB Deconstruct ModifierSet.ghuser +0 -0
  113. honeybee_grasshopper_radiance/user_objects/HB Deconstruct Wea.ghuser +0 -0
  114. honeybee_grasshopper_radiance/user_objects/HB Direct Sun Hours.ghuser +0 -0
  115. honeybee_grasshopper_radiance/user_objects/HB Dynamic Aperture Group.ghuser +0 -0
  116. honeybee_grasshopper_radiance/user_objects/HB Dynamic Shade Group.ghuser +0 -0
  117. honeybee_grasshopper_radiance/user_objects/HB Dynamic State Geometry.ghuser +0 -0
  118. honeybee_grasshopper_radiance/user_objects/HB Dynamic State.ghuser +0 -0
  119. honeybee_grasshopper_radiance/user_objects/HB Exterior Modifier Subset.ghuser +0 -0
  120. honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser +0 -0
  121. honeybee_grasshopper_radiance/user_objects/HB Face Radiance Attributes.ghuser +0 -0
  122. honeybee_grasshopper_radiance/user_objects/HB False Color.ghuser +0 -0
  123. honeybee_grasshopper_radiance/user_objects/HB Get Dynamic Groups.ghuser +0 -0
  124. Views.ghuser +0 -0
  125. honeybee_grasshopper_radiance/user_objects/HB Glare Postprocess.ghuser +0 -0
  126. honeybee_grasshopper_radiance/user_objects/HB Glass Modifier 3.ghuser +0 -0
  127. honeybee_grasshopper_radiance/user_objects/HB Glass Modifier.ghuser +0 -0
  128. honeybee_grasshopper_radiance/user_objects/HB HDR to GIF.ghuser +0 -0
  129. honeybee_grasshopper_radiance/user_objects/HB Imageless Annual Glare.ghuser +0 -0
  130. honeybee_grasshopper_radiance/user_objects/HB Interior Modifier Subset.ghuser +0 -0
  131. honeybee_grasshopper_radiance/user_objects/HB Metal Modifier 3.ghuser +0 -0
  132. honeybee_grasshopper_radiance/user_objects/HB Metal Modifier.ghuser +0 -0
  133. honeybee_grasshopper_radiance/user_objects/HB Mirror Modifier 3.ghuser +0 -0
  134. honeybee_grasshopper_radiance/user_objects/HB Mirror Modifier.ghuser +0 -0
  135. honeybee_grasshopper_radiance/user_objects/HB Model to Rad Folder.ghuser +0 -0
  136. honeybee_grasshopper_radiance/user_objects/HB ModifierSet.ghuser +0 -0
  137. honeybee_grasshopper_radiance/user_objects/HB Opaque Modifier 3.ghuser +0 -0
  138. honeybee_grasshopper_radiance/user_objects/HB Opaque Modifier.ghuser +0 -0
  139. honeybee_grasshopper_radiance/user_objects/HB Point-In-Time Grid-Based.ghuser +0 -0
  140. honeybee_grasshopper_radiance/user_objects/HB Point-In-Time View-Based.ghuser +0 -0
  141. honeybee_grasshopper_radiance/user_objects/HB Radial Grid from Rooms.ghuser +0 -0
  142. honeybee_grasshopper_radiance/user_objects/HB Radial Sensor Grid.ghuser +0 -0
  143. honeybee_grasshopper_radiance/user_objects/HB Radiance Parameter.ghuser +0 -0
  144. honeybee_grasshopper_radiance/user_objects/HB Room Radiance Attributes.ghuser +0 -0
  145. honeybee_grasshopper_radiance/user_objects/HB Search Modifier Sets.ghuser +0 -0
  146. honeybee_grasshopper_radiance/user_objects/HB Search Modifiers.ghuser +0 -0
  147. honeybee_grasshopper_radiance/user_objects/HB Section Plane View.ghuser +0 -0
  148. honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Apertures.ghuser +0 -0
  149. honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Faces.ghuser +0 -0
  150. honeybee_grasshopper_radiance/user_objects/HB Sensor Grid from Rooms.ghuser +0 -0
  151. honeybee_grasshopper_radiance/user_objects/HB Sensor Grid.ghuser +0 -0
  152. honeybee_grasshopper_radiance/user_objects/HB Shade Modifier Subset.ghuser +0 -0
  153. honeybee_grasshopper_radiance/user_objects/HB Sky View.ghuser +0 -0
  154. honeybee_grasshopper_radiance/user_objects/HB Spatial Daylight Autonomy.ghuser +0 -0
  155. honeybee_grasshopper_radiance/user_objects/HB Subface Modifier Subset.ghuser +0 -0
  156. honeybee_grasshopper_radiance/user_objects/HB Translucent Modifier 3.ghuser +0 -0
  157. honeybee_grasshopper_radiance/user_objects/HB Translucent Modifier.ghuser +0 -0
  158. honeybee_grasshopper_radiance/user_objects/HB View from Viewport.ghuser +0 -0
  159. honeybee_grasshopper_radiance/user_objects/HB View.ghuser +0 -0
  160. honeybee_grasshopper_radiance/user_objects/HB Visualize Sky.ghuser +0 -0
  161. honeybee_grasshopper_radiance/user_objects/HB Wea From Clear Sky.ghuser +0 -0
  162. honeybee_grasshopper_radiance/user_objects/HB Wea From EPW.ghuser +0 -0
  163. honeybee_grasshopper_radiance/user_objects/HB Wea From Tau Clear Sky.ghuser +0 -0
  164. honeybee_grasshopper_radiance/user_objects/HB Wea from Zhang-Huang.ghuser +0 -0
  165. honeybee_grasshopper_radiance/user_objects/__init__.py +1 -0
  166. honeybee_grasshopper_radiance-1.35.1.dist-info/METADATA +64 -0
  167. honeybee_grasshopper_radiance-1.35.1.dist-info/RECORD +170 -0
  168. honeybee_grasshopper_radiance-1.35.1.dist-info/WHEEL +5 -0
  169. honeybee_grasshopper_radiance-1.35.1.dist-info/licenses/LICENSE +661 -0
  170. 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