"""Radiance Cylinder.
http://radsite.lbl.gov/radiance/refer/ray.html#Cylinder
"""
from .geometrybase import Geometry
import honeybee.typing as typing
[docs]
class Cylinder(Geometry):
"""Radiance Cylinder.
A cylinder is like a cone, but its starting and ending radii are equal.
.. code-block:: shell
mod cylinder id
0
0
7
x0 y0 z0
x1 y1 z1
rad
Args:
identifier: Text string for a unique Geometry ID. Must not contain spaces
or special characters. This will be used to identify the object across
a model and in the exported Radiance files.
center_pt_start: Cylinder start center point as (x, y, z)
(Default: (0, 0 ,0)).
center_pt_end: Cylinder end center point as (x, y, z) (Default: (0, 0 ,10)).
radius: Cylinder start radius as a number (Default: 10).
modifier: Geometry modifier (Default: None).
dependencies: A list of primitives that this primitive depends on. This
argument is only useful for defining advanced primitives where the
primitive is defined based on other primitives. (Default: [])
Properties:
* identifier
* display_name
* center_pt_start
* center_pt_end
* radius
* values
* modifier
* dependencies
"""
__slots__ = ('_center_pt_start', '_center_pt_end', '_radius')
def __init__(self, identifier, center_pt_start=None, center_pt_end=None, radius=10,
modifier=None, dependencies=None):
"""Radiance Cylinder."""
Geometry.__init__(self, identifier, modifier=modifier, dependencies=dependencies)
self.center_pt_start = center_pt_start or (0, 0, 0)
self.center_pt_end = center_pt_end or (0, 0, 10)
self.radius = radius if radius is not None else 10
self._update_values()
def _update_values(self):
"""update value dictionaries."""
self._values[2] = \
[self.center_pt_start[0], self.center_pt_start[1], self.center_pt_start[2],
self.center_pt_end[0], self.center_pt_end[1], self.center_pt_end[2],
self.radius]
@property
def center_pt_start(self):
"""Cone start center point as (x, y, z). Default is (0, 0 ,0)."""
return self._center_pt_start
@center_pt_start.setter
def center_pt_start(self, value):
self._center_pt_start = tuple(float(v) for v in value)
assert len(self._center_pt_start) == 3, \
'Radiance Cylinder center point must have 3 values for (x, y, z).'
@property
def radius(self):
"""Cone start radius as a number. Default is 10."""
return self._radius
@radius.setter
def radius(self, value):
self._radius = typing.float_positive(value)
@property
def center_pt_end(self):
"""Cone end center point as (x, y, z), Default is (0, 0 ,10)."""
return self._center_pt_end
@center_pt_end.setter
def center_pt_end(self, value):
self._center_pt_end = tuple(float(v) for v in value)
assert len(self._center_pt_end) == 3, \
'Radiance Cylinder center point must have 3 values for (x, y, z).'
[docs]
@classmethod
def from_primitive_dict(cls, primitive_dict):
"""Initialize a Cylinder from a primitive dict.
Args:
data: A dictionary in the format below.
.. code-block:: python
{
"modifier": {}, # primitive modifier (Default: None)
"type": "cylinder", # primitive type
"identifier": "", # primitive identifier
"display_name": "", # primitive display name
"values": [], # values
"dependencies": []
}
"""
assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
if primitive_dict['type'] != cls.__name__.lower():
raise ValueError(
'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
)
modifier, dependencies = cls.filter_dict_input(primitive_dict)
values = primitive_dict['values'][2]
cls_ = cls(
identifier=primitive_dict['identifier'],
center_pt_start=values[0:3],
center_pt_end=values[3:6],
radius=values[6],
modifier=modifier,
dependencies=dependencies
)
if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
cls_.display_name = primitive_dict['display_name']
# this might look redundant but it is NOT. see glass for explanation.
cls_.values = primitive_dict['values']
return cls_
[docs]
@classmethod
def from_dict(cls, data):
"""Initialize a Cylinder from a dictionary.
Args:
data: A dictionary in the format below.
.. code-block:: python
{
"type": "cylinder", # Geometry type
"modifier": {} ,
"identifier": "", # Geometry identifer
"display_name": "", # Geometry display name
"center_pt_start": (0, 0, 0),
"center_pt_end": (0, 0, 10),
"radius": float,
"dependencies": []
}
"""
assert 'type' in data, 'Input dictionary is missing "type".'
if data['type'] != cls.__name__.lower():
raise ValueError(
'Type must be %s not %s.' % (cls.__name__.lower(),
data['type'])
)
modifier, dependencies = cls.filter_dict_input(data)
new_obj = cls(identifier=data["identifier"],
center_pt_start=(data["center_pt_start"]),
center_pt_end=(data["center_pt_end"]),
radius=data["radius"],
modifier=modifier,
dependencies=dependencies)
if 'display_name' in data and data['display_name'] is not None:
new_obj.display_name = data['display_name']
return new_obj
[docs]
def to_dict(self):
"""Translate this object to a dictionary."""
base = {
"modifier": self.modifier.to_dict(),
"type": self.__class__.__name__.lower(),
"identifier": self.identifier,
"center_pt_start": self.center_pt_start,
"radius": self.radius,
"center_pt_end": self.center_pt_end,
'dependencies': [dp.to_dict() for dp in self.dependencies]
}
if self._display_name is not None:
base['display_name'] = self.display_name
return base
def __copy__(self):
mod, depend = self._dup_mod_and_depend()
new_obj = self.__class__(
self.identifier, self.center_pt_start, self.center_pt_end, self.radius,
mod, depend)
new_obj._display_name = self._display_name
return new_obj