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.

Files changed (152) hide show
  1. honeybee_radiance/__init__.py +11 -0
  2. honeybee_radiance/__main__.py +4 -0
  3. honeybee_radiance/_extend_honeybee.py +93 -0
  4. honeybee_radiance/cli/__init__.py +88 -0
  5. honeybee_radiance/cli/dc.py +400 -0
  6. honeybee_radiance/cli/edit.py +529 -0
  7. honeybee_radiance/cli/glare.py +118 -0
  8. honeybee_radiance/cli/grid.py +859 -0
  9. honeybee_radiance/cli/lib.py +458 -0
  10. honeybee_radiance/cli/modifier.py +133 -0
  11. honeybee_radiance/cli/mtx.py +226 -0
  12. honeybee_radiance/cli/multiphase.py +1034 -0
  13. honeybee_radiance/cli/octree.py +640 -0
  14. honeybee_radiance/cli/postprocess.py +1186 -0
  15. honeybee_radiance/cli/raytrace.py +219 -0
  16. honeybee_radiance/cli/rpict.py +125 -0
  17. honeybee_radiance/cli/schedule.py +56 -0
  18. honeybee_radiance/cli/setconfig.py +63 -0
  19. honeybee_radiance/cli/sky.py +545 -0
  20. honeybee_radiance/cli/study.py +66 -0
  21. honeybee_radiance/cli/sunpath.py +331 -0
  22. honeybee_radiance/cli/threephase.py +255 -0
  23. honeybee_radiance/cli/translate.py +400 -0
  24. honeybee_radiance/cli/util.py +121 -0
  25. honeybee_radiance/cli/view.py +261 -0
  26. honeybee_radiance/cli/viewfactor.py +347 -0
  27. honeybee_radiance/config.json +6 -0
  28. honeybee_radiance/config.py +427 -0
  29. honeybee_radiance/dictutil.py +50 -0
  30. honeybee_radiance/dynamic/__init__.py +5 -0
  31. honeybee_radiance/dynamic/group.py +479 -0
  32. honeybee_radiance/dynamic/multiphase.py +557 -0
  33. honeybee_radiance/dynamic/state.py +718 -0
  34. honeybee_radiance/dynamic/stategeo.py +352 -0
  35. honeybee_radiance/geometry/__init__.py +13 -0
  36. honeybee_radiance/geometry/bubble.py +42 -0
  37. honeybee_radiance/geometry/cone.py +215 -0
  38. honeybee_radiance/geometry/cup.py +54 -0
  39. honeybee_radiance/geometry/cylinder.py +197 -0
  40. honeybee_radiance/geometry/geometrybase.py +37 -0
  41. honeybee_radiance/geometry/instance.py +40 -0
  42. honeybee_radiance/geometry/mesh.py +38 -0
  43. honeybee_radiance/geometry/polygon.py +174 -0
  44. honeybee_radiance/geometry/ring.py +214 -0
  45. honeybee_radiance/geometry/source.py +182 -0
  46. honeybee_radiance/geometry/sphere.py +178 -0
  47. honeybee_radiance/geometry/tube.py +46 -0
  48. honeybee_radiance/lib/__init__.py +1 -0
  49. honeybee_radiance/lib/_loadmodifiers.py +72 -0
  50. honeybee_radiance/lib/_loadmodifiersets.py +69 -0
  51. honeybee_radiance/lib/modifiers.py +58 -0
  52. honeybee_radiance/lib/modifiersets.py +63 -0
  53. honeybee_radiance/lightpath.py +204 -0
  54. honeybee_radiance/lightsource/__init__.py +1 -0
  55. honeybee_radiance/lightsource/_gendaylit.py +479 -0
  56. honeybee_radiance/lightsource/dictutil.py +49 -0
  57. honeybee_radiance/lightsource/ground.py +160 -0
  58. honeybee_radiance/lightsource/sky/__init__.py +7 -0
  59. honeybee_radiance/lightsource/sky/_skybase.py +177 -0
  60. honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
  61. honeybee_radiance/lightsource/sky/cie.py +378 -0
  62. honeybee_radiance/lightsource/sky/climatebased.py +501 -0
  63. honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
  64. honeybee_radiance/lightsource/sky/skydome.py +113 -0
  65. honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
  66. honeybee_radiance/lightsource/sky/strutil.py +34 -0
  67. honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
  68. honeybee_radiance/lightsource/sunpath.py +247 -0
  69. honeybee_radiance/modifier/__init__.py +3 -0
  70. honeybee_radiance/modifier/material/__init__.py +30 -0
  71. honeybee_radiance/modifier/material/absdf.py +477 -0
  72. honeybee_radiance/modifier/material/antimatter.py +54 -0
  73. honeybee_radiance/modifier/material/ashik2.py +51 -0
  74. honeybee_radiance/modifier/material/brtdfunc.py +81 -0
  75. honeybee_radiance/modifier/material/bsdf.py +292 -0
  76. honeybee_radiance/modifier/material/dielectric.py +53 -0
  77. honeybee_radiance/modifier/material/glass.py +431 -0
  78. honeybee_radiance/modifier/material/glow.py +246 -0
  79. honeybee_radiance/modifier/material/illum.py +51 -0
  80. honeybee_radiance/modifier/material/interface.py +49 -0
  81. honeybee_radiance/modifier/material/light.py +206 -0
  82. honeybee_radiance/modifier/material/materialbase.py +36 -0
  83. honeybee_radiance/modifier/material/metal.py +167 -0
  84. honeybee_radiance/modifier/material/metal2.py +41 -0
  85. honeybee_radiance/modifier/material/metdata.py +41 -0
  86. honeybee_radiance/modifier/material/metfunc.py +41 -0
  87. honeybee_radiance/modifier/material/mirror.py +340 -0
  88. honeybee_radiance/modifier/material/mist.py +86 -0
  89. honeybee_radiance/modifier/material/plasdata.py +58 -0
  90. honeybee_radiance/modifier/material/plasfunc.py +59 -0
  91. honeybee_radiance/modifier/material/plastic.py +354 -0
  92. honeybee_radiance/modifier/material/plastic2.py +58 -0
  93. honeybee_radiance/modifier/material/prism1.py +57 -0
  94. honeybee_radiance/modifier/material/prism2.py +48 -0
  95. honeybee_radiance/modifier/material/spotlight.py +50 -0
  96. honeybee_radiance/modifier/material/trans.py +518 -0
  97. honeybee_radiance/modifier/material/trans2.py +49 -0
  98. honeybee_radiance/modifier/material/transdata.py +50 -0
  99. honeybee_radiance/modifier/material/transfunc.py +53 -0
  100. honeybee_radiance/modifier/mixture/__init__.py +6 -0
  101. honeybee_radiance/modifier/mixture/mixdata.py +49 -0
  102. honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
  103. honeybee_radiance/modifier/mixture/mixpict.py +52 -0
  104. honeybee_radiance/modifier/mixture/mixtext.py +66 -0
  105. honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
  106. honeybee_radiance/modifier/modifierbase.py +40 -0
  107. honeybee_radiance/modifier/pattern/__init__.py +9 -0
  108. honeybee_radiance/modifier/pattern/brightdata.py +49 -0
  109. honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
  110. honeybee_radiance/modifier/pattern/brighttext.py +81 -0
  111. honeybee_radiance/modifier/pattern/colordata.py +56 -0
  112. honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
  113. honeybee_radiance/modifier/pattern/colorpict.py +54 -0
  114. honeybee_radiance/modifier/pattern/colortext.py +73 -0
  115. honeybee_radiance/modifier/pattern/patternbase.py +34 -0
  116. honeybee_radiance/modifier/texture/__init__.py +4 -0
  117. honeybee_radiance/modifier/texture/texdata.py +29 -0
  118. honeybee_radiance/modifier/texture/texfunc.py +26 -0
  119. honeybee_radiance/modifier/texture/texturebase.py +27 -0
  120. honeybee_radiance/modifierset.py +1091 -0
  121. honeybee_radiance/mutil.py +60 -0
  122. honeybee_radiance/postprocess/__init__.py +1 -0
  123. honeybee_radiance/postprocess/annual.py +108 -0
  124. honeybee_radiance/postprocess/annualdaylight.py +425 -0
  125. honeybee_radiance/postprocess/annualglare.py +201 -0
  126. honeybee_radiance/postprocess/annualirradiance.py +187 -0
  127. honeybee_radiance/postprocess/electriclight.py +119 -0
  128. honeybee_radiance/postprocess/en17037.py +261 -0
  129. honeybee_radiance/postprocess/leed.py +304 -0
  130. honeybee_radiance/postprocess/solartracking.py +90 -0
  131. honeybee_radiance/primitive.py +554 -0
  132. honeybee_radiance/properties/__init__.py +1 -0
  133. honeybee_radiance/properties/_base.py +390 -0
  134. honeybee_radiance/properties/aperture.py +197 -0
  135. honeybee_radiance/properties/door.py +198 -0
  136. honeybee_radiance/properties/face.py +123 -0
  137. honeybee_radiance/properties/model.py +1291 -0
  138. honeybee_radiance/properties/room.py +490 -0
  139. honeybee_radiance/properties/shade.py +186 -0
  140. honeybee_radiance/properties/shademesh.py +116 -0
  141. honeybee_radiance/putil.py +44 -0
  142. honeybee_radiance/reader.py +214 -0
  143. honeybee_radiance/sensor.py +166 -0
  144. honeybee_radiance/sensorgrid.py +1008 -0
  145. honeybee_radiance/view.py +1101 -0
  146. honeybee_radiance/writer.py +951 -0
  147. honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
  148. honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
  149. honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
  150. honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
  151. honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
  152. honeybee_radiance-1.66.190.dist-info/top_level.txt +1 -0
@@ -0,0 +1,197 @@
1
+ """Radiance Cylinder.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Cylinder
4
+ """
5
+ from .geometrybase import Geometry
6
+ import honeybee.typing as typing
7
+
8
+
9
+ class Cylinder(Geometry):
10
+ """Radiance Cylinder.
11
+
12
+ A cylinder is like a cone, but its starting and ending radii are equal.
13
+
14
+ .. code-block:: shell
15
+
16
+ mod cylinder id
17
+ 0
18
+ 0
19
+ 7
20
+ x0 y0 z0
21
+ x1 y1 z1
22
+ rad
23
+
24
+ Args:
25
+ identifier: Text string for a unique Geometry ID. Must not contain spaces
26
+ or special characters. This will be used to identify the object across
27
+ a model and in the exported Radiance files.
28
+ center_pt_start: Cylinder start center point as (x, y, z)
29
+ (Default: (0, 0 ,0)).
30
+ center_pt_end: Cylinder end center point as (x, y, z) (Default: (0, 0 ,10)).
31
+ radius: Cylinder start radius as a number (Default: 10).
32
+ modifier: Geometry modifier (Default: None).
33
+ dependencies: A list of primitives that this primitive depends on. This
34
+ argument is only useful for defining advanced primitives where the
35
+ primitive is defined based on other primitives. (Default: [])
36
+
37
+ Properties:
38
+ * identifier
39
+ * display_name
40
+ * center_pt_start
41
+ * center_pt_end
42
+ * radius
43
+ * values
44
+ * modifier
45
+ * dependencies
46
+ """
47
+ __slots__ = ('_center_pt_start', '_center_pt_end', '_radius')
48
+
49
+ def __init__(self, identifier, center_pt_start=None, center_pt_end=None, radius=10,
50
+ modifier=None, dependencies=None):
51
+ """Radiance Cylinder."""
52
+ Geometry.__init__(self, identifier, modifier=modifier, dependencies=dependencies)
53
+ self.center_pt_start = center_pt_start or (0, 0, 0)
54
+ self.center_pt_end = center_pt_end or (0, 0, 10)
55
+ self.radius = radius if radius is not None else 10
56
+ self._update_values()
57
+
58
+ def _update_values(self):
59
+ """update value dictionaries."""
60
+ self._values[2] = \
61
+ [self.center_pt_start[0], self.center_pt_start[1], self.center_pt_start[2],
62
+ self.center_pt_end[0], self.center_pt_end[1], self.center_pt_end[2],
63
+ self.radius]
64
+
65
+ @property
66
+ def center_pt_start(self):
67
+ """Cone start center point as (x, y, z). Default is (0, 0 ,0)."""
68
+ return self._center_pt_start
69
+
70
+ @center_pt_start.setter
71
+ def center_pt_start(self, value):
72
+ self._center_pt_start = tuple(float(v) for v in value)
73
+ assert len(self._center_pt_start) == 3, \
74
+ 'Radiance Cylinder center point must have 3 values for (x, y, z).'
75
+
76
+ @property
77
+ def radius(self):
78
+ """Cone start radius as a number. Default is 10."""
79
+ return self._radius
80
+
81
+ @radius.setter
82
+ def radius(self, value):
83
+ self._radius = typing.float_positive(value)
84
+
85
+ @property
86
+ def center_pt_end(self):
87
+ """Cone end center point as (x, y, z), Default is (0, 0 ,10)."""
88
+ return self._center_pt_end
89
+
90
+ @center_pt_end.setter
91
+ def center_pt_end(self, value):
92
+ self._center_pt_end = tuple(float(v) for v in value)
93
+ assert len(self._center_pt_end) == 3, \
94
+ 'Radiance Cylinder center point must have 3 values for (x, y, z).'
95
+
96
+ @classmethod
97
+ def from_primitive_dict(cls, primitive_dict):
98
+ """Initialize a Cylinder from a primitive dict.
99
+
100
+ Args:
101
+ data: A dictionary in the format below.
102
+
103
+ .. code-block:: python
104
+
105
+ {
106
+ "modifier": {}, # primitive modifier (Default: None)
107
+ "type": "cylinder", # primitive type
108
+ "identifier": "", # primitive identifier
109
+ "display_name": "", # primitive display name
110
+ "values": [], # values
111
+ "dependencies": []
112
+ }
113
+ """
114
+ assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
115
+ if primitive_dict['type'] != cls.__name__.lower():
116
+ raise ValueError(
117
+ 'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
118
+ )
119
+
120
+ modifier, dependencies = cls.filter_dict_input(primitive_dict)
121
+ values = primitive_dict['values'][2]
122
+
123
+ cls_ = cls(
124
+ identifier=primitive_dict['identifier'],
125
+ center_pt_start=values[0:3],
126
+ center_pt_end=values[3:6],
127
+ radius=values[6],
128
+ modifier=modifier,
129
+ dependencies=dependencies
130
+ )
131
+ if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
132
+ cls_.display_name = primitive_dict['display_name']
133
+
134
+ # this might look redundant but it is NOT. see glass for explanation.
135
+ cls_.values = primitive_dict['values']
136
+ return cls_
137
+
138
+ @classmethod
139
+ def from_dict(cls, data):
140
+ """Initialize a Cylinder from a dictionary.
141
+
142
+ Args:
143
+ data: A dictionary in the format below.
144
+
145
+ .. code-block:: python
146
+
147
+ {
148
+ "type": "cylinder", # Geometry type
149
+ "modifier": {} ,
150
+ "identifier": "", # Geometry identifer
151
+ "display_name": "", # Geometry display name
152
+ "center_pt_start": (0, 0, 0),
153
+ "center_pt_end": (0, 0, 10),
154
+ "radius": float,
155
+ "dependencies": []
156
+ }
157
+ """
158
+ assert 'type' in data, 'Input dictionary is missing "type".'
159
+ if data['type'] != cls.__name__.lower():
160
+ raise ValueError(
161
+ 'Type must be %s not %s.' % (cls.__name__.lower(),
162
+ data['type'])
163
+ )
164
+ modifier, dependencies = cls.filter_dict_input(data)
165
+
166
+ new_obj = cls(identifier=data["identifier"],
167
+ center_pt_start=(data["center_pt_start"]),
168
+ center_pt_end=(data["center_pt_end"]),
169
+ radius=data["radius"],
170
+ modifier=modifier,
171
+ dependencies=dependencies)
172
+ if 'display_name' in data and data['display_name'] is not None:
173
+ new_obj.display_name = data['display_name']
174
+ return new_obj
175
+
176
+ def to_dict(self):
177
+ """Translate this object to a dictionary."""
178
+ base = {
179
+ "modifier": self.modifier.to_dict(),
180
+ "type": self.__class__.__name__.lower(),
181
+ "identifier": self.identifier,
182
+ "center_pt_start": self.center_pt_start,
183
+ "radius": self.radius,
184
+ "center_pt_end": self.center_pt_end,
185
+ 'dependencies': [dp.to_dict() for dp in self.dependencies]
186
+ }
187
+ if self._display_name is not None:
188
+ base['display_name'] = self.display_name
189
+ return base
190
+
191
+ def __copy__(self):
192
+ mod, depend = self._dup_mod_and_depend()
193
+ new_obj = self.__class__(
194
+ self.identifier, self.center_pt_start, self.center_pt_end, self.radius,
195
+ mod, depend)
196
+ new_obj._display_name = self._display_name
197
+ return new_obj
@@ -0,0 +1,37 @@
1
+ """Base Radiance Geometry class (e.g polygon, sphere, source, etc.).
2
+
3
+ Radiance supports a number of native geometry primitives. The one that is most
4
+ commonly used to represent planar geometry is a Polygon but many of the other
5
+ geometry primitives can be used to specify simple types of curved geometry with
6
+ a fraction of the file size, memory, and computational power needed to support
7
+ a planar approximation of curved geometry. More information on Radiance geometry
8
+ Primitives can be found at:
9
+
10
+ https://floyd.lbl.gov/radiance/refer/ray.html#Surfaces
11
+ """
12
+ from ..primitive import Primitive
13
+
14
+
15
+ class Geometry(Primitive):
16
+ """Base class for Radiance geometries.
17
+
18
+ Properties:
19
+ * identifier
20
+ * display_name
21
+ * values
22
+ * modifier
23
+ * dependencies
24
+ * is_geometry
25
+ * is_modifier
26
+ * is_material
27
+ * is_texture
28
+ * is_pattern
29
+ * is_mixture
30
+ * is_opaque
31
+ """
32
+ __slots__ = ()
33
+
34
+ @property
35
+ def is_geometry(self):
36
+ """Get a boolean noting whether this object is a Radiance geometry."""
37
+ return True
@@ -0,0 +1,40 @@
1
+ """Radiance Transfunc Instance.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Instance
4
+ """
5
+ from .geometrybase import Geometry
6
+
7
+
8
+ # TODO(): Implement the class. It's currently creates this geometry as generic Radiance
9
+ # geometry
10
+ class Instance(Geometry):
11
+ """Radiance Instance.
12
+
13
+ An instance is a compound surface, given by the contents of an octree file (created
14
+ by oconv).
15
+
16
+ .. code-block:: shell
17
+
18
+ mod instance id
19
+ 1+ octree transform
20
+ 0
21
+ 0
22
+
23
+ If the modifier is "void", then surfaces will use the modifiers given in the original
24
+ description. Otherwise, the modifier specified is used in their place. The transform
25
+ moves the octree to the desired location in the scene. Multiple instances using the
26
+ same octree take little extra memory, hence very complex descriptions can be rendered
27
+ using this primitive.
28
+
29
+ There are a number of important limitations to be aware of when using instances.
30
+ First, the scene description used to generate the octree must stand on its own,
31
+ without referring to modifiers in the parent description. This is necessary for
32
+ oconv to create the octree. Second, light sources in the octree will not be
33
+ incorporated correctly in the calculation, and they are not recommended. Finally,
34
+ there is no advantage (other than convenience) to using a single instance of an
35
+ octree, or an octree containing only a few surfaces. An xform command on the
36
+ subordinate description is preferred in such cases.
37
+ """
38
+ __slots__ = ()
39
+
40
+ pass
@@ -0,0 +1,38 @@
1
+ """Radiance Transfunc Mesh.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Mesh
4
+ """
5
+ from .geometrybase import Geometry
6
+
7
+
8
+ # TODO(): Implement the class. It's currently creates this geometry as generic Radiance
9
+ # geometry
10
+ class Mesh(Geometry):
11
+ """Radiance Mesh.
12
+
13
+ A mesh is a compound surface, made up of many triangles and an octree data structure
14
+ to accelerate ray intersection. It is typically converted from a Wavefront .OBJ file
15
+ using the obj2mesh program.
16
+
17
+ .. code-block:: shell
18
+
19
+ mod mesh id
20
+ 1+ meshfile transform
21
+ 0
22
+ 0
23
+
24
+ If the modifier is "void", then surfaces will use the modifiers given in the original
25
+ mesh description. Otherwise, the modifier specified is used in their place. The
26
+ transform moves the mesh to the desired location in the scene. Multiple instances
27
+ using the same meshfile take little extra memory, and the compiled mesh itself takes
28
+ much less space than individual polygons would. In the case of an unsmoothed mesh,
29
+ using the mesh primitive reduces memory requirements by a factor of 30 relative to
30
+ individual triangles. If a mesh has smoothed surfaces, we save a factor of 50 or
31
+ more, permitting very detailed geometries that would otherwise exhaust the available
32
+ memory. In addition, the mesh primitive can have associated (u,v) coordinates for
33
+ pattern and texture mapping. These are made available to function files via the Lu
34
+ and Lv variables.
35
+ """
36
+ __slots__ = ()
37
+
38
+ pass
@@ -0,0 +1,174 @@
1
+ """Radiance Polygon.
2
+
3
+ http://radsite.lbl.gov/radiance/refer/ray.html#Polygon
4
+ """
5
+ from .geometrybase import Geometry
6
+
7
+
8
+ class Polygon(Geometry):
9
+ """Radiance Polygon.
10
+
11
+ A polygon is given by a list of three-dimensional vertices, which are ordered
12
+ counter-clockwise as viewed from the front side (into the surface normal). The last
13
+ vertex is automatically connected to the first. Holes are represented in polygons as
14
+ interior vertices connected to the outer perimeter by coincident edges (seams).
15
+
16
+ .. code-block:: shell
17
+
18
+ mod polygon id
19
+ 0
20
+ 0
21
+ 3n
22
+ x1 y1 z1
23
+ x2 y2 z2
24
+ ...
25
+ xn yn zn
26
+
27
+ Args:
28
+ identifier: Text string for a unique Geometry ID. Must not contain spaces
29
+ or special characters. This will be used to identify the object across
30
+ a model and in the exported Radiance files.
31
+ vertices: Minimum of three arrays, each with 3 (x, y, z) values for
32
+ vertices that make up the polygon. Vertices must be ordered
33
+ counter-clockwise as viewed from the front side. The last vertex is
34
+ assumed to be connected to the first.
35
+ modifier: Geometry modifier (Default: None).
36
+ dependencies: A list of primitives that this primitive depends on. This
37
+ argument is only useful for defining advanced primitives where the
38
+ primitive is defined based on other primitives. (Default: [])
39
+
40
+ Properties:
41
+ * identifier
42
+ * display_name
43
+ * vertices
44
+ * modifier
45
+ * dependencies
46
+ * values
47
+
48
+ Usage:
49
+
50
+ .. code-block:: python
51
+
52
+ polygon = Polygon("test_polygon", [(0, 0, 10), (10, 0, 10), (10, 0, 0)])
53
+ print(polygon)
54
+ """
55
+ __slots__ = ('_vertices',)
56
+
57
+ def __init__(self, identifier, vertices, modifier=None, dependencies=None):
58
+ """Radiance Polygon."""
59
+ Geometry.__init__(self, identifier, modifier=modifier, dependencies=dependencies)
60
+ self.vertices = vertices
61
+ self._update_values()
62
+
63
+ def _update_values(self):
64
+ """update values dictionary."""
65
+ self._values[2] = [v for pt in self.vertices for v in pt]
66
+
67
+ @property
68
+ def vertices(self):
69
+ """List of Polygon vertices."""
70
+ return self._vertices
71
+
72
+ @vertices.setter
73
+ def vertices(self, vertices):
74
+ self._vertices = tuple(tuple(float(v) for v in pt) for pt in vertices)
75
+ assert len(self._vertices) > 2, 'Number of polygon vertices must be 3 or more.'
76
+ for vert in self._vertices:
77
+ assert len(vert) == 3, 'Polygon vertices must have 3 values for (x, y, z).'
78
+
79
+ @classmethod
80
+ def from_primitive_dict(cls, primitive_dict):
81
+ """Initialize a Polygon from a primitive dict.
82
+
83
+ Args:
84
+ data: A dictionary in the format below.
85
+
86
+ .. code-block:: python
87
+
88
+ {
89
+ "modifier": {}, # primitive modifier (Default: None)
90
+ "type": "polygon", # primitive type
91
+ "identifier": "", # primitive identifier
92
+ "display_name": "", # primitive display name
93
+ "values": [], # values
94
+ "dependencies": []
95
+ }
96
+ """
97
+ assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
98
+ if primitive_dict['type'] != cls.__name__.lower():
99
+ raise ValueError(
100
+ 'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
101
+ )
102
+
103
+ modifier, dependencies = cls.filter_dict_input(primitive_dict)
104
+ vertices_xyz = primitive_dict['values'][2]
105
+ assert len(vertices_xyz) % 3 == 0, \
106
+ 'Number of coordinates must be divisible by 3.' \
107
+ ' Invalid length: [%d].' % len(vertices_xyz)
108
+
109
+ cls_ = cls(
110
+ identifier=primitive_dict['identifier'],
111
+ vertices=(vertices_xyz[i:i + 3] for i in range(0, len(vertices_xyz), 3)),
112
+ modifier=modifier,
113
+ dependencies=dependencies
114
+ )
115
+ if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
116
+ cls_.display_name = primitive_dict['display_name']
117
+
118
+ # this might look redundant but it is NOT. see glass for explanation.
119
+ cls_.values = primitive_dict['values']
120
+ return cls_
121
+
122
+ @classmethod
123
+ def from_dict(cls, data):
124
+ """Initialize a Polygon from a dictionary.
125
+
126
+ Args:
127
+ data: A dictionary in the format below.
128
+
129
+ .. code-block:: python
130
+
131
+ {
132
+ "type": "polygon", # Geometry type
133
+ "modifier": {} ,
134
+ "identifier": "", # Geometry identifier
135
+ "display_name": "", # Geometry display name
136
+ "vertices": [(0, 0, 10), (10, 0, 10), (10, 0, 0)],
137
+ "dependencies": []
138
+ }
139
+ """
140
+ assert 'type' in data, 'Input dictionary is missing "type".'
141
+ if data['type'] != cls.__name__.lower():
142
+ raise ValueError(
143
+ 'Type must be %s not %s.' % (cls.__name__.lower(), data['type'])
144
+ )
145
+ modifier, dependencies = cls.filter_dict_input(data)
146
+
147
+ new_obj = cls(
148
+ identifier=data["identifier"],
149
+ vertices=data["vertices"],
150
+ modifier=modifier,
151
+ dependencies=dependencies
152
+ )
153
+ if 'display_name' in data and data['display_name'] is not None:
154
+ new_obj.display_name = data['display_name']
155
+ return new_obj
156
+
157
+ def to_dict(self):
158
+ """Translate this object to a dictionary."""
159
+ base = {
160
+ "modifier": self.modifier.to_dict(),
161
+ "type": self.__class__.__name__.lower(),
162
+ "identifier": self.identifier,
163
+ "vertices": self.vertices,
164
+ 'dependencies': [dp.to_dict() for dp in self.dependencies]
165
+ }
166
+ if self._display_name is not None:
167
+ base['display_name'] = self.display_name
168
+ return base
169
+
170
+ def __copy__(self):
171
+ mod, depend = self._dup_mod_and_depend()
172
+ new_obj = self.__class__(self.identifier, self.vertices, mod, depend)
173
+ new_obj._display_name = self._display_name
174
+ return new_obj