mirror of https://codeberg.org/topola/topola.git
layout: move connectivity to new superordinate `Board` struct
This is very rudimentary (merely compiles and doesn't panic). Routing is unlikely to work at the moment. I'll be fixing all this in subsequent commits.
This commit is contained in:
parent
b53dc62df3
commit
8d55fbc837
|
|
@ -12,10 +12,11 @@ macro_rules! dbg_dot {
|
|||
use geo::point;
|
||||
use painter::Painter;
|
||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||
use topola::board::connectivity::BandIndex;
|
||||
use topola::board::Board;
|
||||
use topola::draw::DrawException;
|
||||
use topola::dsn::design::DsnDesign;
|
||||
use topola::geometry::shape::{Shape, ShapeTrait};
|
||||
use topola::layout::connectivity::BandIndex;
|
||||
use topola::layout::dot::FixedDotWeight;
|
||||
use topola::layout::graph::{GeometryIndex, MakePrimitive};
|
||||
use topola::layout::primitive::MakeShape;
|
||||
|
|
@ -126,7 +127,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
|||
self.window,
|
||||
self.renderer,
|
||||
self.font_context,
|
||||
RouterOrLayout::Layout(tracer.layout),
|
||||
RouterOrLayout::Layout(&tracer.board.layout),
|
||||
None,
|
||||
Some(tracer.mesh.clone()),
|
||||
&trace.path,
|
||||
|
|
@ -144,7 +145,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
|||
self.window,
|
||||
self.renderer,
|
||||
self.font_context,
|
||||
RouterOrLayout::Layout(tracer.layout),
|
||||
RouterOrLayout::Layout(&tracer.board.layout),
|
||||
None,
|
||||
Some(tracer.mesh.clone()),
|
||||
&path,
|
||||
|
|
@ -175,7 +176,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
|||
self.window,
|
||||
self.renderer,
|
||||
self.font_context,
|
||||
RouterOrLayout::Layout(tracer.layout),
|
||||
RouterOrLayout::Layout(&tracer.board.layout),
|
||||
None,
|
||||
Some(tracer.mesh.clone()),
|
||||
&trace.path,
|
||||
|
|
@ -248,14 +249,15 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
let design = DsnDesign::load_from_file("tests/data/test.dsn")?;
|
||||
//dbg!(&design);
|
||||
let layout = design.make_layout();
|
||||
let mut router = Router::new(layout);
|
||||
let board = Board::new(layout);
|
||||
let mut router = Router::new(board);
|
||||
|
||||
render_times(
|
||||
&mut event_pump,
|
||||
&window,
|
||||
&mut renderer,
|
||||
&font_context,
|
||||
RouterOrLayout::Layout(&router.layout),
|
||||
RouterOrLayout::Layout(&router.board.layout),
|
||||
None,
|
||||
None,
|
||||
&[],
|
||||
|
|
@ -278,7 +280,7 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
&window,
|
||||
&mut renderer,
|
||||
&font_context,
|
||||
RouterOrLayout::Layout(&router.layout),
|
||||
RouterOrLayout::Layout(&router.board.layout),
|
||||
None,
|
||||
None,
|
||||
&[],
|
||||
|
|
@ -345,7 +347,7 @@ fn render_times(
|
|||
maybe_mesh = None;
|
||||
}
|
||||
|
||||
&router.layout
|
||||
&router.board.layout
|
||||
}
|
||||
RouterOrLayout::Layout(layout) => layout,
|
||||
};
|
||||
|
|
|
|||
39
src/draw.rs
39
src/draw.rs
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
layout::{
|
||||
bend::{BendIndex, LooseBendWeight},
|
||||
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
|
||||
graph::{GetBandIndex, MakePrimitive},
|
||||
graph::{GetNet, MakePrimitive},
|
||||
guide::{Guide, Head, HeadTrait, SegbendHead},
|
||||
primitive::GetOtherJoint,
|
||||
rules::RulesTrait,
|
||||
|
|
@ -58,30 +58,17 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
|
|||
let head = self
|
||||
.extend_head(head, tangent.start_point())
|
||||
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
|
||||
let net = head.face().primitive(self.layout).net();
|
||||
|
||||
match head.face() {
|
||||
DotIndex::Fixed(dot) => {
|
||||
self.layout
|
||||
.add_lone_loose_seg(
|
||||
dot,
|
||||
into.into(),
|
||||
LoneLooseSegWeight {
|
||||
band: head.band(),
|
||||
width: self.layout.band(head.band()).width(),
|
||||
},
|
||||
)
|
||||
.add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { net, width })
|
||||
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
|
||||
}
|
||||
DotIndex::Loose(dot) => {
|
||||
self.layout
|
||||
.add_seq_loose_seg(
|
||||
into.into(),
|
||||
dot,
|
||||
SeqLooseSegWeight {
|
||||
band: head.band(),
|
||||
width: self.layout.band(head.band()).width(),
|
||||
},
|
||||
)
|
||||
.add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { net, width })
|
||||
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
|
||||
}
|
||||
}
|
||||
|
|
@ -215,31 +202,24 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
|
|||
width: f64,
|
||||
offset: f64,
|
||||
) -> Result<SegbendHead, LayoutException> {
|
||||
let net = head.face().primitive(self.layout).net();
|
||||
let segbend = self.layout.insert_segbend(
|
||||
head.face(),
|
||||
around,
|
||||
LooseDotWeight {
|
||||
band: head.band(),
|
||||
net,
|
||||
circle: Circle {
|
||||
pos: to,
|
||||
r: width / 2.0,
|
||||
},
|
||||
},
|
||||
SeqLooseSegWeight {
|
||||
band: head.band(),
|
||||
width,
|
||||
},
|
||||
LooseBendWeight {
|
||||
band: head.band(),
|
||||
width,
|
||||
offset,
|
||||
},
|
||||
SeqLooseSegWeight { net, width },
|
||||
LooseBendWeight { net, width, offset },
|
||||
cw,
|
||||
)?;
|
||||
Ok::<SegbendHead, LayoutException>(SegbendHead {
|
||||
face: self.layout.primitive(segbend.bend).other_joint(segbend.dot),
|
||||
segbend,
|
||||
band: head.band(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -250,10 +230,9 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
|
|||
.layout
|
||||
.primitive(head.segbend.seg)
|
||||
.other_joint(head.segbend.dot.into());
|
||||
let band = head.band;
|
||||
|
||||
self.layout.remove_segbend(&head.segbend, head.face);
|
||||
Some(self.guide().head(prev_dot, band))
|
||||
Some(self.guide().head(prev_dot))
|
||||
}
|
||||
|
||||
fn guide(&self) -> Guide<R> {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use crate::{
|
|||
|
||||
use super::{
|
||||
de::{from_str, Error},
|
||||
structure::Pcb,
|
||||
rules::Rules,
|
||||
structure::Pcb,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -24,10 +24,7 @@ impl DsnDesign {
|
|||
|
||||
let rules = Rules::from_pcb(&pcb);
|
||||
|
||||
Ok(Self {
|
||||
pcb,
|
||||
rules,
|
||||
})
|
||||
Ok(Self { pcb, rules })
|
||||
}
|
||||
|
||||
pub fn make_layout(&self) -> Layout<&Rules> {
|
||||
|
|
@ -67,7 +64,6 @@ impl DsnDesign {
|
|||
for pin in &image.pins {
|
||||
let pin_name = format!("{}-{}", place.name, pin.id);
|
||||
let net_id = pin_nets.get(&pin_name).unwrap();
|
||||
let continent = layout.add_continent(*net_id);
|
||||
|
||||
let padstack = &self
|
||||
.pcb
|
||||
|
|
@ -85,7 +81,10 @@ impl DsnDesign {
|
|||
};
|
||||
|
||||
layout
|
||||
.add_fixed_dot(FixedDotWeight { continent, circle })
|
||||
.add_fixed_dot(FixedDotWeight {
|
||||
net: *net_id as i64,
|
||||
circle,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +99,6 @@ impl DsnDesign {
|
|||
.iter()
|
||||
.map(|via| {
|
||||
let net_id = self.rules.net_ids.get(&via.net.0).unwrap();
|
||||
let continent = layout.add_continent(*net_id);
|
||||
|
||||
// find the padstack referenced by this via placement
|
||||
let padstack = &self
|
||||
|
|
@ -119,19 +117,21 @@ impl DsnDesign {
|
|||
};
|
||||
|
||||
layout
|
||||
.add_fixed_dot(FixedDotWeight { continent, circle })
|
||||
.add_fixed_dot(FixedDotWeight {
|
||||
net: *net_id as i64,
|
||||
circle,
|
||||
})
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
|
||||
for wire in self.pcb.wiring.wires.iter() {
|
||||
let net_id = self.rules.net_ids.get(&wire.net.0).unwrap();
|
||||
let continent = layout.add_continent(*net_id);
|
||||
|
||||
// add the first coordinate in the wire path as a dot and save its index
|
||||
let mut prev_index = layout
|
||||
.add_fixed_dot(FixedDotWeight {
|
||||
continent,
|
||||
net: *net_id as i64,
|
||||
circle: Circle {
|
||||
pos: (
|
||||
wire.path.coords[0].x as f64 / 100.0,
|
||||
|
|
@ -147,7 +147,7 @@ impl DsnDesign {
|
|||
for coord in wire.path.coords.iter().skip(1) {
|
||||
let index = layout
|
||||
.add_fixed_dot(FixedDotWeight {
|
||||
continent,
|
||||
net: *net_id as i64,
|
||||
circle: Circle {
|
||||
pos: (coord.x as f64 / 100.0, -coord.y as f64 / 100.0).into(),
|
||||
r: wire.path.width as f64 / 100.0,
|
||||
|
|
@ -161,7 +161,7 @@ impl DsnDesign {
|
|||
prev_index,
|
||||
index,
|
||||
FixedSegWeight {
|
||||
continent,
|
||||
net: *net_id as i64,
|
||||
width: wire.path.width as f64 / 100.0,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,100 +0,0 @@
|
|||
use crate::{
|
||||
geometry::{shape::ShapeTrait, GetWidth},
|
||||
graph::GetNodeIndex,
|
||||
layout::{
|
||||
connectivity::{BandIndex, BandWeight, ConnectivityWeight, GetNet},
|
||||
dot::{DotIndex, FixedDotIndex},
|
||||
graph::{GeometryIndex, MakePrimitive},
|
||||
loose::{GetNextLoose, LooseIndex},
|
||||
primitive::{GetJoints, GetOtherJoint, MakeShape},
|
||||
Layout,
|
||||
},
|
||||
};
|
||||
|
||||
use super::rules::RulesTrait;
|
||||
|
||||
pub struct Band<'a, R: RulesTrait> {
|
||||
pub index: BandIndex,
|
||||
layout: &'a Layout<R>,
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> Band<'a, R> {
|
||||
pub fn new(index: BandIndex, layout: &'a Layout<R>) -> Self {
|
||||
Self { index, layout }
|
||||
}
|
||||
|
||||
fn weight(&self) -> BandWeight {
|
||||
if let Some(ConnectivityWeight::Band(weight)) = self
|
||||
.layout
|
||||
.connectivity()
|
||||
.node_weight(self.index.node_index())
|
||||
{
|
||||
*weight
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(&self) -> FixedDotIndex {
|
||||
self.weight().from
|
||||
}
|
||||
|
||||
pub fn to(&self) -> Option<FixedDotIndex> {
|
||||
// For now, we do full traversal. Later on, we may want to store the target fixed dot
|
||||
// somewhere.
|
||||
|
||||
let mut maybe_loose = self.layout.primitive(self.from()).first_loose(self.index);
|
||||
let mut prev = None;
|
||||
|
||||
while let Some(loose) = maybe_loose {
|
||||
let prev_prev = prev;
|
||||
prev = maybe_loose;
|
||||
maybe_loose = self.layout.loose(loose).next_loose(prev_prev);
|
||||
}
|
||||
|
||||
match prev {
|
||||
Some(LooseIndex::LoneSeg(seg)) => {
|
||||
Some(self.layout.primitive(seg).other_joint(self.from()))
|
||||
}
|
||||
Some(LooseIndex::SeqSeg(seg)) => {
|
||||
if let DotIndex::Fixed(dot) = self.layout.primitive(seg).joints().0 {
|
||||
Some(dot)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn length(&self) -> f64 {
|
||||
let mut maybe_loose = self.layout.primitive(self.from()).first_loose(self.index);
|
||||
let mut prev = None;
|
||||
let mut length = 0.0;
|
||||
|
||||
while let Some(loose) = maybe_loose {
|
||||
length += GeometryIndex::from(loose)
|
||||
.primitive(self.layout)
|
||||
.shape()
|
||||
.length();
|
||||
|
||||
let prev_prev = prev;
|
||||
prev = maybe_loose;
|
||||
maybe_loose = self.layout.loose(loose).next_loose(prev_prev);
|
||||
}
|
||||
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> GetNet for Band<'a, R> {
|
||||
fn net(&self) -> i64 {
|
||||
self.weight().net
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> GetWidth for Band<'a, R> {
|
||||
fn width(&self) -> f64 {
|
||||
self.weight().width
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,7 @@ use crate::{
|
|||
geometry::{BendWeightTrait, GetOffset, GetWidth, SetOffset},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{
|
||||
connectivity::{BandIndex, ContinentIndex},
|
||||
graph::{
|
||||
GeometryIndex, GeometryWeight, GetBandIndex, GetContinentIndex, GetContinentIndexMut,
|
||||
MakePrimitive, Retag,
|
||||
},
|
||||
graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag},
|
||||
primitive::{GenericPrimitive, Primitive},
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
|
|
@ -77,7 +73,7 @@ impl BendWeightTrait<GeometryWeight> for BendWeight {}
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedBendWeight {
|
||||
pub continent: ContinentIndex,
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
pub offset: f64,
|
||||
}
|
||||
|
|
@ -105,7 +101,7 @@ impl GetWidth for FixedBendWeight {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LooseBendWeight {
|
||||
pub band: BandIndex,
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
pub offset: f64,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
use enum_dispatch::enum_dispatch;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
|
||||
use crate::{graph::GenericIndex, layout::dot::FixedDotIndex};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetNet {
|
||||
fn net(&self) -> i64;
|
||||
}
|
||||
|
||||
pub type ConnectivityGraph = StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>;
|
||||
|
||||
#[enum_dispatch(GetNet)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ConnectivityWeight {
|
||||
Continent(ContinentWeight),
|
||||
Band(BandWeight),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ContinentWeight {
|
||||
pub net: i64,
|
||||
}
|
||||
|
||||
impl GetNet for ContinentWeight {
|
||||
fn net(&self) -> i64 {
|
||||
self.net
|
||||
}
|
||||
}
|
||||
|
||||
pub type ContinentIndex = GenericIndex<ContinentWeight>;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BandWeight {
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
pub from: FixedDotIndex,
|
||||
}
|
||||
|
||||
impl GetNet for BandWeight {
|
||||
fn net(&self) -> i64 {
|
||||
self.net
|
||||
}
|
||||
}
|
||||
|
||||
pub type BandIndex = GenericIndex<BandWeight>;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ConnectivityLabel {
|
||||
Band,
|
||||
}
|
||||
|
|
@ -7,11 +7,7 @@ use crate::{
|
|||
geometry::{DotWeightTrait, GetPos, GetWidth, SetPos},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{
|
||||
connectivity::{BandIndex, ContinentIndex},
|
||||
graph::{
|
||||
GeometryIndex, GeometryWeight, GetBandIndex, GetContinentIndex, GetContinentIndexMut,
|
||||
MakePrimitive, Retag,
|
||||
},
|
||||
graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag},
|
||||
primitive::{GenericPrimitive, Primitive},
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
|
|
@ -79,7 +75,7 @@ impl DotWeightTrait<GeometryWeight> for DotWeight {}
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedDotWeight {
|
||||
pub continent: ContinentIndex,
|
||||
pub net: i64,
|
||||
pub circle: Circle,
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +102,7 @@ impl GetWidth for FixedDotWeight {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LooseDotWeight {
|
||||
pub band: BandIndex,
|
||||
pub net: i64,
|
||||
pub circle: Circle,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@ use enum_dispatch::enum_dispatch;
|
|||
use petgraph::stable_graph::NodeIndex;
|
||||
|
||||
use crate::{
|
||||
board::connectivity::{BandIndex, ContinentIndex},
|
||||
graph::GetNodeIndex,
|
||||
layout::{
|
||||
connectivity::{BandIndex, ContinentIndex},
|
||||
Layout,
|
||||
},
|
||||
layout::Layout,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -27,16 +25,8 @@ pub trait Retag<GeometryIndex> {
|
|||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetContinentIndex {
|
||||
fn continent(&self) -> ContinentIndex;
|
||||
}
|
||||
|
||||
pub trait GetContinentIndexMut {
|
||||
fn continent_mut(&mut self) -> &mut ContinentIndex;
|
||||
}
|
||||
|
||||
pub trait GetBandIndex {
|
||||
fn band(&self) -> BandIndex;
|
||||
pub trait GetNet {
|
||||
fn net(&self) -> i64;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -52,6 +42,12 @@ macro_rules! impl_weight {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetNet for $weight_struct {
|
||||
fn net(&self) -> i64 {
|
||||
self.net
|
||||
}
|
||||
}
|
||||
|
||||
pub type $index_struct = GenericIndex<$weight_struct>;
|
||||
|
||||
impl MakePrimitive for $index_struct {
|
||||
|
|
@ -65,30 +61,12 @@ macro_rules! impl_weight {
|
|||
macro_rules! impl_fixed_weight {
|
||||
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
|
||||
impl_weight!($weight_struct, $weight_variant, $index_struct);
|
||||
|
||||
impl GetContinentIndex for $weight_struct {
|
||||
fn continent(&self) -> ContinentIndex {
|
||||
self.continent
|
||||
}
|
||||
}
|
||||
|
||||
impl GetContinentIndexMut for $weight_struct {
|
||||
fn continent_mut(&mut self) -> &mut ContinentIndex {
|
||||
&mut self.continent
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_loose_weight {
|
||||
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
|
||||
impl_weight!($weight_struct, $weight_variant, $index_struct);
|
||||
|
||||
impl GetBandIndex for $weight_struct {
|
||||
fn band(&self) -> BandIndex {
|
||||
self.band
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use enum_dispatch::enum_dispatch;
|
|||
use geo::Line;
|
||||
|
||||
use crate::{
|
||||
board::connectivity::BandIndex,
|
||||
geometry::shape::{Shape, ShapeTrait},
|
||||
layout::{
|
||||
bend::BendIndex,
|
||||
connectivity::BandIndex,
|
||||
dot::{DotIndex, FixedDotIndex, LooseDotIndex},
|
||||
graph::{GetBandIndex, MakePrimitive},
|
||||
graph::MakePrimitive,
|
||||
primitive::{GetCore, GetInnerOuter, GetOtherJoint, GetWeight, MakeShape},
|
||||
rules::GetConditions,
|
||||
Layout,
|
||||
|
|
@ -25,7 +25,6 @@ use super::{
|
|||
#[enum_dispatch]
|
||||
pub trait HeadTrait {
|
||||
fn face(&self) -> DotIndex;
|
||||
fn band(&self) -> BandIndex;
|
||||
}
|
||||
|
||||
#[enum_dispatch(HeadTrait)]
|
||||
|
|
@ -38,34 +37,24 @@ pub enum Head {
|
|||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BareHead {
|
||||
pub dot: FixedDotIndex,
|
||||
pub band: BandIndex,
|
||||
}
|
||||
|
||||
impl HeadTrait for BareHead {
|
||||
fn face(&self) -> DotIndex {
|
||||
self.dot.into()
|
||||
}
|
||||
|
||||
fn band(&self) -> BandIndex {
|
||||
self.band
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SegbendHead {
|
||||
pub face: LooseDotIndex,
|
||||
pub segbend: Segbend,
|
||||
pub band: BandIndex,
|
||||
}
|
||||
|
||||
impl HeadTrait for SegbendHead {
|
||||
fn face(&self) -> DotIndex {
|
||||
self.face.into()
|
||||
}
|
||||
|
||||
fn band(&self) -> BandIndex {
|
||||
self.band
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Guide<'a, R: RulesTrait> {
|
||||
|
|
@ -233,20 +222,16 @@ impl<'a, R: RulesTrait> Guide<'a, R> {
|
|||
SegbendHead {
|
||||
face: dot,
|
||||
segbend: self.layout.segbend(dot),
|
||||
band: self.layout.primitive(dot).weight().band(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rear_head(&self, dot: LooseDotIndex) -> Head {
|
||||
self.head(
|
||||
self.rear(self.segbend_head(dot)),
|
||||
self.layout.primitive(dot).weight().band(),
|
||||
)
|
||||
self.head(self.rear(self.segbend_head(dot)))
|
||||
}
|
||||
|
||||
pub fn head(&self, dot: DotIndex, band: BandIndex) -> Head {
|
||||
pub fn head(&self, dot: DotIndex) -> Head {
|
||||
match dot {
|
||||
DotIndex::Fixed(fixed) => BareHead { dot: fixed, band }.into(),
|
||||
DotIndex::Fixed(fixed) => BareHead { dot: fixed }.into(),
|
||||
DotIndex::Loose(loose) => self.segbend_head(loose).into(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,10 @@
|
|||
use contracts::debug_ensures;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use geo::Point;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
|
||||
use rstar::RTreeObject;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::band::Band;
|
||||
use super::connectivity::{
|
||||
BandIndex, BandWeight, ConnectivityGraph, ConnectivityLabel, ConnectivityWeight,
|
||||
ContinentIndex, ContinentWeight, GetNet,
|
||||
};
|
||||
use super::loose::{GetNextLoose, Loose, LooseIndex};
|
||||
use super::rules::RulesTrait;
|
||||
use super::segbend::Segbend;
|
||||
|
|
@ -24,13 +18,14 @@ use crate::graph::{GenericIndex, GetNodeIndex};
|
|||
use crate::layout::bend::BendIndex;
|
||||
use crate::layout::collect::Collect;
|
||||
use crate::layout::dot::DotWeight;
|
||||
use crate::layout::graph::GetNet;
|
||||
use crate::layout::guide::Guide;
|
||||
use crate::layout::primitive::GetLimbs;
|
||||
use crate::layout::rules::GetConditions;
|
||||
use crate::layout::{
|
||||
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
|
||||
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||
graph::{GeometryIndex, GeometryWeight, GetContinentIndex, MakePrimitive},
|
||||
graph::{GeometryIndex, GeometryWeight, MakePrimitive},
|
||||
primitive::{GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetOtherJoint, MakeShape},
|
||||
seg::{
|
||||
FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex,
|
||||
|
|
@ -81,7 +76,6 @@ pub struct Layout<R: RulesTrait> {
|
|||
SegIndex,
|
||||
BendIndex,
|
||||
>,
|
||||
connectivity: ConnectivityGraph,
|
||||
rules: R,
|
||||
}
|
||||
|
||||
|
|
@ -89,19 +83,17 @@ impl<R: RulesTrait> Layout<R> {
|
|||
pub fn new(rules: R) -> Self {
|
||||
Self {
|
||||
geometry_with_rtree: GeometryWithRtree::new(),
|
||||
connectivity: StableDiGraph::default(),
|
||||
rules,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_band(&mut self, band: BandIndex) {
|
||||
pub fn remove_band(&mut self, first_loose: SeqLooseSegIndex) {
|
||||
let mut dots = vec![];
|
||||
let mut segs = vec![];
|
||||
let mut bends = vec![];
|
||||
let mut outers = vec![];
|
||||
|
||||
let from = self.band(band).from();
|
||||
let mut maybe_loose = self.primitive(from).first_loose(band);
|
||||
let mut maybe_loose = Some(first_loose.into());
|
||||
let mut prev = None;
|
||||
|
||||
while let Some(loose) = maybe_loose {
|
||||
|
|
@ -149,8 +141,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
for outer in outers {
|
||||
self.update_this_and_outward_bows(outer).unwrap(); // Must never fail.
|
||||
}
|
||||
|
||||
self.connectivity.remove_node(band.node_index());
|
||||
}
|
||||
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() - 4))]
|
||||
|
|
@ -176,30 +166,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: This method shouldn't be public.
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_continent(&mut self, net: i64) -> ContinentIndex {
|
||||
ContinentIndex::new(
|
||||
self.connectivity
|
||||
.add_node(ConnectivityWeight::Continent(ContinentWeight { net })),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: This method shouldn't be public.
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn add_band(&mut self, from: FixedDotIndex, width: f64) -> BandIndex {
|
||||
BandIndex::new(
|
||||
self.connectivity
|
||||
.add_node(ConnectivityWeight::Band(BandWeight {
|
||||
width,
|
||||
net: self.primitive(from).net(),
|
||||
from,
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
|
|
@ -489,18 +455,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
weight: LoneLooseSegWeight,
|
||||
) -> Result<LoneLooseSegIndex, Infringement> {
|
||||
let seg = self.add_seg_infringably(from.into(), to.into(), weight, &[])?;
|
||||
|
||||
self.connectivity.update_edge(
|
||||
self.primitive(from).continent().node_index(),
|
||||
weight.band.node_index(),
|
||||
ConnectivityLabel::Band,
|
||||
);
|
||||
self.connectivity.update_edge(
|
||||
weight.band.node_index(),
|
||||
self.primitive(to).continent().node_index(),
|
||||
ConnectivityLabel::Band,
|
||||
);
|
||||
|
||||
Ok(seg)
|
||||
}
|
||||
|
||||
|
|
@ -515,15 +469,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
weight: SeqLooseSegWeight,
|
||||
) -> Result<SeqLooseSegIndex, Infringement> {
|
||||
let seg = self.add_seg_infringably(from, to.into(), weight, &[])?;
|
||||
|
||||
if let DotIndex::Fixed(dot) = from {
|
||||
self.connectivity.update_edge(
|
||||
self.primitive(dot).continent().node_index(),
|
||||
weight.band.node_index(),
|
||||
ConnectivityLabel::Band,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(seg)
|
||||
}
|
||||
|
||||
|
|
@ -547,22 +492,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
Ok(seg)
|
||||
}
|
||||
|
||||
/*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
pub fn add_fixed_bend(
|
||||
&mut self,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
around: GeometryIndex,
|
||||
weight: FixedBendWeight,
|
||||
) -> Result<FixedBendIndex, ()> {
|
||||
match around {
|
||||
GeometryIndex::FixedDot(core) => self.add_core_bend(from, to, core, weight),
|
||||
GeometryIndex::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}*/
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 3)
|
||||
|| self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() + 4))]
|
||||
|
|
@ -577,15 +506,14 @@ impl<R: RulesTrait> Layout<R> {
|
|||
infringables: &[GeometryIndex],
|
||||
) -> Result<LooseBendIndex, LayoutException> {
|
||||
// It makes no sense to wrap something around or under one of its connectables.
|
||||
let net = self.band(weight.band).net();
|
||||
//
|
||||
if net == around.primitive(self).net() {
|
||||
return Err(AlreadyConnected(net, around.into()).into());
|
||||
if weight.net == around.primitive(self).net() {
|
||||
return Err(AlreadyConnected(weight.net, around.into()).into());
|
||||
}
|
||||
//
|
||||
if let Some(wraparound) = self.wraparoundable(around).wraparound() {
|
||||
if net == wraparound.primitive(self).net() {
|
||||
return Err(AlreadyConnected(net, wraparound.into()).into());
|
||||
if weight.net == wraparound.primitive(self).net() {
|
||||
return Err(AlreadyConnected(weight.net, wraparound.into()).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -847,12 +775,6 @@ impl<R: RulesTrait> Layout<R> {
|
|||
}
|
||||
|
||||
impl<R: RulesTrait> Layout<R> {
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn connectivity(&self) -> &ConnectivityGraph {
|
||||
&self.connectivity
|
||||
}
|
||||
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn geometry(
|
||||
|
|
@ -905,10 +827,4 @@ impl<R: RulesTrait> Layout<R> {
|
|||
pub fn loose(&self, index: LooseIndex) -> Loose<R> {
|
||||
Loose::new(index, self)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
|
||||
#[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
|
||||
pub fn band(&self, index: BandIndex) -> Band<R> {
|
||||
Band::new(index, self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
#[macro_use]
|
||||
pub mod graph;
|
||||
pub mod band;
|
||||
pub mod bend;
|
||||
pub mod collect;
|
||||
pub mod connectivity;
|
||||
pub mod dot;
|
||||
pub mod guide;
|
||||
mod layout;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
use enum_dispatch::enum_dispatch;
|
||||
use petgraph::stable_graph::NodeIndex;
|
||||
|
||||
use crate::board::connectivity::{BandIndex, ContinentIndex};
|
||||
use crate::geometry::{
|
||||
shape::{Shape, ShapeTrait},
|
||||
GetOffset, GetWidth,
|
||||
};
|
||||
use crate::graph::{GenericIndex, GetNodeIndex};
|
||||
use crate::layout::dot::DotWeight;
|
||||
use crate::layout::seg::{
|
||||
FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex,
|
||||
SeqLooseSegWeight,
|
||||
};
|
||||
|
||||
use crate::layout::{
|
||||
bend::{BendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight},
|
||||
connectivity::{BandIndex, ContinentIndex, GetNet},
|
||||
dot::DotWeight,
|
||||
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
|
||||
graph::{GeometryIndex, GeometryWeight, GetBandIndex, GetContinentIndex, Retag},
|
||||
graph::{GeometryIndex, GeometryWeight, Retag},
|
||||
loose::LooseIndex,
|
||||
seg::{
|
||||
FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex,
|
||||
SeqLooseSegWeight,
|
||||
},
|
||||
Layout,
|
||||
};
|
||||
|
||||
use super::graph::GetNet;
|
||||
use super::rules::{Conditions, GetConditions, RulesTrait};
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -126,44 +126,24 @@ macro_rules! impl_primitive {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> {
|
||||
fn net(&self) -> i64 {
|
||||
self.weight().net()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_fixed_primitive {
|
||||
($primitive_struct:ident, $weight_struct:ident) => {
|
||||
impl_primitive!($primitive_struct, $weight_struct);
|
||||
|
||||
impl<'a, R: RulesTrait> GetContinentIndex for $primitive_struct<'a, R> {
|
||||
fn continent(&self) -> ContinentIndex {
|
||||
self.weight().continent()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> {
|
||||
fn net(&self) -> i64 {
|
||||
self.layout()
|
||||
.connectivity()
|
||||
.node_weight(self.continent().node_index())
|
||||
.unwrap()
|
||||
.net()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_loose_primitive {
|
||||
($primitive_struct:ident, $weight_struct:ident) => {
|
||||
impl_primitive!($primitive_struct, $weight_struct);
|
||||
|
||||
impl<'a, R: RulesTrait> GetNet for $primitive_struct<'a, R> {
|
||||
fn net(&self) -> i64 {
|
||||
self.layout()
|
||||
.connectivity()
|
||||
.node_weight(self.weight().band().node_index())
|
||||
.unwrap()
|
||||
.net()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,7 @@ use crate::{
|
|||
geometry::{GetWidth, SegWeightTrait},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{
|
||||
connectivity::{BandIndex, ContinentIndex},
|
||||
graph::{
|
||||
GeometryIndex, GeometryWeight, GetBandIndex, GetContinentIndex, GetContinentIndexMut,
|
||||
MakePrimitive, Retag,
|
||||
},
|
||||
graph::{GeometryIndex, GeometryWeight, GetNet, MakePrimitive, Retag},
|
||||
primitive::{GenericPrimitive, Primitive},
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
|
|
@ -83,7 +79,7 @@ impl SegWeightTrait<GeometryWeight> for SegWeight {}
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedSegWeight {
|
||||
pub continent: ContinentIndex,
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +94,7 @@ impl GetWidth for FixedSegWeight {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LoneLooseSegWeight {
|
||||
pub band: BandIndex,
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +109,7 @@ impl GetWidth for LoneLooseSegWeight {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct SeqLooseSegWeight {
|
||||
pub band: BandIndex,
|
||||
pub net: i64,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ pub mod draw;
|
|||
pub mod graph;
|
||||
#[macro_use]
|
||||
pub mod layout;
|
||||
pub mod board;
|
||||
pub mod dsn;
|
||||
pub mod geometry;
|
||||
pub mod math;
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ use spade::InsertionError;
|
|||
use thiserror::Error;
|
||||
|
||||
use crate::astar::{astar, AstarStrategy, PathTracker};
|
||||
use crate::board::connectivity::BandIndex;
|
||||
use crate::board::Board;
|
||||
use crate::draw::DrawException;
|
||||
use crate::geometry::{shape::ShapeTrait, GetWidth};
|
||||
use crate::layout::guide::HeadTrait;
|
||||
use crate::layout::rules::RulesTrait;
|
||||
use crate::layout::Layout;
|
||||
use crate::layout::{
|
||||
connectivity::BandIndex,
|
||||
dot::FixedDotIndex,
|
||||
graph::{GeometryIndex, MakePrimitive},
|
||||
primitive::MakeShape,
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
};
|
||||
|
||||
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||
|
|
@ -53,7 +53,7 @@ pub trait RouterObserverTrait<R: RulesTrait> {
|
|||
}
|
||||
|
||||
pub struct Router<R: RulesTrait> {
|
||||
pub layout: Layout<R>,
|
||||
pub board: Board<R>,
|
||||
}
|
||||
|
||||
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
|
||||
|
|
@ -84,24 +84,14 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Mesh, f64>
|
|||
{
|
||||
fn is_goal(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> bool {
|
||||
let new_path = tracker.reconstruct_path_to(vertex);
|
||||
let band = self.trace.head.band();
|
||||
let width = self.trace.width;
|
||||
|
||||
self.tracer
|
||||
.rework_path(
|
||||
&mut self.trace,
|
||||
&new_path,
|
||||
self.tracer.layout.band(band).width(),
|
||||
)
|
||||
.rework_path(&mut self.trace, &new_path, width)
|
||||
.unwrap();
|
||||
self.observer.on_rework(&self.tracer, &self.trace);
|
||||
|
||||
self.tracer
|
||||
.finish(
|
||||
&mut self.trace,
|
||||
self.to,
|
||||
self.tracer.layout.band(band).width(),
|
||||
)
|
||||
.is_ok()
|
||||
self.tracer.finish(&mut self.trace, self.to, width).is_ok()
|
||||
}
|
||||
|
||||
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<f64> {
|
||||
|
|
@ -110,18 +100,14 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Mesh, f64>
|
|||
return None;
|
||||
}
|
||||
|
||||
let band = self.trace.head.band();
|
||||
let before_probe_length = self.tracer.layout.band(band).length();
|
||||
let before_probe_length = self.tracer.board.band_length(self.trace.band);
|
||||
|
||||
let result = self.tracer.step(
|
||||
&mut self.trace,
|
||||
edge.target(),
|
||||
self.tracer.layout.band(band).width(),
|
||||
);
|
||||
let width = self.trace.width;
|
||||
let result = self.tracer.step(&mut self.trace, edge.target(), width);
|
||||
self.observer
|
||||
.on_probe(&self.tracer, &self.trace, edge, result);
|
||||
|
||||
let probe_length = self.tracer.layout.band(self.trace.head.band()).length();
|
||||
let probe_length = self.tracer.board.band_length(self.trace.band);
|
||||
|
||||
if result.is_ok() {
|
||||
self.tracer.undo_step(&mut self.trace);
|
||||
|
|
@ -134,17 +120,17 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Mesh, f64>
|
|||
fn estimate_cost(&mut self, vertex: VertexIndex) -> f64 {
|
||||
self.observer.on_estimate(&self.tracer, vertex);
|
||||
let start_point = GeometryIndex::from(vertex)
|
||||
.primitive(self.tracer.layout)
|
||||
.primitive(&self.tracer.board.layout)
|
||||
.shape()
|
||||
.center();
|
||||
let end_point = self.tracer.layout.primitive(self.to).shape().center();
|
||||
let end_point = self.tracer.board.layout.primitive(self.to).shape().center();
|
||||
end_point.euclidean_distance(&start_point)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: RulesTrait> Router<R> {
|
||||
pub fn new(layout: Layout<R>) -> Self {
|
||||
Router { layout }
|
||||
pub fn new(board: Board<R>) -> Self {
|
||||
Router { board }
|
||||
}
|
||||
|
||||
pub fn route_band(
|
||||
|
|
@ -157,16 +143,17 @@ impl<R: RulesTrait> Router<R> {
|
|||
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
||||
// right.
|
||||
//self.mesh.triangulate(&self.layout)?;
|
||||
let mut mesh = Mesh::new(&self.layout);
|
||||
mesh.generate(&self.layout).map_err(|err| RoutingError {
|
||||
from,
|
||||
to,
|
||||
source: err.into(),
|
||||
})?;
|
||||
let mut mesh = Mesh::new(&self.board.layout);
|
||||
mesh.generate(&self.board.layout)
|
||||
.map_err(|err| RoutingError {
|
||||
from,
|
||||
to,
|
||||
source: err.into(),
|
||||
})?;
|
||||
|
||||
let mut tracer = self.tracer(&mesh);
|
||||
let trace = tracer.start(from, width);
|
||||
let band = trace.head.band();
|
||||
let band = trace.band;
|
||||
|
||||
let (_cost, _path) = astar(
|
||||
&mesh,
|
||||
|
|
@ -189,14 +176,14 @@ impl<R: RulesTrait> Router<R> {
|
|||
width: f64,
|
||||
observer: &mut impl RouterObserverTrait<R>,
|
||||
) -> Result<BandIndex, RoutingError> {
|
||||
let from_dot = self.layout.band(band).from();
|
||||
let to_dot = self.layout.band(band).to().unwrap();
|
||||
self.layout.remove_band(band);
|
||||
self.layout.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`.
|
||||
let from_dot = self.board.band_from(band);
|
||||
let to_dot = self.board.band_to(band).unwrap();
|
||||
self.board.remove_band(band);
|
||||
self.board.layout.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`.
|
||||
self.route_band(from_dot, to_dot, width, observer)
|
||||
}
|
||||
|
||||
pub fn tracer<'a>(&'a mut self, mesh: &'a Mesh) -> Tracer<R> {
|
||||
Tracer::new(&mut self.layout, mesh)
|
||||
Tracer::new(&mut self.board, mesh)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
use contracts::debug_ensures;
|
||||
|
||||
use crate::{
|
||||
board::{connectivity::BandIndex, Board},
|
||||
draw::{Draw, DrawException},
|
||||
layout::{
|
||||
bend::LooseBendIndex,
|
||||
dot::FixedDotIndex,
|
||||
guide::{BareHead, Head, SegbendHead},
|
||||
graph::{GetNet, MakePrimitive},
|
||||
guide::{BareHead, Head, HeadTrait, SegbendHead},
|
||||
rules::RulesTrait,
|
||||
Layout,
|
||||
},
|
||||
mesh::{Mesh, VertexIndex},
|
||||
};
|
||||
|
|
@ -16,23 +17,27 @@ use crate::{
|
|||
pub struct Trace {
|
||||
pub path: Vec<VertexIndex>,
|
||||
pub head: Head,
|
||||
pub band: BandIndex,
|
||||
pub width: f64,
|
||||
}
|
||||
|
||||
pub struct Tracer<'a, R: RulesTrait> {
|
||||
pub layout: &'a mut Layout<R>,
|
||||
pub board: &'a mut Board<R>,
|
||||
pub mesh: &'a Mesh,
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> Tracer<'a, R> {
|
||||
pub fn new(layout: &'a mut Layout<R>, mesh: &'a Mesh) -> Self {
|
||||
Tracer { layout, mesh }
|
||||
pub fn new(board: &'a mut Board<R>, mesh: &'a Mesh) -> Self {
|
||||
Tracer { board, mesh }
|
||||
}
|
||||
|
||||
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
||||
let band = self.layout.add_band(from, width);
|
||||
let band = self.board.start_band(from);
|
||||
Trace {
|
||||
path: vec![from.into()],
|
||||
head: BareHead { dot: from, band }.into(),
|
||||
head: BareHead { dot: from }.into(),
|
||||
band,
|
||||
width,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +47,8 @@ impl<'a, R: RulesTrait> Tracer<'a, R> {
|
|||
into: FixedDotIndex,
|
||||
width: f64,
|
||||
) -> Result<(), DrawException> {
|
||||
self.draw().finish_in_dot(trace.head, into, width)
|
||||
self.draw().finish_in_dot(trace.head, into, width)?;
|
||||
Ok(self.board.finish_band(trace.band, into))
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())]
|
||||
|
|
@ -152,6 +158,6 @@ impl<'a, R: RulesTrait> Tracer<'a, R> {
|
|||
}
|
||||
|
||||
fn draw(&mut self) -> Draw<R> {
|
||||
Draw::new(&mut self.layout)
|
||||
Draw::new(&mut self.board.layout)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue