diff --git a/locales/en-US/main.ftl b/locales/en-US/main.ftl index 1d6d48d..9ff9010 100644 --- a/locales/en-US/main.ftl +++ b/locales/en-US/main.ftl @@ -18,6 +18,7 @@ action-undo = Undo action-redo = Redo presort-by-pairwise-detours = Presort by pairwise detours +wrap-around-bands = Wrap around bands show-ratsnest = Show Ratsnest show-navmesh = Show Navmesh diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index a96b823..123dc5a 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -50,7 +50,7 @@ impl Autoroute { }; let (source, target) = autorouter.ratline_endpoints(curr_ratline); - let mut router = Router::new(autorouter.board.layout_mut()); + let mut router = Router::new(autorouter.board.layout_mut(), options.router_options); let this = Self { ratlines_iter, @@ -77,7 +77,8 @@ impl Step, AutorouteStatus, AutorouterError, () let (source, target) = autorouter.ratline_endpoints(curr_ratline); let band_termseg = { - let mut router = Router::new(autorouter.board.layout_mut()); + let mut router = + Router::new(autorouter.board.layout_mut(), self.options.router_options); let RouterStatus::Finished(band_termseg) = route.step(&mut router)? else { return Ok(AutorouteStatus::Running); @@ -102,7 +103,8 @@ impl Step, AutorouteStatus, AutorouterError, () if let Some(new_ratline) = self.ratlines_iter.next() { let (source, target) = autorouter.ratline_endpoints(new_ratline); - let mut router = Router::new(autorouter.board.layout_mut()); + let mut router = + Router::new(autorouter.board.layout_mut(), self.options.router_options); self.curr_ratline = Some(new_ratline); self.route = Some(router.route(source, target, 100.0)?); diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 8be84ee..ae42d6c 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -11,7 +11,7 @@ use crate::{ Infringement, }, layout::via::ViaWeight, - router::{navmesh::NavmeshError, RouterError}, + router::{navmesh::NavmeshError, RouterError, RouterOptions}, triangulation::GetTrianvertexNodeIndex, }; @@ -28,16 +28,14 @@ use super::{ #[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, + pub router_options: RouterOptions, } impl AutorouterOptions { pub fn new() -> Self { Self { presort_by_pairwise_detours: false, - //wrap_around_bands: true, - //squeeze_under_bands: true, + router_options: RouterOptions::new(), } } } diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 896758c..e698eb9 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -142,6 +142,10 @@ impl Top { &mut self.autorouter_options.presort_by_pairwise_detours, tr.text("presort-by-pairwise-detours"), ); + ui.checkbox( + &mut self.autorouter_options.router_options.wrap_around_bands, + tr.text("wrap-around-bands"), + ); }); ui.separator(); diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index 3c77ced..b4e3955 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -31,6 +31,8 @@ use crate::{ triangulation::{GetTrianvertexNodeIndex, Triangulation}, }; +use super::RouterOptions; + #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] pub struct NavvertexIndex(NodeIndex); @@ -129,6 +131,7 @@ impl Navmesh { layout: &Layout, origin: FixedDotIndex, destination: FixedDotIndex, + options: RouterOptions, ) -> Result { let mut triangulation: Triangulation = Triangulation::new(layout.drawing().geometry().graph().node_bound()); @@ -163,7 +166,7 @@ impl Navmesh { } } - Self::new_from_triangulation(layout, triangulation, origin, destination) + Self::new_from_triangulation(layout, triangulation, origin, destination, options) } fn new_from_triangulation( @@ -171,6 +174,7 @@ impl Navmesh { triangulation: Triangulation, origin: FixedDotIndex, destination: FixedDotIndex, + options: RouterOptions, ) -> Result { let mut graph: UnGraph = UnGraph::default(); let mut origin_navvertex = None; @@ -205,17 +209,19 @@ impl Navmesh { trianvertex.into(), ); - let mut gear = - Into::::into(Into::::into(trianvertex)); + if options.wrap_around_bands { + let mut gear = + Into::::into(Into::::into(trianvertex)); - while let Some(bend) = gear.ref_(layout.drawing()).next_gear() { - Self::add_node_to_graph_and_map_as_binavvertex( - &mut graph, - &mut map, - trianvertex, - bend.into(), - ); - gear = bend.into(); + while let Some(bend) = gear.ref_(layout.drawing()).next_gear() { + Self::add_node_to_graph_and_map_as_binavvertex( + &mut graph, + &mut map, + trianvertex, + bend.into(), + ); + gear = bend.into(); + } } }; } diff --git a/src/router/route.rs b/src/router/route.rs index 7ae2e3f..917cf2f 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -27,7 +27,7 @@ impl Route { to: FixedDotIndex, width: f64, ) -> Result { - let navmesh = Navmesh::new(router.layout(), from, to)?; + let navmesh = Navmesh::new(router.layout(), from, to, router.options())?; Ok(Self::new_from_navmesh(router, navmesh, width)) } diff --git a/src/router/router.rs b/src/router/router.rs index ce0ba0a..9c1afed 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -2,6 +2,7 @@ use std::convert::Infallible; use geo::EuclideanDistance; use petgraph::{data::DataMap, visit::EdgeRef}; +use serde::{Deserialize, Serialize}; use thiserror::Error; use crate::{ @@ -32,6 +33,20 @@ use super::{ tracer::{Tracer, TracerException}, }; +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct RouterOptions { + pub wrap_around_bands: bool, + //pub squeeze_under_bands: bool, +} + +impl RouterOptions { + pub fn new() -> Self { + Self { + wrap_around_bands: true, + } + } +} + #[derive(Error, Debug, Clone)] #[error("routing failed")] pub enum RouterError { @@ -182,11 +197,12 @@ impl<'a, R: AccessRules> AstarStrategy #[derive(Debug)] pub struct Router<'a, R: AccessRules> { layout: &'a mut Layout, + options: RouterOptions, } impl<'a, R: AccessRules> Router<'a, R> { - pub fn new(layout: &'a mut Layout) -> Self { - Self { layout } + pub fn new(layout: &'a mut Layout, options: RouterOptions) -> Self { + Self { layout, options } } pub fn route( @@ -205,4 +221,8 @@ impl<'a, R: AccessRules> Router<'a, R> { pub fn layout(&self) -> &Layout { &self.layout } + + pub fn options(&self) -> RouterOptions { + self.options + } }