def dynamic_scene(radiance_folder, model, outdoor, log_file): """Return dynamic scene.""" try: folder = Folder(radiance_folder, model_folder=model) dynamic_scene = folder.dynamic_scene(not outdoor, reload=True) log_file.write(json.dumps(dynamic_scene)) except Exception as e: _logger.exception('Failed to retrieve view files.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def aperture_groups(radiance_folder, model, exterior, log_file): """Return aperture groups.""" try: folder = Folder(radiance_folder, model_folder=model) aperture_groups = folder.aperture_groups(not exterior, reload=True) log_file.write(json.dumps(aperture_groups)) except Exception as e: _logger.exception('Failed to retrieve view files.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def view_files(radiance_folder, model, log_file): """Return view files.""" try: folder = Folder(radiance_folder, model_folder=model) view_files = folder.view_files() log_file.write(json.dumps(view_files)) except Exception as e: _logger.exception('Failed to retrieve view files.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def grid_info_files(radiance_folder, model, log_file): """Return grid information files.""" try: folder = Folder(radiance_folder, model_folder=model) grid_info_files = folder.grid_info_files() log_file.write(json.dumps(grid_info_files)) except Exception as e: _logger.exception('Failed to retrieve grid information files.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def scene_files(radiance_folder, model, default, log_file): """Return scene files.""" try: folder = Folder(radiance_folder, model_folder=model) black_out = not default scene_files = folder.scene_files(black_out=black_out) log_file.write(json.dumps(scene_files)) except Exception as e: _logger.exception('Failed to retrieve scene files.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_writer_to_rad_folder_sensor_grids_views(): """Test the Model to.rad_folder method with assigned sensor grids and views.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.move_shades(Vector3D(0, 0, -0.5)) north_face = garage[1] north_face.apertures_by_ratio(0.1, 0.01) room_grid = room.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) garage_grid = garage.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) room_view = room.properties.radiance.generate_view((0, -1, 0)) garage_view = garage.properties.radiance.generate_view((0, 1, 0)) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage]) model.properties.radiance.sensor_grids = [room_grid] model.properties.radiance.add_sensor_grids([garage_grid]) model.properties.radiance.views = [room_view] model.properties.radiance.add_views([garage_view]) folder = os.path.abspath('./tests/assets/model/rad_folder_grids_views') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) grid_dir = model_folder.grid_folder(full=True) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_House_Zone.pts')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_House_Zone.json')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_Garage.pts')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_Garage.json')) view_dir = model_folder.view_folder(full=True) assert os.path.isfile(os.path.join(view_dir, 'Tiny_House_Zone.vf')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_House_Zone.json')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_Garage.vf')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_Garage.json')) # clean up the folder nukedir(folder, rmdir=True)
def model_to_rad_folder(model, folder=None, config_file=None, minimal=False): r"""Write a honeybee model to a rad folder. The rad files in the resulting folders will include all geometry (Rooms, Faces, Shades, Apertures, Doors), all modifiers, and all states of dynamic objects. It also includes any SensorGrids and Views that are assigned to the model's radiance properties. Args: model: A honeybee Model for which radiance folder will be written. folder: An optional folder to be used as the root of the model's Radiance folder. If None, the files will be written into a sub-directory of the honeybee-core default_simulation_folder. This sub-directory is specifically: default_simulation_folder/[MODEL IDENTIFIER]/Radiance config_file: An optional config file path to modify the default folder names. If None, ``folder.cfg`` in ``honeybee-radiance-folder`` will be used. (Default: None). minimal: Boolean to note whether the radiance strings should be written in a minimal format (with spaces instead of line breaks). Default: False. """ # prepare the folder for simulation model_id = model.identifier if folder is None: folder = os.path.join(folders.default_simulation_folder, model_id, 'Radiance') if not os.path.isdir(folder): preparedir(folder) # create the directory if it's not there model_folder = ModelFolder(folder, 'model', config_file) model_folder.write(folder_type=-1, cfg=folder_config.minimal, overwrite=True) # gather and write static apertures to the folder aps, aps_blk = model.properties.radiance.subfaces_by_blk() mods, mods_blk, mod_combs, mod_names = _collect_modifiers( aps, aps_blk, True) _write_static_files(folder, model_folder.aperture_folder(full=True), 'aperture', aps, aps_blk, mods, mods_blk, mod_combs, mod_names, False, minimal) # gather and write static faces faces, faces_blk = model.properties.radiance.faces_by_blk() f_mods, f_mods_blk, mod_combs, mod_names = _collect_modifiers( faces, faces_blk) _write_static_files(folder, model_folder.scene_folder(full=True), 'envelope', faces, faces_blk, f_mods, f_mods_blk, mod_combs, mod_names, True, minimal) # gather and write static shades shades, shades_blk = model.properties.radiance.shades_by_blk() s_mods, s_mods_blk, mod_combs, mod_names = _collect_modifiers( shades, shades_blk) _write_static_files(folder, model_folder.scene_folder(full=True), 'shades', shades, shades_blk, s_mods, s_mods_blk, mod_combs, mod_names, False, minimal) # write dynamic sub-face groups (apertures and doors) ext_dict = {} out_subfolder = model_folder.aperture_group_folder(full=True) dyn_subface = model.properties.radiance.dynamic_subface_groups if len(dyn_subface) != 0: preparedir(out_subfolder) for group in dyn_subface: if group.is_indoor: # TODO: Implement dynamic interior apertures once the radiance folder # structure is clear about how the "light path" should be input raise NotImplementedError( 'Dynamic interior apertures are not currently' ' supported by Model.to.rad_folder.') else: st_d = _write_dynamic_subface_files(folder, out_subfolder, group, minimal) _write_mtx_files(folder, out_subfolder, group, st_d, minimal) ext_dict[group.identifier] = st_d _write_dynamic_json(folder, out_subfolder, ext_dict) # write dynamic shade groups out_dict = {} in_dict = {} out_subfolder = model_folder.dynamic_scene_folder(full=True, indoor=False) in_subfolder = model_folder.dynamic_scene_folder(full=True, indoor=True) dyn_shade = model.properties.radiance.dynamic_shade_groups if len(dyn_shade) != 0: preparedir(out_subfolder) indoor_created = False for group in dyn_shade: if group.is_indoor: if not indoor_created: preparedir(in_subfolder) indoor_created = True st_d = _write_dynamic_shade_files(folder, in_subfolder, group, minimal) in_dict[group.identifier] = st_d else: st_d = _write_dynamic_shade_files(folder, out_subfolder, group, minimal) out_dict[group.identifier] = st_d _write_dynamic_json(folder, out_subfolder, out_dict) if indoor_created: _write_dynamic_json(folder, in_subfolder, in_dict) # copy all bsdfs into the bsdf folder bsdf_folder = model_folder.bsdf_folder(full=True) bsdf_mods = model.properties.radiance.bsdf_modifiers if len(bsdf_mods) != 0: preparedir(bsdf_folder) for bdf_mod in bsdf_mods: bsdf_name = os.path.split(bdf_mod.bsdf_file)[-1] new_bsdf_path = os.path.join(bsdf_folder, bsdf_name) shutil.copy(bdf_mod.bsdf_file, new_bsdf_path) # write the assigned sensor grids and views into the correct folder grid_dir = model_folder.grid_folder(full=True) grids = model.properties.radiance.sensor_grids if len(grids) != 0: grids_info = [] preparedir(grid_dir) model.properties.radiance.check_duplicate_sensor_grid_display_names() for grid in grids: grid.to_file(grid_dir) info_file = os.path.join(grid_dir, '{}.json'.format(grid.display_name)) with open(info_file, 'w') as fp: json.dump(grid.info_dict(model), fp, indent=4) grid_info = {'name': grid.display_name, 'count': grid.count} grids_info.append(grid_info) # write information file for all the grids. grids_info_file = os.path.join(grid_dir, '_info.json') with open(grids_info_file, 'w') as fp: json.dump(grids_info, fp, indent=2) view_dir = model_folder.view_folder(full=True) views = model.properties.radiance.views if len(views) != 0: views_info = [] preparedir(view_dir) model.properties.radiance.check_duplicate_view_display_names() for view in views: view.to_file(view_dir) info_file = os.path.join(view_dir, '{}.json'.format(view.display_name)) with open(info_file, 'w') as fp: json.dump(view.info_dict(model), fp, indent=4) # TODO: see if it make sense to use to_dict here instead of only taking the # name view_info = {'name': view.display_name} views_info.append(view_info) # write information file for all the views. views_info_file = os.path.join(view_dir, '_info.json') with open(views_info_file, 'w') as fp: json.dump(views_info, fp, indent=2) return folder
def test_writer_to_rad_folder_shade_drop(): """Test the Model to.rad_folder method with shades that drop half-way.""" room = Room.from_box('Store_Entrance', 10, 10, 6) # create the apertures on the south side and put them in the same dynamic group pts_1 = [Point3D(1, 0, 1), Point3D(4, 0, 1), Point3D(4, 0, 3), Point3D(1, 0, 3)] pts_2 = [Point3D(1, 0, 3), Point3D(4, 0, 3), Point3D(4, 0, 5), Point3D(1, 0, 5)] pts_3 = [Point3D(6, 0, 1), Point3D(9, 0, 1), Point3D(9, 0, 3), Point3D(6, 0, 3)] pts_4 = [Point3D(6, 0, 3), Point3D(9, 0, 3), Point3D(9, 0, 5), Point3D(6, 0, 5)] pts_5 = [Point3D(4.5, 0, 0.25), Point3D(5.5, 0, 0.25), Point3D(5.5, 0, 5), Point3D(4.5, 0, 5)] s_left_bottom = Aperture('s_left_bottom', Face3D(pts_1)) s_left_top = Aperture('s_left_top', Face3D(pts_2)) s_right_bottom = Aperture('s_right_bottom', Face3D(pts_3)) s_right_top = Aperture('s_right_top', Face3D(pts_4)) entry = Aperture('entry', Face3D(pts_5)) south_face = room[3] south_apertures = [s_left_bottom, s_left_top, s_right_bottom, s_right_top, entry] south_face.add_apertures(south_apertures) for ap in south_apertures: ap.properties.radiance.dynamic_group_identifier = 'SouthWall' # create the apertures on the east side and put them in the same dynamic group pts_6 = [Point3D(10, 1, 1), Point3D(10, 9, 1), Point3D(10, 9, 3), Point3D(10, 1, 3)] pts_7 = [Point3D(10, 1, 3), Point3D(10, 9, 3), Point3D(10, 9, 5), Point3D(10, 1, 5)] e_bottom = Aperture('e_bottom', Face3D(pts_6)) e_top = Aperture('e_top', Face3D(pts_7)) east_face = room[2] east_apertures = [e_bottom, e_top] east_face.add_apertures(east_apertures) for ap in east_apertures: ap.properties.radiance.dynamic_group_identifier = 'EastWall' # create the states bare_glass = Glass.from_single_transmittance('BareGlass', 0.7) protected_glass = Glass.from_single_transmittance('ProtectedGlass', 0.3) bare = RadianceSubFaceState(bare_glass) protected = RadianceSubFaceState(protected_glass) # assign states to individual apertures s_left_bottom.properties.radiance.states = \ [bare.duplicate(), bare.duplicate(), protected.duplicate()] s_right_bottom.properties.radiance.states = \ [bare.duplicate(), bare.duplicate(), protected.duplicate()] s_left_top.properties.radiance.states = \ [bare.duplicate(), protected.duplicate(), protected.duplicate()] s_right_top.properties.radiance.states = \ [bare.duplicate(), protected.duplicate(), protected.duplicate()] entry.properties.radiance.modifier = bare_glass e_bottom.properties.radiance.states = \ [bare.duplicate(), bare.duplicate(), protected.duplicate()] e_top.properties.radiance.states = \ [bare.duplicate(), protected.duplicate(), protected.duplicate()] # export the model radiance folder model = Model('Apple_Store', [room]) folder = os.path.abspath('./tests/assets/model/rad_folder_shade_drop') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) ap_dir = model_folder.aperture_group_folder(full=True) assert os.path.isfile(os.path.join(ap_dir, 'states.json')) group_name = entry.properties.radiance.dynamic_group_identifier assert os.path.isfile(os.path.join(ap_dir, '{}..black.rad'.format(group_name))) for i in range(len(entry.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..default..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(entry.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..direct..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) group_name = e_bottom.properties.radiance.dynamic_group_identifier assert os.path.isfile(os.path.join(ap_dir, '{}..black.rad'.format(group_name))) for i in range(len(e_bottom.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..default..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(e_bottom.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..direct..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) # clean up the folder nukedir(folder, rmdir=True)
def test_writer_to_rad_folder_multiphase(): """Test the Model to.rad_folder method with multi-phase objects like BSDFs.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) south_face = room[3] south_face.apertures_by_ratio(0.5, 0.01) south_aperture = south_face.apertures[0] north_face = room[1] north_face.apertures_by_ratio(0.5, 0.01) north_aperture = north_face.apertures[0] folder = os.path.abspath('./tests/assets/') clear_bsdf = BSDF(os.path.join(folder, 'clear.xml')) diff_bsdf = BSDF(os.path.join(folder, 'diffuse50.xml')) clear = RadianceSubFaceState(clear_bsdf) diffuse = RadianceSubFaceState(diff_bsdf) south_aperture.properties.radiance.dynamic_group_identifier = 'SouthDynamicWindow' south_aperture.properties.radiance.states = [clear, diffuse] north_aperture.properties.radiance.dynamic_group_identifier = 'NorthDynamicWindow' north_aperture.properties.radiance.states = [clear.duplicate(), diffuse.duplicate()] north_aperture.properties.radiance.states[0].gen_geos_from_tmtx_thickness(0.1) north_aperture.properties.radiance.states[1].gen_geos_from_tmtx_thickness(0.2) model = Model('Tiny_House', [room]) folder = os.path.abspath('./tests/assets/model/rad_folder_multiphase') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) bsdf_dir = model_folder.bsdf_folder(full=True) assert os.path.isfile(os.path.join(bsdf_dir, 'clear.xml')) assert os.path.isfile(os.path.join(bsdf_dir, 'diffuse50.xml')) ap_dir = model_folder.aperture_group_folder(full=True) assert os.path.isfile(os.path.join(ap_dir, 'states.json')) group_name = south_aperture.properties.radiance.dynamic_group_identifier assert os.path.isfile(os.path.join(ap_dir, '{}..black.rad'.format(group_name))) assert os.path.isfile(os.path.join(ap_dir, '{}..mtx.rad'.format(group_name))) for i in range(len(south_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..default..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(south_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..direct..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) group_name = north_aperture.properties.radiance.dynamic_group_identifier assert os.path.isfile(os.path.join(ap_dir, '{}..black.rad'.format(group_name))) for i in range(len(north_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..default..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(north_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..direct..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(north_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..dmtx..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(north_aperture.properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..vmtx..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) # clean up the folder nukedir(folder, rmdir=True)
def test_writer_to_rad_folder_dynamic(): """Test the Model to.rad_folder method with dynamic geometry.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) south_face = room[3] south_face.apertures_by_ratio(0.5, 0.01) shd1 = StateGeometry.from_vertices( 'outdoor_awning', [[0, 0, 2], [5, 0, 2], [5, 2, 2], [0, 2, 2]]) ecglass1 = Glass.from_single_transmittance('ElectrochromicState1', 0.4) ecglass2 = Glass.from_single_transmittance('ElectrochromicState2', 0.27) ecglass3 = Glass.from_single_transmittance('ElectrochromicState3', 0.14) ecglass4 = Glass.from_single_transmittance('ElectrochromicState4', 0.01) tint1 = RadianceSubFaceState(ecglass1) tint2 = RadianceSubFaceState(ecglass2) tint3 = RadianceSubFaceState(ecglass3, [shd1]) tint4 = RadianceSubFaceState(ecglass4, [shd1.duplicate()]) states = (tint1, tint2, tint3, tint4) south_face.apertures[0].properties.radiance.dynamic_group_identifier = \ 'ElectrochromicWindow' south_face.apertures[0].properties.radiance.states = states shd2 = Shade.from_vertices( 'indoor_light_shelf', [[0, 0, 2], [-1, 0, 2], [-1, 2, 2], [0, 2, 2]]) ref_1 = Plastic.from_single_reflectance('outdoor_light_shelf_0.5', 0.5) ref_2 = Plastic.from_single_reflectance('indoor_light_shelf_0.70', 0.7) light_shelf_1 = RadianceShadeState(ref_1) light_shelf_2 = RadianceShadeState(ref_2) shelf_states = (light_shelf_1, light_shelf_2) shd2.properties.radiance.dynamic_group_identifier = 'DynamicLightShelf' shd2.properties.radiance.states = shelf_states room.add_indoor_shade(shd2) north_face = room[1] north_face.overhang(0.25, indoor=False) door_verts = [Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5)] door = Door('Front_Door', Face3D(door_verts)) north_face.add_door(door) aperture_verts = [Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5)] aperture = Aperture('Front_Aperture', Face3D(aperture_verts)) triple_pane = Glass.from_single_transmittance('custom_triple_pane_0.3', 0.3) aperture.properties.radiance.modifier = triple_pane north_face.add_aperture(aperture) tree_canopy_geo = Face3D.from_regular_polygon( 6, 2, Plane(Vector3D(0, 0, 1), Point3D(5, -3, 4))) tree_canopy = Shade('Tree_Canopy', tree_canopy_geo) sum_tree_trans = Trans.from_single_reflectance('SummerLeaves', 0.3, 0.0, 0.1, 0.15, 0.15) win_tree_trans = Trans.from_single_reflectance('WinterLeaves', 0.1, 0.0, 0.1, 0.1, 0.6) summer = RadianceShadeState(sum_tree_trans) winter = RadianceShadeState(win_tree_trans) tree_canopy.properties.radiance.dynamic_group_identifier = 'DeciduousTree' tree_canopy.properties.radiance.states = (summer, winter) ground_geo = Face3D.from_rectangle(10, 10, Plane(o=Point3D(0, -10, 0))) ground = Shade('Ground', ground_geo) grass = Plastic.from_single_reflectance('grass', 0.3) snow = Plastic.from_single_reflectance('snow', 0.7) summer_ground = RadianceShadeState(grass) winter_ground = RadianceShadeState(snow) ground.properties.radiance.dynamic_group_identifier = 'SeasonalGround' ground.properties.radiance.states = (summer_ground, winter_ground) east_face = room[2] east_face.apertures_by_ratio(0.1, 0.01) west_face = garage[4] west_face.apertures_by_ratio(0.1, 0.01) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage], orphaned_shades=[ground, tree_canopy]) folder = os.path.abspath('./tests/assets/model/rad_folder_dynamic') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) ap_dir = model_folder.aperture_group_folder(full=True) assert os.path.isfile(os.path.join(ap_dir, 'states.json')) group_name = south_face.apertures[0].properties.radiance.dynamic_group_identifier assert os.path.isfile(os.path.join(ap_dir, '{}..black.rad'.format(group_name))) for i in range(len(south_face.apertures[0].properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..default..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) for i in range(len(south_face.apertures[0].properties.radiance.states)): d_file = (os.path.join(ap_dir, '{}..direct..{}.rad'.format(group_name, i))) assert os.path.isfile(d_file) out_scene_dir = model_folder.dynamic_scene_folder(full=True, indoor=False) assert os.path.isfile(os.path.join(out_scene_dir, 'states.json')) grp_name = tree_canopy.properties.radiance.dynamic_group_identifier for i in range(len(tree_canopy.properties.radiance.states)): d_file = (os.path.join(out_scene_dir, '{}..default..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) for i in range(len(tree_canopy.properties.radiance.states)): d_file = (os.path.join(out_scene_dir, '{}..direct..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) grp_name = ground.properties.radiance.dynamic_group_identifier for i in range(len(ground.properties.radiance.states)): d_file = (os.path.join(out_scene_dir, '{}..default..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) for i in range(len(ground.properties.radiance.states)): d_file = (os.path.join(out_scene_dir, '{}..direct..{}.rad'.format(grp_name, i))) d_file = (os.path.join(out_scene_dir, '{}..direct..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) in_scene_dir = model_folder.dynamic_scene_folder(full=True, indoor=True) assert os.path.isfile(os.path.join(in_scene_dir, 'states.json')) grp_name = shd2.properties.radiance.dynamic_group_identifier for i in range(len(shd2.properties.radiance.states)): d_file = (os.path.join(in_scene_dir, '{}..default..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) for i in range(len(shd2.properties.radiance.states)): d_file = (os.path.join(in_scene_dir, '{}..direct..{}.rad'.format(grp_name, i))) assert os.path.isfile(d_file) # clean up the folder nukedir(folder, rmdir=True)
def test_writer_to_rad_folder(): """Test the Model to.rad_folder method.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) dark_floor = Plastic.from_single_reflectance('DarkFloor', 0.1) room[0].properties.radiance.modifier = dark_floor room[5].properties.radiance.modifier_blk = dark_floor south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.move_shades(Vector3D(0, 0, -0.5)) light_shelf_out = Plastic.from_single_reflectance('outdoor_light_shelf_0.5', 0.5) light_shelf_in = Plastic.from_single_reflectance('indoor_light_shelf_0.70', 0.7) south_face.apertures[0].outdoor_shades[0].properties.radiance.modifier = light_shelf_out south_face.apertures[0].indoor_shades[0].properties.radiance.modifier = light_shelf_in north_face = room[1] north_face.overhang(0.25, indoor=False) door_verts = [Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5)] door = Door('Front_Door', Face3D(door_verts)) north_face.add_door(door) aperture_verts = [Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5)] aperture = Aperture('Front_Aperture', Face3D(aperture_verts)) triple_pane = Glass.from_single_transmittance('custom_triple_pane_0.3', 0.3) aperture.properties.radiance.modifier = triple_pane north_face.add_aperture(aperture) tree_canopy_geo = Face3D.from_regular_polygon( 6, 2, Plane(Vector3D(0, 0, 1), Point3D(5, -3, 4))) tree_canopy = Shade('Tree_Canopy', tree_canopy_geo) tree_trans = Trans.from_single_reflectance('Leaves', 0.3, 0.0, 0.1, 0.15, 0.15) tree_canopy.properties.radiance.modifier = tree_trans table_geo = Face3D.from_rectangle(2, 2, Plane(o=Point3D(1.5, 4, 1))) table = Shade('Table', table_geo) room.add_indoor_shade(table) east_face = room[2] east_face.apertures_by_ratio(0.1, 0.01) west_face = garage[4] west_face.apertures_by_ratio(0.1, 0.01) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage], orphaned_shades=[tree_canopy]) folder = os.path.abspath('./tests/assets/model/rad_folder') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) ap_dir = model_folder.aperture_folder(full=True) assert os.path.isfile(os.path.join(ap_dir, 'aperture.rad')) assert os.path.isfile(os.path.join(ap_dir, 'aperture.mat')) assert os.path.isfile(os.path.join(ap_dir, 'aperture.blk')) scene_dir = model_folder.scene_folder(full=True) assert os.path.isfile(os.path.join(scene_dir, 'envelope.rad')) assert os.path.isfile(os.path.join(scene_dir, 'envelope.mat')) assert os.path.isfile(os.path.join(scene_dir, 'envelope.blk')) assert os.path.isfile(os.path.join(scene_dir, 'shades.rad')) assert os.path.isfile(os.path.join(scene_dir, 'shades.mat')) assert os.path.isfile(os.path.join(scene_dir, 'shades.blk')) # clean up the folder nukedir(folder, rmdir=True)
def model_to_rad_folder( model, folder=None, config_file=None, minimal=False, grids=None, views=None, full_match=False ): r"""Write a honeybee model to a rad folder. The rad files in the resulting folders will include all geometry (Rooms, Faces, Shades, Apertures, Doors), all modifiers, and all states of dynamic objects. It also includes any SensorGrids and Views that are assigned to the model's radiance properties. Args: model: A honeybee Model for which radiance folder will be written. folder: An optional folder to be used as the root of the model's Radiance folder. If None, the files will be written into a sub-directory of the honeybee-core default_simulation_folder. This sub-directory is specifically: default_simulation_folder/[MODEL IDENTIFIER]/Radiance config_file: An optional config file path to modify the default folder names. If None, ``folder.cfg`` in ``honeybee-radiance-folder`` will be used. (Default: None). minimal: Boolean to note whether the radiance strings should be written in a minimal format (with spaces instead of line breaks). Default: False. grids: A list of sensor grid names to filter the sensor grids in the model. Use this argument to indicate specific sensor grids that should be included. By default all the sensor grids will be exported. You can use wildcard symbols in names. Use relative path from inside grids folder. views: A list of view files that should be exported to folder. Use this argument to limit what will be written to the radiance folder. You can use wildcard symbols in names. Use relative path from inside views folder. full_match: A boolean to filter grids and views by their identifiers as full matches. Setting this to True indicates that wildcard symbols will not be used in the filtering of grids and views. In this case the names of grids and views are filtered as is. (Default: False). """ # prepare the folder for simulation model_id = model.identifier if folder is None: folder = os.path.join(folders.default_simulation_folder, model_id, 'radiance') if not os.path.isdir(folder): preparedir(folder) # create the directory if it's not there model_folder = ModelFolder(folder, 'model', config_file) model_folder.write(folder_type=-1, cfg=folder_config.minimal, overwrite=True) # gather and write static apertures to the folder aps, aps_blk = model.properties.radiance.subfaces_by_blk() mods, mods_blk, mod_combs, mod_names = _collect_modifiers(aps, aps_blk, True) _write_static_files( folder, model_folder.aperture_folder(full=True), 'aperture', aps, aps_blk, mods, mods_blk, mod_combs, mod_names, False, minimal) # gather and write static faces faces, faces_blk = model.properties.radiance.faces_by_blk() f_mods, f_mods_blk, mod_combs, mod_names = _collect_modifiers(faces, faces_blk) _write_static_files( folder, model_folder.scene_folder(full=True), 'envelope', faces, faces_blk, f_mods, f_mods_blk, mod_combs, mod_names, True, minimal) # gather and write static shades shades, shades_blk = model.properties.radiance.shades_by_blk() s_mods, s_mods_blk, mod_combs, mod_names = _collect_modifiers(shades, shades_blk) _write_static_files( folder, model_folder.scene_folder(full=True), 'shades', shades, shades_blk, s_mods, s_mods_blk, mod_combs, mod_names, False, minimal) # write dynamic sub-face groups (apertures and doors) ext_dict = {} out_subfolder = model_folder.aperture_group_folder(full=True) dyn_subface = model.properties.radiance.dynamic_subface_groups if len(dyn_subface) != 0: preparedir(out_subfolder) for group in dyn_subface: if group.is_indoor: # TODO: Implement dynamic interior apertures once the radiance folder # structure is clear about how the "light path" should be input raise NotImplementedError('Dynamic interior apertures are not currently' ' supported by Model.to.rad_folder.') else: st_d = _write_dynamic_subface_files( folder, out_subfolder, group, minimal) _write_mtx_files(folder, out_subfolder, group, st_d, minimal) ext_dict[group.identifier] = st_d _write_dynamic_json(folder, out_subfolder, ext_dict) # write dynamic shade groups out_dict = {} in_dict = {} out_subfolder = model_folder.dynamic_scene_folder(full=True, indoor=False) in_subfolder = model_folder.dynamic_scene_folder(full=True, indoor=True) dyn_shade = model.properties.radiance.dynamic_shade_groups if len(dyn_shade) != 0: preparedir(out_subfolder) indoor_created = False for group in dyn_shade: if group.is_indoor: if not indoor_created: preparedir(in_subfolder) indoor_created = True st_d = _write_dynamic_shade_files(folder, in_subfolder, group, minimal) in_dict[group.identifier] = st_d else: st_d = _write_dynamic_shade_files(folder, out_subfolder, group, minimal) out_dict[group.identifier] = st_d _write_dynamic_json(folder, out_subfolder, out_dict) if indoor_created: _write_dynamic_json(folder, in_subfolder, in_dict) # copy all bsdfs into the bsdf folder bsdf_folder = model_folder.bsdf_folder(full=True) bsdf_mods = model.properties.radiance.bsdf_modifiers if len(bsdf_mods) != 0: preparedir(bsdf_folder) bsdfs_info = [] for bdf_mod in bsdf_mods: bsdf_name = os.path.split(bdf_mod.bsdf_file)[-1] new_bsdf_path = os.path.join(bsdf_folder, bsdf_name) shutil.copy(bdf_mod.bsdf_file, new_bsdf_path) bsdfs_info.append( { 'name': bdf_mod.display_name, 'identifier': bdf_mod.identifier, 'path': os.path.join(model_folder.bsdf_folder(full=False), bsdf_name) }) bsdf_info_file = os.path.join(bsdf_folder, '_info.json') with open(bsdf_info_file, 'w') as fp: json.dump(bsdfs_info, fp, indent=2) # write the assigned sensor grids and views into the correct folder grid_dir = model_folder.grid_folder(full=True) _write_sensor_grids(grid_dir, model, grids, full_match) view_dir = model_folder.view_folder(full=True) _write_views(view_dir, model, views, full_match) model_folder.combined_receivers(auto_mtx_path=False) return folder