Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(create): Expose construction and modifier for louver shade #237

Merged
merged 1 commit into from May 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file modified honeybee_grasshopper_core/icon/HB Louver Shades.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 23 additions & 9 deletions honeybee_grasshopper_core/json/HB_Louver_Shades.json

Large diffs are not rendered by default.

@@ -1,5 +1,5 @@
{
"version": "1.2.0",
"version": "1.2.1",
"nickname": "GuideSurface",
"outputs": [
[
Expand Down
119 changes: 83 additions & 36 deletions honeybee_grasshopper_core/src/HB Louver Shades.py
Expand Up @@ -22,32 +22,32 @@
are input here, different depths will be assigned based on
cardinal direction, starting with north and moving clockwise.
_shade_count_: A positive integer for the number of louvers to generate.
Note that this input should be None if there is an input for
_dist_between_. If an array of values are input here, different
If there is an input below for _dist_between_, an attempt will
still be made to meet the _shade_count_ but, if there are more
shades than can fit on the input hb_obj, the number of shades
will be truncated. If an array of values are input here, different
shade counts will be assigned based on cardinal direction, starting
with north and moving clockwise. Default: 1.
with north and moving clockwise. (Default: 1).
_dist_between_: A number for the approximate distance between each louver.
Note that this input should be None if there is an input for
_shade_count_. If an array of values are input here, different
distances between louvers will be assigned based on cardinal
direction, starting with north and moving clockwise.
If an array of values are input here, different distances between
louvers will be assigned based on cardinal direction, starting
with north and moving clockwise.
_facade_offset_: A number for the distance from the louver edge to the
facade. If an array of values are input here, different offsets will
be assigned based on cardinal direction, starting with north and
moving clockwise. Default: 0.
moving clockwise. (Default: 0).
_angle_: A number for the for an angle to rotate the louvers in degrees.
If an array of values are input here, different angles will be
assigned based on cardinal direction, starting with north and moving
clockwise. Default: 0.
vertical_: Optional boolean to note whether the lovers are vertical.
If False, the louvers will be horizontal. If an array of values are
input here, different vertical booleans will be assigned based on
cardinal direction, starting with north and moving clockwise.
Default: False.
clockwise. (Default: 0).
vertical_: Optional boolean to note whether the lovers are vertical. If False,
the louvers will be horizontal. If an array of values are input
here, different vertical booleans will be assigned based on cardinal
direction, starting with north and moving clockwise. (Default: False).
flip_start_: Optional boolean to note whether the side the louvers start
from should be flipped. If False, louvers will be generated starting
on top or the right side. If True, louvers will start contours from
the bottom or left. If an array of values are input here, different
on top or the right side. If True, louvers will start from the
bottom or left. If an array of values are input here, different
flip start booleans will be assigned based on cardinal direction,
starting with north and moving clockwise. Default: False.
indoor_: Optional boolean for whether louvers should be generated facing the
Expand All @@ -56,8 +56,18 @@
input here, different indoor booleans will be assigned based on
cardinal direction, starting with north and moving clockwise.
Note that, by default, indoor shades are not used in energy simulations
but they are used in all simulations involving Radiance. Default: False.

but they are used in all simulations involving Radiance. (Default: False).
ep_constr_: Optional Honeybee ShadeConstruction to be applied to the input _hb_objs.
This can also be text for a construction to be looked up in the shade
construction library. If an array of text or construction objects
are input here, different constructions will be assigned based on
cardinal direction, starting with north and moving clockwise.
rad_mod_: Optional Honeybee Modifier to be applied to the input _hb_objs.
This can also be text for a modifier to be looked up in the shade
modifier library. If an array of text or modifier objects
are input here, different modifiers will be assigned based on
cardinal direction, starting with north and moving clockwise.

Returns:
report: Reports, errors, warnings, etc.
hb_objs: The input Honeybee Face or Room or Aperture with louvered shades
Expand All @@ -66,7 +76,7 @@

ghenv.Component.Name = "HB Louver Shades"
ghenv.Component.NickName = 'LouverShades'
ghenv.Component.Message = '1.2.1'
ghenv.Component.Message = '1.2.2'
ghenv.Component.Category = 'Honeybee'
ghenv.Component.SubCategory = '0 :: Create'
ghenv.Component.AdditionalHelpFromDocStrings = "5"
Expand All @@ -87,6 +97,20 @@
except ImportError as e:
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))

try: # import the honeybee-energy extension
from honeybee_energy.lib.constructions import shade_construction_by_identifier
except ImportError as e:
if len(ep_constr_) != 0:
raise ValueError('ep_constr_ has been specified but honeybee-energy '
'has failed to import.\n{}'.format(e))

try: # import the honeybee-radiance extension
from honeybee_radiance.lib.modifiers import modifier_by_identifier
except ImportError as e:
if len(rad_mod_) != 0:
raise ValueError('rad_mod_ has been specified but honeybee-radiance '
'has failed to import.\n{}'.format(e))

try: # import the ladybug_rhino dependencies
from ladybug_rhino.config import tolerance
from ladybug_rhino.grasshopper import all_required_inputs
Expand All @@ -100,16 +124,25 @@ def can_host_louvers(face):
isinstance(face.type, Wall)


def assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr):
def assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr, ep, rad):
"""Assign louvers to an Aperture based on a set of inputs."""
if depth == 0 or count == 0:
return None
if count is not None:
louvers = ap.louvers_by_count(count, depth, off, angle, vec, flip, indr,
tolerance)
if dist is None:
louvers = ap.louvers_by_count(
count, depth, off, angle, vec, flip, indr, tolerance)
else:
louvers = ap.louvers_by_distance_between(dist, depth, off, angle, vec,
flip, indr, tolerance)
louvers = ap.louvers_by_distance_between(
dist, depth, off, angle, vec, flip, indr, tolerance, max_count=count)

