honeybee-vtk
🐝 VTK - Honeybee extension for viewing HBJSON in a web browser.
Installation
pip install honeybee-vtk
QuickStart
import honeybee_vtk
Translate a HBJSON file to an HTML or vtkjs file
Usage: honeybee-vtk translate [OPTIONS] HBJSON_FILE
Translate a HBJSON file to an HTML or a vtkjs file.
Args:
hbjson-file: Path to an HBJSON file.
Options:
-n, --name TEXT Name of the output file. [default: model]
-f, --folder DIRECTORY Path to target folder. [default: .]
-ft, --file-type [html|vtkjs|vtp|vtk]
Switch between html and vtkjs formats
[default: html]
-mdm, --model-display-mode [shaded|surface|surfacewithedges|wireframe|points]
Set display mode for the model. [default:
shaded]
-gdm, --grid-display-mode [shaded|surface|surfacewithedges|wireframe|points]
Set display mode for the grid. [default:
shaded]
-go, --grid-options [ignore|points|meshes]
Export sensor grids as either points or
meshes. [default: ignore]
-sh, --show-html, --show Open the generated HTML file in a browser.
[default: False]
-cf, --config PATH File Path to the config json file which can
be used to mount simulation data on HBJSON.
-vd, --validate-data Validate simulation data before loading on
the model. This is recommended when using
this command locally. [default: False]
--help Show this message and exit.
Export images from an HBJSON file
Usage: honeybee-vtk export-images [OPTIONS] HBJSON_FILE
Export images from radiance views in a HBJSON file.
Args:
hbjson-file: Path to an HBJSON file.
Options:
-f, --folder DIRECTORY Path to target folder. [default: .]
-it, --image-type [png|jpg|ps|tiff|bmp|pnm]
choose the type of image file. [default:
jpg]
-iw, --image-width INTEGER Width of images in pixels. If not set,
Radiance default x dimension of view will be
used. [default: 0]
-ih, --image-height INTEGER Height of images in pixels.If not set,
Radiance default y dimension of view will be
used. [default: 0]
-bc, --background-color <INTEGER INTEGER INTEGER>...
Set background color for images [default:
255, 255, 255]
-mdm, --model-display-mode [shaded|surface|surfacewithedges|wireframe|points]
Set display mode for the model. [default:
shaded]
-go, --grid-options [ignore|points|meshes]
Export sensor grids as either points or
meshes. [default: ignore]
-gdm, --grid-display-mode [shaded|surface|surfacewithedges|wireframe|points]
Set display mode for the Sensorgrids.
[default: surfacewithedges]
-vf, --view PATH File Path to the Radiance view file.
Multiple view files are accepted.
-cf, --config PATH File Path to the config json file which can
be used to mount simulation data on HBJSON.
-vd, --validate-data Validate simulation data before loading on
the model. This is recommended when using
this command locally. [default: False]
--grid / --model Boolean to decide whether to export the
images of a whole model or only the grids.
Set it to True to export the grids.
[default: False]
-gf, --grid-filter TEXT Filter sensor grids by name. Use this option
multiple times to use multiple grid
identifiers as filters. [default: ]
--text-content TEXT Text to be displayed on the image.
-th, --text-height INTEGER Set the height of the text in pixels.
[default: 15]
-tc, --text-color <INTEGER INTEGER INTEGER>...
Set the text color. [default: 0, 0, 0]
-tp, --text-position <FLOAT FLOAT>...
Set the text position in the image. The
setting is applied at the lower left point
of the text. (0,0) will give you the lower
left corner of the image. (1,1) will give
you the upper right corner of the image.
[default: 0.5, 0.0]
-tb, --text-bold Set the text to be bold. [default: False]
--help Show this message and exit.
Write a config file to be consumed by the Translate command
Usage: honeybee-vtk config [OPTIONS] INPUT_FILE
Write a config file to be consumed by honeybee-vtk.
Args:
input_file: A path to the input file in json format.
folder_path: Path to the folder where the config file shall be written.
Defaults to the current working directory.
name: A string as the name of the config file. Defaults to 'config'.
Options:
-fp, --folder-path PATH Path to the folder where the config file shall be
written. [default: .]
-n, --name TEXT Name of the config file. [default: config]
--help Show this message and exit.
Create arrows and write to a vtp file and open it in a minimalist desktop viewer
from ladybug_geometry.geometry3d import Point3D, Vector3D
from honeybee_vtk.to_vtk import create_arrow
points = [Point3D(0, 0, 0), Point3D(1, 1, 0), Point3D(1, 0, 0)]
vectors = [Vector3D(0, 0, 1), Vector3D(1, 1, 1), Vector3D(2, 0, 0)]
arrows = create_arrow(points, vectors)
arrows.to_vtk('.', 'arrows')
Create a group of points and color them based on distance from origin, write them to a vtp file and and open it in a minimalist desktop viewer
from ladybug_geometry.geometry3d import Point3D
from honeybee_vtk.to_vtk import convert_points
points = []
for x in range(-50, 50, 5):
for y in range(-50, 50, 5):
for z in range(-50, 50, 5):
points.append(Point3D(x, y, z))
origin = Point3D(0, 0, 0)
distance = [pt.distance_to_point(origin) for pt in points]
pts = convert_points(points)
pts.add_data(distance, name='distance', cell=False)
pts.color_by('distance', cell=False)
pts.to_vtk('.', 'colored_points')
Draw a sunpath
from ladybug.location import Location
from ladybug.sunpath import Sunpath, Point3D, Vector3D
from honeybee_vtk.to_vtk import convert_polyline, create_polyline
from honeybee_vtk.types import JoinedPolyData
import math
sydney = Location('Sydney', 'AUS', latitude=-33.87, longitude=151.22, time_zone=10)
sp = Sunpath.from_location(sydney)
radius = 100
origin = Point3D(0, 0, 0)
polylines = sp.hourly_analemma_polyline3d(origin=origin, daytime_only=True, radius=radius)
sp_pls = [convert_polyline(pl) for pl in polylines]
north = origin.move(Vector3D(0, radius, 0))
plot_points = [
north.rotate_xy(math.radians(angle), origin)
for angle in range(0, 365, 5)
]
plot = create_polyline(plot_points)
sunpath = JoinedPolyData.from_polydata(sp_pls)
sunpath.append(plot)
sunpath.to_vtk('.', 'sunpath')
Draw a sunpath with hourly data
from ladybug.epw import EPW
from ladybug.sunpath import Sunpath, Point3D, Vector3D
from honeybee_vtk.to_vtk import convert_points, convert_polyline, create_polyline
from honeybee_vtk.types import JoinedPolyData
import math
epw = EPW('./tests/assets/in.epw')
location = epw.location
sp = Sunpath.from_location(location)
radius = 100
origin = Point3D(0, 0, 0)
polylines = sp.hourly_analemma_polyline3d(origin=origin, daytime_only=True, radius=radius)
sp_pls = [convert_polyline(pl) for pl in polylines]
north = origin.move(Vector3D(0, radius, 0))
plot_points = [
north.rotate_xy(math.radians(angle), origin)
for angle in range(0, 365, 5)
]
plot = create_polyline(plot_points)
sunpath = JoinedPolyData.from_polydata(sp_pls)
sunpath.append(plot)
sunpath.to_vtk('.', 'sunpath')
day = sp.hourly_analemma_suns(daytime_only=True)
pts = []
hours = []
for suns in day:
for sun in suns:
pts.append(origin.move(sun.sun_vector.reverse() * radius))
hours.append(sun.hoy)
radiation_data = epw.global_horizontal_radiation
filtered_radiation_data = radiation_data.filter_by_hoys(hours)
sun_positions = convert_points(pts)
sun_positions.add_data(
filtered_radiation_data.values, name='Globale Horizontal Radiation', cell=False
)
sun_positions.color_by('Global Horizontal Radiation', cell=False)
sun_positions.to_vtk('.', 'sun_positions')
Load HB model
from honeybee_vtk.model import Model
hbjson = r'./tests/assets/gridbased.hbjson'
model = Model.from_hbjson(hbjson)
model.to_html(folder='.', name='two-rooms', show=True)
Load HB model - change display mode and colors
from honeybee_vtk.model import Model, DisplayMode
from ladybug.color import Color
hbjson = r'./tests/assets/gridbased.hbjson'
model = Model.from_hbjson(hbjson)
model.update_display_mode(DisplayMode.SurfaceWithEdges)
model.shades.display_mode = DisplayMode.Wireframe
model.shades.color = Color(0, 0, 0, 255)
model.to_html('.', name='two-rooms', show=True)
Load HB Model and daylight factor results
from honeybee_vtk.model import Model, DisplayMode, SensorGridOptions
import pathlib
hbjson = r'./tests/assets/revit_model/model.hbjson'
results_folder = r'./tests/assets/revit_model/df_results'
model = Model.from_hbjson(hbjson, load_grids=SensorGridOptions.Mesh)
daylight_factor = []
for grid in model.sensor_grids.data:
res_file = pathlib.Path(results_folder, f'{grid.identifier}.res')
grid_res = [float(v) for v in res_file.read_text().splitlines()]
daylight_factor.append(grid_res)
model.sensor_grids.add_data_fields(daylight_factor, name='Daylight Factor', per_face=True)
model.sensor_grids.color_by = 'Daylight Factor'
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
model.update_display_mode(DisplayMode.Wireframe)
model.shades.display_mode = DisplayMode.SurfaceWithEdges
model.to_html('c:/ladybug', name='revit-model', show=True)
Load HB Model and annual daylight results
from honeybee_vtk.model import Model, DisplayMode, SensorGridOptions
import pathlib
hbjson = r'./tests/assets/gridbased.hbjson'
results_folder = r'./tests/assets/annual_metrics'
model = Model.from_hbjson(hbjson, load_grids=SensorGridOptions.Mesh)
annual_metrics = [
{'folder': 'da', 'extension': 'da', 'name': 'Daylight Autonomy'},
{'folder': 'cda', 'extension': 'cda', 'name': 'Continuous Daylight Autonomy'},
{'folder': 'udi', 'extension': 'udi', 'name': 'Useful Daylight Illuminance'},
{'folder': 'udi_lower', 'extension': 'udi', 'name': 'Lower Daylight Illuminance'},
{'folder': 'udi_upper', 'extension': 'udi', 'name': 'Excessive Daylight Illuminance'}
]
for metric in annual_metrics:
results = []
for grid in model.sensor_grids.data:
res_file = pathlib.Path(
results_folder, metric['folder'], f'{grid.identifier}.{metric["extension"]}'
)
grid_res = [float(v) for v in res_file.read_text().splitlines()]
results.append(grid_res)
model.sensor_grids.add_data_fields(results, name=metric['name'], per_face=True)
model.sensor_grids.color_by = 'Useful Daylight Illuminance'
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
model.update_display_mode(DisplayMode.Wireframe)
model.to_html('.', name='two-rooms', show=True)
Save model with results as an image
from honeybee_vtk.model import Model, DisplayMode, SensorGridOptions
from honeybee_vtk.scene import Scene
import pathlib
hbjson = r'./tests/assets/gridbased.hbjson'
results_folder = r'./tests/assets/df_results'
model = Model.from_hbjson(hbjson, load_grids=SensorGridOptions.Mesh)
daylight_factor = []
for grid in model.sensor_grids.data:
res_file = pathlib.Path(results_folder, f'{grid.identifier}.res')
grid_res = [float(v) for v in res_file.read_text().splitlines()]
daylight_factor.append(grid_res)
model.sensor_grids.add_data_fields(
daylight_factor, name='Daylight Factor', per_face=True, data_range=(0, 20)
)
model.sensor_grids.color_by = 'Daylight Factor'
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
model.update_display_mode(DisplayMode.Wireframe)
model.shades.display_mode = DisplayMode.SurfaceWithEdges
scene = Scene()
scene.add_model(model)
color_range = model.sensor_grids.active_field_info.color_range()
scene.to_image('.', name='daylight_factor', image_scale=2, color_range=color_range)