Skip to content

Commit

Permalink
feat(geometry): Add direct Sun Study Component
Browse files Browse the repository at this point in the history
This commit adds a component to run direct sun studies with Rhino geometry.  It makes use of the highly reusable functions within ladybug-core and ladybug-rhino to do so such that the whole process happens in less than 50 lines of Python.  I expect the radiation and view components to be similar as they will make use of the same functions.
  • Loading branch information
chriswmackey authored and Chris Mackey committed Sep 18, 2020
1 parent ac6b6fc commit 4ba6d47
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 4 deletions.
152 changes: 152 additions & 0 deletions ladybug_grasshopper/src/LB Direct Sun Study.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Ladybug: A Plugin for Environmental Analysis (GPL)
# This file is part of Ladybug.
#
# Copyright (c) 2020, Ladybug Tools.
# You should have received a copy of the GNU General Public License
# along with Ladybug; If not, see <http://www.gnu.org/licenses/>.
#
# @license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>

"""
Calculate the number of hours of direct sunlight received by geometry using sun
vectors obtained from the "LB SunPath" component.
_
Such direct sun calculations can be used for shadow studies of outdoor enviroments
or can be used to estimate glare potential from direct sun on the indoors.
_
Note that this component uses the CAD environment's ray intersection methods to
etermine if the sun is visible, which can be fast for geometries with low
complexity but does not scale well for complex geometries or many test points.
For such complex studies, honeybee-radiance should be used.
-
Args:
_vectors: Sun vectors from the "LB SunPath" component, which will be used
to determine the number of hours of direct sunlight received by the
test _geometry.
_timestep_: A positive integer for the number of timesteps per hour at
which the "LB SunPath" component generated sun vectors. This is used
to correctly interpret the time duration represented by each of
the input sun vectors. (Default: 1 for 1 vector per hour).
_geometry: Rhino Breps and/or Rhino Meshes for which direct sun analysis
will be conducted. If Breps are input, they will be subdivided using
the _grid_size to yeild individual points at which analysis will
occur. If a Mesh is input, direct sun analysis analysis will be
performed for each face of this mesh instead of subdividing it.
context_: Rhino Breps and/or Rhino Meshes representing context geometry
that can block sunlight to the test _geometry.
_grid_size: A positive number in Rhino model units for the size of grid
cells at which the input _geometry will be subdivided for direct sun
analysis. The smaller the grid size, the higher the resolution of
the analysis and the longer the calculation will take. So it is
recommended that one start with a large value here and decrease
the value as needed. However, the grid size should usually be
smaller than the dimensions of the smallest piece of the _geometry
and context_ in order to yield meaningful results.
_offset_dist_: A number for the distance to move points from the surfaces
of the input _geometry. Typically, this should be a small positive
number to ensure points are not blocked by the mesh. (Default: 10 cm
in the equivalent Rhino Model units)
legend_par_: Optional legend parameters from the "LB Legend Parameters"
that will be used to customize the display of the results.
parallel_: Set to "True" to run the study using multiple CPUs. This can
dramatically decrease calculation time but can interfere with
other computational processes that might be running on your
machine. (Default: False).
_run: Set to "True" to run the component and perform direct sun analysis.
If set to "False" but all other required inputs are specified, this
component will output points showing the resolution of the analysis
(but not run the study) so that an estimate of study run time can
be obtained.
Returns:
report: ...
points: The grid of points on the test _geometry that are be used to perform
the direct sun analysis. Note that these points are generated even
when _run is set to "False" so that an estimate of study run time can
be obtained.
results: A list of numbers that aligns with the points. Each number indicates
the number of hours of direct sunlight received by each of the
points. Note that is is the number of hours out of the total
number of connected _vectors.
mesh: A colored mesh of the test _geometry representing the hours of direct
sunlight received by this input _geometry
legend: A legend showing the number of hours that correspond to the colors
of the mesh.
title: A text object for the study title.
sun_visible: A Data Tree (list of lists) that contains values for the
vector-by-vector results of the study. Each sub-list (aka. branch
of the Data Tree) represents one of the points used for analysis.
The length of each sub-list matches the number of _vectors used
for the analysis. Each value in the sub-list is either a "1",
indicating that the sun is visible for that vector, or a "0",
indicating that the sun is not visible for that vector.
"""

ghenv.Component.Name = "LB Direct Sun Study"
ghenv.Component.NickName = 'DirectSunStudy'
ghenv.Component.Message = '0.1.0'
ghenv.Component.Category = 'Ladybug'
ghenv.Component.SubCategory = '3 :: Analyze Geometry'
ghenv.Component.AdditionalHelpFromDocStrings = '1'

