fairyfly-core 0.2.3__tar.gz → 0.2.5__tar.gz
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.
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/PKG-INFO +1 -1
- fairyfly_core-0.2.5/fairyfly/colorobj.py +346 -0
- fairyfly_core-0.2.5/fairyfly/dictutil.py +40 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/PKG-INFO +1 -1
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/SOURCES.txt +2 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/CODE_OF_CONDUCT.md +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/CONTRIBUTING.md +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/LICENSE +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/MANIFEST.in +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/README.md +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/dev-requirements.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/__init__.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/__main__.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/_base.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/_lockable.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/boundary.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/checkdup.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/cli/__init__.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/cli/setconfig.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/config.json +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/config.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/extensionutil.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/logutil.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/model.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/properties.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/search.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/shape.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/typing.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/units.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/writer/__init__.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/writer/boundary.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/writer/model.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly/writer/shape.py +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/dependency_links.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/entry_points.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/requires.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/fairyfly_core.egg-info/top_level.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/requirements.txt +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/setup.cfg +0 -0
- {fairyfly_core-0.2.3 → fairyfly_core-0.2.5}/setup.py +0 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Module for coloring geometry with attributes."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
|
|
5
|
+
from .shape import Shape
|
|
6
|
+
from .boundary import Boundary
|
|
7
|
+
from .search import get_attr_nested
|
|
8
|
+
|
|
9
|
+
from ladybug.graphic import GraphicContainer
|
|
10
|
+
from ladybug.legend import LegendParameters, LegendParametersCategorized
|
|
11
|
+
from ladybug_geometry.geometry3d.pointvector import Point3D
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class _ColorObject(object):
|
|
15
|
+
"""Base class for visualization objects.
|
|
16
|
+
|
|
17
|
+
Properties:
|
|
18
|
+
* legend_parameters
|
|
19
|
+
* attr_name
|
|
20
|
+
* attr_name_end
|
|
21
|
+
* attributes
|
|
22
|
+
* attributes_unique
|
|
23
|
+
* attributes_original
|
|
24
|
+
* min_point
|
|
25
|
+
* max_point
|
|
26
|
+
* graphic_container
|
|
27
|
+
"""
|
|
28
|
+
__slots__ = ('_attr_name', '_legend_parameters', '_attr_name_end',
|
|
29
|
+
'_attributes', '_attributes_unique', '_attributes_original',
|
|
30
|
+
'_min_point', '_max_point')
|
|
31
|
+
|
|
32
|
+
def __init__(self, legend_parameters=None):
|
|
33
|
+
"""Initialize ColorObject."""
|
|
34
|
+
# assign the legend parameters of this object
|
|
35
|
+
self.legend_parameters = legend_parameters
|
|
36
|
+
|
|
37
|
+
self._attr_name = None
|
|
38
|
+
self._attr_name_end = None
|
|
39
|
+
self._attributes = None
|
|
40
|
+
self._attributes_unique = None
|
|
41
|
+
self._attributes_original = None
|
|
42
|
+
self._min_point = None
|
|
43
|
+
self._max_point = None
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def legend_parameters(self):
|
|
47
|
+
"""Get or set the legend parameters."""
|
|
48
|
+
return self._legend_parameters
|
|
49
|
+
|
|
50
|
+
@legend_parameters.setter
|
|
51
|
+
def legend_parameters(self, value):
|
|
52
|
+
if value is not None:
|
|
53
|
+
assert isinstance(value, LegendParameters) and not \
|
|
54
|
+
isinstance(value, LegendParametersCategorized), \
|
|
55
|
+
'Expected LegendParameters. Got {}.'.format(type(value))
|
|
56
|
+
self._legend_parameters = value
|
|
57
|
+
else:
|
|
58
|
+
self._legend_parameters = LegendParameters()
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def attr_name(self):
|
|
62
|
+
"""Get a text string of an attribute that the input objects should have."""
|
|
63
|
+
return self._attr_name
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def attr_name_end(self):
|
|
67
|
+
"""Get text for the last attribute in the attr_name.
|
|
68
|
+
|
|
69
|
+
Useful when attr_name is nested.
|
|
70
|
+
"""
|
|
71
|
+
return self._attr_name_end
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def attributes(self):
|
|
75
|
+
"""Get a tuple of text for the attributes assigned to the objects.
|
|
76
|
+
|
|
77
|
+
If the input attr_name is a valid attribute for the object but None is
|
|
78
|
+
assigned, the output will be 'None'. If the input attr_name is not valid
|
|
79
|
+
for the input object, 'N/A' will be returned.
|
|
80
|
+
"""
|
|
81
|
+
return self._attributes
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def attributes_unique(self):
|
|
85
|
+
"""Get a tuple of text for the unique attributes assigned to the objects."""
|
|
86
|
+
return self._attributes_unique
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def attributes_original(self):
|
|
90
|
+
"""Get a tuple of objects for the attributes assigned to the objects.
|
|
91
|
+
|
|
92
|
+
These will follow the original object typing of the attribute and won't
|
|
93
|
+
be strings like the attributes.
|
|
94
|
+
"""
|
|
95
|
+
return self._attributes_original
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def min_point(self):
|
|
99
|
+
"""Get a Point3D for the minimum of the box around the objects."""
|
|
100
|
+
return self._min_point
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def max_point(self):
|
|
104
|
+
"""Get a Point3D for the maximum of the box around the objects."""
|
|
105
|
+
return self._max_point
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def graphic_container(self):
|
|
109
|
+
"""Get a ladybug GraphicContainer that relates to this object.
|
|
110
|
+
|
|
111
|
+
The GraphicContainer possesses almost all things needed to visualize the
|
|
112
|
+
ColorShapes object including the legend, value_colors, etc.
|
|
113
|
+
"""
|
|
114
|
+
# produce a range of values from the collected attributes
|
|
115
|
+
attr_dict = {i: val for i, val in enumerate(self.attributes_unique)}
|
|
116
|
+
attr_dict_rev = {val: i for i, val in attr_dict.items()}
|
|
117
|
+
try:
|
|
118
|
+
values = tuple(attr_dict_rev[r_attr] for r_attr in self.attributes)
|
|
119
|
+
except KeyError: # possibly caused by float cast to -0.0
|
|
120
|
+
values = []
|
|
121
|
+
for r_attr in self.attributes:
|
|
122
|
+
if r_attr == '-0.0':
|
|
123
|
+
values.append(attr_dict_rev['0.0'])
|
|
124
|
+
else:
|
|
125
|
+
values.append(attr_dict_rev[r_attr])
|
|
126
|
+
|
|
127
|
+
# produce legend parameters with an ordinal dict for the attributes
|
|
128
|
+
l_par = self.legend_parameters.duplicate()
|
|
129
|
+
if l_par.is_segment_count_default:
|
|
130
|
+
l_par.segment_count = len(self.attributes_unique)
|
|
131
|
+
l_par.ordinal_dictionary = attr_dict
|
|
132
|
+
if l_par.is_title_default:
|
|
133
|
+
l_par.title = self.attr_name_end.replace('_', ' ').title()
|
|
134
|
+
|
|
135
|
+
return GraphicContainer(values, self.min_point, self.max_point, l_par)
|
|
136
|
+
|
|
137
|
+
def _process_attribute_name(self, attr_name):
|
|
138
|
+
"""Process the attribute name and assign it to this object."""
|
|
139
|
+
self._attr_name = str(attr_name)
|
|
140
|
+
at_split = self._attr_name.split('.')
|
|
141
|
+
if len(at_split) == 1:
|
|
142
|
+
self._attr_name_end = at_split[-1]
|
|
143
|
+
elif at_split[-1] == 'display_name':
|
|
144
|
+
self._attr_name_end = at_split[-2]
|
|
145
|
+
elif at_split[-1] == '__name__' and at_split[-2] == '__class__':
|
|
146
|
+
self._attr_name_end = at_split[-3]
|
|
147
|
+
else:
|
|
148
|
+
self._attr_name_end = at_split[-1]
|
|
149
|
+
|
|
150
|
+
def _process_attributes(self, ff_objs):
|
|
151
|
+
"""Process the attributes of fairyfly objects."""
|
|
152
|
+
nd = self.legend_parameters.decimal_count
|
|
153
|
+
attributes = [get_attr_nested(obj, self._attr_name, nd, False)
|
|
154
|
+
for obj in ff_objs]
|
|
155
|
+
attributes_unique = set(attributes)
|
|
156
|
+
float_attr = [atr for atr in attributes_unique if isinstance(atr, float)]
|
|
157
|
+
str_attr = [str(atr) for atr in attributes_unique if not isinstance(atr, float)]
|
|
158
|
+
float_attr.sort()
|
|
159
|
+
str_attr.sort()
|
|
160
|
+
self._attributes = tuple(str(val) for val in attributes)
|
|
161
|
+
self._attributes_unique = tuple(str_attr) + tuple(str(val) for val in float_attr)
|
|
162
|
+
self._attributes_original = \
|
|
163
|
+
tuple(get_attr_nested(obj, self._attr_name, cast_to_str=False)
|
|
164
|
+
for obj in ff_objs)
|
|
165
|
+
|
|
166
|
+
def _calculate_min_max(self, ff_objs):
|
|
167
|
+
"""Calculate maximum and minimum Point3D for a set of shapes."""
|
|
168
|
+
st_rm_min, st_rm_max = ff_objs[0].min, ff_objs[0].max
|
|
169
|
+
min_pt = [st_rm_min.x, st_rm_min.y, st_rm_min.z]
|
|
170
|
+
max_pt = [st_rm_max.x, st_rm_max.y, st_rm_max.z]
|
|
171
|
+
|
|
172
|
+
for shape in ff_objs[1:]:
|
|
173
|
+
rm_min, rm_max = shape.min, shape.max
|
|
174
|
+
if rm_min.x < min_pt[0]:
|
|
175
|
+
min_pt[0] = rm_min.x
|
|
176
|
+
if rm_min.y < min_pt[1]:
|
|
177
|
+
min_pt[1] = rm_min.y
|
|
178
|
+
if rm_min.z < min_pt[2]:
|
|
179
|
+
min_pt[2] = rm_min.z
|
|
180
|
+
if rm_max.x > max_pt[0]:
|
|
181
|
+
max_pt[0] = rm_max.x
|
|
182
|
+
if rm_max.y > max_pt[1]:
|
|
183
|
+
max_pt[1] = rm_max.y
|
|
184
|
+
if rm_max.z > max_pt[2]:
|
|
185
|
+
max_pt[2] = rm_max.z
|
|
186
|
+
|
|
187
|
+
self._min_point = Point3D(min_pt[0], min_pt[1], min_pt[2])
|
|
188
|
+
self._max_point = Point3D(max_pt[0], max_pt[1], max_pt[2])
|
|
189
|
+
|
|
190
|
+
def ToString(self):
|
|
191
|
+
"""Overwrite .NET ToString."""
|
|
192
|
+
return self.__repr__()
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class ColorShape(_ColorObject):
|
|
196
|
+
"""Object for visualizing shape attributes.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
shapes: An array of fairyfly Shapes, which will be colored with the attribute.
|
|
200
|
+
attr_name: A text string of an attribute that the input shapes should have.
|
|
201
|
+
This can have '.' that separate the nested attributes from one another.
|
|
202
|
+
For example, 'properties.therm.materials'.
|
|
203
|
+
legend_parameters: An optional LegendParameter object to change the display
|
|
204
|
+
of the ColorShape (Default: None).
|
|
205
|
+
|
|
206
|
+
Properties:
|
|
207
|
+
* shapes
|
|
208
|
+
* attr_name
|
|
209
|
+
* legend_parameters
|
|
210
|
+
* attr_name_end
|
|
211
|
+
* attributes
|
|
212
|
+
* attributes_unique
|
|
213
|
+
* attributes_original
|
|
214
|
+
* geometry
|
|
215
|
+
* graphic_container
|
|
216
|
+
* min_point
|
|
217
|
+
* max_point
|
|
218
|
+
"""
|
|
219
|
+
__slots__ = ('_shapes',)
|
|
220
|
+
|
|
221
|
+
def __init__(self, shapes, attr_name, legend_parameters=None):
|
|
222
|
+
"""Initialize ColorShape."""
|
|
223
|
+
try: # check the input shapes
|
|
224
|
+
shapes = tuple(shapes)
|
|
225
|
+
except TypeError:
|
|
226
|
+
raise TypeError('Input shapes must be an array. Got {}.'.format(type(shapes)))
|
|
227
|
+
assert len(shapes) > 0, 'ColorShapes must have at least one shape.'
|
|
228
|
+
for shape in shapes:
|
|
229
|
+
assert isinstance(shape, Shape), 'Expected fairyfly Shape for ' \
|
|
230
|
+
'ColorShape shapes. Got {}.'.format(type(shape))
|
|
231
|
+
self._shapes = shapes
|
|
232
|
+
self._calculate_min_max(shapes)
|
|
233
|
+
|
|
234
|
+
# assign the legend parameters of this object
|
|
235
|
+
self.legend_parameters = legend_parameters
|
|
236
|
+
|
|
237
|
+
# get the attributes of the input shapes
|
|
238
|
+
self._process_attribute_name(attr_name)
|
|
239
|
+
self._process_attributes(shapes)
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def shapes(self):
|
|
243
|
+
"""Get a tuple of fairyfly Shapes assigned to this object."""
|
|
244
|
+
return self._shapes
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def geometry(self):
|
|
248
|
+
"""Get a nested array with each sub-array having the Face3D of each shape."""
|
|
249
|
+
return [s.geometry for s in self.shapes]
|
|
250
|
+
|
|
251
|
+
def __repr__(self):
|
|
252
|
+
"""Color Shape representation."""
|
|
253
|
+
return 'Color Shape:\n{} Shapes\n{}'.format(len(self.shapes), self.attr_name_end)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class ColorBoundary(_ColorObject):
|
|
257
|
+
"""Object for visualizing boundary attributes.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
boundaries: An array of fairyfly Boundaries which will be colored with
|
|
261
|
+
their attributes.
|
|
262
|
+
attr_name: A text string of an attribute that the input faces should have.
|
|
263
|
+
This can have '.' that separate the nested attributes from one another.
|
|
264
|
+
For example, 'properties.therm.condition.temperature'.
|
|
265
|
+
legend_parameters: An optional LegendParameter object to change the display
|
|
266
|
+
of the ColorBoundary (Default: None).
|
|
267
|
+
|
|
268
|
+
Properties:
|
|
269
|
+
* boundaries
|
|
270
|
+
* attr_name
|
|
271
|
+
* legend_parameters
|
|
272
|
+
* attr_name_end
|
|
273
|
+
* attributes_unique
|
|
274
|
+
* attributes
|
|
275
|
+
* attributes_original
|
|
276
|
+
* flat_geometry
|
|
277
|
+
* graphic_container
|
|
278
|
+
* min_point
|
|
279
|
+
* max_point
|
|
280
|
+
"""
|
|
281
|
+
__slots__ = ('_boundaries',)
|
|
282
|
+
|
|
283
|
+
def __init__(self, boundaries, attr_name, legend_parameters=None):
|
|
284
|
+
"""Initialize ColorBoundary."""
|
|
285
|
+
try: # check the input boundaries
|
|
286
|
+
boundaries = tuple(boundaries)
|
|
287
|
+
except TypeError:
|
|
288
|
+
raise TypeError(
|
|
289
|
+
'Input boundaries must be an array. Got {}.'.format(type(boundaries)))
|
|
290
|
+
assert len(boundaries) > 0, 'ColorBoundary must have at least one boundary.'
|
|
291
|
+
for bound in boundaries:
|
|
292
|
+
assert isinstance(bound, Boundary), 'Expected fairyfly Boundary for ' \
|
|
293
|
+
'ColorBoundary. Got {}.'.format(type(bound))
|
|
294
|
+
self._boundaries = boundaries
|
|
295
|
+
self._calculate_min_max(boundaries)
|
|
296
|
+
|
|
297
|
+
# assign the legend parameters of this object
|
|
298
|
+
self.legend_parameters = legend_parameters
|
|
299
|
+
|
|
300
|
+
# get the attributes of the input faces
|
|
301
|
+
self._process_attribute_name(attr_name)
|
|
302
|
+
self._process_attributes(boundaries)
|
|
303
|
+
|
|
304
|
+
@property
|
|
305
|
+
def boundaries(self):
|
|
306
|
+
"""Get the fairyfly Boundaries assigned to this object.
|
|
307
|
+
"""
|
|
308
|
+
return self._boundaries
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
def attributes(self):
|
|
312
|
+
"""Get a tuple of text for the attributes assigned to the objects.
|
|
313
|
+
|
|
314
|
+
If the input attr_name is a valid attribute for the object but None is
|
|
315
|
+
assigned, the output will be 'None'. If the input attr_name is not valid
|
|
316
|
+
for the input object, 'N/A' will be returned.
|
|
317
|
+
"""
|
|
318
|
+
flat_attr = []
|
|
319
|
+
for bnd, attrib in zip(self._boundaries, self._attributes):
|
|
320
|
+
flat_attr.extend([attrib] * len(bnd))
|
|
321
|
+
return flat_attr
|
|
322
|
+
|
|
323
|
+
@property
|
|
324
|
+
def attributes_original(self):
|
|
325
|
+
"""Get a tuple of objects for the attributes assigned to the objects.
|
|
326
|
+
|
|
327
|
+
These will follow the original object typing of the attribute and won't
|
|
328
|
+
be strings like the attributes.
|
|
329
|
+
"""
|
|
330
|
+
flat_attr = []
|
|
331
|
+
for bnd, attrib in zip(self._boundaries, self._attributes_original):
|
|
332
|
+
flat_attr.extend([attrib] * len(bnd))
|
|
333
|
+
return flat_attr
|
|
334
|
+
|
|
335
|
+
@property
|
|
336
|
+
def flat_geometry(self):
|
|
337
|
+
"""Get an array of LineSegment3D on this object.
|
|
338
|
+
|
|
339
|
+
The geometries here align with the attributes and graphic_container colors.
|
|
340
|
+
"""
|
|
341
|
+
return [lin for bound in self._boundaries for lin in bound]
|
|
342
|
+
|
|
343
|
+
def __repr__(self):
|
|
344
|
+
"""Color Shape representation."""
|
|
345
|
+
return 'Color Boundary:\n{} Boundary\n{}'.format(
|
|
346
|
+
len(self.boundaries), self.attr_name_end)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Utilities to convert any dictionary to Python objects.
|
|
3
|
+
|
|
4
|
+
Note that importing this module will import almost all modules within the
|
|
5
|
+
library in order to be able to re-serialize almost any dictionary produced
|
|
6
|
+
from the library.
|
|
7
|
+
"""
|
|
8
|
+
from fairyfly.model import Model
|
|
9
|
+
from fairyfly.shape import Shape
|
|
10
|
+
from fairyfly.boundary import Boundary
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def dict_to_object(fairyfly_dict, raise_exception=True):
|
|
14
|
+
"""Re-serialize a dictionary of almost any object within fairyfly.
|
|
15
|
+
|
|
16
|
+
This includes any Model, Shape or Boundary object.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
fairyfly_dict: A dictionary of any Fairyfly object. Note
|
|
20
|
+
that this should be a non-abridged dictionary to be valid.
|
|
21
|
+
raise_exception: Boolean to note whether an exception should be raised
|
|
22
|
+
if the object is not identified as a part of fairyfly.
|
|
23
|
+
Default: True.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
A Python object derived from the input fairyfly_dict.
|
|
27
|
+
"""
|
|
28
|
+
try: # get the type key from the dictionary
|
|
29
|
+
obj_type = fairyfly_dict['type']
|
|
30
|
+
except KeyError:
|
|
31
|
+
raise ValueError('Fairyfly dictionary lacks required "type" key.')
|
|
32
|
+
|
|
33
|
+
if obj_type == 'Model':
|
|
34
|
+
return Model.from_dict(fairyfly_dict)
|
|
35
|
+
elif obj_type == 'Shape':
|
|
36
|
+
return Shape.from_dict(fairyfly_dict)
|
|
37
|
+
elif obj_type == 'Boundary':
|
|
38
|
+
return Boundary.from_dict(fairyfly_dict)
|
|
39
|
+
elif raise_exception:
|
|
40
|
+
raise ValueError('{} is not a recognized fairyfly object'.format(obj_type))
|
|
@@ -12,8 +12,10 @@ fairyfly/_base.py
|
|
|
12
12
|
fairyfly/_lockable.py
|
|
13
13
|
fairyfly/boundary.py
|
|
14
14
|
fairyfly/checkdup.py
|
|
15
|
+
fairyfly/colorobj.py
|
|
15
16
|
fairyfly/config.json
|
|
16
17
|
fairyfly/config.py
|
|
18
|
+
fairyfly/dictutil.py
|
|
17
19
|
fairyfly/extensionutil.py
|
|
18
20
|
fairyfly/logutil.py
|
|
19
21
|
fairyfly/model.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|