honeybee-schema 1.59.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_schema/__init__.py +1 -0
- honeybee_schema/__main__.py +4 -0
- honeybee_schema/_base.py +42 -0
- honeybee_schema/altnumber.py +18 -0
- honeybee_schema/boundarycondition.py +81 -0
- honeybee_schema/cli.py +115 -0
- honeybee_schema/comparison.py +208 -0
- honeybee_schema/doe2/__init__.py +0 -0
- honeybee_schema/doe2/properties.py +75 -0
- honeybee_schema/energy/__init__.py +0 -0
- honeybee_schema/energy/_base.py +64 -0
- honeybee_schema/energy/construction.py +324 -0
- honeybee_schema/energy/constructionset.py +359 -0
- honeybee_schema/energy/daylight.py +62 -0
- honeybee_schema/energy/designday.py +212 -0
- honeybee_schema/energy/generator.py +140 -0
- honeybee_schema/energy/global_constructionset.py +129 -0
- honeybee_schema/energy/hvac/__init__.py +0 -0
- honeybee_schema/energy/hvac/_template.py +38 -0
- honeybee_schema/energy/hvac/allair.py +257 -0
- honeybee_schema/energy/hvac/detailed.py +20 -0
- honeybee_schema/energy/hvac/doas.py +248 -0
- honeybee_schema/energy/hvac/heatcool.py +309 -0
- honeybee_schema/energy/hvac/idealair.py +107 -0
- honeybee_schema/energy/internalmass.py +25 -0
- honeybee_schema/energy/load.py +627 -0
- honeybee_schema/energy/material.py +949 -0
- honeybee_schema/energy/programtype.py +117 -0
- honeybee_schema/energy/properties.py +382 -0
- honeybee_schema/energy/schedule.py +350 -0
- honeybee_schema/energy/shw.py +53 -0
- honeybee_schema/energy/simulation.py +440 -0
- honeybee_schema/energy/ventcool.py +337 -0
- honeybee_schema/geometry.py +161 -0
- honeybee_schema/model.py +473 -0
- honeybee_schema/projectinfo.py +94 -0
- honeybee_schema/radiance/__init__.py +0 -0
- honeybee_schema/radiance/_base.py +22 -0
- honeybee_schema/radiance/asset.py +191 -0
- honeybee_schema/radiance/global_modifierset.py +92 -0
- honeybee_schema/radiance/modifier.py +373 -0
- honeybee_schema/radiance/modifierset.py +296 -0
- honeybee_schema/radiance/properties.py +149 -0
- honeybee_schema/radiance/state.py +69 -0
- honeybee_schema/updater/__init__.py +0 -0
- honeybee_schema/updater/version_1_39_12.py +14 -0
- honeybee_schema/updater/version_1_40_1.py +153 -0
- honeybee_schema/updater/version_1_43_1.py +18 -0
- honeybee_schema/updater/version_1_43_2.py +12 -0
- honeybee_schema/updater/version_1_43_5.py +11 -0
- honeybee_schema/validation.py +205 -0
- honeybee_schema-1.59.1.dist-info/METADATA +108 -0
- honeybee_schema-1.59.1.dist-info/RECORD +57 -0
- honeybee_schema-1.59.1.dist-info/WHEEL +5 -0
- honeybee_schema-1.59.1.dist-info/entry_points.txt +2 -0
- honeybee_schema-1.59.1.dist-info/licenses/LICENSE +23 -0
- honeybee_schema-1.59.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,337 @@
|
|
1
|
+
"""Ventilative cooling Schema"""
|
2
|
+
from pydantic import Field, constr
|
3
|
+
|
4
|
+
from .._base import NoExtraBaseModel
|
5
|
+
from ._base import EnergyBaseModel
|
6
|
+
from enum import Enum
|
7
|
+
|
8
|
+
|
9
|
+
class VentilationControlAbridged(NoExtraBaseModel):
|
10
|
+
|
11
|
+
type: constr(regex='^VentilationControlAbridged$') = 'VentilationControlAbridged'
|
12
|
+
|
13
|
+
min_indoor_temperature: float = Field(
|
14
|
+
-100,
|
15
|
+
ge=-100,
|
16
|
+
le=100,
|
17
|
+
description='A number for the minimum indoor temperature at which to '
|
18
|
+
'ventilate in Celsius. Typically, this variable is used to initiate ventilation.'
|
19
|
+
)
|
20
|
+
|
21
|
+
max_indoor_temperature: float = Field(
|
22
|
+
100,
|
23
|
+
ge=-100,
|
24
|
+
le=100,
|
25
|
+
description='A number for the maximum indoor temperature at which to '
|
26
|
+
'ventilate in Celsius. This can be used to set a maximum temperature at '
|
27
|
+
'which point ventilation is stopped and a cooling system is turned on.'
|
28
|
+
)
|
29
|
+
|
30
|
+
min_outdoor_temperature: float = Field(
|
31
|
+
-100,
|
32
|
+
ge=-100,
|
33
|
+
le=100,
|
34
|
+
description='A number for the minimum outdoor temperature at which to ventilate '
|
35
|
+
'in Celsius. This can be used to ensure ventilative cooling does not happen '
|
36
|
+
'during the winter even if the Room is above the min_indoor_temperature.'
|
37
|
+
)
|
38
|
+
|
39
|
+
max_outdoor_temperature: float = Field(
|
40
|
+
100,
|
41
|
+
ge=-100,
|
42
|
+
le=100,
|
43
|
+
description='A number for the maximum indoor temperature at which to ventilate '
|
44
|
+
'in Celsius. This can be used to set a limit for when it is considered too hot '
|
45
|
+
'outside for ventilative cooling.'
|
46
|
+
)
|
47
|
+
|
48
|
+
delta_temperature: float = Field(
|
49
|
+
-100,
|
50
|
+
ge=-100,
|
51
|
+
le=100,
|
52
|
+
description='A number for the temperature differential in Celsius between '
|
53
|
+
'indoor and outdoor below which ventilation is shut off. This should usually '
|
54
|
+
'be a positive number so that ventilation only occurs when the outdoors is '
|
55
|
+
'cooler than the indoors. Negative numbers indicate how much hotter the '
|
56
|
+
'outdoors can be than the indoors before ventilation is stopped.'
|
57
|
+
)
|
58
|
+
|
59
|
+
schedule: str = Field(
|
60
|
+
default=None,
|
61
|
+
min_length=1,
|
62
|
+
max_length=100,
|
63
|
+
description='Identifier of the schedule for the ventilation over the course of '
|
64
|
+
'the year. Note that this is applied on top of any setpoints. The type of this '
|
65
|
+
'schedule should be On/Off and values should be either 0 (no possibility of '
|
66
|
+
'ventilation) or 1 (ventilation possible).'
|
67
|
+
)
|
68
|
+
|
69
|
+
|
70
|
+
class VentilationType(str, Enum):
|
71
|
+
exhaust = 'Exhaust'
|
72
|
+
intake = 'Intake'
|
73
|
+
balanced = 'Balanced'
|
74
|
+
|
75
|
+
|
76
|
+
class VentilationFan(EnergyBaseModel):
|
77
|
+
|
78
|
+
type: constr(regex='^VentilationFan$') = 'VentilationFan'
|
79
|
+
|
80
|
+
flow_rate: float = Field(
|
81
|
+
...,
|
82
|
+
gt=0,
|
83
|
+
description='A number for the flow rate of the fan in m3/s.'
|
84
|
+
)
|
85
|
+
|
86
|
+
ventilation_type: VentilationType = Field(
|
87
|
+
default=VentilationType.balanced,
|
88
|
+
description='Text to indicate the type of type of ventilation. Choose '
|
89
|
+
'from the options below. For either Exhaust or Intake, values for '
|
90
|
+
'fan pressure and efficiency define the fan electric consumption. For Exhaust '
|
91
|
+
'ventilation, the conditions of the air entering the space are assumed '
|
92
|
+
'to be equivalent to outside air conditions. For Intake and Balanced '
|
93
|
+
'ventilation, an appropriate amount of fan heat is added to the '
|
94
|
+
'entering air stream. For Balanced ventilation, both an intake fan '
|
95
|
+
'and an exhaust fan are assumed to co-exist, both having the same '
|
96
|
+
'flow rate and power consumption (using the entered values for fan '
|
97
|
+
'pressure rise and fan total efficiency). Thus, the fan electric '
|
98
|
+
'consumption for Balanced ventilation is twice that for the Exhaust or '
|
99
|
+
'Intake ventilation types which employ only a single fan.'
|
100
|
+
)
|
101
|
+
|
102
|
+
pressure_rise: float = Field(
|
103
|
+
...,
|
104
|
+
gt=0,
|
105
|
+
description='A number for the the pressure rise across the fan in Pascals '
|
106
|
+
'(N/m2). This is often a function of the fan speed and the conditions in '
|
107
|
+
'which the fan is operating since having the fan blow air through filters '
|
108
|
+
'or narrow ducts will increase the pressure rise that is needed to '
|
109
|
+
'deliver the input flow rate. The pressure rise plays an important role in '
|
110
|
+
'determining the amount of energy consumed by the fan. Smaller fans like '
|
111
|
+
'a 0.05 m3/s desk fan tend to have lower pressure rises around 60 Pa. '
|
112
|
+
'Larger fans, such as a 6 m3/s fan used for ventilating a large room tend '
|
113
|
+
'to have higher pressure rises around 400 Pa. The highest pressure rises '
|
114
|
+
'are typically for large fans blowing air through ducts and filters, which '
|
115
|
+
'can have pressure rises as high as 1000 Pa.'
|
116
|
+
)
|
117
|
+
|
118
|
+
efficiency: float = Field(
|
119
|
+
...,
|
120
|
+
ge=0,
|
121
|
+
le=1,
|
122
|
+
description='A number between 0 and 1 for the overall efficiency of the fan. '
|
123
|
+
'Specifically, this is the ratio of the power delivered to the fluid '
|
124
|
+
'to the electrical input power. It is the product of the fan motor '
|
125
|
+
'efficiency and the fan impeller efficiency. Fans that have a higher blade '
|
126
|
+
'diameter and operate at lower speeds with smaller pressure rises for '
|
127
|
+
'their size tend to have higher efficiencies. Because motor efficiencies '
|
128
|
+
'are typically between 0.8 and 0.9, the best overall fan efficiencies '
|
129
|
+
'tend to be around 0.7 with most typical fan efficiencies between 0.5 and '
|
130
|
+
'0.7. The lowest efficiencies often happen for small fans in situations '
|
131
|
+
'with high pressure rises for their size, which can result in efficiencies '
|
132
|
+
'as low as 0.15.'
|
133
|
+
)
|
134
|
+
|
135
|
+
control: VentilationControlAbridged = Field(
|
136
|
+
default=None,
|
137
|
+
description='A VentilationControl object that dictates the conditions under '
|
138
|
+
'which the fan is turned on. If None, a default VentilationControl will '
|
139
|
+
'be generated, which will keep the fan on all of the time.'
|
140
|
+
)
|
141
|
+
|
142
|
+
|
143
|
+
class VentilationOpening(NoExtraBaseModel):
|
144
|
+
|
145
|
+
type: constr(regex='^VentilationOpening$') = 'VentilationOpening'
|
146
|
+
|
147
|
+
fraction_area_operable: float = Field(
|
148
|
+
0.5,
|
149
|
+
ge=0,
|
150
|
+
le=1,
|
151
|
+
description='A number for the fraction of the window area that is operable.'
|
152
|
+
)
|
153
|
+
|
154
|
+
fraction_height_operable: float = Field(
|
155
|
+
1.0,
|
156
|
+
ge=0,
|
157
|
+
le=1,
|
158
|
+
description='A number for the fraction of the distance from the bottom of the '
|
159
|
+
'window to the top that is operable'
|
160
|
+
)
|
161
|
+
|
162
|
+
discharge_coefficient: float = Field(
|
163
|
+
0.45,
|
164
|
+
ge=0,
|
165
|
+
le=1,
|
166
|
+
description='A number that will be multiplied by the area of the window in the '
|
167
|
+
'stack (buoyancy-driven) part of the equation to account for additional '
|
168
|
+
'friction from window geometry, insect screens, etc. Typical values include '
|
169
|
+
'0.45, for unobstructed windows WITH insect screens and 0.65 for unobstructed '
|
170
|
+
'windows WITHOUT insect screens. This value should be lowered if windows are '
|
171
|
+
'of an awning or casement type and are not allowed to fully open.'
|
172
|
+
)
|
173
|
+
|
174
|
+
wind_cross_vent: bool = Field(
|
175
|
+
False,
|
176
|
+
description='Boolean to indicate if there is an opening of roughly equal area '
|
177
|
+
'on the opposite side of the Room such that wind-driven cross ventilation will '
|
178
|
+
'be induced. If False, the assumption is that the operable area is primarily on '
|
179
|
+
'one side of the Room and there is no wind-driven ventilation.'
|
180
|
+
)
|
181
|
+
|
182
|
+
flow_coefficient_closed: float = Field(
|
183
|
+
default=0,
|
184
|
+
ge=0,
|
185
|
+
description='An optional number in kg/s-m, at 1 Pa per meter of crack length, '
|
186
|
+
'used to calculate the mass flow rate when the opening is closed; required to '
|
187
|
+
'run an AirflowNetwork simulation. The DesignBuilder Cracks template defines '
|
188
|
+
'the flow coefficient for a tight, low-leakage closed external window to be '
|
189
|
+
'0.00001, and the flow coefficient for a very poor, high-leakage closed '
|
190
|
+
'external window to be 0.003.'
|
191
|
+
)
|
192
|
+
|
193
|
+
flow_exponent_closed: float = Field(
|
194
|
+
default=0.65,
|
195
|
+
ge=0.5,
|
196
|
+
le=1,
|
197
|
+
description='An optional dimensionless number between 0.5 and 1 used to '
|
198
|
+
'calculate the mass flow rate when the opening is closed; required to run an '
|
199
|
+
'AirflowNetwork simulation. This value represents the leak geometry impact '
|
200
|
+
'on airflow, with 0.5 generally corresponding to turbulent orifice flow and 1 '
|
201
|
+
'generally corresponding to laminar flow. The default of 0.65 is '
|
202
|
+
'representative of many cases of wall and window leakage, used when the '
|
203
|
+
'exponent cannot be measured.'
|
204
|
+
)
|
205
|
+
|
206
|
+
two_way_threshold: float = Field(
|
207
|
+
default=0.0001,
|
208
|
+
gt=0,
|
209
|
+
description='A number in kg/m3 indicating the minimum density difference above '
|
210
|
+
'which two-way flow may occur due to stack effect, required to run an '
|
211
|
+
'AirflowNetwork simulation. This value is required because the air density '
|
212
|
+
'difference between two zones (which drives two-way air flow) will tend '
|
213
|
+
'towards division by zero errors as the air density difference approaches '
|
214
|
+
'zero. The default of 0.0001 is a typical default value used for AirflowNetwork '
|
215
|
+
'openings.'
|
216
|
+
)
|
217
|
+
|
218
|
+
|
219
|
+
class AFNCrack(NoExtraBaseModel):
|
220
|
+
"""Properties for airflow through a crack."""
|
221
|
+
|
222
|
+
type: constr(regex='^AFNCrack$') = 'AFNCrack'
|
223
|
+
|
224
|
+
flow_coefficient: float = Field(
|
225
|
+
...,
|
226
|
+
gt=0,
|
227
|
+
description='A number in kg/s-m at 1 Pa per meter of crack length at the '
|
228
|
+
'conditions defined in the ReferenceCrack condition; required to run an '
|
229
|
+
'AirflowNetwork simulation. The DesignBuilder Cracks template defines the flow '
|
230
|
+
'coefficient for a tight, low-leakage wall to be 0.00001 and 0.001 for external '
|
231
|
+
'and internal constructions, respectively. Flow coefficients for a very poor, '
|
232
|
+
'high-leakage wall are defined to be 0.0004 and 0.019 for external and internal '
|
233
|
+
'constructions, respectively.'
|
234
|
+
)
|
235
|
+
|
236
|
+
flow_exponent: float = Field(
|
237
|
+
default=0.65,
|
238
|
+
ge=0.5,
|
239
|
+
le=1,
|
240
|
+
description='An optional dimensionless number between 0.5 and 1 used to '
|
241
|
+
'calculate the crack mass flow rate; required to run an '
|
242
|
+
'AirflowNetwork simulation. This value represents the leak geometry impact '
|
243
|
+
'on airflow, with 0.5 generally corresponding to turbulent orifice flow and 1 '
|
244
|
+
'generally corresponding to laminar flow. The default of 0.65 is '
|
245
|
+
'representative of many cases of wall and window leakage, used when the '
|
246
|
+
'exponent cannot be measured.'
|
247
|
+
)
|
248
|
+
|
249
|
+
|
250
|
+
class VentilationControlType(str, Enum):
|
251
|
+
single_zone = 'SingleZone'
|
252
|
+
multi_zone_with_distribution = 'MultiZoneWithDistribution'
|
253
|
+
multi_zone_without_distribution = 'MultiZoneWithoutDistribution'
|
254
|
+
|
255
|
+
|
256
|
+
class BuildingType(str, Enum):
|
257
|
+
lowrise = 'LowRise'
|
258
|
+
highrise = 'HighRise'
|
259
|
+
|
260
|
+
|
261
|
+
class VentilationSimulationControl(NoExtraBaseModel):
|
262
|
+
"""The global parameters used in the ventilation simulation."""
|
263
|
+
|
264
|
+
type: constr(regex='^VentilationSimulationControl$') = 'VentilationSimulationControl'
|
265
|
+
|
266
|
+
vent_control_type: VentilationControlType = Field(
|
267
|
+
default=VentilationControlType.single_zone,
|
268
|
+
description='Text indicating type of ventilation control. Choices are: '
|
269
|
+
'SingleZone, MultiZoneWithDistribution, MultiZoneWithoutDistribution. The '
|
270
|
+
'MultiZone options will model air flow with the AirflowNetwork model, which '
|
271
|
+
'is generally more accurate then the SingleZone option, but will take '
|
272
|
+
'considerably longer to simulate, and requires defining more ventilation '
|
273
|
+
'parameters to explicitly account for weather and building-induced pressure '
|
274
|
+
'differences, and the leakage geometry corresponding to specific windows, '
|
275
|
+
'doors, and surface cracks.'
|
276
|
+
)
|
277
|
+
|
278
|
+
reference_temperature: float = Field(
|
279
|
+
default=20,
|
280
|
+
ge=-273.15,
|
281
|
+
description='Reference temperature measurement in Celsius under which the '
|
282
|
+
'surface crack data were obtained.'
|
283
|
+
)
|
284
|
+
|
285
|
+
reference_pressure: float = Field(
|
286
|
+
default=101325,
|
287
|
+
ge=31000,
|
288
|
+
le=120000,
|
289
|
+
description='Reference barometric pressure measurement in Pascals under which '
|
290
|
+
'the surface crack data were obtained.'
|
291
|
+
)
|
292
|
+
|
293
|
+
reference_humidity_ratio: float = Field(
|
294
|
+
default=0,
|
295
|
+
ge=0,
|
296
|
+
description='Reference humidity ratio measurement in kgWater/kgDryAir under '
|
297
|
+
'which the surface crack data were obtained.'
|
298
|
+
)
|
299
|
+
|
300
|
+
building_type: BuildingType = Field(
|
301
|
+
default=BuildingType.lowrise,
|
302
|
+
description='Text indicating relationship between building footprint and '
|
303
|
+
'height used to calculate the wind pressure coefficients for exterior surfaces.'
|
304
|
+
'Choices are: LowRise and HighRise. LowRise corresponds to rectangular building '
|
305
|
+
'whose height is less then three times the width and length of the footprint. '
|
306
|
+
'HighRise corresponds to a rectangular building whose height is more than three '
|
307
|
+
'times the width and length of the footprint. This parameter is required to '
|
308
|
+
'automatically calculate wind pressure coefficients for the AirflowNetwork '
|
309
|
+
'simulation. If used for complex building geometries that cannot be described '
|
310
|
+
'as a highrise or lowrise rectangular mass, the resulting air flow and pressure '
|
311
|
+
'simulated on the building surfaces may be inaccurate.'
|
312
|
+
)
|
313
|
+
|
314
|
+
long_axis_angle: float = Field(
|
315
|
+
default=0,
|
316
|
+
ge=0,
|
317
|
+
le=180,
|
318
|
+
description='The clockwise rotation in degrees from true North of the long axis '
|
319
|
+
'of the building. This parameter is required to automatically calculate wind '
|
320
|
+
'pressure coefficients for the AirflowNetwork simulation. If used for complex '
|
321
|
+
'building geometries that cannot be described as a highrise or lowrise '
|
322
|
+
'rectangular mass, the resulting air flow and pressure simulated on the '
|
323
|
+
'building surfaces may be inaccurate.'
|
324
|
+
)
|
325
|
+
|
326
|
+
aspect_ratio: float = Field(
|
327
|
+
default=1,
|
328
|
+
gt=0,
|
329
|
+
le=1,
|
330
|
+
description='Aspect ratio of a rectangular footprint, defined as the ratio of '
|
331
|
+
'length of the short axis divided by the length of the long axis. This '
|
332
|
+
'parameter is required to automatically calculate wind '
|
333
|
+
'pressure coefficients for the AirflowNetwork simulation. If used for complex '
|
334
|
+
'building geometries that cannot be described as a highrise or lowrise '
|
335
|
+
'rectangular mass, the resulting air flow and pressure simulated on the '
|
336
|
+
'building surfaces may be inaccurate.'
|
337
|
+
)
|
@@ -0,0 +1,161 @@
|
|
1
|
+
"""Geometry objects for model."""
|
2
|
+
from pydantic import Field, constr, conlist, conint
|
3
|
+
from typing import List
|
4
|
+
from ._base import NoExtraBaseModel
|
5
|
+
|
6
|
+
|
7
|
+
class Point3D(NoExtraBaseModel):
|
8
|
+
"""A point object in 3D space."""
|
9
|
+
|
10
|
+
type: constr(regex='^Point3D$') = 'Point3D'
|
11
|
+
|
12
|
+
x: float = Field(
|
13
|
+
...,
|
14
|
+
description='Number for X coordinate.'
|
15
|
+
)
|
16
|
+
|
17
|
+
y: float = Field(
|
18
|
+
...,
|
19
|
+
description='Number for Y coordinate.'
|
20
|
+
)
|
21
|
+
|
22
|
+
z: float = Field(
|
23
|
+
...,
|
24
|
+
description='Number for Z coordinate.'
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
class LineSegment3D(NoExtraBaseModel):
|
29
|
+
"""A single line segment face in 3D space."""
|
30
|
+
|
31
|
+
type: constr(regex='^LineSegment3D$') = 'LineSegment3D'
|
32
|
+
|
33
|
+
p: List[float] = Field(
|
34
|
+
...,
|
35
|
+
description="Line segment base point as 3 (x, y, z) values.",
|
36
|
+
min_items=3,
|
37
|
+
max_items=3
|
38
|
+
)
|
39
|
+
|
40
|
+
v: List[float] = Field(
|
41
|
+
...,
|
42
|
+
description="Line segment direction vector as 3 (x, y, z) values.",
|
43
|
+
min_items=3,
|
44
|
+
max_items=3
|
45
|
+
)
|
46
|
+
|
47
|
+
|
48
|
+
class Plane(NoExtraBaseModel):
|
49
|
+
|
50
|
+
type: constr(regex='^Plane$') = 'Plane'
|
51
|
+
|
52
|
+
n: List[float] = Field(
|
53
|
+
...,
|
54
|
+
description="Plane normal as 3 (x, y, z) values.",
|
55
|
+
min_items=3,
|
56
|
+
max_items=3
|
57
|
+
)
|
58
|
+
|
59
|
+
o: List[float] = Field(
|
60
|
+
...,
|
61
|
+
description="Plane origin as 3 (x, y, z) values",
|
62
|
+
min_items=3,
|
63
|
+
max_items=3
|
64
|
+
)
|
65
|
+
|
66
|
+
x: List[float] = Field(
|
67
|
+
default=None,
|
68
|
+
description="Plane x-axis as 3 (x, y, z) values. If None, it is autocalculated.",
|
69
|
+
min_items=3,
|
70
|
+
max_items=3
|
71
|
+
)
|
72
|
+
|
73
|
+
|
74
|
+
class Face3D(NoExtraBaseModel):
|
75
|
+
"""A single planar face in 3D space."""
|
76
|
+
|
77
|
+
type: constr(regex='^Face3D$') = 'Face3D'
|
78
|
+
|
79
|
+
boundary: List[conlist(float, min_items=3, max_items=3)] = Field(
|
80
|
+
...,
|
81
|
+
min_items=3,
|
82
|
+
description='A list of points representing the outer boundary vertices of '
|
83
|
+
'the face. The list should include at least 3 points and each point '
|
84
|
+
'should be a list of 3 (x, y, z) values.'
|
85
|
+
)
|
86
|
+
|
87
|
+
holes: List[conlist(conlist(float, min_items=3, max_items=3), min_items=3)] = Field(
|
88
|
+
default=None,
|
89
|
+
description='Optional list of lists with one list for each hole in the face.'
|
90
|
+
'Each hole should be a list of at least 3 points and each point a list '
|
91
|
+
'of 3 (x, y, z) values. If None, it will be assumed that there are no '
|
92
|
+
'holes in the face.'
|
93
|
+
)
|
94
|
+
|
95
|
+
plane: Plane = Field(
|
96
|
+
default=None,
|
97
|
+
description='Optional Plane indicating the plane in which the face exists.'
|
98
|
+
'If None, the plane will usually be derived from the boundary points.'
|
99
|
+
)
|
100
|
+
|
101
|
+
|
102
|
+
class Color(NoExtraBaseModel):
|
103
|
+
"""A RGB color."""
|
104
|
+
|
105
|
+
type: constr(regex='^Color$') = 'Color'
|
106
|
+
|
107
|
+
r: int = Field(
|
108
|
+
...,
|
109
|
+
ge=0,
|
110
|
+
le=255,
|
111
|
+
description='Value for red channel.'
|
112
|
+
)
|
113
|
+
|
114
|
+
g: int = Field(
|
115
|
+
...,
|
116
|
+
ge=0,
|
117
|
+
le=255,
|
118
|
+
description='Value for green channel.'
|
119
|
+
)
|
120
|
+
|
121
|
+
b: int = Field(
|
122
|
+
...,
|
123
|
+
ge=0,
|
124
|
+
le=255,
|
125
|
+
description='Value for blue channel.'
|
126
|
+
)
|
127
|
+
|
128
|
+
a: int = Field(
|
129
|
+
default=255,
|
130
|
+
ge=0,
|
131
|
+
le=255,
|
132
|
+
description='Value for the alpha channel, which defines the opacity as a '
|
133
|
+
'number between 0 (fully transparent) and 255 (fully opaque).'
|
134
|
+
)
|
135
|
+
|
136
|
+
|
137
|
+
class Mesh3D(NoExtraBaseModel):
|
138
|
+
"""A mesh in 3D space."""
|
139
|
+
|
140
|
+
type: constr(regex='^Mesh3D$') = 'Mesh3D'
|
141
|
+
|
142
|
+
vertices: List[conlist(float, min_items=3, max_items=3)] = Field(
|
143
|
+
...,
|
144
|
+
min_items=3,
|
145
|
+
description='A list of points representing the vertices of the mesh. '
|
146
|
+
'The list should include at least 3 points and each point '
|
147
|
+
'should be a list of 3 (x, y, z) values.'
|
148
|
+
)
|
149
|
+
|
150
|
+
faces: List[conlist(conint(ge=0), min_items=3, max_items=4)] = Field(
|
151
|
+
...,
|
152
|
+
min_items=1,
|
153
|
+
description='A list of lists with each sub-list having either 3 or 4 '
|
154
|
+
'integers. These integers correspond to indices within the list of vertices.'
|
155
|
+
)
|
156
|
+
|
157
|
+
colors: List[Color] = Field(
|
158
|
+
None,
|
159
|
+
description='An optional list of colors that correspond to either the faces '
|
160
|
+
'of the mesh or the vertices of the mesh.'
|
161
|
+
)
|