import rhinoscriptsyntax as rs import random allobjs = rs.AllObjects() rs.DeleteObjects(allobjs) def create_building(base_point, width, depth, height, facade_type): """ """ # Define base rectangle rect_pts = [ (base_point[0] - width / 2, base_point[1] - depth / 2, base_point[2]), (base_point[0] + width / 2, base_point[1] - depth / 2, base_point[2]), (base_point[0] + width / 2, base_point[1] + depth / 2, base_point[2]), (base_point[0] - width / 2, base_point[1] + depth / 2, base_point[2]), (base_point[0] - width / 2, base_point[1] - depth / 2, base_point[2]), ] # Create the base and top rectangles base_curve = rs.AddPolyline(rect_pts) top_pts = [(x, y, z + height) for x, y, z in rect_pts] top_curve = rs.AddPolyline(top_pts) # Loft between base and top curves building = rs.AddLoftSrf([base_curve, top_curve])[0] # Add a roof (cap the top of the building) rs.AddPlanarSrf(top_curve) # Apply facade apply_facade(base_point, width, depth, height, facade_type) # Clean up rs.DeleteObject(base_curve) rs.DeleteObject(top_curve) return building def apply_facade(base_point, width, depth, height, facade_type): if facade_type == "wavy": apply_wavy_facade(base_point, width, depth, height) elif facade_type == "angular": apply_angular_facade(base_point, width, depth, height) def apply_wavy_facade(base_point, width, depth, height): num_waves = 10 wave_height = width / 8 for i in range(num_waves): wave_x = base_point[0] - width / 2 + i * (width / num_waves) for j in range(int(height / (2 * wave_height))): z = base_point[2] + j * (2 * wave_height) points = [ (wave_x, base_point[1] - depth / 2, z), (wave_x + wave_height / 2, base_point[1] - depth / 2, z + wave_height), (wave_x, base_point[1] - depth / 2, z + 2 * wave_height) ] rs.AddPolyline(points) def apply_angular_facade(base_point, width, depth, height): num_sections = 5 for i in range(num_sections): section_height = height / num_sections z = base_point[2] + i * section_height angle_shift = random.uniform(-width / 4, width / 4) points = [ (base_point[0] - width / 2, base_point[1] - depth / 2 + angle_shift, z), (base_point[0] + width / 2, base_point[1] - depth / 2 - angle_shift, z), (base_point[0] + width / 2, base_point[1] + depth / 2 + angle_shift, z), (base_point[0] - width / 2, base_point[1] + depth / 2 - angle_shift, z), (base_point[0] - width / 2, base_point[1] - depth / 2 + angle_shift, z) ] rs.AddPolyline(points) def create_city_section(): """ a section with randomized buildings """ # area dimensions and number of buildings area_width = 1000 area_depth = 1000 num_buildings = 100 building_positions = [] for _ in range(num_buildings): while True: # Randomize building base point base_x = random.uniform(-area_width / 2, area_width / 2) base_y = random.uniform(-area_depth / 2, area_depth / 2) base_point = (base_x, base_y, 0) # Randomize building dimensions width = random.uniform(10, 50) depth = random.uniform(10, 50) height = random.uniform(50, 300) # Check if the building overlaps with existing ones if not does_building_overlap(base_point, width, depth, building_positions): building_positions.append((base_point, width, depth)) break # Randomize facade type facade_type = random.choice(["wavy", "angular"]) # Create the building create_building(base_point, width, depth, height, facade_type) def does_building_overlap(base_point, width, depth, existing_positions): """ Check if a building overlaps with existing ones """ for pos, w, d in existing_positions: if (abs(base_point[0] - pos[0]) < (width / 2 + w / 2) and abs(base_point[1] - pos[1]) < (depth / 2 + d / 2)): return True return False def add_landmarks(): landmarks = [ {"width": 70, "depth": 70, "height": 500, "location": (-200, 200, 0), "facade_type": "angular"}, {"width": 50, "depth": 50, "height": 400, "location": (300, -300, 0), "facade_type": "wavy"}, {"width": 60, "depth": 60, "height": 450, "location": (0, 0, 0), "facade_type": "angular"} ] for landmark in landmarks: create_building(landmark["location"], landmark["width"], landmark["depth"], landmark["height"], landmark["facade_type"]) if __name__ == "__main__": create_city_section() add_landmarks() rs.EnableRedraw(True)