from inire.geometry.collision import CollisionEngine from inire.geometry.primitives import Port from inire.router.astar import AStarRouter from inire.router.cost import CostEvaluator from inire.router.danger_map import DangerMap from inire.router.pathfinder import PathFinder from inire.utils.visualization import plot_routing_results def main() -> None: print("Running Example 03: Locked Paths (Incremental Routing - Bus Scenario)...") # 1. Setup Environment bounds = (0, 0, 120, 120) engine = CollisionEngine(clearance=2.0) danger_map = DangerMap(bounds=bounds) danger_map.precompute([]) # Start with empty space evaluator = CostEvaluator(engine, danger_map, greedy_h_weight=1.2) router = AStarRouter(evaluator, node_limit=200000) pf = PathFinder(router, evaluator) # 2. Phase 1: Route a "Bus" of 3 parallel nets # We give them a small jog to make the locked geometry more interesting netlist_p1 = { "bus_0": (Port(10, 40, 0), Port(110, 45, 0)), "bus_1": (Port(10, 50, 0), Port(110, 55, 0)), "bus_2": (Port(10, 60, 0), Port(110, 65, 0)), } print("Phase 1: Routing bus (3 nets)...") results_p1 = pf.route_all(netlist_p1, dict.fromkeys(netlist_p1, 2.0)) # Lock all Phase 1 nets path_polys = [] for nid, res in results_p1.items(): if res.is_valid: print(f" Locking {nid}...") engine.lock_net(nid) path_polys.extend([p for comp in res.path for p in comp.geometry]) else: print(f" Warning: {nid} failed to route correctly.") # Update danger map with the newly locked geometry print("Updating DangerMap with locked paths...") danger_map.precompute(path_polys) # 3. Phase 2: Route secondary nets that must navigate around the locked bus # These nets cross the bus vertically. netlist_p2 = { "cross_left": (Port(30, 10, 90), Port(30, 110, 90)), "cross_right": (Port(80, 110, 270), Port(80, 10, 270)), # Top to bottom } print("Phase 2: Routing crossing nets around locked bus...") # We use a slightly different width for variety results_p2 = pf.route_all(netlist_p2, dict.fromkeys(netlist_p2, 1.5)) # 4. Check Results for nid, res in results_p2.items(): status = "Success" if res.is_valid else "Failed" print(f" {nid:12}: {status}, collisions={res.collisions}") # 5. Visualize all_results = {**results_p1, **results_p2} all_netlists = {**netlist_p1, **netlist_p2} fig, ax = plot_routing_results(all_results, [], bounds, netlist=all_netlists) fig.savefig("examples/03_locked_paths.png") print("Saved plot to examples/03_locked_paths.png") if __name__ == "__main__": main()