Source code for dtcc_builder.geometry_builders.meshes

from dtcc_model import (
    Mesh,
    VolumeMesh,
    Building,
    Terrain,
    City,
    Surface,
    MultiSurface,
    GeometryType,
)

from dtcc_builder.model import (
    create_builder_polygon,
    create_builder_surface,
    create_builder_multisurface,
    builder_mesh_to_mesh,
    mesh_to_builder_mesh,
    create_builder_city,
    raster_to_builder_gridfield,
)

from dtcc_builder import _dtcc_builder

from dtcc_builder.polygons.polygons import (
    polygon_merger,
    simplify_polygon,
    remove_slivers,
    fix_clearance,
)

from dtcc_builder.building.modify import (
    merge_building_footprints,
    simplify_building_footprints,
    fix_building_footprint_clearance,
)

from dtcc_builder.meshing.convert import mesh_to_raster

from dtcc_builder.logging import debug, info, warning, error


[docs] def build_surface_mesh( city: City, lod: GeometryType = GeometryType.LOD1, min_building_detail: float = 0.5, min_building_area: float = 15.0, merge_buildings: bool = True, merge_tolerance: float = 0.5, building_mesh_triangle_size: float = 2.0, max_mesh_size: float = 10.0, min_mesh_angle: float = 25.0, merge_meshes: bool = True, smoothing: int = 0, sort_triangles: bool = False, ) -> Mesh: """ Build a mesh from the surfaces of the buildings in the city. Parameters ---------- `city` : dtcc_model.City The city to build the mesh from. `min_building_detail` : float, optional The minimum detail of the buildin to resolve, by default 0.5. `min_building_area` : float, optional The smallest building to include, by default 15.0. `merge_buildings` : bool, optional merge building footprints, by default True. `max_mesh_size` : float, optional The maximum size of the mesh, by default 1.0. `min_mesh_angle` : float, optional The minimum angle of the mesh, by default 30.0. `merge_meshes` : bool, optional Whether to merge the meshes to a single mesh, by default True. `smoothing` : float, optional The smoothing of the mesh, by default 0.0. Returns ------- `dtcc_model.Mesh` """ buildings = city.buildings if merge_buildings: info(f"Merging {len(buildings)} buildings...") merged_buildings = merge_building_footprints( buildings, lod, min_area=min_building_area ) simplifed_footprints = simplify_building_footprints( merged_buildings, min_building_detail / 2, lod=GeometryType.LOD0 ) clearance_fix = fix_building_footprint_clearance( simplifed_footprints, min_building_detail ) building_footprints = [ b.get_footprint(GeometryType.LOD0) for b in clearance_fix ] info(f"After merging: {len(building_footprints)} buildings.") else: building_footprints = [b.get_footprint(lod) for b in buildings] subdomain_resolution = [building_mesh_triangle_size] * len(building_footprints) terrain = city.terrain if terrain is None: raise ValueError("City has no terrain data. Please compute terrain first.") terrain_raster = terrain.raster terrain_mesh = terrain.mesh if terrain_raster is None and terrain_mesh is None: raise ValueError("City terrain has no data. Please compute terrain first.") if terrain_raster is None and terrain_mesh is not None: terrain_raster = mesh_to_raster(terrain_mesh, cell_size=max_mesh_size) builder_dem = raster_to_builder_gridfield(terrain_raster) builder_surfaces = [ create_builder_surface(p) for p in building_footprints if p is not None ] builder_mesh = _dtcc_builder.build_city_surface_mesh( builder_surfaces, subdomain_resolution, builder_dem, max_mesh_size, min_mesh_angle, smoothing, merge_meshes, sort_triangles, ) if merge_meshes: result_mesh = builder_mesh_to_mesh(builder_mesh[0]) else: result_mesh = [builder_mesh_to_mesh(bm) for bm in builder_mesh] return result_mesh