autorouter: accessibly store pin-pairs between which routed bands are

This commit is contained in:
Mikolaj Wielgus 2024-06-04 22:15:01 +02:00
parent 352a96f895
commit 86d2555b36
6 changed files with 71 additions and 23 deletions

View File

@ -95,12 +95,11 @@ impl Autoroute {
(None, None)
};
let mut router = Router::new_from_navmesh(
autorouter.board.layout_mut(),
match autorouter.board.route_band(
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
);
match router.route_band(100.0, observer) {
100.0,
observer,
) {
Ok(band) => {
autorouter
.ratsnest

View File

@ -2,6 +2,7 @@ use std::collections::HashMap;
use crate::{
drawing::{
band::BandIndex,
dot::{FixedDotIndex, FixedDotWeight},
graph::{GetLayer, GetMaybeNet, PrimitiveIndex},
rules::RulesTrait,
@ -15,6 +16,7 @@ use crate::{
Layout,
},
math::Circle,
router::{navmesh::Navmesh, Router, RouterError, RouterObserverTrait},
};
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
@ -25,6 +27,7 @@ pub struct Board<R: RulesTrait> {
node_to_pinname: HashMap<NodeIndex, String>,
layer_to_layername: HashMap<u64, String>,
net_to_netname: HashMap<usize, String>,
pinname_pair_to_band: HashMap<(String, String), BandIndex>,
}
impl<R: RulesTrait> Board<R> {
@ -34,6 +37,7 @@ impl<R: RulesTrait> Board<R> {
node_to_pinname: HashMap::new(),
layer_to_layername: HashMap::new(),
net_to_netname: HashMap::new(),
pinname_pair_to_band: HashMap::new(),
}
}
@ -116,6 +120,32 @@ impl<R: RulesTrait> Board<R> {
zone
}
pub fn route_band(
&mut self,
navmesh: Navmesh,
width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<BandIndex, RouterError> {
let source_pinname = self
.node_pinname(GenericNode::Primitive(navmesh.source().into()))
.unwrap()
.to_string();
let target_pinname = self
.node_pinname(GenericNode::Primitive(navmesh.target().into()))
.unwrap()
.to_string();
let mut router = Router::new_from_navmesh(self.layout_mut(), navmesh);
let result = router.route_band(100.0, observer);
if let Ok(band) = result {
self.pinname_pair_to_band
.insert((source_pinname, target_pinname), band);
}
result
}
pub fn bename_layer(&mut self, layer: u64, layername: String) {
self.layer_to_layername.insert(layer, layername);
}
@ -155,6 +185,22 @@ impl<R: RulesTrait> Board<R> {
self.net_to_netname.get(&net)
}
pub fn band_between_pins(&self, pinname1: &String, pinname2: &String) -> Option<BandIndex> {
if let Some(band) = self
.pinname_pair_to_band
.get(&(pinname1.to_string(), pinname2.to_string()))
{
Some(*band)
} else if let Some(band) = self
.pinname_pair_to_band
.get(&(pinname2.to_string(), pinname1.to_string()))
{
Some(*band)
} else {
None
}
}
pub fn layout(&self) -> &Layout<R> {
&self.layout
}

View File

@ -255,8 +255,8 @@ impl eframe::App for App {
let mut execute = invoker.execute_walk(Command::Autoroute(selection));
if let Execute::Autoroute(ref mut autoroute) = execute {
let from = autoroute.navmesh().as_ref().unwrap().from();
let to = autoroute.navmesh().as_ref().unwrap().to();
let from = autoroute.navmesh().as_ref().unwrap().source();
let to = autoroute.navmesh().as_ref().unwrap().target();
{
let mut shared_data = shared_data_arc_mutex.lock().unwrap();

View File

@ -1,6 +1,6 @@
use crate::drawing::seg::{LoneLooseSegIndex, SeqLooseSegIndex};
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
pub enum BandIndex {
Straight(LoneLooseSegIndex),
Bended(SeqLooseSegIndex),

View File

@ -82,8 +82,8 @@ impl HasPosition for TrianvertexWeight {
pub struct Navmesh {
triangulation: Triangulation<TrianvertexIndex, TrianvertexWeight, ()>,
navvertex_to_trianvertex: Vec<Option<TrianvertexIndex>>,
from: FixedDotIndex,
to: FixedDotIndex,
source: FixedDotIndex,
target: FixedDotIndex,
}
#[derive(Error, Debug, Clone)]
@ -95,26 +95,29 @@ pub enum NavmeshError {
impl Navmesh {
pub fn new(
layout: &Layout<impl RulesTrait>,
from: FixedDotIndex,
to: FixedDotIndex,
source: FixedDotIndex,
target: FixedDotIndex,
) -> Result<Self, NavmeshError> {
let mut this = Self {
triangulation: Triangulation::new(layout.drawing().geometry().graph().node_bound()),
navvertex_to_trianvertex: Vec::new(),
from,
to,
source,
target,
};
this.navvertex_to_trianvertex
.resize(layout.drawing().geometry().graph().node_bound(), None);
let layer = layout.drawing().primitive(from).layer();
let maybe_net = layout.drawing().primitive(from).maybe_net();
let layer = layout.drawing().primitive(source).layer();
let maybe_net = layout.drawing().primitive(source).maybe_net();
for node in layout.drawing().layer_primitive_nodes(layer) {
let primitive = node.primitive(layout.drawing());
if let Some(primitive_net) = primitive.maybe_net() {
if node == from.into() || node == to.into() || Some(primitive_net) != maybe_net {
if node == source.into()
|| node == target.into()
|| Some(primitive_net) != maybe_net
{
match node {
PrimitiveIndex::FixedDot(dot) => {
this.triangulation.add_vertex(TrianvertexWeight {
@ -164,12 +167,12 @@ impl Navmesh {
}
}
pub fn from(&self) -> FixedDotIndex {
self.from
pub fn source(&self) -> FixedDotIndex {
self.source
}
pub fn to(&self) -> FixedDotIndex {
self.to
pub fn target(&self) -> FixedDotIndex {
self.target
}
}

View File

@ -169,8 +169,8 @@ impl<'a, R: RulesTrait> Router<'a, R> {
width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<BandIndex, RouterError> {
let from = self.navmesh.from();
let to = self.navmesh.to();
let from = self.navmesh.source();
let to = self.navmesh.target();
let mut tracer = Tracer::new(self.layout);
let trace = tracer.start(from, width);