Skip to main content

Honeybee extension for translating HBJSON to VTK

Project description

honeybee-vtk

🐝 VTK - Honeybee extension for viewing HBJSON in a web browser.

HBJSON exported to web

Build Status Coverage Status Python 3.7

GitHub tag (latest by date) GitHub

GitHub last commit GitHub issues GitHub closed issues

Installation

pip install honeybee-vtk

QuickStart

import honeybee_vtk

Usage

Usage: honeybee-vtk translate [OPTIONS] HBJSON_FILE

  Translate a HBJSON file to several VTK, XML, or HTML file.

  The output file is either a zipped file that contains all the generated
  VTK/XML files or an HTML file.

  Args:
      hbjson-file: Path to input HBJSON file.

Options:
  -n, --name TEXT                 Name of the output file. If not provided,
                                  the name of input HBJSON file will be used.

  -f, --folder DIRECTORY          Path to target folder.  [default: .]
  -t, --file-type [vtk|xml|html]  Switch between VTK, XML, and HTML formats.
                                  Default is HTML.  [default: html]

  -ig, --include-grids            Export grids.  [default: False]
  -is, --include-sensors [vectors|points]
                                  Export sensors as either arrows or color-
                                  grouped points.

  -in, --include-normals [vectors|points]
                                  Export aperture normals as either arrows or
                                  color-grouped points.

  -sh, --show-html, --show        Open the generated HTML file in a browser.
                                  [default: False]

  --help                          Show this message and exit.

Viewing an HBJSON generated from a model that ships with Ladybug Tools. You can send this HTML to someone and they will be able to open the see the same model.

honeybee-vtk translate "path to hbjson file" --include-grids --include-sensors="vectors" --show

Exporting points colored based on the direction of the normals for apertures and grid sensors. This is useful for models with very high number of sensors or apertures.

honeybee-vtk translate "path to hbjson file" --include-grids --include-sensors="points" --include-normals="points" --show

Saving the files in VTK format and then viewing in Paraview Glance. This is useful if you prefer smaller file sizes. Use "xml" in file-type to export XML files. If you wish to share a model that you have formatted in Paraview Glance, click on "Save State" button in the navbar of Paraview Glance. This will download a .glance file that you can share with others and they will be able to load this file back in Paraview Glance and see the model the way you formatted it.

honeybee-vtk translate "path to hbjson file" --folder="path to the target folder" --file-type="vtk"

API Documentation

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')

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]

# convert points to polydata
pts = convert_points(points)
pts.add_data(distance, name='distance', cell=False)
pts.color_by('distance', cell=False)
pts.to_vtk('.', 'colored_points')

arrows

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

# Create location. You can also extract location data from an epw file.
sydney = Location('Sydney', 'AUS', latitude=-33.87, longitude=151.22, time_zone=10)

# Initiate sunpath
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]

# add a circle
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)

# join polylines into a single polydata
sunpath = JoinedPolyData.from_polydata(sp_pls)
# add plot
sunpath.append(plot)

sunpath.to_vtk('.', 'sunpath')

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

# Get location from epw file
epw = EPW('./tests/assets/in.epw')
location = epw.location

# Initiate sunpath
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]

# add a circle
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)

# join polylines into a single polydata
sunpath = JoinedPolyData.from_polydata(sp_pls)
# add plot
sunpath.append(plot)
sunpath.to_vtk('.', 'sunpath')

# add sun positions and color them based on radiation
day = sp.hourly_analemma_suns(daytime_only=True)
# calculate sun positions from sun vector
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')

sunpath with data

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)

HBJSON model

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)

# update model visualization to show edges
model.update_display_mode(DisplayMode.SurfaceWithEdges)

# set shades to wireframe mode and change their color to black
model.shades.display_mode = DisplayMode.Wireframe
model.shades.color = Color(0, 0, 0, 255)

# create an HTML file with embedded visualization. You can share this HTML as is
# and it will include all the information.
model.to_html('.', name='two-rooms', show=True)

# alternatively you can write it as a vtkjs file and visualize it in ParaviewGlance
# the `to_html` method calls this method under the hood.
# model.to_vtkjs(folder='.')

