Source code for honeybee_3dm.model

"""Creating Honeybee model objects from rhino3dm surfaces and closed volumes"""
import os
import rhino3dm

from honeybee.model import Model

from .face import import_objects, import_objects_with_config
from .helper import get_unit_system, check_parent_in_config
from .layer import child_parent_dict, visible_layers
from .config import check_config


[docs]def import_3dm(path, name=None, *, config_path=None): """Import a rhino3dm file as a Honeybee model. This function outputs a Honeybee model from the faces, shades, apertures, and doors on a rhino3dm file. By default, all the rhino objects will be converted to Honeybee Faces based on the objects normal direction. A config file can be used to assign objects to specific Honeybee face types and Honeybee object types. Args: path: A text string for the path to the rhino3dm file. name: A text string that will be used as the name of the Honeybee model. Default will be the same as Rhino file name. config_path: A text string path to the config file on disk. Defaults to not using a config file. Returns: A Honeybee model. """ # RHINO FILE if not os.path.isfile(path): raise FileNotFoundError( 'The path to rhino file is not valid.' ) rhino3dm_file = rhino3dm.File3dm.Read(path) if not rhino3dm_file: raise ValueError(f'Input Rhino file: {path} returns None object.') # CONFIG FILE if config_path: if not os.path.isfile(config_path): raise FileNotFoundError( 'The path is not a valid path.' ' If file exists, try using double backslashes in file path' ' and try again.' ) # Validate the config file and get it as a directory config = check_config(rhino3dm_file, config_path) else: config = None # Extracting unit parameters from rhino model_tolerance = rhino3dm_file.Settings.ModelAbsoluteTolerance model_angle_tolerance = rhino3dm_file.Settings.ModelAngleToleranceDegrees model_unit = get_unit_system(rhino3dm_file) # Place holders hb_rooms, hb_faces, hb_shades, hb_apertures, hb_doors, hb_grids = tuple( [[] for _ in range(6)]) # A dictionary with child layer : parent layer structure child_to_parent = child_parent_dict(rhino3dm_file) # Get all the visible layers from rhino if visible_layers(rhino3dm_file): rhino_visible_layers = visible_layers(rhino3dm_file) rhino_visible_layer_names = [layer.Name for layer in rhino_visible_layers] else: raise ValueError( 'Please turn on the layers in rhino you wish to import objects from.' ) # If config is provided if config: for layer in rhino3dm_file.Layers: # If the layer is not in config and not "on" in rhino, ignore if layer.Name not in config['layers'] and \ layer.Name not in rhino_visible_layer_names: continue # Import objects from each layer in the config file elif layer.Name in config['layers']: hb_objs = import_objects_with_config( rhino3dm_file, layer, model_tolerance, config=config) hb_faces.extend(hb_objs[0]) hb_shades.extend(hb_objs[1]) hb_apertures.extend(hb_objs[2]) hb_doors.extend(hb_objs[3]) hb_grids.extend(hb_objs[4]) # skip child layers that might already have been imported elif check_parent_in_config(rhino3dm_file, config, layer.Name, child_to_parent[layer.Name]): continue # Import objects from each layer not in the config file elif layer.Name in rhino_visible_layer_names: hb_faces.extend(import_objects(rhino3dm_file, layer, tolerance=model_tolerance)) else: # If config is not provided # Only use layers that are "on" in rhino for layer in rhino_visible_layers: hb_faces.extend(import_objects(rhino3dm_file, layer, tolerance=model_tolerance)) # Honeybee model name name = name or '.'.join(os.path.basename(path).split('.')[:-1]) # Honeybee Model hb_model = Model( identifier=name, rooms=hb_rooms, orphaned_faces=hb_faces, orphaned_shades=hb_shades, orphaned_apertures=hb_apertures, orphaned_doors=hb_doors, units=model_unit, tolerance=model_tolerance, angle_tolerance=model_angle_tolerance ) # Assigning grids to Honeybee model hb_model.properties.radiance.sensor_grids = hb_grids # Returning a Honeybee model return hb_model