def calc_solid(face_footprint, range_floors, flr2flr_height, config):

    # create faces for every floor and extrude the solid
    moved_face_list = []
    for floor_counter in range_floors:
        dist2mve = floor_counter * flr2flr_height
        # get midpt of face
        orig_pt = calculate.face_midpt(face_footprint)
        # move the pt 1 level up
        dest_pt = modify.move_pt(orig_pt, (0, 0, 1), dist2mve)
        moved_face = modify.move(orig_pt, dest_pt, face_footprint)
        moved_face_list.append(moved_face)

    # make checks to satisfy a closed geometry also called a shell

    vertical_shell = construct.make_loft(moved_face_list)
    vertical_face_list = fetch.topo_explorer(vertical_shell, "face")
    roof = moved_face_list[-1]
    footprint = moved_face_list[0]
    all_faces = []
    all_faces.append(footprint)
    all_faces.extend(vertical_face_list)
    all_faces.append(roof)
    building_shell_list = construct.sew_faces(all_faces)

    # make sure all the normals are correct (they are pointing out)
    bldg_solid = construct.make_solid(building_shell_list[0])
    bldg_solid = modify.fix_close_solid(bldg_solid)

    if config.general.debug:
        # visualize building progress while debugging
        face_list = fetch.topo_explorer(bldg_solid, "face")
        edges = calculate.face_normal_as_edges(face_list, 5)
        utility.visualise([face_list, edges], ["WHITE", "BLACK"])
    return bldg_solid
Ejemplo n.º 2
0
    ]
    walls_s = [
        val for sublist in geometry_3D_surroundings for val in sublist['walls']
    ]
    windows_s = [
        val for sublist in geometry_3D_surroundings
        for val in sublist['windows']
    ]
    roof_s = [
        val for sublist in geometry_3D_surroundings for val in sublist['roofs']
    ]

    geometry_buildings_nonop.extend(windows)
    geometry_buildings_nonop.extend(windows_s)
    geometry_buildings.extend(walls)
    geometry_buildings.extend(roofs)
    geometry_buildings.extend(footprint)
    geometry_buildings.extend(walls_s)
    geometry_buildings.extend(roof_s)
    normals_terrain = calculate.face_normal_as_edges(geometry_terrain, 5)
    utility.visualise([
        geometry_terrain, geometry_buildings, geometry_buildings_nonop,
        walls_intercept
    ], ["GREEN", "WHITE", "BLUE", "RED"])  # install Wxpython

    utility.visualise([walls_intercept], ["RED"])

    utility.visualise([walls], ["RED"])

    utility.visualise([windows], ["RED"])
