mirror of https://codeberg.org/topola/topola.git
autorouter: autoroute only selected
This commit is contained in:
parent
a6fb1157e3
commit
f893f73cd8
|
|
@ -1,11 +1,12 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
iter::Peekable,
|
iter::Peekable,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::{
|
use petgraph::{
|
||||||
graph::{EdgeIndex, EdgeIndices, NodeIndex},
|
graph::{EdgeIndex, EdgeIndices},
|
||||||
visit::{EdgeRef, IntoEdgeReferences},
|
visit::{EdgeRef, IntoEdgeReferences},
|
||||||
};
|
};
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
|
|
@ -17,22 +18,24 @@ use crate::{
|
||||||
graph::{GetLayer, GetMaybeNet},
|
graph::{GetLayer, GetMaybeNet},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
},
|
},
|
||||||
layout::{connectivity::BandIndex, Layout},
|
layout::{connectivity::BandIndex, Layout, NodeIndex},
|
||||||
router::{navmesh::Navmesh, Router, RouterObserverTrait, RoutingError},
|
router::{navmesh::Navmesh, Router, RouterObserverTrait, RoutingError},
|
||||||
triangulation::GetVertexIndex,
|
triangulation::GetVertexIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Autoroute {
|
pub struct Autoroute {
|
||||||
edge_indices: EdgeIndices<usize>,
|
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
||||||
navmesh: Option<Navmesh>, // Useful for debugging.
|
navmesh: Option<Navmesh>, // Useful for debugging.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Autoroute {
|
impl Autoroute {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut edge_indices: EdgeIndices<usize>,
|
ratlines: impl IntoIterator<Item = EdgeIndex<usize>> + 'static,
|
||||||
autorouter: &mut Autorouter<impl RulesTrait>,
|
autorouter: &mut Autorouter<impl RulesTrait>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let Some(cur_edge) = edge_indices.next() else {
|
let mut ratlines_iter = Box::new(ratlines.into_iter());
|
||||||
|
|
||||||
|
let Some(cur_edge) = ratlines_iter.next() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,7 +44,7 @@ impl Autoroute {
|
||||||
let navmesh = Some(Navmesh::new(&layout, from, to).ok()?);
|
let navmesh = Some(Navmesh::new(&layout, from, to).ok()?);
|
||||||
|
|
||||||
let this = Self {
|
let this = Self {
|
||||||
edge_indices,
|
ratlines_iter,
|
||||||
navmesh,
|
navmesh,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,7 +56,7 @@ impl Autoroute {
|
||||||
autorouter: &mut Autorouter<R>,
|
autorouter: &mut Autorouter<R>,
|
||||||
observer: &mut impl RouterObserverTrait<R>,
|
observer: &mut impl RouterObserverTrait<R>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let new_navmesh = if let Some(cur_edge) = self.edge_indices.next() {
|
let new_navmesh = if let Some(cur_edge) = self.ratlines_iter.next() {
|
||||||
let (from, to) = Self::edge_from_to(autorouter, cur_edge);
|
let (from, to) = Self::edge_from_to(autorouter, cur_edge);
|
||||||
|
|
||||||
let layout = autorouter.layout.lock().unwrap();
|
let layout = autorouter.layout.lock().unwrap();
|
||||||
|
|
@ -119,16 +122,44 @@ impl<R: RulesTrait> Autorouter<R> {
|
||||||
Ok(Self { layout, ratsnest })
|
Ok(Self { layout, ratsnest })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoroute(&mut self, layer: u64, observer: &mut impl RouterObserverTrait<R>) {
|
pub fn autoroute(
|
||||||
if let Some(mut autoroute) = self.autoroute_walk() {
|
&mut self,
|
||||||
|
selection: &HashSet<NodeIndex>,
|
||||||
|
observer: &mut impl RouterObserverTrait<R>,
|
||||||
|
) {
|
||||||
|
if let Some(mut autoroute) = self.autoroute_walk(selection) {
|
||||||
while autoroute.next(self, observer) {
|
while autoroute.next(self, observer) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoroute_walk(&mut self) -> Option<Autoroute> {
|
pub fn autoroute_walk(&mut self, selection: &HashSet<NodeIndex>) -> Option<Autoroute> {
|
||||||
Autoroute::new(self.ratsnest.graph().edge_indices(), self)
|
Autoroute::new(
|
||||||
|
self.ratsnest
|
||||||
|
.graph()
|
||||||
|
.edge_indices()
|
||||||
|
.filter(|edge| {
|
||||||
|
let (from, to) = self.ratsnest.graph().edge_endpoints(*edge).unwrap();
|
||||||
|
|
||||||
|
let from_vertex = self
|
||||||
|
.ratsnest
|
||||||
|
.graph()
|
||||||
|
.node_weight(from)
|
||||||
|
.unwrap()
|
||||||
|
.vertex_index();
|
||||||
|
let to_vertex = self
|
||||||
|
.ratsnest
|
||||||
|
.graph()
|
||||||
|
.node_weight(to)
|
||||||
|
.unwrap()
|
||||||
|
.vertex_index();
|
||||||
|
|
||||||
|
selection.contains(&from_vertex.into()) && selection.contains(&to_vertex.into())
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
self,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> &Arc<Mutex<Layout<R>>> {
|
pub fn layout(&self) -> &Arc<Mutex<Layout<R>>> {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,15 @@ pub enum RatsnestVertexIndex {
|
||||||
Zone(GenericIndex<ZoneWeight>),
|
Zone(GenericIndex<ZoneWeight>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RatsnestVertexIndex> for crate::layout::NodeIndex {
|
||||||
|
fn from(vertex: RatsnestVertexIndex) -> crate::layout::NodeIndex {
|
||||||
|
match vertex {
|
||||||
|
RatsnestVertexIndex::FixedDot(dot) => crate::layout::NodeIndex::Primitive(dot.into()),
|
||||||
|
RatsnestVertexIndex::Zone(zone) => crate::layout::NodeIndex::Compound(zone.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct VertexWeight {
|
pub struct VertexWeight {
|
||||||
vertex: RatsnestVertexIndex,
|
vertex: RatsnestVertexIndex,
|
||||||
|
|
|
||||||
|
|
@ -196,13 +196,15 @@ impl eframe::App for App {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if ui.button("Autoroute").clicked() {
|
if ui.button("Autoroute").clicked() {
|
||||||
if let Some(layout_arc_mutex) = &self.layout {
|
if let (Some(layout_arc_mutex), Some(overlay)) = (&self.layout, &self.overlay) {
|
||||||
let layout = layout_arc_mutex.clone();
|
let layout = layout_arc_mutex.clone();
|
||||||
let shared_data_arc_mutex = self.shared_data.clone();
|
let shared_data_arc_mutex = self.shared_data.clone();
|
||||||
|
let selection = overlay.selection().clone();
|
||||||
|
|
||||||
execute(async move {
|
execute(async move {
|
||||||
let mut autorouter = Autorouter::new(layout).unwrap();
|
let mut autorouter = Autorouter::new(layout).unwrap();
|
||||||
if let Some(mut autoroute) = autorouter.autoroute_walk() {
|
|
||||||
|
if let Some(mut autoroute) = autorouter.autoroute_walk(&selection) {
|
||||||
let from = autoroute.navmesh().as_ref().unwrap().from();
|
let from = autoroute.navmesh().as_ref().unwrap().from();
|
||||||
let to = autoroute.navmesh().as_ref().unwrap().to();
|
let to = autoroute.navmesh().as_ref().unwrap().to();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue