diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index 142d322..a96b823 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -10,7 +10,7 @@ use crate::{ use super::{ invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles}, - Autorouter, AutorouterError, + Autorouter, AutorouterError, AutorouterOptions, }; pub enum AutorouteStatus { @@ -32,6 +32,7 @@ impl TryInto<()> for AutorouteStatus { pub struct Autoroute { ratlines_iter: Box>>, + options: AutorouterOptions, route: Option, curr_ratline: Option>, } @@ -40,6 +41,7 @@ impl Autoroute { pub fn new( autorouter: &mut Autorouter, ratlines: impl IntoIterator> + 'static, + options: AutorouterOptions, ) -> Result { let mut ratlines_iter = Box::new(ratlines.into_iter()); @@ -52,8 +54,9 @@ impl Autoroute { let this = Self { ratlines_iter, - curr_ratline: Some(curr_ratline), + options, route: Some(router.route(source, target, 100.0)?), + curr_ratline: Some(curr_ratline), }; Ok(this) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 2bcfee0..8be84ee 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -1,4 +1,5 @@ use petgraph::graph::EdgeIndex; +use serde::{Deserialize, Serialize}; use spade::InsertionError; use thiserror::Error; @@ -24,6 +25,23 @@ use super::{ selection::{BandSelection, PinSelection}, }; +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct AutorouterOptions { + pub presort_by_pairwise_detours: bool, + //pub wrap_around_bands: bool, + //pub squeeze_under_bands: bool, +} + +impl AutorouterOptions { + pub fn new() -> Self { + Self { + presort_by_pairwise_detours: false, + //wrap_around_bands: true, + //squeeze_under_bands: true, + } + } +} + #[derive(Error, Debug, Clone)] pub enum AutorouterError { #[error("nothing to route")] @@ -51,15 +69,20 @@ impl Autorouter { Ok(Self { board, ratsnest }) } - pub fn autoroute(&mut self, selection: &PinSelection) -> Result { - self.autoroute_ratlines(self.selected_ratlines(selection)) + pub fn autoroute( + &mut self, + selection: &PinSelection, + options: AutorouterOptions, + ) -> Result { + self.autoroute_ratlines(self.selected_ratlines(selection), options) } pub(super) fn autoroute_ratlines( &mut self, ratlines: Vec>, + options: AutorouterOptions, ) -> Result { - Autoroute::new(self, ratlines) + Autoroute::new(self, ratlines, options) } pub fn undo_autoroute(&mut self, selection: &PinSelection) -> Result<(), AutorouterError> { @@ -106,6 +129,7 @@ impl Autorouter { pub fn compare_detours( &mut self, selection: &PinSelection, + options: AutorouterOptions, ) -> Result { let ratlines = self.selected_ratlines(selection); let ratline1 = *ratlines @@ -114,15 +138,16 @@ impl Autorouter { let ratline2 = *ratlines .get(1) .ok_or(AutorouterError::NeedExactlyTwoRatlines)?; - self.compare_detours_ratlines(ratline1, ratline2) + self.compare_detours_ratlines(ratline1, ratline2, options) } pub(super) fn compare_detours_ratlines( &mut self, ratline1: EdgeIndex, ratline2: EdgeIndex, + options: AutorouterOptions, ) -> Result { - CompareDetours::new(self, ratline1, ratline2) + CompareDetours::new(self, ratline1, ratline2, options) } pub fn measure_length( diff --git a/src/autorouter/compare_detours.rs b/src/autorouter/compare_detours.rs index a1c5ce3..0ba9ae0 100644 --- a/src/autorouter/compare_detours.rs +++ b/src/autorouter/compare_detours.rs @@ -12,7 +12,7 @@ use crate::{ use super::{ autoroute::{Autoroute, AutorouteStatus}, invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles}, - Autorouter, AutorouterError, + Autorouter, AutorouterError, AutorouterOptions, }; pub enum CompareDetoursStatus { @@ -47,10 +47,11 @@ impl CompareDetours { autorouter: &mut Autorouter, ratline1: EdgeIndex, ratline2: EdgeIndex, + options: AutorouterOptions, ) -> Result { Ok(Self { - autoroute: autorouter.autoroute_ratlines(vec![ratline1, ratline2])?, - next_autoroute: Some(autorouter.autoroute_ratlines(vec![ratline2, ratline1])?), + autoroute: autorouter.autoroute_ratlines(vec![ratline1, ratline2], options)?, + next_autoroute: Some(autorouter.autoroute_ratlines(vec![ratline2, ratline1], options)?), ratline1, ratline2, total_length1: 0.0, diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 20e3d1a..5331b29 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -22,7 +22,7 @@ use super::{ place_via::PlaceVia, remove_bands::RemoveBands, selection::{BandSelection, PinSelection}, - Autorouter, AutorouterError, + Autorouter, AutorouterError, AutorouterOptions, }; #[enum_dispatch] @@ -71,10 +71,10 @@ impl TryInto<()> for InvokerStatus { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Command { - Autoroute(PinSelection), + Autoroute(PinSelection, AutorouterOptions), PlaceVia(ViaWeight), RemoveBands(BandSelection), - CompareDetours(PinSelection), + CompareDetours(PinSelection, AutorouterOptions), MeasureLength(BandSelection), } @@ -254,19 +254,25 @@ impl Invoker { #[debug_requires(self.ongoing_command.is_none())] fn dispatch_command(&mut self, command: &Command) -> Result { match command { - Command::Autoroute(selection) => { + Command::Autoroute(selection, options) => { let mut ratlines = self.autorouter.selected_ratlines(selection); - ratlines.sort_unstable_by(|a, b| { - let mut compare_detours = - self.autorouter.compare_detours_ratlines(*a, *b).unwrap(); - if let Ok((al, bl)) = compare_detours.finish(&mut self.autorouter) { - PartialOrd::partial_cmp(&al, &bl).unwrap() - } else { - Ordering::Equal - } - }); + + if options.presort_by_pairwise_detours { + ratlines.sort_unstable_by(|a, b| { + let mut compare_detours = self + .autorouter + .compare_detours_ratlines(*a, *b, *options) + .unwrap(); + if let Ok((al, bl)) = compare_detours.finish(&mut self.autorouter) { + PartialOrd::partial_cmp(&al, &bl).unwrap() + } else { + Ordering::Equal + } + }); + } + Ok::(Execute::Autoroute( - self.autorouter.autoroute_ratlines(ratlines)?, + self.autorouter.autoroute_ratlines(ratlines, *options)?, )) } Command::PlaceVia(weight) => { @@ -275,8 +281,8 @@ impl Invoker { Command::RemoveBands(selection) => Ok::(Execute::RemoveBands( self.autorouter.remove_bands(selection)?, )), - Command::CompareDetours(selection) => Ok::( - Execute::CompareDetours(self.autorouter.compare_detours(selection)?), + Command::CompareDetours(selection, options) => Ok::( + Execute::CompareDetours(self.autorouter.compare_detours(selection, *options)?), ), Command::MeasureLength(selection) => Ok::( Execute::MeasureLength(self.autorouter.measure_length(selection)?), @@ -289,8 +295,8 @@ impl Invoker { let command = self.history.last_done()?; match command { - Command::Autoroute(ref selection) => { - self.autorouter.undo_autoroute(selection); + Command::Autoroute(ref selection, ..) => { + self.autorouter.undo_autoroute(selection)?; } Command::PlaceVia(weight) => { self.autorouter.undo_place_via(*weight); diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 58b7054..e14406f 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -5,8 +5,9 @@ use std::{ }; use topola::{ - autorouter::invoker::{ - Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus, + autorouter::{ + invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus}, + AutorouterOptions, }, specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata}, }; @@ -248,10 +249,12 @@ impl Top { ) { let selection = overlay.selection().clone(); overlay.clear_selection(); - maybe_execute - .insert(ExecuteWithStatus::new(invoker.execute_stepper( - Command::Autoroute(selection.pin_selection), - )?)); + maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper( + Command::Autoroute( + selection.pin_selection, + AutorouterOptions::new(), + ), + )?)); } } } else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) { @@ -304,7 +307,10 @@ impl Top { let selection = overlay.selection().clone(); overlay.clear_selection(); maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper( - Command::CompareDetours(selection.pin_selection), + Command::CompareDetours( + selection.pin_selection, + AutorouterOptions::new(), + ), )?)); } }