"""Building feature assembly (`building=*`).""" from osmassets.mesh import MeshBatch, add_roof, add_wall_panel, make_prism from osmassets.osm import parse_height def add_details(name, ring, height, industrial, materials, collection): footprint = ring[:-1] if len(ring) > 1 and ring[0] == ring[-1] else ring if len(footprint) < 3: return glass_mat = materials["factory_glass"] if industrial else materials["glass"] glass_batch = MeshBatch(name + "_Windows", collection, glass_mat) edges = list(zip(footprint, footprint[1:] + footprint[:1])) if industrial: band_height = min(1.8, max(0.75, height * 0.16)) band_base = max(0.9, height * 0.52) for start, end in edges: add_wall_panel(glass_batch, start, end, band_base, band_height, thickness=0.055, inset=0.12) else: floor_height = 3.25 floor_count = max(1, int((height - 0.7) / floor_height)) for floor in range(floor_count): band_base = 0.55 + floor * floor_height + 0.95 if band_base + 1.25 > height - 0.18: break for start, end in edges: add_wall_panel(glass_batch, start, end, band_base, 1.25, thickness=0.045, inset=0.10) glass_batch.finish() def assemble(ring, way_id, tag, office_overrides, collection, materials): industrial = (tag.get("building") == "industrial" and way_id not in office_overrides) source_height = max(3.0, parse_height(tag, 12.0)) height = source_height if industrial or source_height >= 30.0 else 11.4 material = materials["industrial"] if industrial else materials["default"] building_name = "Building_" + way_id building_obj = make_prism(building_name, ring, 0.08, height, material, collection) if building_obj: building_obj["osm_height"] = source_height building_obj["render_height"] = height building_obj["building_kind"] = "industrial" if industrial else "office" building_obj["osm_building_tag"] = tag.get("building", "") building_obj["office_override"] = way_id in office_overrides bevel = building_obj.modifiers.new("Soft facade edges", "BEVEL") bevel.width = 0.16 bevel.segments = 2 roof_mat = (materials["industrial_roof"] if industrial else materials["office_roof"]) add_roof(building_name, ring, height + 0.095, roof_mat, collection) add_details(building_name, ring, height, industrial, materials, collection) return 1, int(industrial), ring