try:
from ladybug.graphic import GraphicContainer
except ImportError as e:
raise ImportError('\nFailed to import ladybug:\n\t{}'.format(e))

try:
from ladybug_rhino.config import conversion_to_meters
from ladybug_rhino.togeometry import to_joined_gridded_mesh3d, to_vector3d
from ladybug_rhino.fromgeometry import from_mesh3d, from_point3d, from_vector3d
from ladybug_rhino.fromobjects import legend_objects
from ladybug_rhino.text import text_objects
from ladybug_rhino.intersect import mesh_geometry, intersect_mesh_rays
from ladybug_rhino.grasshopper import all_required_inputs, hide_output, \
show_output, list_to_data_tree
except ImportError as e:
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))


if all_required_inputs(ghenv.Component):
# set the default offset distance
_offset_dist_ = _offset_dist_ if _offset_dist_ is not None \
else 0.1 / conversion_to_meters()

if _run: # run the entire study
# mesh the input geometry and context
study_mesh = to_joined_gridded_mesh3d(_geometry, _grid_size, _offset_dist_)
shade_mesh = mesh_geometry(_geometry + context_)

# get the study points and reverse the sun vectors (for backward ray-tracting)
rev_vec = [from_vector3d(to_vector3d(vec).reverse()) for vec in _vectors]
points = [from_point3d(pt) for pt in study_mesh.face_centroids]
hide_output(ghenv.Component, 1)

# intersect the rays with the mesh and output the sun_visible data
int_matrix = intersect_mesh_rays(shade_mesh, points, rev_vec, parallel_)
sun_visible = list_to_data_tree(int_matrix)

# compute the results
if _timestep_ and _timestep_ != 1: # divide by the timestep before output
results = [sum(val / _timestep_ for val in int_list)
for int_list in int_matrix]
else: # no division required
results = [sum(int_list) for int_list in int_matrix]

# create the mesh and legend outputs
graphic = GraphicContainer(results, study_mesh.min, study_mesh.max, legend_par_)
graphic.legend_parameters.title = 'hours'
title = text_objects('Direct Sun Study', graphic.lower_title_location,
graphic.legend_parameters.text_height * 1.5,
graphic.legend_parameters.font)

# create all of the visual outputs
study_mesh.colors = graphic.value_colors
mesh = from_mesh3d(study_mesh)
legend = legend_objects(graphic.legend)

else: # only show the resolution of the mesh
study_mesh = to_joined_gridded_mesh3d(_geometry, _grid_size, _offset_dist_)
points = [from_point3d(pt) for pt in study_mesh.face_centroids]
show_output(ghenv.Component, 1)
8 changes: 4 additions & 4 deletions ladybug_grasshopper/src/LB Generate Point Grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Args:
_geometry: Brep or Mesh from which to generate the points and grid.
_grid_size: Number for the size of the test grid.
_dist_surface_: Number for the distance to move points from the surfaces
_offset_dist_: Number for the distance to move points from the surfaces
of the input _geometry. Typically, this should be a small positive
number to ensure points are not blocked by the mesh. Default is 0.
Expand All @@ -28,7 +28,7 @@

ghenv.Component.Name = "LB Generate Point Grid"
ghenv.Component.NickName = 'GenPts'
ghenv.Component.Message = '0.1.2'
ghenv.Component.Message = '0.1.3'
ghenv.Component.Category = 'Ladybug'
ghenv.Component.SubCategory = '4 :: Extra'
ghenv.Component.AdditionalHelpFromDocStrings = '1'
Expand All @@ -43,9 +43,9 @@

if all_required_inputs(ghenv.Component):
# check the input and generate the mesh.
_dist_surface_ = _dist_surface_ or 0
_offset_dist_ = _offset_dist_ or 0
try: # assume it's a Rhino Brep
lb_mesh = to_gridded_mesh3d(_geometry, _grid_size, _dist_surface_)
lb_mesh = to_gridded_mesh3d(_geometry, _grid_size, _offset_dist_)
except TypeError: # assume it's a Rhino Mesh
try:
lb_mesh = to_mesh3d(_geometry)
Expand Down
Binary file not shown.
Binary file modified ladybug_grasshopper/user_objects/LB Generate Point Grid.ghuser
Binary file not shown.

0 comments on commit 4ba6d47

Please sign in to comment.