diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index f36e54a..ebe4541 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -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 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 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 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, }; diff --git a/src/draw.rs b/src/draw.rs index dc8a0a4..f947e4e 100644 --- a/src/draw.rs +++ b/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 { + 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 { 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 { diff --git a/src/dsn/design.rs b/src/dsn/design.rs index 55b63e1..1c89faf 100644 --- a/src/dsn/design.rs +++ b/src/dsn/design.rs @@ -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, }, ) diff --git a/src/layout/band.rs b/src/layout/band.rs deleted file mode 100644 index f621525..0000000 --- a/src/layout/band.rs +++ /dev/null @@ -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, -} - -impl<'a, R: RulesTrait> Band<'a, R> { - pub fn new(index: BandIndex, layout: &'a Layout) -> 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 { - // 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 - } -} diff --git a/src/layout/bend.rs b/src/layout/bend.rs index bef35bf..0aa4945 100644 --- a/src/layout/bend.rs +++ b/src/layout/bend.rs @@ -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 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, } diff --git a/src/layout/connectivity.rs b/src/layout/connectivity.rs deleted file mode 100644 index c7ee7fd..0000000 --- a/src/layout/connectivity.rs +++ /dev/null @@ -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; - -#[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; - -#[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; - -#[derive(Debug, Clone, Copy)] -pub enum ConnectivityLabel { - Band, -} diff --git a/src/layout/dot.rs b/src/layout/dot.rs index 0136c2d..814984b 100644 --- a/src/layout/dot.rs +++ b/src/layout/dot.rs @@ -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 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, } diff --git a/src/layout/graph.rs b/src/layout/graph.rs index 546b6cd..0ef8432 100644 --- a/src/layout/graph.rs +++ b/src/layout/graph.rs @@ -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 { } #[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 - } - } }; } diff --git a/src/layout/guide.rs b/src/layout/guide.rs index f545c26..867ec07 100644 --- a/src/layout/guide.rs +++ b/src/layout/guide.rs @@ -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(), } } diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 75e9c73..a52f2ff 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -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 { SegIndex, BendIndex, >, - connectivity: ConnectivityGraph, rules: R, } @@ -89,19 +83,17 @@ impl Layout { 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 Layout { 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 Layout { } } - // 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 Layout { weight: LoneLooseSegWeight, ) -> Result { 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 Layout { weight: SeqLooseSegWeight, ) -> Result { 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 Layout { 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 { - 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 Layout { infringables: &[GeometryIndex], ) -> Result { // 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 Layout { } impl Layout { - #[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 Layout { pub fn loose(&self, index: LooseIndex) -> Loose { 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 { - Band::new(index, self) - } } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 508c9ed..9a3e2d2 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -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; diff --git a/src/layout/primitive.rs b/src/layout/primitive.rs index 4c7a97b..6c953a6 100644 --- a/src/layout/primitive.rs +++ b/src/layout/primitive.rs @@ -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() - } - } }; } diff --git a/src/layout/seg.rs b/src/layout/seg.rs index 0478fa1..67af603 100644 --- a/src/layout/seg.rs +++ b/src/layout/seg.rs @@ -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 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, } diff --git a/src/lib.rs b/src/lib.rs index e0b2dac..31dddbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/router.rs b/src/router.rs index 894bf35..f2cdf31 100644 --- a/src/router.rs +++ b/src/router.rs @@ -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 { } pub struct Router { - pub layout: Layout, + pub board: Board, } struct RouterAstarStrategy<'a, RO: RouterObserverTrait, R: RulesTrait> { @@ -84,24 +84,14 @@ impl<'a, RO: RouterObserverTrait, 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 { @@ -110,18 +100,14 @@ impl<'a, RO: RouterObserverTrait, 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: 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 Router { - pub fn new(layout: Layout) -> Self { - Router { layout } + pub fn new(board: Board) -> Self { + Router { board } } pub fn route_band( @@ -157,16 +143,17 @@ impl Router { // 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 Router { width: f64, observer: &mut impl RouterObserverTrait, ) -> Result { - 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 { - Tracer::new(&mut self.layout, mesh) + Tracer::new(&mut self.board, mesh) } } diff --git a/src/tracer.rs b/src/tracer.rs index 72d9d03..9faff89 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -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, pub head: Head, + pub band: BandIndex, + pub width: f64, } pub struct Tracer<'a, R: RulesTrait> { - pub layout: &'a mut Layout, + pub board: &'a mut Board, pub mesh: &'a Mesh, } impl<'a, R: RulesTrait> Tracer<'a, R> { - pub fn new(layout: &'a mut Layout, mesh: &'a Mesh) -> Self { - Tracer { layout, mesh } + pub fn new(board: &'a mut Board, 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 { - Draw::new(&mut self.layout) + Draw::new(&mut self.board.layout) } }