def building2d23d(locator, geometry_terrain, config, height_col, nfloor_col):
    """
    :param locator: InputLocator - provides paths to files in a scenario
    :type locator: cea.inputlocator.InputLocator
    :param config: the configuration object to use
    :type config: cea.config.Configuration
    :param height_col: name of the columns storing the height of buildings
    :param nfloor_col: name ofthe column storing the number of floors in buildings.
    :return:
    """

    # settings: parameters that configure the level of simplification of geometry
    settings = config.radiation_daysim
    consider_windows = True  #legacy from config file. now it is always true
    district_shp_path = locator.get_district_geometry()

    # path to zone geometry database
    zone_shp_path = locator.get_zone_geometry()

    # path to database of architecture properties
    architecture_dbf_path = locator.get_building_architecture()

    # read district shapefile and names of buildings of the district and the zone of analysis
    district_building_records = gdf.from_file(district_shp_path)
    zone_building_records = gdf.from_file(zone_shp_path)
    zone_building_names = zone_building_records['Name'].values

    #calculate district geometry (These are the surroundings of the zone oif interest and we simplify it to speet up computations)
    #first make sure that the district file does not contain buildings in the zone, if it does then erase them
    district_building_records = district_building_records.loc[
        ~district_building_records["Name"].isin(zone_building_names)]
    district_building_records.reset_index(inplace=True, drop=True)

    #now append to the district building records, those of the zone
    district_building_records = district_building_records.append(
        zone_building_records, ignore_index=True)
    district_building_records.set_index('Name', inplace=True)
    district_building_names = district_building_records.index.values

    # Read architecture properties
    architecture_wwr = gdf.from_file(architecture_dbf_path).set_index('Name')

    #make shell out of tin_occface_list and create OCC object
    terrain_shell = construct.make_shell(geometry_terrain)
    terrain_intersection_curves = IntCurvesFace_ShapeIntersector()
    terrain_intersection_curves.Load(terrain_shell, 1e-6)

    #empty list where to store the closed geometries
    geometry_3D_zone = []
    geometry_3D_surroundings = []

    for name in district_building_names:
        print('Generating geometry for building %(name)s' % locals())
        height = float(district_building_records.loc[name, height_col])
        nfloors = int(district_building_records.loc[name, nfloor_col])

        # simplify geometry tol =1 for buildings of interest, tol = 5 for surroundings
        if (name in zone_building_names) and settings.consider_floors:
            range_floors = range(nfloors + 1)
            flr2flr_height = height / nfloors
            geometry = district_building_records.ix[name].geometry.simplify(
                settings.zone_geometry, preserve_topology=True)
        else:
            range_floors = [0, 1]
            flr2flr_height = height
            geometry = district_building_records.ix[name].geometry.simplify(
                settings.surrounding_geometry, preserve_topology=True)

        # burn buildings footprint into the terrain and return the location of the new face
        print('burning building ', name)
        face_footprint = burn_buildings(geometry, terrain_intersection_curves)

        # create floors and form a solid
        building_solid = calc_solid(face_footprint, range_floors,
                                    flr2flr_height, config)

        # now get all surfaces and create windows only if the buildings are in the area of study
        window_list = []
        wall_list = []
        orientation = []
        orientation_win = []
        normals_w = []
        normals_win = []
        if (name in zone_building_names):
            if (consider_windows):
                # identify building surfaces according to angle:
                face_list = py3dmodel.fetch.faces_frm_solid(building_solid)
                facade_list_north, facade_list_west, \
                facade_list_east, facade_list_south, roof_list, footprint_list = identify_surfaces_type(face_list)

                # get window properties
                wwr_west = architecture_wwr.ix[name, "wwr_west"]
                wwr_east = architecture_wwr.ix[name, "wwr_east"]
                wwr_north = architecture_wwr.ix[name, "wwr_north"]
                wwr_south = architecture_wwr.ix[name, "wwr_south"]

                window_west, wall_west, normals_windows, normals_walls = calc_windows_walls(
                    facade_list_west, wwr_west)
                if len(window_west) != 0:
                    window_list.extend(window_west)
                    orientation_win.extend(['west'] * len(window_west))
                    normals_win.extend(normals_windows)
                wall_list.extend(wall_west)
                orientation.extend(['west'] * len(wall_west))
                normals_w.extend(normals_walls)

                window_east, wall_east, normals_windows, normals_walls = calc_windows_walls(
                    facade_list_east, wwr_east)
                if len(window_east) != 0:
                    window_list.extend(window_east)
                    orientation_win.extend(['east'] * len(window_east))
                    normals_win.extend(normals_windows)
                wall_list.extend(wall_east)
                orientation.extend(['east'] * len(wall_east))
                normals_w.extend(normals_walls)

                window_north, wall_north, normals_windows_north, normals_walls_north = calc_windows_walls(
                    facade_list_north, wwr_north)
                if len(window_north) != 0:
                    window_list.extend(window_north)
                    orientation_win.extend(['north'] * len(window_north))
                    normals_win.extend(normals_windows_north)
                wall_list.extend(wall_north)
                orientation.extend(['north'] * len(wall_north))
                normals_w.extend(normals_walls_north)

                window_south, wall_south, normals_windows_south, normals_walls_south = calc_windows_walls(
                    facade_list_south, wwr_south)
                if len(window_south) != 0:
                    window_list.extend(window_south)
                    orientation_win.extend(['south'] * len(window_south))
                    normals_win.extend(normals_windows_south)
                wall_list.extend(wall_south)
                orientation.extend(['south'] * len(wall_south))
                normals_w.extend(normals_walls_south)

                geometry_3D_zone.append({
                    "name": name,
                    "windows": window_list,
                    "walls": wall_list,
                    "roofs": roof_list,
                    "footprint": footprint_list,
                    "orientation_walls": orientation,
                    "orientation_windows": orientation_win,
                    "normals_windows": normals_win,
                    "normals_walls": normals_w
                })

            else:
                facade_list, roof_list, footprint_list = gml3dmodel.identify_building_surfaces(
                    building_solid)
                wall_list = facade_list
                geometry_3D_zone.append({
                    "name": name,
                    "windows": window_list,
                    "walls": wall_list,
                    "roofs": roof_list,
                    "footprint": footprint_list,
                    "orientation_walls": orientation,
                    "orientation_windows": orientation_win,
                    "normals_windows": normals_win,
                    "normals_walls": normals_w
                })

            if config.general.debug:
                # visualize building progress while debugging
                edges1 = calculate.face_normal_as_edges(wall_list, 5)
                edges2 = calculate.face_normal_as_edges(roof_list, 5)
                edges3 = calculate.face_normal_as_edges(footprint_list, 5)
                utility.visualise([
                    wall_list, roof_list, footprint_list, edges1, edges2,
                    edges3
                ], ["WHITE", "WHITE", "WHITE", "BLACK", "BLACK", "BLACK"])
        else:
            facade_list, roof_list, footprint_list = urbangeom.identify_building_surfaces(
                building_solid)
            wall_list = facade_list
            geometry_3D_surroundings.append({
                "name": name,
                "windows": window_list,
                "walls": wall_list,
                "roofs": roof_list,
                "footprint": footprint_list,
                "orientation_walls": orientation,
                "orientation_windows": orientation_win,
                "normals_windows": normals_win,
                "normals_walls": normals_w
            })

            if config.general.debug:
                # visualize building progress while debugging
                edges1 = calculate.face_normal_as_edges(wall_list, 5)
                edges2 = calculate.face_normal_as_edges(roof_list, 5)
                edges3 = calculate.face_normal_as_edges(footprint_list, 5)
                utility.visualise([
                    wall_list, roof_list, footprint_list, edges1, edges2,
                    edges3
                ], ["WHITE", "WHITE", "WHITE", "BLACK", "BLACK", "BLACK"])
    return geometry_3D_zone, geometry_3D_surroundings