honeybee-radiance 1.66.190__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of honeybee-radiance might be problematic. Click here for more details.
- honeybee_radiance/__init__.py +11 -0
- honeybee_radiance/__main__.py +4 -0
- honeybee_radiance/_extend_honeybee.py +93 -0
- honeybee_radiance/cli/__init__.py +88 -0
- honeybee_radiance/cli/dc.py +400 -0
- honeybee_radiance/cli/edit.py +529 -0
- honeybee_radiance/cli/glare.py +118 -0
- honeybee_radiance/cli/grid.py +859 -0
- honeybee_radiance/cli/lib.py +458 -0
- honeybee_radiance/cli/modifier.py +133 -0
- honeybee_radiance/cli/mtx.py +226 -0
- honeybee_radiance/cli/multiphase.py +1034 -0
- honeybee_radiance/cli/octree.py +640 -0
- honeybee_radiance/cli/postprocess.py +1186 -0
- honeybee_radiance/cli/raytrace.py +219 -0
- honeybee_radiance/cli/rpict.py +125 -0
- honeybee_radiance/cli/schedule.py +56 -0
- honeybee_radiance/cli/setconfig.py +63 -0
- honeybee_radiance/cli/sky.py +545 -0
- honeybee_radiance/cli/study.py +66 -0
- honeybee_radiance/cli/sunpath.py +331 -0
- honeybee_radiance/cli/threephase.py +255 -0
- honeybee_radiance/cli/translate.py +400 -0
- honeybee_radiance/cli/util.py +121 -0
- honeybee_radiance/cli/view.py +261 -0
- honeybee_radiance/cli/viewfactor.py +347 -0
- honeybee_radiance/config.json +6 -0
- honeybee_radiance/config.py +427 -0
- honeybee_radiance/dictutil.py +50 -0
- honeybee_radiance/dynamic/__init__.py +5 -0
- honeybee_radiance/dynamic/group.py +479 -0
- honeybee_radiance/dynamic/multiphase.py +557 -0
- honeybee_radiance/dynamic/state.py +718 -0
- honeybee_radiance/dynamic/stategeo.py +352 -0
- honeybee_radiance/geometry/__init__.py +13 -0
- honeybee_radiance/geometry/bubble.py +42 -0
- honeybee_radiance/geometry/cone.py +215 -0
- honeybee_radiance/geometry/cup.py +54 -0
- honeybee_radiance/geometry/cylinder.py +197 -0
- honeybee_radiance/geometry/geometrybase.py +37 -0
- honeybee_radiance/geometry/instance.py +40 -0
- honeybee_radiance/geometry/mesh.py +38 -0
- honeybee_radiance/geometry/polygon.py +174 -0
- honeybee_radiance/geometry/ring.py +214 -0
- honeybee_radiance/geometry/source.py +182 -0
- honeybee_radiance/geometry/sphere.py +178 -0
- honeybee_radiance/geometry/tube.py +46 -0
- honeybee_radiance/lib/__init__.py +1 -0
- honeybee_radiance/lib/_loadmodifiers.py +72 -0
- honeybee_radiance/lib/_loadmodifiersets.py +69 -0
- honeybee_radiance/lib/modifiers.py +58 -0
- honeybee_radiance/lib/modifiersets.py +63 -0
- honeybee_radiance/lightpath.py +204 -0
- honeybee_radiance/lightsource/__init__.py +1 -0
- honeybee_radiance/lightsource/_gendaylit.py +479 -0
- honeybee_radiance/lightsource/dictutil.py +49 -0
- honeybee_radiance/lightsource/ground.py +160 -0
- honeybee_radiance/lightsource/sky/__init__.py +7 -0
- honeybee_radiance/lightsource/sky/_skybase.py +177 -0
- honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
- honeybee_radiance/lightsource/sky/cie.py +378 -0
- honeybee_radiance/lightsource/sky/climatebased.py +501 -0
- honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
- honeybee_radiance/lightsource/sky/skydome.py +113 -0
- honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
- honeybee_radiance/lightsource/sky/strutil.py +34 -0
- honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
- honeybee_radiance/lightsource/sunpath.py +247 -0
- honeybee_radiance/modifier/__init__.py +3 -0
- honeybee_radiance/modifier/material/__init__.py +30 -0
- honeybee_radiance/modifier/material/absdf.py +477 -0
- honeybee_radiance/modifier/material/antimatter.py +54 -0
- honeybee_radiance/modifier/material/ashik2.py +51 -0
- honeybee_radiance/modifier/material/brtdfunc.py +81 -0
- honeybee_radiance/modifier/material/bsdf.py +292 -0
- honeybee_radiance/modifier/material/dielectric.py +53 -0
- honeybee_radiance/modifier/material/glass.py +431 -0
- honeybee_radiance/modifier/material/glow.py +246 -0
- honeybee_radiance/modifier/material/illum.py +51 -0
- honeybee_radiance/modifier/material/interface.py +49 -0
- honeybee_radiance/modifier/material/light.py +206 -0
- honeybee_radiance/modifier/material/materialbase.py +36 -0
- honeybee_radiance/modifier/material/metal.py +167 -0
- honeybee_radiance/modifier/material/metal2.py +41 -0
- honeybee_radiance/modifier/material/metdata.py +41 -0
- honeybee_radiance/modifier/material/metfunc.py +41 -0
- honeybee_radiance/modifier/material/mirror.py +340 -0
- honeybee_radiance/modifier/material/mist.py +86 -0
- honeybee_radiance/modifier/material/plasdata.py +58 -0
- honeybee_radiance/modifier/material/plasfunc.py +59 -0
- honeybee_radiance/modifier/material/plastic.py +354 -0
- honeybee_radiance/modifier/material/plastic2.py +58 -0
- honeybee_radiance/modifier/material/prism1.py +57 -0
- honeybee_radiance/modifier/material/prism2.py +48 -0
- honeybee_radiance/modifier/material/spotlight.py +50 -0
- honeybee_radiance/modifier/material/trans.py +518 -0
- honeybee_radiance/modifier/material/trans2.py +49 -0
- honeybee_radiance/modifier/material/transdata.py +50 -0
- honeybee_radiance/modifier/material/transfunc.py +53 -0
- honeybee_radiance/modifier/mixture/__init__.py +6 -0
- honeybee_radiance/modifier/mixture/mixdata.py +49 -0
- honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
- honeybee_radiance/modifier/mixture/mixpict.py +52 -0
- honeybee_radiance/modifier/mixture/mixtext.py +66 -0
- honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
- honeybee_radiance/modifier/modifierbase.py +40 -0
- honeybee_radiance/modifier/pattern/__init__.py +9 -0
- honeybee_radiance/modifier/pattern/brightdata.py +49 -0
- honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
- honeybee_radiance/modifier/pattern/brighttext.py +81 -0
- honeybee_radiance/modifier/pattern/colordata.py +56 -0
- honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
- honeybee_radiance/modifier/pattern/colorpict.py +54 -0
- honeybee_radiance/modifier/pattern/colortext.py +73 -0
- honeybee_radiance/modifier/pattern/patternbase.py +34 -0
- honeybee_radiance/modifier/texture/__init__.py +4 -0
- honeybee_radiance/modifier/texture/texdata.py +29 -0
- honeybee_radiance/modifier/texture/texfunc.py +26 -0
- honeybee_radiance/modifier/texture/texturebase.py +27 -0
- honeybee_radiance/modifierset.py +1091 -0
- honeybee_radiance/mutil.py +60 -0
- honeybee_radiance/postprocess/__init__.py +1 -0
- honeybee_radiance/postprocess/annual.py +108 -0
- honeybee_radiance/postprocess/annualdaylight.py +425 -0
- honeybee_radiance/postprocess/annualglare.py +201 -0
- honeybee_radiance/postprocess/annualirradiance.py +187 -0
- honeybee_radiance/postprocess/electriclight.py +119 -0
- honeybee_radiance/postprocess/en17037.py +261 -0
- honeybee_radiance/postprocess/leed.py +304 -0
- honeybee_radiance/postprocess/solartracking.py +90 -0
- honeybee_radiance/primitive.py +554 -0
- honeybee_radiance/properties/__init__.py +1 -0
- honeybee_radiance/properties/_base.py +390 -0
- honeybee_radiance/properties/aperture.py +197 -0
- honeybee_radiance/properties/door.py +198 -0
- honeybee_radiance/properties/face.py +123 -0
- honeybee_radiance/properties/model.py +1291 -0
- honeybee_radiance/properties/room.py +490 -0
- honeybee_radiance/properties/shade.py +186 -0
- honeybee_radiance/properties/shademesh.py +116 -0
- honeybee_radiance/putil.py +44 -0
- honeybee_radiance/reader.py +214 -0
- honeybee_radiance/sensor.py +166 -0
- honeybee_radiance/sensorgrid.py +1008 -0
- honeybee_radiance/view.py +1101 -0
- honeybee_radiance/writer.py +951 -0
- honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
- honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
- honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
- honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
- honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
- honeybee_radiance-1.66.190.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
"""honeybee radiance model-editing commands."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from ladybug_geometry.geometry3d import Vector3D, Face3D
|
|
8
|
+
from honeybee.model import Model
|
|
9
|
+
from honeybee.units import parse_distance_string
|
|
10
|
+
from honeybee.typing import clean_rad_string, clean_and_id_rad_string
|
|
11
|
+
|
|
12
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
13
|
+
from honeybee_radiance.properties.model import ModelRadianceProperties
|
|
14
|
+
|
|
15
|
+
_logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.group(help='Commands for editing radiance properties of Honeybee Models.')
|
|
19
|
+
def edit():
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@edit.command('reset-resource-ids')
|
|
24
|
+
@click.argument('model-file', type=click.Path(
|
|
25
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
26
|
+
@click.option(
|
|
27
|
+
'--by-name/--by-name-and-uuid', ' /-uuid', help='Flag to note whether '
|
|
28
|
+
'newly-generated resource object IDs should be derived only from a '
|
|
29
|
+
'cleaned display_name or whether this new ID should also have a unique '
|
|
30
|
+
'set of 8 characters appended to it to guarantee uniqueness.', default=True
|
|
31
|
+
)
|
|
32
|
+
@click.option(
|
|
33
|
+
'--reset-modifiers/--keep-modifiers', ' /-m', help='Flag to note whether '
|
|
34
|
+
'the IDs of all modifiers in the model should be reset.',
|
|
35
|
+
default=True, show_default=True
|
|
36
|
+
)
|
|
37
|
+
@click.option(
|
|
38
|
+
'--reset-modifier-sets/--keep-modifier-sets', ' /-ms', help='Flag to '
|
|
39
|
+
'note whether the IDs of all modifier sets in the model should be reset.',
|
|
40
|
+
default=True, show_default=True
|
|
41
|
+
)
|
|
42
|
+
@click.option(
|
|
43
|
+
'--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
44
|
+
'string of the converted model. By default this will be printed out to '
|
|
45
|
+
'stdout', type=click.File('w'), default='-', show_default=True
|
|
46
|
+
)
|
|
47
|
+
def reset_resource_ids(
|
|
48
|
+
model_file, by_name, reset_modifiers, reset_modifier_sets, output_file
|
|
49
|
+
):
|
|
50
|
+
"""Reset the identifiers of resource objects in a Model file.
|
|
51
|
+
|
|
52
|
+
This is useful when human-readable names are needed when the model is
|
|
53
|
+
exported to other formats like RAD and the uniqueness of the
|
|
54
|
+
identifiers is less of a concern.
|
|
55
|
+
|
|
56
|
+
\b
|
|
57
|
+
Args:
|
|
58
|
+
model_file: Full path to a Honeybee Model (HBJSON) file.
|
|
59
|
+
"""
|
|
60
|
+
try:
|
|
61
|
+
# load the model file and separately load up the resource objects
|
|
62
|
+
if sys.version_info < (3, 0):
|
|
63
|
+
with open(model_file) as inf:
|
|
64
|
+
data = json.load(inf)
|
|
65
|
+
else:
|
|
66
|
+
with open(model_file, encoding='utf-8') as inf:
|
|
67
|
+
data = json.load(inf)
|
|
68
|
+
# reset the identifiers of resources in the dictionary
|
|
69
|
+
add_uuid = not by_name
|
|
70
|
+
model_dict = ModelRadianceProperties.reset_resource_ids_in_dict(
|
|
71
|
+
data, add_uuid, reset_modifiers, reset_modifier_sets)
|
|
72
|
+
# write the dictionary into a JSON
|
|
73
|
+
output_file.write(json.dumps(model_dict))
|
|
74
|
+
except Exception as e:
|
|
75
|
+
_logger.exception('Resetting resource identifiers failed.\n{}'.format(e))
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
else:
|
|
78
|
+
sys.exit(0)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@edit.command('add-room-sensors')
|
|
82
|
+
@click.argument('model-file', type=click.Path(
|
|
83
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
84
|
+
@click.option('--grid-size', '-s', help='A number for the dimension of the mesh grid '
|
|
85
|
+
'cells. This can include the units of the distance (eg. 1ft) '
|
|
86
|
+
'or, if no units are provided, the value will be interpreted in the '
|
|
87
|
+
'honeybee model units.', type=str, default='0.5m', show_default=True)
|
|
88
|
+
@click.option('--offset', '-o', help='A number for the distance at which the '
|
|
89
|
+
'the sensor grid should be offset from the floor. This can include the '
|
|
90
|
+
'units of the distance (eg. 3ft) or, if no units are provided, the '
|
|
91
|
+
'value will be interpreted in the honeybee model units.',
|
|
92
|
+
type=str, default='0.8m', show_default=True)
|
|
93
|
+
@click.option('--include-mesh/--exclude-mesh', ' /-xm', help='Flag to note whether to '
|
|
94
|
+
'include a Mesh3D object that aligns with the grid positions '
|
|
95
|
+
'under the "mesh" property of each grid. Excluding the mesh can greatly '
|
|
96
|
+
'reduce model size but will mean Radiance results cannot be visualized '
|
|
97
|
+
'as colored meshes.', default=True)
|
|
98
|
+
@click.option('--keep-out/--remove-out', ' /-out', help='Flag to note whether an extra '
|
|
99
|
+
'check should be run to remove sensor points that lie outside the Room '
|
|
100
|
+
'volume. Note that this can add significantly to the runtime and this '
|
|
101
|
+
'check is not necessary in the case that all walls are vertical '
|
|
102
|
+
'and all floors are horizontal.', default=True, show_default=True)
|
|
103
|
+
@click.option('--wall-offset', '-w', help='A number for the distance at which sensors '
|
|
104
|
+
'close to walls should be removed. This can include the units of the '
|
|
105
|
+
'distance (eg. 3ft) or, if no units are provided, the value will be '
|
|
106
|
+
'interpreted in the honeybee model units. Note that this option has '
|
|
107
|
+
'no effect unless the value is more than half of the grid-size.',
|
|
108
|
+
type=str, default='0m', show_default=True)
|
|
109
|
+
@click.option('--room', '-r', multiple=True, help='Room identifier(s) to specify the '
|
|
110
|
+
'room(s) for which sensor grids should be generated. By default, all '
|
|
111
|
+
'rooms will get sensor grids.')
|
|
112
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
113
|
+
'string of the new model. By default this will be printed out '
|
|
114
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
115
|
+
def add_room_sensors(model_file, grid_size, offset, include_mesh, keep_out, wall_offset,
|
|
116
|
+
room, output_file):
|
|
117
|
+
"""Add SensorGrids to a honeybee model generated from the Room's floors.
|
|
118
|
+
|
|
119
|
+
The grids will have the rooms referenced in their room_identifier property.
|
|
120
|
+
|
|
121
|
+
\b
|
|
122
|
+
Args:
|
|
123
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
# re-serialize the Model and extract rooms and units
|
|
127
|
+
model = Model.from_file(model_file)
|
|
128
|
+
rooms = model.rooms if room is None or len(room) == 0 else \
|
|
129
|
+
[r for r in model.rooms if r.identifier in room]
|
|
130
|
+
grid_size = parse_distance_string(grid_size, model.units)
|
|
131
|
+
offset = parse_distance_string(offset, model.units)
|
|
132
|
+
wall_offset = parse_distance_string(wall_offset, model.units)
|
|
133
|
+
|
|
134
|
+
# loop through the rooms and generate sensor grids
|
|
135
|
+
sensor_grids = []
|
|
136
|
+
remove_out = not keep_out
|
|
137
|
+
for room in rooms:
|
|
138
|
+
sg = room.properties.radiance.generate_sensor_grid(
|
|
139
|
+
grid_size, offset=offset, remove_out=remove_out, wall_offset=wall_offset)
|
|
140
|
+
if sg is not None:
|
|
141
|
+
sensor_grids.append(sg)
|
|
142
|
+
if not include_mesh:
|
|
143
|
+
for sg in sensor_grids:
|
|
144
|
+
sg.mesh = None
|
|
145
|
+
model.properties.radiance.add_sensor_grids(sensor_grids)
|
|
146
|
+
|
|
147
|
+
# write the Model JSON string
|
|
148
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
149
|
+
except Exception as e:
|
|
150
|
+
_logger.exception('Adding Model sensor grids failed.\n{}'.format(e))
|
|
151
|
+
sys.exit(1)
|
|
152
|
+
else:
|
|
153
|
+
sys.exit(0)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@edit.command('add-room-radial-sensors')
|
|
157
|
+
@click.argument('model-file', type=click.Path(
|
|
158
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
159
|
+
@click.option('--grid-size', '-s', help='A number for the dimension of the '
|
|
160
|
+
'radial grid. This can include the units of the distance (eg. 1ft) '
|
|
161
|
+
'or, if no units are provided, the value will be interpreted in the '
|
|
162
|
+
'honeybee model units.', type=str, default='0.5m', show_default=True)
|
|
163
|
+
@click.option('--offset', '-o', help='A number for the distance at which the '
|
|
164
|
+
'the sensor grid should be offset from the floor. This can include the '
|
|
165
|
+
'units of the distance (eg. 3ft) or, if no units are provided, the '
|
|
166
|
+
'value will be interpreted in the honeybee model units.',
|
|
167
|
+
type=str, default='1.2m', show_default=True)
|
|
168
|
+
@click.option('--include-mesh/--exclude-mesh', ' /-xm', help='Flag to note whether to '
|
|
169
|
+
'include a Mesh3D object that aligns with the grid positions '
|
|
170
|
+
'under the "mesh" property of each grid. Excluding the mesh can greatly '
|
|
171
|
+
'reduce model size but will mean Radiance results cannot be visualized '
|
|
172
|
+
'as colored meshes.', default=True)
|
|
173
|
+
@click.option('--keep-out/--remove-out', ' /-out', help='Flag to note whether an extra '
|
|
174
|
+
'check should be run to remove sensor points that lie outside the Room '
|
|
175
|
+
'volume. Note that this can add significantly to the runtime and this '
|
|
176
|
+
'check is not necessary in the case that all walls are vertical '
|
|
177
|
+
'and all floors are horizontal.', default=True, show_default=True)
|
|
178
|
+
@click.option('--wall-offset', '-w', help='A number for the distance at which sensors '
|
|
179
|
+
'close to walls should be removed. This can include the units of the '
|
|
180
|
+
'distance (eg. 3ft) or, if no units are provided, the value will be '
|
|
181
|
+
'interpreted in the honeybee model units. Note that this option has '
|
|
182
|
+
'no effect unless the value is more than half of the grid-size.',
|
|
183
|
+
type=str, default='0m', show_default=True)
|
|
184
|
+
@click.option('--dir-count', '-d', help='A positive integer for the number of '
|
|
185
|
+
'radial directions to be generated around each position.',
|
|
186
|
+
type=click.INT, default=8, show_default=True)
|
|
187
|
+
@click.option('--start-vector', '-v', help='An optional list of three values '
|
|
188
|
+
'(separated by spaces) set the start direction of the generated '
|
|
189
|
+
'directions. This can be used to orient the resulting sensors to '
|
|
190
|
+
'specific parts of the scene. It can also change the elevation of the '
|
|
191
|
+
'resulting directions since this start vector will always be rotated in '
|
|
192
|
+
'the XY plane to generate the resulting directions.',
|
|
193
|
+
type=str, default='0 -1 0', show_default=True)
|
|
194
|
+
@click.option('--mesh-radius', '-m', help='An optional number to override the radius '
|
|
195
|
+
'of the meshes generated around each sensor. If unspecified, it will be '
|
|
196
|
+
'equal to 45 percent of the grid-size. Set to zero to ensure no mesh is '
|
|
197
|
+
'added to the resulting sensor grids.', type=float, default=None)
|
|
198
|
+
@click.option('--room', '-r', multiple=True, help='Room identifier(s) to specify the '
|
|
199
|
+
'room(s) for which sensor grids should be generated. By default, all '
|
|
200
|
+
'rooms will get sensor grids.')
|
|
201
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
202
|
+
'string of the new model. By default this will be printed out '
|
|
203
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
204
|
+
def add_room_radial_sensors(
|
|
205
|
+
model_file, grid_size, offset, include_mesh, keep_out, wall_offset,
|
|
206
|
+
dir_count, start_vector, mesh_radius, room, output_file):
|
|
207
|
+
"""Add SensorGrids to a honeybee model generated from the Room's floors.
|
|
208
|
+
|
|
209
|
+
The grids will have the rooms referenced in their room_identifier property.
|
|
210
|
+
|
|
211
|
+
\b
|
|
212
|
+
Args:
|
|
213
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
214
|
+
"""
|
|
215
|
+
try:
|
|
216
|
+
# re-serialize the Model and extract rooms and units
|
|
217
|
+
model = Model.from_file(model_file)
|
|
218
|
+
rooms = model.rooms if room is None or len(room) == 0 else \
|
|
219
|
+
[r for r in model.rooms if r.identifier in room]
|
|
220
|
+
grid_size = parse_distance_string(grid_size, model.units)
|
|
221
|
+
offset = parse_distance_string(offset, model.units)
|
|
222
|
+
wall_offset = parse_distance_string(wall_offset, model.units)
|
|
223
|
+
vec = [float(v) for v in start_vector.split()]
|
|
224
|
+
st_vec = Vector3D(*vec)
|
|
225
|
+
|
|
226
|
+
# loop through the rooms and generate sensor grids
|
|
227
|
+
sensor_grids = []
|
|
228
|
+
remove_out = not keep_out
|
|
229
|
+
for room in rooms:
|
|
230
|
+
sg = room.properties.radiance.generate_sensor_grid_radial(
|
|
231
|
+
grid_size, offset=offset, remove_out=remove_out, wall_offset=wall_offset,
|
|
232
|
+
dir_count=dir_count, start_vector=st_vec, mesh_radius=mesh_radius)
|
|
233
|
+
if sg is not None:
|
|
234
|
+
sensor_grids.append(sg)
|
|
235
|
+
if not include_mesh:
|
|
236
|
+
for sg in sensor_grids:
|
|
237
|
+
sg.mesh = None
|
|
238
|
+
model.properties.radiance.add_sensor_grids(sensor_grids)
|
|
239
|
+
|
|
240
|
+
# write the Model JSON string
|
|
241
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
242
|
+
except Exception as e:
|
|
243
|
+
_logger.exception('Adding Model sensor grids failed.\n{}'.format(e))
|
|
244
|
+
sys.exit(1)
|
|
245
|
+
else:
|
|
246
|
+
sys.exit(0)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@edit.command('add-face-sensors')
|
|
250
|
+
@click.argument('model-file', type=click.Path(
|
|
251
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
252
|
+
@click.option('--grid-size', '-s', help='A number for the dimension of the mesh grid '
|
|
253
|
+
'cells. This can include the units of the distance (eg. 1ft) '
|
|
254
|
+
'or, if no units are provided, the value will be interpreted in the '
|
|
255
|
+
'honeybee model units.', type=str, default='0.5m', show_default=True)
|
|
256
|
+
@click.option('--offset', '-o', help='A number for the distance at which the '
|
|
257
|
+
'the sensor grid should be offset from the floor. This can include the '
|
|
258
|
+
'units of the distance (eg. 3ft) or, if no units are provided, the '
|
|
259
|
+
'value will be interpreted in the honeybee model units.',
|
|
260
|
+
type=str, default='0.1m', show_default=True)
|
|
261
|
+
@click.option('--face-type', '-t', help='Text to specify the type of face that will be '
|
|
262
|
+
'used to generate grids. Note that only Faces with Outdoors boundary '
|
|
263
|
+
'conditions will be used, meaning that most Floors will typically '
|
|
264
|
+
'be excluded unless they represent the underside of a cantilever. '
|
|
265
|
+
'Choose from Wall, Roof, Floor, All.',
|
|
266
|
+
type=str, default='Wall', show_default=True)
|
|
267
|
+
@click.option('--full-geometry/--punched-geometry', ' /-p', help='Flag to note whether '
|
|
268
|
+
'the punched_geometry of the faces should be used with the areas '
|
|
269
|
+
'of sub-faces removed from the grid or the full geometry should be used.',
|
|
270
|
+
default=True)
|
|
271
|
+
@click.option('--include-mesh/--exclude-mesh', ' /-xm', help='Flag to note whether to '
|
|
272
|
+
'include a Mesh3D object that aligns with the grid positions '
|
|
273
|
+
'under the "mesh" property of each grid. Excluding the mesh can greatly '
|
|
274
|
+
'reduce model size but will mean Radiance results cannot be visualized '
|
|
275
|
+
'as colored meshes.', default=True)
|
|
276
|
+
@click.option('--room', '-r', multiple=True, help='Room identifier(s) to specify the '
|
|
277
|
+
'room(s) for which sensor grids should be generated. By default, all '
|
|
278
|
+
'rooms will get sensor grids.')
|
|
279
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
280
|
+
'string of the new model. By default this will be printed out '
|
|
281
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
282
|
+
def add_face_sensors(model_file, grid_size, offset, face_type, full_geometry,
|
|
283
|
+
include_mesh, room, output_file):
|
|
284
|
+
"""Add SensorGrids to a honeybee model generated from the model's faces.
|
|
285
|
+
|
|
286
|
+
\b
|
|
287
|
+
Args:
|
|
288
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
289
|
+
"""
|
|
290
|
+
try:
|
|
291
|
+
# re-serialize the Model and extract rooms and units
|
|
292
|
+
model = Model.from_file(model_file)
|
|
293
|
+
rooms = None if room is None or len(room) == 0 else \
|
|
294
|
+
[r for r in model.rooms if r.identifier in room]
|
|
295
|
+
grid_size = parse_distance_string(grid_size, model.units)
|
|
296
|
+
offset = parse_distance_string(offset, model.units)
|
|
297
|
+
punched_geometry = not full_geometry
|
|
298
|
+
|
|
299
|
+
# loop through the rooms and generate sensor grids
|
|
300
|
+
sensor_grids = []
|
|
301
|
+
if rooms is None:
|
|
302
|
+
sg = model.properties.radiance.generate_exterior_face_sensor_grid(
|
|
303
|
+
grid_size, offset=offset, face_type=face_type,
|
|
304
|
+
punched_geometry=punched_geometry)
|
|
305
|
+
sensor_grids.append(sg)
|
|
306
|
+
else:
|
|
307
|
+
for room in rooms:
|
|
308
|
+
sg = room.properties.radiance.generate_exterior_face_sensor_grid(
|
|
309
|
+
grid_size, offset=offset, face_type=face_type,
|
|
310
|
+
punched_geometry=punched_geometry)
|
|
311
|
+
if sg is not None:
|
|
312
|
+
sensor_grids.append(sg)
|
|
313
|
+
if not include_mesh:
|
|
314
|
+
for sg in sensor_grids:
|
|
315
|
+
sg.mesh = None
|
|
316
|
+
model.properties.radiance.add_sensor_grids(sensor_grids)
|
|
317
|
+
|
|
318
|
+
# write the Model JSON string
|
|
319
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
320
|
+
except Exception as e:
|
|
321
|
+
_logger.exception('Adding Model sensor grids failed.\n{}'.format(e))
|
|
322
|
+
sys.exit(1)
|
|
323
|
+
else:
|
|
324
|
+
sys.exit(0)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
@edit.command('add-aperture-sensors')
|
|
328
|
+
@click.argument('model-file', type=click.Path(
|
|
329
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
330
|
+
@click.option('--grid-size', '-s', help='A number for the dimension of the mesh grid '
|
|
331
|
+
'cells. This can include the units of the distance (eg. 1ft) '
|
|
332
|
+
'or, if no units are provided, the value will be interpreted in the '
|
|
333
|
+
'honeybee model units.', type=str, default='0.5m', show_default=True)
|
|
334
|
+
@click.option('--offset', '-o', help='A number for the distance at which the '
|
|
335
|
+
'the sensor grid should be offset from the apertures. This can include the '
|
|
336
|
+
'units of the distance (eg. 3ft) or, if no units are provided, the '
|
|
337
|
+
'value will be interpreted in the honeybee model units.',
|
|
338
|
+
type=str, default='0.1m', show_default=True)
|
|
339
|
+
@click.option('--aperture-type', '-t', help='Text to specify the type of aperture that '
|
|
340
|
+
'will be used to generate grids. Note that only Faces with Outdoors '
|
|
341
|
+
'boundary conditions will be used, meaning that most Floors will typically'
|
|
342
|
+
' be excluded unless they represent the underside of a cantilever. '
|
|
343
|
+
'Choose from Window, Skylight, All.',
|
|
344
|
+
type=str, default='All', show_default=True)
|
|
345
|
+
@click.option('--include-mesh/--exclude-mesh', ' /-xm', help='Flag to note whether to '
|
|
346
|
+
'include a Mesh3D object that aligns with the grid positions '
|
|
347
|
+
'under the "mesh" property of each grid. Excluding the mesh can greatly '
|
|
348
|
+
'reduce model size but will mean Radiance results cannot be visualized '
|
|
349
|
+
'as colored meshes.', default=True)
|
|
350
|
+
@click.option('--room', '-r', multiple=True, help='Room identifier(s) to specify the '
|
|
351
|
+
'room(s) for which sensor grids should be generated. By default, all '
|
|
352
|
+
'rooms will get sensor grids.')
|
|
353
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
354
|
+
'string of the new model. By default this will be printed out '
|
|
355
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
356
|
+
def add_aperture_sensors(
|
|
357
|
+
model_file, grid_size, offset, aperture_type, include_mesh, room, output_file):
|
|
358
|
+
"""Add SensorGrids to a honeybee model generated from the model's apertures.
|
|
359
|
+
|
|
360
|
+
\b
|
|
361
|
+
Args:
|
|
362
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
363
|
+
"""
|
|
364
|
+
try:
|
|
365
|
+
# re-serialize the Model and extract rooms and units
|
|
366
|
+
model = Model.from_file(model_file)
|
|
367
|
+
rooms = None if room is None or len(room) == 0 else \
|
|
368
|
+
[r for r in model.rooms if r.identifier in room]
|
|
369
|
+
grid_size = parse_distance_string(grid_size, model.units)
|
|
370
|
+
offset = parse_distance_string(offset, model.units)
|
|
371
|
+
|
|
372
|
+
# loop through the rooms and generate sensor grids
|
|
373
|
+
sensor_grids = []
|
|
374
|
+
if rooms is None:
|
|
375
|
+
sg = model.properties.radiance.generate_exterior_aperture_sensor_grid(
|
|
376
|
+
grid_size, offset=offset, aperture_type=aperture_type)
|
|
377
|
+
sensor_grids.append(sg)
|
|
378
|
+
else:
|
|
379
|
+
for room in rooms:
|
|
380
|
+
sg = room.properties.radiance.generate_exterior_aperture_sensor_grid(
|
|
381
|
+
grid_size, offset=offset, aperture_type=aperture_type)
|
|
382
|
+
if sg is not None:
|
|
383
|
+
sensor_grids.append(sg)
|
|
384
|
+
if not include_mesh:
|
|
385
|
+
for sg in sensor_grids:
|
|
386
|
+
sg.mesh = None
|
|
387
|
+
model.properties.radiance.add_sensor_grids(sensor_grids)
|
|
388
|
+
|
|
389
|
+
# write the Model JSON string
|
|
390
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
391
|
+
except Exception as e:
|
|
392
|
+
_logger.exception('Adding Model sensor grids failed.\n{}'.format(e))
|
|
393
|
+
sys.exit(1)
|
|
394
|
+
else:
|
|
395
|
+
sys.exit(0)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
@edit.command('add-face3d-sensors')
|
|
399
|
+
@click.argument('model-file', type=click.Path(
|
|
400
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
401
|
+
@click.argument('face3d-file', type=click.Path(
|
|
402
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
403
|
+
@click.option('--grid-name', '-n', help='Text string for the name of the SensorGrid, '
|
|
404
|
+
'which will also be used to assign SensorGrid ID. This will be used to '
|
|
405
|
+
'identify the object across a model and in the exported Radiance files '
|
|
406
|
+
'so it is recommended that it be relatively unique. If unspecified, '
|
|
407
|
+
'a random name will be generated.', type=str, default=None)
|
|
408
|
+
@click.option('--grid-size', '-s', help='A number for the dimension of the mesh grid '
|
|
409
|
+
'cells. This can include the units of the distance (eg. 1ft) '
|
|
410
|
+
'or, if no units are provided, the value will be interpreted in the '
|
|
411
|
+
'honeybee model units.', type=str, default='0.5m', show_default=True)
|
|
412
|
+
@click.option('--offset', '-o', help='A number for the distance at which the the sensor '
|
|
413
|
+
'grid should be offset from the base geometry. This can include the '
|
|
414
|
+
'units of the distance (eg. 3ft) or, if no units are provided, the '
|
|
415
|
+
'value will be interpreted in the honeybee model units.',
|
|
416
|
+
type=str, default='0', show_default=True)
|
|
417
|
+
@click.option('--no-flip/--flip', ' /-fl', help='Flag to note whether the mesh '
|
|
418
|
+
'normals should be reversed from the direction of the face geometries'
|
|
419
|
+
'and the --offset move the sensors in the opposite direction from the '
|
|
420
|
+
'face normals.', default=True, show_default=True)
|
|
421
|
+
@click.option('--include-mesh/--exclude-mesh', ' /-xm', help='Flag to note whether to '
|
|
422
|
+
'include a Mesh3D object that aligns with the grid positions '
|
|
423
|
+
'under the "mesh" property of each grid. Excluding the mesh can greatly '
|
|
424
|
+
'reduce model size but will mean Radiance results cannot be visualized '
|
|
425
|
+
'as colored meshes.', default=True)
|
|
426
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
427
|
+
'string of the new model. By default this will be printed out '
|
|
428
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
429
|
+
def add_face3d_sensors(
|
|
430
|
+
model_file, face3d_file, grid_name, grid_size, offset, no_flip,
|
|
431
|
+
include_mesh, output_file):
|
|
432
|
+
"""Add SensorGrids to a honeybee model generated from a JSON array of Face3D objects.
|
|
433
|
+
|
|
434
|
+
\b
|
|
435
|
+
Args:
|
|
436
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
437
|
+
face3d_file: Full path to a JSON file containing an array of Face3D objects
|
|
438
|
+
that will be used to generate the sensor grid. This could also be a
|
|
439
|
+
nested array (list of lists of Face3Ds), in which case a separate
|
|
440
|
+
SensorGrid will be computed for each sub-list.
|
|
441
|
+
"""
|
|
442
|
+
try:
|
|
443
|
+
# re-serialize the Model
|
|
444
|
+
model = Model.from_file(model_file)
|
|
445
|
+
|
|
446
|
+
# re-serialize the Face3Ds
|
|
447
|
+
with open(face3d_file) as inf:
|
|
448
|
+
data = json.load(inf)
|
|
449
|
+
face_arrays = []
|
|
450
|
+
for obj in data:
|
|
451
|
+
if isinstance(obj, list):
|
|
452
|
+
face_arrays.append([Face3D.from_dict(f) for f in obj])
|
|
453
|
+
else: # assume that it is a single Face3D
|
|
454
|
+
face_arrays.append([Face3D.from_dict(obj)])
|
|
455
|
+
|
|
456
|
+
# process all of the other inputs
|
|
457
|
+
grid_size = parse_distance_string(grid_size, model.units)
|
|
458
|
+
offset = parse_distance_string(offset, model.units)
|
|
459
|
+
base_id = clean_rad_string(grid_name) if grid_name is not None \
|
|
460
|
+
else clean_and_id_rad_string('SensorGrid')
|
|
461
|
+
flip = not no_flip
|
|
462
|
+
|
|
463
|
+
# loop through the Face3Ds and generate sensor grids
|
|
464
|
+
sensor_grids = []
|
|
465
|
+
for i, faces in enumerate(face_arrays):
|
|
466
|
+
grid_id = base_id if len(face_arrays) == 1 else '{}_{}'.format(base_id, i)
|
|
467
|
+
try:
|
|
468
|
+
sensor_grids.append(
|
|
469
|
+
SensorGrid.from_face3d(grid_id, faces, grid_size, None, offset, flip)
|
|
470
|
+
)
|
|
471
|
+
except AssertionError: # none of the Face3Ds make a valid grid
|
|
472
|
+
continue
|
|
473
|
+
if not include_mesh:
|
|
474
|
+
for sg in sensor_grids:
|
|
475
|
+
sg.mesh = None
|
|
476
|
+
model.properties.radiance.add_sensor_grids(sensor_grids)
|
|
477
|
+
|
|
478
|
+
# write the Model JSON string
|
|
479
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
480
|
+
except Exception as e:
|
|
481
|
+
_logger.exception('Adding Model sensor grids failed.\n{}'.format(e))
|
|
482
|
+
sys.exit(1)
|
|
483
|
+
else:
|
|
484
|
+
sys.exit(0)
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
@edit.command('mirror-model-sensors')
|
|
488
|
+
@click.argument('model-file', type=click.Path(
|
|
489
|
+
exists=True, file_okay=True, dir_okay=False, resolve_path=True))
|
|
490
|
+
@click.option('--output-file', '-f', help='Optional hbjson file to output the JSON '
|
|
491
|
+
'string of the converted model. By default this will be printed out '
|
|
492
|
+
'to stdout', type=click.File('w'), default='-', show_default=True)
|
|
493
|
+
def mirror_model_sensors(model_file, output_file):
|
|
494
|
+
"""Mirror a honeybee Model's SensorGrids and format them for thermal mapping.
|
|
495
|
+
|
|
496
|
+
This involves setting the direction of every sensor to point up (0, 0, 1) and
|
|
497
|
+
then adding a mirrored sensor grid with the same sensor positions that all
|
|
498
|
+
point downward. In thermal mapping workflows, the upward-pointing grids can
|
|
499
|
+
be used to account for direct and diffuse shortwave irradiance while the
|
|
500
|
+
downward pointing grids account for ground-reflected shortwave irradiance.
|
|
501
|
+
|
|
502
|
+
\b
|
|
503
|
+
Args:
|
|
504
|
+
model_file: Full path to a HBJSON or HBPkl Model file.
|
|
505
|
+
"""
|
|
506
|
+
try:
|
|
507
|
+
# re-serialize the Model and loop through the sensor grids to reformat them
|
|
508
|
+
model = Model.from_file(model_file)
|
|
509
|
+
mirror_grids, up_dir, down_dir = [], None, (0, 0, -1)
|
|
510
|
+
for grid in model.properties.radiance.sensor_grids:
|
|
511
|
+
# ensure that all sensors are pointing upward
|
|
512
|
+
grid.group_identifier = None
|
|
513
|
+
for sensor in grid:
|
|
514
|
+
sensor.dir = up_dir
|
|
515
|
+
# create the mirror grid will all sensors pointing downward
|
|
516
|
+
mir_grid = grid.duplicate()
|
|
517
|
+
mir_grid.identifier = '{}_ref'.format(grid.identifier)
|
|
518
|
+
for sensor in mir_grid:
|
|
519
|
+
sensor.dir = down_dir
|
|
520
|
+
mirror_grids.append(mir_grid)
|
|
521
|
+
model.properties.radiance.add_sensor_grids(mirror_grids)
|
|
522
|
+
|
|
523
|
+
# write the Model JSON string
|
|
524
|
+
output_file.write(json.dumps(model.to_dict()))
|
|
525
|
+
except Exception as e:
|
|
526
|
+
_logger.exception('Model sensor grid mirroring failed.\n{}'.format(e))
|
|
527
|
+
sys.exit(1)
|
|
528
|
+
else:
|
|
529
|
+
sys.exit(0)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""honeybee radiance dcglare command."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from honeybee_radiance.config import folders
|
|
8
|
+
from honeybee_radiance_command.dcglare import Dcglare, DcglareOptions
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group(help='Commands to run dcglare in Radiance.')
|
|
15
|
+
def dcglare():
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dcglare.command('two-phase')
|
|
20
|
+
@click.argument(
|
|
21
|
+
'dc-direct',
|
|
22
|
+
type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
|
|
23
|
+
)
|
|
24
|
+
@click.argument(
|
|
25
|
+
'dc-total',
|
|
26
|
+
type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
|
|
27
|
+
)
|
|
28
|
+
@click.argument(
|
|
29
|
+
'sky-mtx',
|
|
30
|
+
type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
|
|
31
|
+
)
|
|
32
|
+
@click.argument(
|
|
33
|
+
'view-rays',
|
|
34
|
+
type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True)
|
|
35
|
+
)
|
|
36
|
+
@click.option(
|
|
37
|
+
'--glare-limit', '-l', type=float,
|
|
38
|
+
help='When this option is provided, the program calculates glare autonomy, where '
|
|
39
|
+
'any DGP value at or above the limit indicates the presence of glare. If the option '
|
|
40
|
+
'is not provided, the program calculates DGP under each sky condition in the sky '
|
|
41
|
+
'matrix instead.'
|
|
42
|
+
)
|
|
43
|
+
@click.option(
|
|
44
|
+
'--threshold-factor', '-b', type=float,
|
|
45
|
+
help='If larger than 100, it is used as constant threshold in cd/m2. If less than '
|
|
46
|
+
'or equal to 100, this factor multiplied by the average luminance in each view will '
|
|
47
|
+
'be used as threshold for detecting the glare sources (not recommended). The '
|
|
48
|
+
'default value is 2000 (fixed threshold method).'
|
|
49
|
+
)
|
|
50
|
+
@click.option(
|
|
51
|
+
'--occupancy-schedule', '-sf',
|
|
52
|
+
type=click.Path(exists=False, dir_okay=False, resolve_path=True),
|
|
53
|
+
help='In the event that the sky matrix includes unoccupied hours that should not '
|
|
54
|
+
'contribute to the glare autonomy calculation, file will be read to determine which '
|
|
55
|
+
'entries from the sky file matrix will be included in this calculation. Each line '
|
|
56
|
+
'of file is expected to contain a numeric value at the end of a comma-delimited '
|
|
57
|
+
'list, with zero corresponding to unoccupied. This argument is used only if '
|
|
58
|
+
'--glare-limit (or -l) is specified.'
|
|
59
|
+
)
|
|
60
|
+
@click.option(
|
|
61
|
+
'--output', '-o', default='output.dgp',
|
|
62
|
+
help='Path to output file. If a relative path is provided it '
|
|
63
|
+
'should be relative to project folder.'
|
|
64
|
+
)
|
|
65
|
+
@click.option(
|
|
66
|
+
'--dry-run', is_flag=True, default=False, show_default=True,
|
|
67
|
+
help='A flag to show the command without running it.'
|
|
68
|
+
)
|
|
69
|
+
def two_phase_command(
|
|
70
|
+
dc_direct, dc_total, sky_mtx, view_rays, glare_limit, threshold_factor,
|
|
71
|
+
occupancy_schedule, output, dry_run):
|
|
72
|
+
"""Run dcglare command for dcdirect and dctotal.
|
|
73
|
+
|
|
74
|
+
\b
|
|
75
|
+
Args:
|
|
76
|
+
dc-direct: Path to direct contribution matrix calculated with a single ambient
|
|
77
|
+
bounce.
|
|
78
|
+
dc-total: Path to total contribution matrix.
|
|
79
|
+
sky-mtx: Path to sky mtx.
|
|
80
|
+
view-rays: Path to file of view rays.
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
occupancy_schedule = None if \
|
|
84
|
+
(occupancy_schedule and not os.path.isfile(occupancy_schedule)) \
|
|
85
|
+
else occupancy_schedule
|
|
86
|
+
try:
|
|
87
|
+
options = DcglareOptions()
|
|
88
|
+
options.vf = view_rays
|
|
89
|
+
if glare_limit:
|
|
90
|
+
options.l = glare_limit
|
|
91
|
+
if threshold_factor:
|
|
92
|
+
options.b = threshold_factor
|
|
93
|
+
if occupancy_schedule:
|
|
94
|
+
options.sf = occupancy_schedule
|
|
95
|
+
|
|
96
|
+
# create command
|
|
97
|
+
out_dir = os.path.dirname(output)
|
|
98
|
+
if not os.path.isdir(out_dir):
|
|
99
|
+
os.makedirs(out_dir)
|
|
100
|
+
dcglare = Dcglare(
|
|
101
|
+
options=options, output=output,
|
|
102
|
+
dc_direct=dc_direct, dc_total=dc_total, sky_matrix=sky_mtx
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
if dry_run:
|
|
106
|
+
click.echo(dcglare)
|
|
107
|
+
else:
|
|
108
|
+
env = None
|
|
109
|
+
if folders.env != {}:
|
|
110
|
+
env = folders.env
|
|
111
|
+
env = dict(os.environ, **env) if env else None
|
|
112
|
+
dcglare.run(env=env)
|
|
113
|
+
|
|
114
|
+
except Exception:
|
|
115
|
+
_logger.exception('Failed to run dcglare command.')
|
|
116
|
+
sys.exit(1)
|
|
117
|
+
else:
|
|
118
|
+
sys.exit(0)
|