Modified HBJSON model

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)

# load the results for each grid
# note that we load the results using the order for model to ensure the order will match
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)

# add the results to sensor grids as a new field
# per face is set to True since we loaded grids as a mesh
model.sensor_grids.add_data_fields(daylight_factor, name='Daylight Factor', per_face=True)
model.sensor_grids.color_by = 'Daylight Factor'

# make it pop!
# change display mode for sensor grids to be surface with edges
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
# update model visualization to wireframe
model.update_display_mode(DisplayMode.Wireframe)
# make shades to be shaded with edge
model.shades.display_mode = DisplayMode.SurfaceWithEdges

# export the model to a HTML file with embedded viewer and open the page in a browser
model.to_html('c:/ladybug', name='revit-model', show=True)

# alternatively you can write it as a vtkjs file and visualize it in ParaviewGlance
# the `to_html` method calls this method under the hood.
# model.to_vtkjs(folder='.')

Daylight factor results

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)

# load the results for each grid
# note that we load the results using the order for model to ensure the order will match
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)

    # add the results to sensor grids as a new field
    # per face is set to True since we loaded grids as a mesh
    model.sensor_grids.add_data_fields(results, name=metric['name'], per_face=True)

# Set color by to Useful Daylight Illuminance
model.sensor_grids.color_by = 'Useful Daylight Illuminance'

# make it pop!
# change display mode for sensor grids to be surface with edges
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
# update model visualization to wireframe
model.update_display_mode(DisplayMode.Wireframe)

# export the model to a HTML file with embedded viewer and open the page in a browser
model.to_html('.', name='two-rooms', show=True)

# alternatively you can write it as a vtkjs file and visualize it in ParaviewGlance
# the `to_html` method calls this method under the hood.
# model.to_vtkjs(folder='.')

Annual daylight results

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)

# load the results for each grid
# note that we load the results using the order for model to ensure the order will match
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)

# add the results to sensor grids as a new field
# per face is set to True since we loaded grids as a mesh
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'

# make it pop!
# change display mode for sensor grids to be surface with edges
model.sensor_grids.display_mode = DisplayMode.SurfaceWithEdges
# update model visualization to wireframe
model.update_display_mode(DisplayMode.Wireframe)
# make shades to be shaded with edge
model.shades.display_mode = DisplayMode.SurfaceWithEdges

# create a scene to render the model
scene = Scene()
scene.add_model(model)
# set a scale bar based on daylight factor values
color_range = model.sensor_grids.active_field_info.color_range()

# you can also save the scene as an image.
# right now you can't control the camera but camera control can be implemented.
scene.to_image('.', name='daylight_factor', image_scale=2, color_range=color_range)

# alternatively you can start an interactive window
# scene.show(color_range)

Captured image

Interactive renderer

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

honeybee-vtk-0.9.0.tar.gz (34.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

honeybee_vtk-0.9.0-py2.py3-none-any.whl (2.1 MB view details)

Uploaded Python 2Python 3

File details

Details for the file honeybee-vtk-0.9.0.tar.gz.

File metadata

  • Download URL: honeybee-vtk-0.9.0.tar.gz
  • Upload date:
  • Size: 34.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.7.10

File hashes

Hashes for honeybee-vtk-0.9.0.tar.gz
Algorithm Hash digest
SHA256 72a6401e38cdb5f74e91a385259c6ef87421be7652cb23aa46c4dbf64c5383e1
MD5 433cf3814ad77b777ac771e56101b67a
BLAKE2b-256 f144c1af04cf226991fa2c850f3c0c94f1e9a2a132be59181d77d9f06c681086

See more details on using hashes here.

File details

Details for the file honeybee_vtk-0.9.0-py2.py3-none-any.whl.

File metadata

  • Download URL: honeybee_vtk-0.9.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.7.10

File hashes

Hashes for honeybee_vtk-0.9.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 313d759bad150f6394284ef9314d17c960c9d6b2ac764018f2aae83426486233
MD5 3391e78168c62cce3a4b0455c3b6fec3
BLAKE2b-256 9fcd2eb289b8acb82f0b15c6381db993a5c012416c78e2a6c24020f60714418b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page