mirror of https://codeberg.org/topola/topola.git
egui,autorouter,router: add option to toggle wrapping around bands
This commit is contained in:
parent
4d0c38664e
commit
0b7e5f1b9b
|
|
@ -18,6 +18,7 @@ action-undo = Undo
|
||||||
action-redo = Redo
|
action-redo = Redo
|
||||||
|
|
||||||
presort-by-pairwise-detours = Presort by pairwise detours
|
presort-by-pairwise-detours = Presort by pairwise detours
|
||||||
|
wrap-around-bands = Wrap around bands
|
||||||
|
|
||||||
show-ratsnest = Show Ratsnest
|
show-ratsnest = Show Ratsnest
|
||||||
show-navmesh = Show Navmesh
|
show-navmesh = Show Navmesh
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl Autoroute {
|
||||||
};
|
};
|
||||||
|
|
||||||
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
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 {
|
let this = Self {
|
||||||
ratlines_iter,
|
ratlines_iter,
|
||||||
|
|
@ -77,7 +77,8 @@ impl<M: AccessMesadata> Step<Autorouter<M>, AutorouteStatus, AutorouterError, ()
|
||||||
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
||||||
|
|
||||||
let band_termseg = {
|
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 {
|
let RouterStatus::Finished(band_termseg) = route.step(&mut router)? else {
|
||||||
return Ok(AutorouteStatus::Running);
|
return Ok(AutorouteStatus::Running);
|
||||||
|
|
@ -102,7 +103,8 @@ impl<M: AccessMesadata> Step<Autorouter<M>, AutorouteStatus, AutorouterError, ()
|
||||||
|
|
||||||
if let Some(new_ratline) = self.ratlines_iter.next() {
|
if let Some(new_ratline) = self.ratlines_iter.next() {
|
||||||
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
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.curr_ratline = Some(new_ratline);
|
||||||
self.route = Some(router.route(source, target, 100.0)?);
|
self.route = Some(router.route(source, target, 100.0)?);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
Infringement,
|
Infringement,
|
||||||
},
|
},
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
router::{navmesh::NavmeshError, RouterError},
|
router::{navmesh::NavmeshError, RouterError, RouterOptions},
|
||||||
triangulation::GetTrianvertexNodeIndex,
|
triangulation::GetTrianvertexNodeIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,16 +28,14 @@ use super::{
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
pub struct AutorouterOptions {
|
pub struct AutorouterOptions {
|
||||||
pub presort_by_pairwise_detours: bool,
|
pub presort_by_pairwise_detours: bool,
|
||||||
//pub wrap_around_bands: bool,
|
pub router_options: RouterOptions,
|
||||||
//pub squeeze_under_bands: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AutorouterOptions {
|
impl AutorouterOptions {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
presort_by_pairwise_detours: false,
|
presort_by_pairwise_detours: false,
|
||||||
//wrap_around_bands: true,
|
router_options: RouterOptions::new(),
|
||||||
//squeeze_under_bands: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,10 @@ impl Top {
|
||||||
&mut self.autorouter_options.presort_by_pairwise_detours,
|
&mut self.autorouter_options.presort_by_pairwise_detours,
|
||||||
tr.text("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();
|
ui.separator();
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ use crate::{
|
||||||
triangulation::{GetTrianvertexNodeIndex, Triangulation},
|
triangulation::{GetTrianvertexNodeIndex, Triangulation},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::RouterOptions;
|
||||||
|
|
||||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct NavvertexIndex(NodeIndex<usize>);
|
pub struct NavvertexIndex(NodeIndex<usize>);
|
||||||
|
|
||||||
|
|
@ -129,6 +131,7 @@ impl Navmesh {
|
||||||
layout: &Layout<impl AccessRules>,
|
layout: &Layout<impl AccessRules>,
|
||||||
origin: FixedDotIndex,
|
origin: FixedDotIndex,
|
||||||
destination: FixedDotIndex,
|
destination: FixedDotIndex,
|
||||||
|
options: RouterOptions,
|
||||||
) -> Result<Self, NavmeshError> {
|
) -> Result<Self, NavmeshError> {
|
||||||
let mut triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()> =
|
let mut triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()> =
|
||||||
Triangulation::new(layout.drawing().geometry().graph().node_bound());
|
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(
|
fn new_from_triangulation(
|
||||||
|
|
@ -171,6 +174,7 @@ impl Navmesh {
|
||||||
triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()>,
|
triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()>,
|
||||||
origin: FixedDotIndex,
|
origin: FixedDotIndex,
|
||||||
destination: FixedDotIndex,
|
destination: FixedDotIndex,
|
||||||
|
options: RouterOptions,
|
||||||
) -> Result<Self, NavmeshError> {
|
) -> Result<Self, NavmeshError> {
|
||||||
let mut graph: UnGraph<NavvertexWeight, (), usize> = UnGraph::default();
|
let mut graph: UnGraph<NavvertexWeight, (), usize> = UnGraph::default();
|
||||||
let mut origin_navvertex = None;
|
let mut origin_navvertex = None;
|
||||||
|
|
@ -205,17 +209,19 @@ impl Navmesh {
|
||||||
trianvertex.into(),
|
trianvertex.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut gear =
|
if options.wrap_around_bands {
|
||||||
Into::<GearIndex>::into(Into::<BinavvertexNodeIndex>::into(trianvertex));
|
let mut gear =
|
||||||
|
Into::<GearIndex>::into(Into::<BinavvertexNodeIndex>::into(trianvertex));
|
||||||
|
|
||||||
while let Some(bend) = gear.ref_(layout.drawing()).next_gear() {
|
while let Some(bend) = gear.ref_(layout.drawing()).next_gear() {
|
||||||
Self::add_node_to_graph_and_map_as_binavvertex(
|
Self::add_node_to_graph_and_map_as_binavvertex(
|
||||||
&mut graph,
|
&mut graph,
|
||||||
&mut map,
|
&mut map,
|
||||||
trianvertex,
|
trianvertex,
|
||||||
bend.into(),
|
bend.into(),
|
||||||
);
|
);
|
||||||
gear = bend.into();
|
gear = bend.into();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl Route {
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Self, RouterError> {
|
) -> Result<Self, RouterError> {
|
||||||
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))
|
Ok(Self::new_from_navmesh(router, navmesh, width))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::convert::Infallible;
|
||||||
|
|
||||||
use geo::EuclideanDistance;
|
use geo::EuclideanDistance;
|
||||||
use petgraph::{data::DataMap, visit::EdgeRef};
|
use petgraph::{data::DataMap, visit::EdgeRef};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -32,6 +33,20 @@ use super::{
|
||||||
tracer::{Tracer, TracerException},
|
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)]
|
#[derive(Error, Debug, Clone)]
|
||||||
#[error("routing failed")]
|
#[error("routing failed")]
|
||||||
pub enum RouterError {
|
pub enum RouterError {
|
||||||
|
|
@ -182,11 +197,12 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Router<'a, R: AccessRules> {
|
pub struct Router<'a, R: AccessRules> {
|
||||||
layout: &'a mut Layout<R>,
|
layout: &'a mut Layout<R>,
|
||||||
|
options: RouterOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: AccessRules> Router<'a, R> {
|
impl<'a, R: AccessRules> Router<'a, R> {
|
||||||
pub fn new(layout: &'a mut Layout<R>) -> Self {
|
pub fn new(layout: &'a mut Layout<R>, options: RouterOptions) -> Self {
|
||||||
Self { layout }
|
Self { layout, options }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn route(
|
pub fn route(
|
||||||
|
|
@ -205,4 +221,8 @@ impl<'a, R: AccessRules> Router<'a, R> {
|
||||||
pub fn layout(&self) -> &Layout<R> {
|
pub fn layout(&self) -> &Layout<R> {
|
||||||
&self.layout
|
&self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn options(&self) -> RouterOptions {
|
||||||
|
self.options
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue