mirror of https://codeberg.org/topola/topola.git
autorouter: accessibly store pin-pairs between which routed bands are
This commit is contained in:
parent
352a96f895
commit
86d2555b36
|
|
@ -95,12 +95,11 @@ impl Autoroute {
|
||||||
(None, None)
|
(None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut router = Router::new_from_navmesh(
|
match autorouter.board.route_band(
|
||||||
autorouter.board.layout_mut(),
|
|
||||||
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
|
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
|
||||||
);
|
100.0,
|
||||||
|
observer,
|
||||||
match router.route_band(100.0, observer) {
|
) {
|
||||||
Ok(band) => {
|
Ok(band) => {
|
||||||
autorouter
|
autorouter
|
||||||
.ratsnest
|
.ratsnest
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
|
band::BandIndex,
|
||||||
dot::{FixedDotIndex, FixedDotWeight},
|
dot::{FixedDotIndex, FixedDotWeight},
|
||||||
graph::{GetLayer, GetMaybeNet, PrimitiveIndex},
|
graph::{GetLayer, GetMaybeNet, PrimitiveIndex},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
|
|
@ -15,6 +16,7 @@ use crate::{
|
||||||
Layout,
|
Layout,
|
||||||
},
|
},
|
||||||
math::Circle,
|
math::Circle,
|
||||||
|
router::{navmesh::Navmesh, Router, RouterError, RouterObserverTrait},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
|
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
|
||||||
|
|
@ -25,6 +27,7 @@ pub struct Board<R: RulesTrait> {
|
||||||
node_to_pinname: HashMap<NodeIndex, String>,
|
node_to_pinname: HashMap<NodeIndex, String>,
|
||||||
layer_to_layername: HashMap<u64, String>,
|
layer_to_layername: HashMap<u64, String>,
|
||||||
net_to_netname: HashMap<usize, String>,
|
net_to_netname: HashMap<usize, String>,
|
||||||
|
pinname_pair_to_band: HashMap<(String, String), BandIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Board<R> {
|
impl<R: RulesTrait> Board<R> {
|
||||||
|
|
@ -34,6 +37,7 @@ impl<R: RulesTrait> Board<R> {
|
||||||
node_to_pinname: HashMap::new(),
|
node_to_pinname: HashMap::new(),
|
||||||
layer_to_layername: HashMap::new(),
|
layer_to_layername: HashMap::new(),
|
||||||
net_to_netname: HashMap::new(),
|
net_to_netname: HashMap::new(),
|
||||||
|
pinname_pair_to_band: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +120,32 @@ impl<R: RulesTrait> Board<R> {
|
||||||
zone
|
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) {
|
pub fn bename_layer(&mut self, layer: u64, layername: String) {
|
||||||
self.layer_to_layername.insert(layer, layername);
|
self.layer_to_layername.insert(layer, layername);
|
||||||
}
|
}
|
||||||
|
|
@ -155,6 +185,22 @@ impl<R: RulesTrait> Board<R> {
|
||||||
self.net_to_netname.get(&net)
|
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> {
|
pub fn layout(&self) -> &Layout<R> {
|
||||||
&self.layout
|
&self.layout
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -255,8 +255,8 @@ impl eframe::App for App {
|
||||||
let mut execute = invoker.execute_walk(Command::Autoroute(selection));
|
let mut execute = invoker.execute_walk(Command::Autoroute(selection));
|
||||||
|
|
||||||
if let Execute::Autoroute(ref mut autoroute) = execute {
|
if let Execute::Autoroute(ref mut autoroute) = execute {
|
||||||
let from = autoroute.navmesh().as_ref().unwrap().from();
|
let from = autoroute.navmesh().as_ref().unwrap().source();
|
||||||
let to = autoroute.navmesh().as_ref().unwrap().to();
|
let to = autoroute.navmesh().as_ref().unwrap().target();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut shared_data = shared_data_arc_mutex.lock().unwrap();
|
let mut shared_data = shared_data_arc_mutex.lock().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::drawing::seg::{LoneLooseSegIndex, SeqLooseSegIndex};
|
use crate::drawing::seg::{LoneLooseSegIndex, SeqLooseSegIndex};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum BandIndex {
|
pub enum BandIndex {
|
||||||
Straight(LoneLooseSegIndex),
|
Straight(LoneLooseSegIndex),
|
||||||
Bended(SeqLooseSegIndex),
|
Bended(SeqLooseSegIndex),
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,8 @@ impl HasPosition for TrianvertexWeight {
|
||||||
pub struct Navmesh {
|
pub struct Navmesh {
|
||||||
triangulation: Triangulation<TrianvertexIndex, TrianvertexWeight, ()>,
|
triangulation: Triangulation<TrianvertexIndex, TrianvertexWeight, ()>,
|
||||||
navvertex_to_trianvertex: Vec<Option<TrianvertexIndex>>,
|
navvertex_to_trianvertex: Vec<Option<TrianvertexIndex>>,
|
||||||
from: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
to: FixedDotIndex,
|
target: FixedDotIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
|
|
@ -95,26 +95,29 @@ pub enum NavmeshError {
|
||||||
impl Navmesh {
|
impl Navmesh {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
layout: &Layout<impl RulesTrait>,
|
layout: &Layout<impl RulesTrait>,
|
||||||
from: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
to: FixedDotIndex,
|
target: FixedDotIndex,
|
||||||
) -> Result<Self, NavmeshError> {
|
) -> Result<Self, NavmeshError> {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
triangulation: Triangulation::new(layout.drawing().geometry().graph().node_bound()),
|
triangulation: Triangulation::new(layout.drawing().geometry().graph().node_bound()),
|
||||||
navvertex_to_trianvertex: Vec::new(),
|
navvertex_to_trianvertex: Vec::new(),
|
||||||
from,
|
source,
|
||||||
to,
|
target,
|
||||||
};
|
};
|
||||||
this.navvertex_to_trianvertex
|
this.navvertex_to_trianvertex
|
||||||
.resize(layout.drawing().geometry().graph().node_bound(), None);
|
.resize(layout.drawing().geometry().graph().node_bound(), None);
|
||||||
|
|
||||||
let layer = layout.drawing().primitive(from).layer();
|
let layer = layout.drawing().primitive(source).layer();
|
||||||
let maybe_net = layout.drawing().primitive(from).maybe_net();
|
let maybe_net = layout.drawing().primitive(source).maybe_net();
|
||||||
|
|
||||||
for node in layout.drawing().layer_primitive_nodes(layer) {
|
for node in layout.drawing().layer_primitive_nodes(layer) {
|
||||||
let primitive = node.primitive(layout.drawing());
|
let primitive = node.primitive(layout.drawing());
|
||||||
|
|
||||||
if let Some(primitive_net) = primitive.maybe_net() {
|
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 {
|
match node {
|
||||||
PrimitiveIndex::FixedDot(dot) => {
|
PrimitiveIndex::FixedDot(dot) => {
|
||||||
this.triangulation.add_vertex(TrianvertexWeight {
|
this.triangulation.add_vertex(TrianvertexWeight {
|
||||||
|
|
@ -164,12 +167,12 @@ impl Navmesh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from(&self) -> FixedDotIndex {
|
pub fn source(&self) -> FixedDotIndex {
|
||||||
self.from
|
self.source
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to(&self) -> FixedDotIndex {
|
pub fn target(&self) -> FixedDotIndex {
|
||||||
self.to
|
self.target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,8 +169,8 @@ impl<'a, R: RulesTrait> Router<'a, R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
observer: &mut impl RouterObserverTrait<R>,
|
observer: &mut impl RouterObserverTrait<R>,
|
||||||
) -> Result<BandIndex, RouterError> {
|
) -> Result<BandIndex, RouterError> {
|
||||||
let from = self.navmesh.from();
|
let from = self.navmesh.source();
|
||||||
let to = self.navmesh.to();
|
let to = self.navmesh.target();
|
||||||
let mut tracer = Tracer::new(self.layout);
|
let mut tracer = Tracer::new(self.layout);
|
||||||
let trace = tracer.start(from, width);
|
let trace = tracer.start(from, width);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue