From 33de21ba0ef63f62fb234656e7f35e016814fc7d Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Wed, 7 Oct 2026 18:37:33 -0600 Subject: [PATCH] Route with the exact engine by default; warn when an engine does not check The grid engine was the default and its copper is not checked against exact shapes: a full reroute of the Labrador lid with no flags came out with 15 tracks_crossing and 87 clearance violations under KiCad's DRC while the report listed only unrouted connections. The exact engine (what mckicad and every benchmark already use) is now the default, and grid or room runs end with a warning that their output needs a DRC. --- src/rpmroute/cli.py | 20 ++++++++++++++++---- tests/test_cli.py | 22 +++++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/rpmroute/cli.py b/src/rpmroute/cli.py index 468d929..2879603 100644 --- a/src/rpmroute/cli.py +++ b/src/rpmroute/cli.py @@ -94,11 +94,12 @@ def build_parser() -> argparse.ArgumentParser: parser.add_argument( "--engine", choices=sorted(ENGINE_OPTIONS), - default="grid", + default="exact", help=( - "routing track: grid (default; multi-layer rip-up maze, highest coverage), " - "exact (orthogonal, exact-geometry DRC-verified output), " - "room (continuous expansion rooms, routes off-grid channels)" + "routing track: exact (default; every route checked against exact pad and " + "copper shapes, DRC-clean output), grid (quick maze on the grid alone: its " + "copper is NOT clearance-checked and can short), room (continuous expansion " + "rooms, routes off-grid channels; not clearance-checked either)" ), ) parser.add_argument( @@ -386,6 +387,17 @@ def main(argv: list[str] | None = None) -> int: for net, a, b, zone in in_zone: print(f" {net}: {a} to {b} (both in zone {zone})", file=sys.stderr) + if args.engine != "exact": + # These engines route on approximations and do not check the copper + # they write against exact shapes: a board can come out with shorts + # that this report would otherwise never mention. + print( + f"rpmroute: WARNING: the {args.engine} engine does not check its copper for " + "clearance or shorts; run KiCad's DRC on the result, or route with " + "--engine exact (the default)", + file=sys.stderr, + ) + if args.output: with open(args.output, "w", encoding="utf-8") as f: f.write(ses_text) diff --git a/tests/test_cli.py b/tests/test_cli.py index cc64dc7..f0d129e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -71,13 +71,25 @@ def test_cli_every_engine_routes_a_fixture(engine, tmp_path): assert "(wire" in text -def test_cli_default_engine_is_grid(tmp_path): - """The default must stay grid — the drop-in JAR replacement behaviour.""" +def test_cli_default_engine_is_exact(tmp_path): + """The default is the engine that checks its copper: grid output can short + and say nothing (a user routing with no flags shipped 15 crossings).""" default = tmp_path / "default.ses" - grid = tmp_path / "grid.ses" + exact = tmp_path / "exact.ses" assert main([str(FIXTURE), "-do", str(default)]) == 0 - assert main([str(FIXTURE), "--engine", "grid", "-do", str(grid)]) == 0 - assert default.read_text() == grid.read_text() + assert main([str(FIXTURE), "--engine", "exact", "-do", str(exact)]) == 0 + assert default.read_text() == exact.read_text() + + +@pytest.mark.parametrize("engine", ["grid", "room"]) +def test_unchecked_engines_say_so(tmp_path, capsys, engine): + assert main([str(FIXTURE), "--engine", engine, "-do", str(tmp_path / "out.ses")]) == 0 + assert "does not check its copper" in capsys.readouterr().err + + +def test_the_exact_engine_does_not_warn(tmp_path, capsys): + assert main([str(FIXTURE), "-do", str(tmp_path / "out.ses")]) == 0 + assert "WARNING" not in capsys.readouterr().err def test_cli_room_pack_routes(tmp_path):