# try to assign the energyplus construction
if ep is not None:
for shd in louvers:
shd.properties.energy.construction = ep
# try to assign the radiance modifier
if rad is not None:
for shd in louvers:
shd.properties.radiance.modifier = rad


if all_required_inputs(ghenv.Component):
Expand All @@ -123,10 +156,7 @@ def assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr):
indoor_ = indoor_ if len(indoor_) != 0 else [False]

# process the defaults for _shade_count_ vs _dist_between
if len(_shade_count_) != 0 and len(_dist_between_) != 0:
raise ValueError('Inputs for _shade_count_ and _dist_between_ are both set.'
'\nThis component accepts either method but not both.')
elif len(_shade_count_) == 0 and len(_dist_between_) == 0:
if len(_shade_count_) == 0 and len(_dist_between_) == 0:
_shade_count_ = [1]
_dist_between_ = [None]
elif len(_shade_count_) != 0:
Expand All @@ -141,9 +171,25 @@ def assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr):
else:
vertical_ = [Vector2D(0, 1)]

# process the input constructions
if len(ep_constr_) != 0:
for i, constr in enumerate(ep_constr_):
if isinstance(constr, str):
ep_constr_[i] = shade_construction_by_identifier(constr)
else:
ep_constr_ = [None]

# process the input modifiers
if len(rad_mod_) != 0:
for i, mod in enumerate(rad_mod_):
if isinstance(mod, str):
rad_mod_[i] = modifier_by_identifier(mod)
else:
rad_mod_ = [None]

# gather all of the inputs together
all_inputs = [_depth, _shade_count_, _dist_between_, _facade_offset_, _angle_,
vertical_, flip_start_, indoor_]
vertical_, flip_start_, indoor_, ep_constr_, rad_mod_]

# ensure matching list lengths across all values
all_inputs, num_orient = check_matching_inputs(all_inputs)
Expand All @@ -157,24 +203,25 @@ def assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr):
for face in obj.faces:
if can_host_louvers(face):
orient_i = face_orient_index(face, angles)
depth, count, dist, off, angle, vec, flip, indr = \
depth, count, dist, off, angle, vec, flip, indr, con, mod = \
inputs_by_index(orient_i, all_inputs)
for ap in face.apertures:
assign_louvers(ap, depth, count, dist, off, angle, vec,
flip, indr)
flip, indr, con, mod)
elif isinstance(obj, Face):
if can_host_louvers(obj):
orient_i = face_orient_index(obj, angles)
depth, count, dist, off, angle, vec, flip, indr = \
depth, count, dist, off, angle, vec, flip, indr, con, mod = \
inputs_by_index(orient_i, all_inputs)
for ap in obj.apertures:
assign_louvers(ap, depth, count, dist, off, angle, vec,
flip, indr)
flip, indr, con, mod)
elif isinstance(obj, Aperture):
orient_i = face_orient_index(obj, angles)
depth, count, dist, off, angle, vec, flip, indr = \
depth, count, dist, off, angle, vec, flip, indr, con, mod = \
inputs_by_index(orient_i, all_inputs)
assign_louvers(obj, depth, count, dist, off, angle, vec, flip, indr)
assign_louvers(obj, depth, count, dist, off, angle, vec, flip,
indr, con, mod)
else:
raise TypeError(
'Input _hb_objs must be a Room, Face, or Aperture. Not {}.'.format(type(obj)))
Expand Up @@ -49,10 +49,10 @@

ghenv.Component.Name = 'HB Properties by Guide Surface'
ghenv.Component.NickName = 'GuideSurface'
ghenv.Component.Message = '1.2.0'
ghenv.Component.Message = '1.2.1'
ghenv.Component.Category = 'Honeybee'
ghenv.Component.SubCategory = '0 :: Create'
ghenv.Component.AdditionalHelpFromDocStrings = '0'
ghenv.Component.AdditionalHelpFromDocStrings = '3'

try: # import the core honeybee dependencies
from honeybee.facetype import face_types
Expand Down
Binary file modified honeybee_grasshopper_core/user_objects/HB Louver Shades.ghuser
Binary file not shown.
Binary file not shown.
Binary file modified samples/model_creation_workflows.gh
Binary file not shown.