Source code for honeybee_vtk.actor

"""Vtk actors that are added to a vtk scene."""

from __future__ import annotations
import vtk
from typing import List, Tuple
from .types import JoinedPolyData, ModelDataSet
from .filter import filter_using_thresholds
from ._helper import _validate_input
from ladybug_geometry.geometry3d.pointvector import Point3D
from .legend_parameter import LegendParameter
from .vtkjs.schema import DisplayMode


[docs]class Actor: """Create a vtk actor from a ModelDataSet. Objects in Honeybee such as walls, floors, ceilings, shades, apertures, rooms are called actors in vtk terms. The actors are created from the Modeldatasets in a Model object. Args: modeldataset: A ModelDataSet object from a honeybee-vtk Model. """ def __init__(self, modeldataset: ModelDataSet) -> None: self.modeldataset = modeldataset self._name = self._modeldataset.name self._monochrome_color = None @property def modeldataset(self) -> ModelDataSet: """A honeybee-vtk Model object.""" return self._modeldataset @modeldataset.setter def modeldataset(self, val: ModelDataSet) -> None: if isinstance(val, ModelDataSet): self._modeldataset = val else: raise ValueError( f'A {type(ModelDataSet)} object created using honeybee-vtk required.' f' Instead got {type(val)}.' ) @property def name(self) -> str: return self._name @property def monochrome_color(self) -> Tuple[float, float, float]: """Color to be used if actors are to be painted in a monochrome color.""" return self._monochrome_color @property def legend_parameter(self) -> LegendParameter: """Legend parameter of the last added data on the underlying Modeldataset object.""" return self._modeldataset.active_field_info.legend_parameter @property def bounds(self) -> List[Point3D]: """Bounds of the actor.""" vtk_actor = self.to_vtk() bounds = vtk_actor.GetBounds() pt_min = Point3D(bounds[0], bounds[2], bounds[4]) pt_max = Point3D(bounds[1], bounds[3], bounds[5]) return [pt_min, pt_max] @property def centroid(self) -> Point3D: """Centroid of the actor.""" points = self.bounds x = sum([point.x for point in points]) / len(points) y = sum([point.y for point in points]) / len(points) z = sum([point.z for point in points]) / len(points) return Point3D(x, y, z)
[docs] def get_monochrome(self, monochrome_color: Tuple[float, float, float]) -> None: """Get actors in monochrome color. This is especially useful when the wireframe display-mode is being used. Args: monochrome_color: A color that you'd like to paint actors with. Color here is a tuple of three decimal values representing R,G, and B. """ if _validate_input(monochrome_color, [float], max_val=1.0): self._monochrome_color = monochrome_color else: raise ValueError( 'monochrome color is a tuple with three decimal values less than 1' ' representing R, G, and B.' )
[docs] def to_vtk(self) -> vtk.vtkActor: """Create a vtk actor from a ModelDataSet object.""" # calculate point data based on cell data cell_to_point = vtk.vtkCellDataToPointData() if len(self._modeldataset.data) > 1: polydata = JoinedPolyData.from_polydata(self._modeldataset.data) polydata = filter_using_thresholds( polydata, self._modeldataset.active_field_info.lower_threshold, self._modeldataset.active_field_info.upper_threshold) cell_to_point.SetInputConnection(polydata.GetOutputPort()) else: polydata = self._modeldataset.data[0] polydata = filter_using_thresholds( polydata, self._modeldataset.active_field_info.lower_threshold, self._modeldataset.active_field_info.upper_threshold) cell_to_point.SetInputData(polydata) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(cell_to_point.GetOutputPort()) # map cell data to pointdata if self._modeldataset.fields_info: field_info = self._modeldataset.active_field_info mapper.SetColorModeToMapScalars() mapper.SetScalarModeToUsePointData() mapper.SetScalarVisibility(True) mapper.SetLookupTable(field_info.legend_parameter.get_lookuptable()) mapper.SetScalarRange(field_info.legend_parameter.range) mapper.Update() actor = vtk.vtkActor() actor.SetMapper(mapper) # Assign Ladybug Tools colors if self._monochrome_color: actor.GetProperty().SetColor(self._monochrome_color) else: actor.GetProperty().SetColor(self._modeldataset.rgb_to_decimal()) if self._modeldataset.edge_visibility: actor.GetProperty().EdgeVisibilityOn() if self._modeldataset.display_mode == DisplayMode.Wireframe: actor.GetProperty().SetRepresentationToWireframe() # This is import for grids with sensor points instead of meshes elif self._modeldataset.display_mode == DisplayMode.Points: actor.GetProperty().SetPointSize(15) return actor
[docs] @staticmethod def get_bounds(actors: List[Actor]) -> List[Point3D]: """Get a list of Ladybug Point3D objects that represent the bounds of actors. Bounds of an actor are the outermost vertices of an actor. A bound is a tuple of x, y, and z coordinates. Args: actors: A list of honeybee-vtk actor objects. Returns: A list of Ladybug Point3D objects. """ points = [] for actor in actors: vtk_actor = actor.to_vtk() bound = vtk_actor.GetBounds() pt_min = Point3D(bound[0], bound[2], bound[4]) pt_max = Point3D(bound[1], bound[3], bound[5]) min_max = [pt_min, pt_max] points.extend(min_max) return points
[docs] @staticmethod def get_centroid(actors: List[Actor]) -> Point3D: """Get Centroid of actors. This method is used in CLI to create a default Top view camera for models that don't have any radiance views. Args: actors: A list of honeybee-vtk actor objects. Returns: Centroid as a Point3D object. """ points = Actor.get_bounds(actors) x = sum([point.x for point in points]) / len(points) y = sum([point.y for point in points]) / len(points) z = sum([point.z for point in points]) / len(points) return Point3D(x, y, z)