From 09c98f2d1736cb402c2f7f9b8da13b74ecbcd82d Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 19 Jul 2025 13:06:02 +0200 Subject: [PATCH] feat(autorouter/autoroute): Add option to toggle permutation Updated with the following command in Fish shell: ``` for f in tests/**.cmd; jq ".done?.[].Autoroute[1].permutate |= false" $f | sponge $f; end ``` --- crates/topola-cli/src/main.rs | 1 + crates/topola-egui/src/actions.rs | 1 + crates/topola-egui/src/menu_bar.rs | 14 ++++++--- locales/en-US/main.ftl | 2 ++ src/autorouter/autoroute.rs | 7 ++++- src/autorouter/autorouter.rs | 1 + .../0603_breakout/autoroute_all.cmd | 6 ++-- .../autoroute_signals.cmd | 12 +++++--- .../route_all.cmd | 5 ++-- .../autoroute_all.cmd | 3 +- .../autoroute_all_in_an_order.cmd | 29 ++++++++++++------- .../autoroute_all.cmd | 6 ++-- 12 files changed, 61 insertions(+), 26 deletions(-) diff --git a/crates/topola-cli/src/main.rs b/crates/topola-cli/src/main.rs index 6afd676..2891b82 100644 --- a/crates/topola-cli/src/main.rs +++ b/crates/topola-cli/src/main.rs @@ -40,6 +40,7 @@ fn main() -> Result<(), std::io::Error> { PinSelection::new_select_layer(&board, 0), AutorouterOptions { presort_by: PresortBy::RatlineIntersectionCountAndLength, + permutate: true, router_options: RouterOptions { wrap_around_bands: true, squeeze_through_under_bends: false, diff --git a/crates/topola-egui/src/actions.rs b/crates/topola-egui/src/actions.rs index 724508e..a96c76e 100644 --- a/crates/topola-egui/src/actions.rs +++ b/crates/topola-egui/src/actions.rs @@ -336,6 +336,7 @@ impl RouteActions { ui.selectable_value(&mut autorouter_options.presort_by, PresortBy::RatlineIntersectionCountAndLength, tr.text("tr-menu-route-options-presort-by-ratline-intersection-count-and-length")); ui.selectable_value(&mut autorouter_options.presort_by, PresortBy::PairwiseDetours, tr.text("tr-menu-route-options-presort-by-pairwise-detours")); }); + ui.checkbox(&mut autorouter_options.permutate, tr.text("tr-menu-route-options-permutate")); ui.checkbox( &mut autorouter_options .router_options diff --git a/crates/topola-egui/src/menu_bar.rs b/crates/topola-egui/src/menu_bar.rs index c949199..ac7b142 100644 --- a/crates/topola-egui/src/menu_bar.rs +++ b/crates/topola-egui/src/menu_bar.rs @@ -44,6 +44,7 @@ impl MenuBar { Self { autorouter_options: AutorouterOptions { presort_by: PresortBy::RatlineIntersectionCountAndLength, + permutate: true, router_options: RouterOptions { routed_band_width: 100.0, wrap_around_bands: true, @@ -318,7 +319,6 @@ impl MenuBar { error_dialog.push_error("tr-module-invoker", format!("{}", err)); } } - let opts = self.autorouter_options; if actions.edit.remove_bands.consume_key_triggered(ctx, ui) { schedule(error_dialog, workspace, |selection| { Command::RemoveBands(selection.band_selection) @@ -340,13 +340,16 @@ impl MenuBar { selection: selection.pin_selection, allowed_edges: BTreeSet::new(), active_layer, - routed_band_width: opts.router_options.routed_band_width, + routed_band_width: self + .autorouter_options + .router_options + .routed_band_width, } }); } } else if actions.route.autoroute.consume_key_triggered(ctx, ui) { schedule(error_dialog, workspace, |selection| { - Command::Autoroute(selection.pin_selection, opts) + Command::Autoroute(selection.pin_selection, self.autorouter_options) }); } else if actions .inspect @@ -354,7 +357,10 @@ impl MenuBar { .consume_key_triggered(ctx, ui) { schedule(error_dialog, workspace, |selection| { - Command::CompareDetours(selection.pin_selection, opts) + Command::CompareDetours( + selection.pin_selection, + self.autorouter_options, + ) }); } else if actions .inspect diff --git a/locales/en-US/main.ftl b/locales/en-US/main.ftl index 084f42a..68d4634 100644 --- a/locales/en-US/main.ftl +++ b/locales/en-US/main.ftl @@ -51,6 +51,8 @@ tr-menu-route-options-presort-by = Presort by tr-menu-route-options-presort-by-ratline-intersection-count-and-length = Intersection Count and Length tr-menu-route-options-presort-by-pairwise-detours = Pairwise Detours +tr-menu-route-options-permutate = Permutate + ## Continuously applied, so use imperfective aspect if possible, e.g. in Polish ## it should be "przeciskaj pod taśmami" instead of "przeciśnij pod taśmami". diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index 2203bb6..dc6dfa7 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -234,6 +234,7 @@ impl AutorouteExecutionPermutator { Ok(Self { stepper: AutorouteExecutionStepper::new(autorouter, ratlines.clone(), options)?, + // Note: I assume here that the first permutation is the same as the original order. permutations_iter: ratlines.into_iter().permutations(ratlines_len), options, }) @@ -251,7 +252,11 @@ impl Step, Option, AutorouteContinue ) -> Result, AutorouteContinueStatus>, AutorouterError> { match self.stepper.step(autorouter) { Ok(ok) => Ok(ok), - Err(..) => { + Err(err) => { + if !self.options.permutate { + return Err(err); + } + self.stepper.abort(autorouter); let Some(new_permutation) = self.permutations_iter.next() else { diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index ebfa63a..8c47ead 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -42,6 +42,7 @@ pub enum PresortBy { #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct AutorouterOptions { pub presort_by: PresortBy, + pub permutate: bool, pub router_options: RouterOptions, } diff --git a/tests/single_layer/0603_breakout/autoroute_all.cmd b/tests/single_layer/0603_breakout/autoroute_all.cmd index bd520b4..0caec98 100644 --- a/tests/single_layer/0603_breakout/autoroute_all.cmd +++ b/tests/single_layer/0603_breakout/autoroute_all.cmd @@ -18,7 +18,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }, @@ -40,7 +41,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] } diff --git a/tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd b/tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd index 13e5d84..61e9d44 100644 --- a/tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd +++ b/tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd @@ -54,7 +54,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }, @@ -112,7 +113,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }, @@ -170,7 +172,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }, @@ -228,7 +231,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] } diff --git a/tests/single_layer/smd_non_rectangular_buck_converter/route_all.cmd b/tests/single_layer/smd_non_rectangular_buck_converter/route_all.cmd index dd10ae1..40fb1ec 100644 --- a/tests/single_layer/smd_non_rectangular_buck_converter/route_all.cmd +++ b/tests/single_layer/smd_non_rectangular_buck_converter/route_all.cmd @@ -42,10 +42,11 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] } ], "undone": [] -} \ No newline at end of file +} diff --git a/tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd b/tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd index 46877e6..c2c05bf 100644 --- a/tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd +++ b/tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd @@ -34,7 +34,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] } diff --git a/tests/single_layer/tht_de9_to_tht_de9/autoroute_all_in_an_order.cmd b/tests/single_layer/tht_de9_to_tht_de9/autoroute_all_in_an_order.cmd index 80d62e3..f8e3d44 100644 --- a/tests/single_layer/tht_de9_to_tht_de9/autoroute_all_in_an_order.cmd +++ b/tests/single_layer/tht_de9_to_tht_de9/autoroute_all_in_an_order.cmd @@ -18,7 +18,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -40,7 +41,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -62,7 +64,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -84,7 +87,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -106,7 +110,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -128,7 +133,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -150,7 +156,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -172,7 +179,8 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] }, @@ -194,10 +202,11 @@ "routed_band_width": 100.0, "wrap_around_bands": true, "squeeze_through_under_bends": true - } + }, + "permutate": false } ] } ], "undone": [] -} \ No newline at end of file +} diff --git a/tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd b/tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd index 68f9a67..09e5625 100644 --- a/tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd +++ b/tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd @@ -54,7 +54,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }, @@ -76,7 +77,8 @@ "wrap_around_bands": true, "squeeze_through_under_bends": true, "routed_band_width": 100.0 - } + }, + "permutate": false } ] }