voxcity 1.0.13__py3-none-any.whl → 1.0.15__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.
@@ -29,7 +29,17 @@ from .solar import (
29
29
  discretize_sky_directions
30
30
  )
31
31
 
32
- from .raytracing import RayTracer
32
+ from .raytracing import (
33
+ RayTracer,
34
+ ray_aabb_intersect,
35
+ ray_voxel_first_hit,
36
+ ray_canopy_absorption,
37
+ ray_voxel_transmissivity,
38
+ ray_trace_to_target,
39
+ ray_point_to_point_transmissivity,
40
+ sample_hemisphere_direction,
41
+ hemisphere_solid_angle,
42
+ )
33
43
 
34
44
  from .svf import SVFCalculator
35
45
 
@@ -70,6 +80,15 @@ from .sky import (
70
80
  TREGENZA_BAND_BOUNDARIES,
71
81
  )
72
82
 
83
+ # Computation mask utilities
84
+ from .mask import (
85
+ create_computation_mask,
86
+ draw_computation_mask,
87
+ get_mask_from_drawing,
88
+ visualize_computation_mask,
89
+ get_mask_info,
90
+ )
91
+
73
92
  # VoxCity integration
74
93
  from .integration import (
75
94
  load_voxcity,
@@ -90,6 +109,11 @@ from .integration import (
90
109
  get_cumulative_building_solar_irradiance,
91
110
  get_global_solar_irradiance_using_epw,
92
111
  get_building_global_solar_irradiance_using_epw,
112
+ # Volumetric solar irradiance functions
113
+ get_volumetric_solar_irradiance_map,
114
+ get_cumulative_volumetric_solar_irradiance,
115
+ get_volumetric_solar_irradiance_using_epw,
116
+ clear_volumetric_flux_cache,
93
117
  save_irradiance_mesh,
94
118
  load_irradiance_mesh,
95
119
  # Temporal utilities
@@ -98,6 +122,7 @@ from .integration import (
98
122
  clear_radiation_model_cache,
99
123
  clear_building_radiation_model_cache,
100
124
  clear_all_radiation_caches,
125
+ clear_all_caches,
101
126
  )
102
127
 
103
128
  __version__ = "0.1.0"
@@ -115,6 +140,14 @@ __all__ = [
115
140
  'discretize_sky_directions',
116
141
  # Ray tracing
117
142
  'RayTracer',
143
+ 'ray_aabb_intersect',
144
+ 'ray_voxel_first_hit',
145
+ 'ray_canopy_absorption',
146
+ 'ray_voxel_transmissivity',
147
+ 'ray_trace_to_target',
148
+ 'ray_point_to_point_transmissivity',
149
+ 'sample_hemisphere_direction',
150
+ 'hemisphere_solid_angle',
118
151
  # SVF
119
152
  'SVFCalculator',
120
153
  # CSF
@@ -148,6 +181,12 @@ __all__ = [
148
181
  'visualize_sky_patches',
149
182
  'TREGENZA_BANDS',
150
183
  'TREGENZA_BAND_BOUNDARIES',
184
+ # Computation mask utilities
185
+ 'create_computation_mask',
186
+ 'draw_computation_mask',
187
+ 'get_mask_from_drawing',
188
+ 'visualize_computation_mask',
189
+ 'get_mask_info',
151
190
  # VoxCity integration
152
191
  'load_voxcity',
153
192
  'convert_voxcity_to_domain',
@@ -167,6 +206,11 @@ __all__ = [
167
206
  'get_cumulative_building_solar_irradiance',
168
207
  'get_global_solar_irradiance_using_epw',
169
208
  'get_building_global_solar_irradiance_using_epw',
209
+ # Volumetric solar irradiance functions
210
+ 'get_volumetric_solar_irradiance_map',
211
+ 'get_cumulative_volumetric_solar_irradiance',
212
+ 'get_volumetric_solar_irradiance_using_epw',
213
+ 'clear_volumetric_flux_cache',
170
214
  'save_irradiance_mesh',
171
215
  'load_irradiance_mesh',
172
216
  # Cache management
@@ -238,6 +238,63 @@ class Domain:
238
238
  self._set_lad_kernel(lad_array)
239
239
  self._update_plant_top()
240
240
 
241
+ def set_from_voxel_data(self, voxel_data: np.ndarray, tree_code: int = -2, solid_codes: Optional[list] = None):
242
+ """
243
+ Set domain from a 3D voxel data array.
244
+
245
+ Args:
246
+ voxel_data: 3D numpy array with voxel class codes
247
+ tree_code: Class code for trees (default -2)
248
+ solid_codes: List of codes that are solid (default: all non-zero except tree_code)
249
+ """
250
+ if solid_codes is None:
251
+ # All non-zero codes except tree are solid
252
+ solid_codes = []
253
+
254
+ self._set_from_voxel_data_kernel(voxel_data, tree_code)
255
+
256
+ @ti.kernel
257
+ def _set_from_voxel_data_kernel(self, voxel_data: ti.types.ndarray(), tree_code: ti.i32):
258
+ for i, j, k in ti.ndrange(self.nx, self.ny, self.nz):
259
+ val = voxel_data[i, j, k]
260
+ if val == tree_code:
261
+ self.is_tree[i, j, k] = 1
262
+ self.is_solid[i, j, k] = 0
263
+ elif val != 0:
264
+ self.is_solid[i, j, k] = 1
265
+ self.is_tree[i, j, k] = 0
266
+ else:
267
+ self.is_solid[i, j, k] = 0
268
+ self.is_tree[i, j, k] = 0
269
+
270
+ def add_tree_box(
271
+ self,
272
+ x_range: Tuple[int, int],
273
+ y_range: Tuple[int, int],
274
+ z_range: Tuple[int, int],
275
+ lad_value: float = 1.0
276
+ ):
277
+ """
278
+ Add a box-shaped tree canopy region to the domain.
279
+
280
+ This is a simpler alternative to add_tree() for rectangular tree regions.
281
+
282
+ Args:
283
+ x_range, y_range, z_range: Grid index ranges (start, end)
284
+ lad_value: Leaf Area Density value (m^2/m^3)
285
+ """
286
+ self._add_tree_box_kernel(x_range[0], x_range[1], y_range[0], y_range[1],
287
+ z_range[0], z_range[1], lad_value)
288
+ self._update_plant_top()
289
+
290
+ @ti.kernel
291
+ def _add_tree_box_kernel(self, i_min: ti.i32, i_max: ti.i32, j_min: ti.i32,
292
+ j_max: ti.i32, k_min: ti.i32, k_max: ti.i32, lad: ti.f32):
293
+ for i, j, k in ti.ndrange((i_min, i_max), (j_min, j_max), (k_min, k_max)):
294
+ if 0 <= i < self.nx and 0 <= j < self.ny and 0 <= k < self.nz:
295
+ self.is_tree[i, j, k] = 1
296
+ self.lad[i, j, k] = lad
297
+
241
298
  @ti.kernel
242
299
  def _set_lad_kernel(self, lad_array: ti.types.ndarray()):
243
300
  for i, j, k in self.lad: