diff --git a/Cargo.toml b/Cargo.toml index 9b6ece9..48c580a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,6 @@ version = "0.11.0" [dependencies.petgraph] version = "0.6.3" -[dependencies.slab] -version = "0.4.9" - [dependencies.spade] version = "2.2.0" diff --git a/src/connectivity.rs b/src/connectivity.rs new file mode 100644 index 0000000..fcba316 --- /dev/null +++ b/src/connectivity.rs @@ -0,0 +1,42 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::StableDiGraph; + +use crate::{geometry::GetNet, graph::GenericIndex}; + +pub type ConnectivityGraph = StableDiGraph; + +#[enum_dispatch(GetNet)] +#[derive(Debug, Clone, Copy)] +pub enum ConnectivityWeight { + Component(ComponentWeight), + Band(BandWeight), +} + +#[derive(Debug, Clone, Copy)] +pub struct ComponentWeight { + pub net: i64, +} + +impl GetNet for ComponentWeight { + fn net(&self) -> i64 { + self.net + } +} + +#[derive(Debug, Clone, Copy)] +pub struct BandWeight { + pub net: i64, + pub width: f64, +} + +impl GetNet for BandWeight { + fn net(&self) -> i64 { + self.net + } +} + +pub type BandIndex = GenericIndex; + +#[enum_dispatch] +#[derive(Debug, Clone, Copy)] +pub enum ConnectivityLabel {} diff --git a/src/draw.rs b/src/draw.rs index 50d38a2..49c1ed7 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -3,8 +3,8 @@ use geo::{EuclideanLength, Point}; use thiserror::Error; use crate::{ - graph::{ - BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBand, GetNet, LooseBendIndex, + geometry::{ + BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetNet, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, WraparoundableIndex, }, diff --git a/src/geometry.rs b/src/geometry.rs new file mode 100644 index 0000000..f703eb0 --- /dev/null +++ b/src/geometry.rs @@ -0,0 +1,287 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::{NodeIndex, StableDiGraph}; +use std::marker::PhantomData; + +use crate::{ + connectivity::{BandIndex, BandWeight, ComponentWeight, ConnectivityWeight}, + graph::{GenericIndex, GetNodeIndex}, + layout::Layout, + math::Circle, + primitive::{GenericPrimitive, Primitive}, +}; + +#[enum_dispatch] +pub trait Retag { + fn retag(&self, index: NodeIndex) -> Index; +} + +#[enum_dispatch] +pub trait GetNet { + fn net(&self) -> i64; +} + +pub trait GetNetMut { + fn net_mut(&mut self) -> &mut i64; +} + +pub trait GetBandIndex { + fn band(&self) -> BandIndex; +} + +#[enum_dispatch] +pub trait GetWidth { + fn width(&self) -> f64; +} + +pub trait GetOffset { + fn offset(&self) -> f64; +} + +macro_rules! impl_weight { + ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { + impl Retag for $weight_struct { + fn retag(&self, index: NodeIndex) -> Index { + Index::$weight_variant($index_struct::new(index)) + } + } + + pub type $index_struct = GenericIndex<$weight_struct>; + + impl MakePrimitive for $index_struct { + fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a> { + Primitive::$weight_variant(GenericPrimitive::new(*self, layout)) + } + } + }; +} + +macro_rules! impl_fixed_weight { + ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { + impl_weight!($weight_struct, $weight_variant, $index_struct); + + impl GetNet for $weight_struct { + fn net(&self) -> i64 { + self.net + } + } + + impl GetNetMut for $weight_struct { + fn net_mut(&mut self) -> &mut i64 { + &mut self.net + } + } + }; +} + +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 + } + } + }; +} + +pub type GeometryGraph = StableDiGraph; + +#[enum_dispatch(Retag)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum GeometryWeight { + FixedDot(FixedDotWeight), + LooseDot(LooseDotWeight), + FixedSeg(FixedSegWeight), + LooseSeg(LooseSegWeight), + FixedBend(FixedBendWeight), + LooseBend(LooseBendWeight), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Index { + FixedDot(FixedDotIndex), + LooseDot(LooseDotIndex), + FixedSeg(FixedSegIndex), + LooseSeg(LooseSegIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum DotIndex { + Fixed(FixedDotIndex), + Loose(LooseDotIndex), +} + +impl From for Index { + fn from(dot: DotIndex) -> Self { + match dot { + DotIndex::Fixed(fixed) => Index::FixedDot(fixed), + DotIndex::Loose(loose) => Index::LooseDot(loose), + } + } +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum SegIndex { + Fixed(FixedSegIndex), + Loose(LooseSegIndex), +} + +impl From for Index { + fn from(seg: SegIndex) -> Self { + match seg { + SegIndex::Fixed(seg) => Index::FixedSeg(seg), + SegIndex::Loose(seg) => Index::LooseSeg(seg), + } + } +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum BendIndex { + Fixed(FixedBendIndex), + Loose(LooseBendIndex), +} + +impl From for Index { + fn from(bend: BendIndex) -> Self { + match bend { + BendIndex::Fixed(bend) => Index::FixedBend(bend), + BendIndex::Loose(bend) => Index::LooseBend(bend), + } + } +} + +impl From for WraparoundableIndex { + fn from(bend: BendIndex) -> Self { + match bend { + BendIndex::Fixed(bend) => WraparoundableIndex::FixedBend(bend), + BendIndex::Loose(bend) => WraparoundableIndex::LooseBend(bend), + } + } +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum WraparoundableIndex { + FixedDot(FixedDotIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + +impl From for Index { + fn from(wraparoundable: WraparoundableIndex) -> Self { + match wraparoundable { + WraparoundableIndex::FixedDot(dot) => Index::FixedDot(dot), + WraparoundableIndex::FixedBend(bend) => Index::FixedBend(bend), + WraparoundableIndex::LooseBend(bend) => Index::LooseBend(bend), + } + } +} +pub trait DotWeight: GetWidth + Into + Copy {} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FixedDotWeight { + pub net: i64, + pub circle: Circle, +} + +impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex); +impl DotWeight for FixedDotWeight {} + +impl GetWidth for FixedDotWeight { + fn width(&self) -> f64 { + self.circle.r * 2.0 + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct LooseDotWeight { + pub band: BandIndex, + pub circle: Circle, +} + +impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex); +impl DotWeight for LooseDotWeight {} + +impl GetWidth for LooseDotWeight { + fn width(&self) -> f64 { + self.circle.r * 2.0 + } +} + +pub trait SegWeight: Into + Copy {} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FixedSegWeight { + pub net: i64, + pub width: f64, +} + +impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex); +impl SegWeight for FixedSegWeight {} + +impl GetWidth for FixedSegWeight { + fn width(&self) -> f64 { + self.width + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct LooseSegWeight { + pub band: BandIndex, +} + +impl_loose_weight!(LooseSegWeight, LooseSeg, LooseSegIndex); +impl SegWeight for LooseSegWeight {} + +pub trait BendWeight: Into + Copy {} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FixedBendWeight { + pub net: i64, + pub width: f64, + pub cw: bool, +} + +impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex); +impl BendWeight for FixedBendWeight {} + +impl GetWidth for FixedBendWeight { + fn width(&self) -> f64 { + self.width + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct LooseBendWeight { + pub band: BandIndex, + pub offset: f64, + pub cw: bool, +} + +impl GetOffset for LooseBendWeight { + fn offset(&self) -> f64 { + self.offset + } +} + +impl_loose_weight!(LooseBendWeight, LooseBend, LooseBendIndex); +impl BendWeight for LooseBendWeight {} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum GeometryLabel { + Adjacent, + Outer, + Core, +} + +#[enum_dispatch] +pub trait MakePrimitive { + fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>; +} diff --git a/src/graph.rs b/src/graph.rs index 53ff905..5408380 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,298 +1,20 @@ -use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; use std::{ hash::{Hash, Hasher}, marker::PhantomData, }; -use crate::{ - layout::Layout, - math::Circle, - primitive::{GenericPrimitive, Primitive}, -}; +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::NodeIndex; -#[enum_dispatch] -pub trait Retag { - fn retag(&self, index: NodeIndex) -> Index; -} - -#[enum_dispatch] -pub trait GetNet { - fn net(&self) -> i64; -} - -pub trait GetNetMut { - fn net_mut(&mut self) -> &mut i64; -} - -pub trait GetBand { - fn band(&self) -> usize; -} - -#[enum_dispatch] -pub trait GetWidth { - fn width(&self) -> f64; -} - -pub trait GetOffset { - fn offset(&self) -> f64; -} - -macro_rules! impl_weight { - ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { - impl Retag for $weight_struct { - fn retag(&self, index: NodeIndex) -> Index { - Index::$weight_variant($index_struct { - node_index: index, - marker: PhantomData, - }) - } - } - - pub type $index_struct = GenericIndex<$weight_struct>; - - impl MakePrimitive for $index_struct { - fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a> { - Primitive::$weight_variant(GenericPrimitive::new(*self, layout)) - } - } - }; -} - -macro_rules! impl_fixed_weight { - ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { - impl_weight!($weight_struct, $weight_variant, $index_struct); - - impl GetNet for $weight_struct { - fn net(&self) -> i64 { - self.net - } - } - - impl GetNetMut for $weight_struct { - fn net_mut(&mut self) -> &mut i64 { - &mut self.net - } - } - }; -} - -macro_rules! impl_loose_weight { - ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { - impl_weight!($weight_struct, $weight_variant, $index_struct); - - impl GetBand for $weight_struct { - fn band(&self) -> usize { - self.band - } - } - }; -} - -#[enum_dispatch(Retag)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum Weight { - FixedDot(FixedDotWeight), - LooseDot(LooseDotWeight), - FixedSeg(FixedSegWeight), - LooseSeg(LooseSegWeight), - FixedBend(FixedBendWeight), - LooseBend(LooseBendWeight), -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum Index { - FixedDot(FixedDotIndex), - LooseDot(LooseDotIndex), - FixedSeg(FixedSegIndex), - LooseSeg(LooseSegIndex), - FixedBend(FixedBendIndex), - LooseBend(LooseBendIndex), -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum DotIndex { - Fixed(FixedDotIndex), - Loose(LooseDotIndex), -} - -impl From for Index { - fn from(dot: DotIndex) -> Self { - match dot { - DotIndex::Fixed(fixed) => Index::FixedDot(fixed), - DotIndex::Loose(loose) => Index::LooseDot(loose), - } - } -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum SegIndex { - Fixed(FixedSegIndex), - Loose(LooseSegIndex), -} - -impl From for Index { - fn from(seg: SegIndex) -> Self { - match seg { - SegIndex::Fixed(seg) => Index::FixedSeg(seg), - SegIndex::Loose(seg) => Index::LooseSeg(seg), - } - } -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum BendIndex { - Fixed(FixedBendIndex), - Loose(LooseBendIndex), -} - -impl From for Index { - fn from(bend: BendIndex) -> Self { - match bend { - BendIndex::Fixed(bend) => Index::FixedBend(bend), - BendIndex::Loose(bend) => Index::LooseBend(bend), - } - } -} - -impl From for WraparoundableIndex { - fn from(bend: BendIndex) -> Self { - match bend { - BendIndex::Fixed(bend) => WraparoundableIndex::FixedBend(bend), - BendIndex::Loose(bend) => WraparoundableIndex::LooseBend(bend), - } - } -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum WraparoundableIndex { - FixedDot(FixedDotIndex), - FixedBend(FixedBendIndex), - LooseBend(LooseBendIndex), -} - -impl From for Index { - fn from(wraparoundable: WraparoundableIndex) -> Self { - match wraparoundable { - WraparoundableIndex::FixedDot(dot) => Index::FixedDot(dot), - WraparoundableIndex::FixedBend(bend) => Index::FixedBend(bend), - WraparoundableIndex::LooseBend(bend) => Index::LooseBend(bend), - } - } -} -pub trait DotWeight: GetWidth + Into + Copy {} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct FixedDotWeight { - pub net: i64, - pub circle: Circle, -} - -impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex); -impl DotWeight for FixedDotWeight {} - -impl GetWidth for FixedDotWeight { - fn width(&self) -> f64 { - self.circle.r * 2.0 - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct LooseDotWeight { - pub band: usize, - pub circle: Circle, -} - -impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex); -impl DotWeight for LooseDotWeight {} - -impl GetWidth for LooseDotWeight { - fn width(&self) -> f64 { - self.circle.r * 2.0 - } -} - -pub trait SegWeight: Into + Copy {} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct FixedSegWeight { - pub net: i64, - pub width: f64, -} - -impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex); -impl SegWeight for FixedSegWeight {} - -impl GetWidth for FixedSegWeight { - fn width(&self) -> f64 { - self.width - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct LooseSegWeight { - pub band: usize, -} - -impl_loose_weight!(LooseSegWeight, LooseSeg, LooseSegIndex); -impl SegWeight for LooseSegWeight {} - -pub trait BendWeight: Into + Copy {} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct FixedBendWeight { - pub net: i64, - pub width: f64, - pub cw: bool, -} - -impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex); -impl BendWeight for FixedBendWeight {} - -impl GetWidth for FixedBendWeight { - fn width(&self) -> f64 { - self.width - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct LooseBendWeight { - pub band: usize, - pub offset: f64, - pub cw: bool, -} - -impl GetOffset for LooseBendWeight { - fn offset(&self) -> f64 { - self.offset - } -} - -impl_loose_weight!(LooseBendWeight, LooseBend, LooseBendIndex); -impl BendWeight for LooseBendWeight {} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum Label { - Adjacent, - Outer, - Core, -} +// Due to apparent limitations of enum_dispatch we're forced to import some types backwards. +use crate::connectivity::{BandWeight, ComponentWeight, ConnectivityWeight}; +use crate::geometry::{BendIndex, DotIndex, Index, SegIndex, WraparoundableIndex}; #[enum_dispatch] pub trait GetNodeIndex { fn node_index(&self) -> NodeIndex; } -#[enum_dispatch] -pub trait MakePrimitive { - fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>; -} - #[derive(Debug, Clone, Copy)] pub struct GenericIndex { node_index: NodeIndex, diff --git a/src/guide.rs b/src/guide.rs index de96ad4..6cd68d9 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -2,7 +2,8 @@ use enum_dispatch::enum_dispatch; use geo::Line; use crate::{ - graph::{BendIndex, DotIndex, FixedDotIndex, GetBand, LooseDotIndex, MakePrimitive}, + connectivity::BandIndex, + geometry::{BendIndex, DotIndex, FixedDotIndex, GetBandIndex, LooseDotIndex, MakePrimitive}, layout::Layout, math::{self, Circle, NoTangents}, primitive::{GetCore, GetInnerOuter, GetOtherEnd, GetWeight, MakeShape}, @@ -14,7 +15,7 @@ use crate::{ #[enum_dispatch] pub trait HeadTrait { fn face(&self) -> DotIndex; - fn band(&self) -> usize; + fn band(&self) -> BandIndex; } #[enum_dispatch(HeadTrait)] @@ -27,7 +28,7 @@ pub enum Head { #[derive(Debug, Clone, Copy)] pub struct BareHead { pub dot: FixedDotIndex, - pub band: usize, + pub band: BandIndex, } impl HeadTrait for BareHead { @@ -35,7 +36,7 @@ impl HeadTrait for BareHead { self.dot.into() } - fn band(&self) -> usize { + fn band(&self) -> BandIndex { self.band } } @@ -44,7 +45,7 @@ impl HeadTrait for BareHead { pub struct SegbendHead { pub face: LooseDotIndex, pub segbend: Segbend, - pub band: usize, + pub band: BandIndex, } impl HeadTrait for SegbendHead { @@ -52,7 +53,7 @@ impl HeadTrait for SegbendHead { self.face.into() } - fn band(&self) -> usize { + fn band(&self) -> BandIndex { self.band } } @@ -215,7 +216,7 @@ impl<'a, 'b> Guide<'a, 'b> { ) } - pub fn head(&self, dot: DotIndex, band: usize) -> Head { + pub fn head(&self, dot: DotIndex, band: BandIndex) -> Head { match dot { DotIndex::Fixed(fixed) => BareHead { dot: fixed, band }.into(), DotIndex::Loose(loose) => self.segbend_head(loose).into(), diff --git a/src/layout.rs b/src/layout.rs index 8b4b103..a47909b 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -6,15 +6,16 @@ use petgraph::visit::EdgeRef; use petgraph::Direction::Incoming; use rstar::primitives::GeomWithData; use rstar::{RTree, RTreeObject}; -use slab::Slab; use thiserror::Error; -use crate::graph::{ +use crate::connectivity::{BandIndex, ConnectivityLabel, ConnectivityWeight}; +use crate::geometry::{ BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex, - FixedSegWeight, GenericIndex, GetNet, GetNodeIndex, Index, Label, LooseBendIndex, + FixedSegWeight, GeometryGraph, GeometryLabel, GeometryWeight, GetNet, Index, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive, - Retag, SegWeight, Weight, WraparoundableIndex, + Retag, SegWeight, WraparoundableIndex, }; +use crate::graph::{GenericIndex, GetNodeIndex}; use crate::guide::Guide; use crate::math::NoTangents; use crate::primitive::{ @@ -52,31 +53,25 @@ pub struct Collision(pub Shape, pub Index); #[error("{1:?} is already connected to net {0}")] pub struct AlreadyConnected(pub i64, pub Index); -#[derive(Debug, Clone, Copy)] -pub struct Band { - pub net: i64, - pub width: f64, -} - #[derive(Debug)] pub struct Layout { rtree: RTree, - pub bands: Slab, - pub graph: StableDiGraph, + pub connectivity: StableDiGraph, + pub geometry: GeometryGraph, } -#[debug_invariant(self.graph.node_count() == self.rtree.size())] +#[debug_invariant(self.geometry.node_count() == self.rtree.size())] #[debug_invariant(self.test_envelopes())] impl Layout { pub fn new() -> Self { Layout { rtree: RTree::new(), - bands: Slab::new(), - graph: StableDiGraph::default(), + connectivity: StableDiGraph::default(), + geometry: StableDiGraph::default(), } } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 4))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count() - 4))] pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) { let maybe_outer = self.primitive(segbend.bend).outer(); @@ -99,18 +94,18 @@ impl Layout { } } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count() - 1))] fn remove(&mut self, index: Index) { // Unnecessary retag. It should be possible to elide it. - let weight = *self.graph.node_weight(index.node_index()).unwrap(); + let weight = *self.geometry.node_weight(index.node_index()).unwrap(); self.remove_from_rtree(weight.retag(index.node_index())); - self.graph.remove_node(index.node_index()); + self.geometry.remove_node(index.node_index()); } - #[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()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result { self.add_dot_infringably(weight, &[]) } @@ -122,8 +117,8 @@ impl Layout { self.add_dot_infringably(weight, &[]) }*/ - #[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()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] fn add_dot_infringably( &mut self, weight: W, @@ -132,7 +127,7 @@ impl Layout { where GenericIndex: Into + Copy, { - let dot = GenericIndex::::new(self.graph.add_node(weight.into())); + let dot = GenericIndex::::new(self.geometry.add_node(weight.into())); self.insert_into_rtree(dot.into()); self.fail_and_remove_if_infringes_except(dot.into(), infringables)?; @@ -140,10 +135,10 @@ impl Layout { Ok(dot) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn add_fixed_seg( &mut self, from: FixedDotIndex, @@ -153,10 +148,10 @@ impl Layout { self.add_seg_infringably(from, to, weight, &[]) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn insert_segbend( &mut self, from: DotIndex, @@ -204,8 +199,8 @@ impl Layout { Ok::(segbend) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec { let bend_primitive = self.primitive(bend); let mut v = vec![]; @@ -224,8 +219,8 @@ impl Layout { v } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec { let bend_primitive = self.primitive(bend); let mut v = vec![]; @@ -247,8 +242,8 @@ impl Layout { v } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec { match around { WraparoundableIndex::FixedDot(dot) => { @@ -276,8 +271,8 @@ impl Layout { } // XXX: Move this to primitives? - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn bow(&self, bend: LooseBendIndex) -> Vec { let mut bow: Vec = vec![]; bow.push(bend.into()); @@ -297,8 +292,8 @@ impl Layout { bow } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn outer_bows(&self, bend: LooseBendIndex) -> Vec { let mut outer_bows = vec![]; let mut rail = bend; @@ -344,32 +339,35 @@ impl Layout { outer_bows*/ } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()) - || self.graph.edge_count() == old(self.graph.edge_count() - 1) - || self.graph.edge_count() == old(self.graph.edge_count() + 1))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()) + || self.geometry.edge_count() == old(self.geometry.edge_count() - 1) + || self.geometry.edge_count() == old(self.geometry.edge_count() + 1))] fn reattach_bend(&mut self, bend: LooseBendIndex, maybe_new_inner: Option) { self.remove_from_rtree(bend.into()); if let Some(old_inner_edge) = self - .graph + .geometry .edges_directed(bend.node_index(), Incoming) - .filter(|edge| *edge.weight() == Label::Outer) + .filter(|edge| *edge.weight() == GeometryLabel::Outer) .next() { - self.graph.remove_edge(old_inner_edge.id()); + self.geometry.remove_edge(old_inner_edge.id()); } if let Some(new_inner) = maybe_new_inner { - self.graph - .add_edge(new_inner.node_index(), bend.node_index(), Label::Outer); + self.geometry.add_edge( + new_inner.node_index(), + bend.node_index(), + GeometryLabel::Outer, + ); } self.insert_into_rtree(bend.into()); } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn update_this_and_outward_bows( &mut self, around: LooseBendIndex, @@ -415,10 +413,10 @@ impl Layout { Ok::<(), LayoutException>(()) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn add_segbend( &mut self, from: DotIndex, @@ -437,10 +435,10 @@ impl Layout { ) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] fn add_segbend_infringably( &mut self, from: DotIndex, @@ -481,10 +479,10 @@ impl Layout { }) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn add_loose_seg( &mut self, from: DotIndex, @@ -494,10 +492,10 @@ impl Layout { self.add_seg_infringably(from, to, weight, &[]) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] fn add_seg_infringably( &mut self, from: impl GetNodeIndex, @@ -508,12 +506,12 @@ impl Layout { where GenericIndex: Into + Copy, { - let seg = GenericIndex::::new(self.graph.add_node(weight.into())); + let seg = GenericIndex::::new(self.geometry.add_node(weight.into())); - self.graph - .add_edge(from.node_index(), seg.node_index(), Label::Adjacent); - self.graph - .add_edge(seg.node_index(), to.node_index(), Label::Adjacent); + self.geometry + .add_edge(from.node_index(), seg.node_index(), GeometryLabel::Adjacent); + self.geometry + .add_edge(seg.node_index(), to.node_index(), GeometryLabel::Adjacent); self.insert_into_rtree(seg.into()); self.fail_and_remove_if_infringes_except(seg.into(), infringables)?; @@ -537,11 +535,11 @@ impl Layout { } }*/ - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3) - || self.graph.edge_count() == old(self.graph.edge_count() + 4))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3) + || self.geometry.edge_count() == old(self.geometry.edge_count() + 4))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] fn add_loose_bend_infringably( &mut self, from: LooseDotIndex, @@ -551,13 +549,14 @@ impl Layout { infringables: &[Index], ) -> Result { // It makes no sense to wrap something around or under one of its connectables. - let net = self.bands[weight.band].net; + let net = self + .connectivity + .node_weight(weight.band.node_index()) + .unwrap() + .net(); // if net == around.primitive(self).net() { - return Err(AlreadyConnected( - net, - around.into(), - ).into()); + return Err(AlreadyConnected(net, around.into()).into()); } // if let Some(wraparound) = match around { @@ -566,10 +565,7 @@ impl Layout { WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(), } { if net == wraparound.primitive(self).net() { - return Err(AlreadyConnected( - net, - wraparound.into(), - ).into()); + return Err(AlreadyConnected(net, wraparound.into()).into()); } } @@ -586,10 +582,10 @@ impl Layout { } } - #[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()))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] fn add_core_bend_infringably( &mut self, from: impl GetNodeIndex, @@ -601,24 +597,27 @@ impl Layout { where GenericIndex: Into + Copy, { - let bend = LooseBendIndex::new(self.graph.add_node(weight.into())); + let bend = LooseBendIndex::new(self.geometry.add_node(weight.into())); - self.graph - .add_edge(from.node_index(), bend.node_index(), Label::Adjacent); - self.graph - .add_edge(bend.node_index(), to.node_index(), Label::Adjacent); - self.graph - .add_edge(bend.node_index(), core.node_index(), Label::Core); + self.geometry.add_edge( + from.node_index(), + bend.node_index(), + GeometryLabel::Adjacent, + ); + self.geometry + .add_edge(bend.node_index(), to.node_index(), GeometryLabel::Adjacent); + self.geometry + .add_edge(bend.node_index(), core.node_index(), GeometryLabel::Core); self.insert_into_rtree(bend.into()); self.fail_and_remove_if_infringes_except(bend.into(), infringables)?; Ok(bend) } - #[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()))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))] - #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 4))] + #[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] fn add_outer_bend_infringably( &mut self, from: impl GetNodeIndex, @@ -628,14 +627,14 @@ impl Layout { infringables: &[Index], ) -> Result { let core = *self - .graph + .geometry .neighbors(inner.node_index()) .filter(|ni| { matches!( - self.graph - .edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap()) + self.geometry + .edge_weight(self.geometry.find_edge(inner.node_index(), *ni).unwrap()) .unwrap(), - Label::Core + GeometryLabel::Core ) }) .map(|ni| FixedDotIndex::new(ni)) @@ -643,28 +642,33 @@ impl Layout { .first() .unwrap(); - let bend = LooseBendIndex::new(self.graph.add_node(weight.into())); + let bend = LooseBendIndex::new(self.geometry.add_node(weight.into())); - self.graph - .add_edge(from.node_index(), bend.node_index(), Label::Adjacent); - self.graph - .add_edge(bend.node_index(), to.node_index(), Label::Adjacent); - self.graph - .add_edge(bend.node_index(), core.node_index(), Label::Core); - self.graph - .add_edge(inner.node_index(), bend.node_index(), Label::Outer); + self.geometry.add_edge( + from.node_index(), + bend.node_index(), + GeometryLabel::Adjacent, + ); + self.geometry + .add_edge(bend.node_index(), to.node_index(), GeometryLabel::Adjacent); + self.geometry + .add_edge(bend.node_index(), core.node_index(), GeometryLabel::Core); + self.geometry + .add_edge(inner.node_index(), bend.node_index(), GeometryLabel::Outer); self.insert_into_rtree(bend.into()); self.fail_and_remove_if_infringes_except(bend.into(), infringables)?; Ok(bend) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn flip_bend(&mut self, bend: FixedBendIndex) { self.remove_from_rtree(bend.into()); - let Some(Weight::FixedBend(weight)) = self.graph.node_weight_mut(bend.node_index()) else { + let Some(GeometryWeight::FixedBend(weight)) = + self.geometry.node_weight_mut(bend.node_index()) + else { unreachable!(); }; @@ -681,9 +685,9 @@ impl Layout { Segbend::from_dot(dot, self) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count()))] - #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count() - 1))] + #[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count()))] + #[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count() - 1))] fn fail_and_remove_if_infringes_except( &mut self, index: Index, @@ -705,7 +709,7 @@ impl Layout { } pub fn node_count(&self) -> usize { - self.graph.node_count() + self.geometry.node_count() } fn node_indices(&self) -> impl Iterator + '_ { @@ -723,8 +727,8 @@ impl Layout { ) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn move_dot_infringably( &mut self, dot: LooseDotIndex, @@ -741,11 +745,13 @@ impl Layout { let old_weight = dot_weight; dot_weight.circle.pos = to; - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight); + *self.geometry.node_weight_mut(dot.node_index()).unwrap() = + GeometryWeight::LooseDot(dot_weight); if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) { // Restore original state. - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight); + *self.geometry.node_weight_mut(dot.node_index()).unwrap() = + GeometryWeight::LooseDot(old_weight); self.insert_into_rtree(dot.into()); self.insert_into_rtree(self.primitive(dot).bend().into()); @@ -764,14 +770,14 @@ impl Layout { Ok(()) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { GenericPrimitive::new(index, self) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn detect_infringement_except(&self, index: Index, except: &[Index]) -> Option { let shape = index.primitive(self).shape(); @@ -789,8 +795,8 @@ impl Layout { } // TODO: Collision and infringement are the same for now. Change this. - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn detect_collision(&self, index: Index) -> Option { let shape = index.primitive(self).shape(); @@ -806,15 +812,15 @@ impl Layout { .and_then(|collidee| Some(Collision(shape, collidee))) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn insert_into_rtree(&mut self, index: Index) { let shape = index.primitive(self).shape(); self.rtree.insert(RTreeWrapper::new(shape, index)); } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn remove_from_rtree(&mut self, index: Index) { let shape = index.primitive(self).shape(); let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index)); diff --git a/src/main.rs b/src/main.rs index c67a099..0d808b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,10 +8,11 @@ macro_rules! dbg_dot { }; } -#[macro_use] -mod graph; mod astar; +mod connectivity; mod draw; +mod geometry; +mod graph; mod guide; mod layout; mod math; @@ -26,7 +27,7 @@ mod triangulation; use draw::DrawException; use geo::point; -use graph::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive}; +use geometry::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive}; use layout::{Infringement, Layout, LayoutException}; use mesh::{Mesh, MeshEdgeReference, VertexIndex}; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; @@ -54,7 +55,7 @@ use pathfinder_resources::embedded::EmbeddedResourceLoader; use std::time::Duration; use tracer::{Trace, Tracer}; -use crate::graph::FixedDotWeight; +use crate::geometry::FixedDotWeight; use crate::math::Circle; use crate::router::Router; diff --git a/src/mesh.rs b/src/mesh.rs index 0562e40..f1b2db1 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -10,7 +10,8 @@ use spade::{HasPosition, InsertionError, Point2}; use crate::primitive::{GetCore, Primitive}; use crate::triangulation::TriangulationEdgeReference; use crate::{ - graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex, MakePrimitive}, + geometry::{FixedBendIndex, FixedDotIndex, Index, LooseBendIndex, MakePrimitive}, + graph::GetNodeIndex, layout::Layout, primitive::MakeShape, shape::ShapeTrait, @@ -74,7 +75,7 @@ impl Mesh { vertex_to_triangulation_vertex: Vec::new(), }; this.vertex_to_triangulation_vertex - .resize(layout.graph.node_bound(), None); + .resize(layout.geometry.node_bound(), None); this } diff --git a/src/primitive.rs b/src/primitive.rs index 4c560ca..de85df7 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -4,12 +4,13 @@ use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; use petgraph::Direction::{Incoming, Outgoing}; -use crate::graph::{ - DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GenericIndex, - GetBand, GetNet, GetNodeIndex, GetOffset, GetWidth, Index, Label, LooseBendIndex, +use crate::geometry::{ + DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryLabel, + GeometryWeight, GetBandIndex, GetNet, GetOffset, GetWidth, Index, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive, - Retag, Weight, + Retag, }; +use crate::graph::{GenericIndex, GetNodeIndex}; use crate::layout::Layout; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; @@ -65,20 +66,20 @@ pub trait GetWraparound: GetLayout + GetNodeIndex { pub trait GetFirstRail: GetLayout + GetNodeIndex { fn first_rail(&self) -> Option { self.layout() - .graph + .geometry .neighbors_directed(self.node_index(), Incoming) .filter(|ni| { matches!( self.layout() - .graph + .geometry .edge_weight( self.layout() - .graph + .geometry .find_edge(*ni, self.node_index()) .unwrap() ) .unwrap(), - Label::Core + GeometryLabel::Core ) }) .map(|ni| LooseBendIndex::new(ni)) @@ -89,20 +90,20 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex { pub trait GetCore: GetLayout + GetNodeIndex { fn core(&self) -> FixedDotIndex { self.layout() - .graph + .geometry .neighbors(self.node_index()) .filter(|ni| { matches!( self.layout() - .graph + .geometry .edge_weight( self.layout() - .graph + .geometry .find_edge(self.node_index(), *ni) .unwrap() ) .unwrap(), - Label::Core + GeometryLabel::Core ) }) .map(|ni| FixedDotIndex::new(ni)) @@ -114,20 +115,20 @@ pub trait GetCore: GetLayout + GetNodeIndex { pub trait GetInnerOuter: GetLayout + GetNodeIndex { fn inner(&self) -> Option { self.layout() - .graph + .geometry .neighbors_directed(self.node_index(), Incoming) .filter(|ni| { matches!( self.layout() - .graph + .geometry .edge_weight( self.layout() - .graph + .geometry .find_edge(*ni, self.node_index()) .unwrap() ) .unwrap(), - Label::Outer + GeometryLabel::Outer ) }) .map(|ni| LooseBendIndex::new(ni)) @@ -136,20 +137,20 @@ pub trait GetInnerOuter: GetLayout + GetNodeIndex { fn outer(&self) -> Option { self.layout() - .graph + .geometry .neighbors_directed(self.node_index(), Outgoing) .filter(|ni| { matches!( self.layout() - .graph + .geometry .edge_weight( self.layout() - .graph + .geometry .find_edge(self.node_index(), *ni) .unwrap() ) .unwrap(), - Label::Outer + GeometryLabel::Outer ) }) .map(|ni| LooseBendIndex::new(ni)) @@ -161,7 +162,7 @@ macro_rules! impl_primitive { ($primitive_struct:ident, $weight_struct:ident) => { impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> { fn weight(&self) -> $weight_struct { - if let Weight::$primitive_struct(weight) = self.tagged_weight() { + if let GeometryWeight::$primitive_struct(weight) = self.tagged_weight() { weight } else { unreachable!() @@ -189,7 +190,11 @@ macro_rules! impl_loose_primitive { impl<'a> GetNet for $primitive_struct<'a> { fn net(&self) -> i64 { - self.layout().bands[self.weight().band()].net + self.layout() + .connectivity + .node_weight(self.weight().band().node_index()) + .unwrap() + .net() } } }; @@ -216,31 +221,31 @@ impl<'a, W> GenericPrimitive<'a, W> { Self { index, layout } } - fn tagged_weight(&self) -> Weight { + fn tagged_weight(&self) -> GeometryWeight { *self .layout - .graph + .geometry .node_weight(self.index.node_index()) .unwrap() } fn adjacents(&self) -> Vec> { self.layout - .graph + .geometry .neighbors_undirected(self.index.node_index()) .filter(|ni| { matches!( self.layout - .graph + .geometry .edge_weight( self.layout - .graph + .geometry .find_edge_undirected(self.index.node_index(), *ni) .unwrap() .0, ) .unwrap(), - Label::Adjacent + GeometryLabel::Adjacent ) }) .collect() @@ -303,27 +308,27 @@ impl_loose_primitive!(LooseDot, LooseDotWeight); impl<'a> LooseDot<'a> { pub fn seg(&self) -> Option { self.layout - .graph + .geometry .neighbors_undirected(self.index.node_index()) .filter(|ni| { matches!( self.layout - .graph + .geometry .edge_weight( self.layout - .graph + .geometry .find_edge_undirected(self.index.node_index(), *ni) .unwrap() .0, ) .unwrap(), - Label::Adjacent + GeometryLabel::Adjacent ) }) .filter(|ni| { matches!( - self.layout.graph.node_weight(*ni).unwrap(), - Weight::LooseSeg(..) + self.layout.geometry.node_weight(*ni).unwrap(), + GeometryWeight::LooseSeg(..) ) }) .map(|ni| LooseSegIndex::new(ni)) @@ -332,27 +337,27 @@ impl<'a> LooseDot<'a> { pub fn bend(&self) -> LooseBendIndex { self.layout - .graph + .geometry .neighbors_undirected(self.index.node_index()) .filter(|ni| { matches!( self.layout - .graph + .geometry .edge_weight( self.layout - .graph + .geometry .find_edge_undirected(self.index.node_index(), *ni) .unwrap() .0, ) .unwrap(), - Label::Adjacent + GeometryLabel::Adjacent ) }) .filter(|ni| { matches!( - self.layout.graph.node_weight(*ni).unwrap(), - Weight::LooseBend(..) + self.layout.geometry.node_weight(*ni).unwrap(), + GeometryWeight::LooseBend(..) ) }) .map(|ni| LooseBendIndex::new(ni)) @@ -418,9 +423,10 @@ impl<'a> GetWidth for LooseSeg<'a> { impl<'a> GetEnds for LooseSeg<'a> { fn ends(&self) -> (DotIndex, LooseDotIndex) { let v = self.adjacents(); - if let Weight::FixedDot(..) = self.layout.graph.node_weight(v[0]).unwrap() { + if let GeometryWeight::FixedDot(..) = self.layout.geometry.node_weight(v[0]).unwrap() { (FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) - } else if let Weight::FixedDot(..) = self.layout.graph.node_weight(v[1]).unwrap() { + } else if let GeometryWeight::FixedDot(..) = self.layout.geometry.node_weight(v[1]).unwrap() + { (FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0])) } else { (LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) diff --git a/src/router.rs b/src/router.rs index fcdd9d9..5c23ed1 100644 --- a/src/router.rs +++ b/src/router.rs @@ -5,7 +5,7 @@ use thiserror::Error; use crate::astar::{astar, AstarStrategy, PathTracker}; use crate::draw::DrawException; -use crate::graph::FixedDotIndex; +use crate::geometry::FixedDotIndex; use crate::layout::Layout; use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex}; @@ -121,12 +121,11 @@ impl Router { // 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(), - })?; + mesh.generate(&self.layout).map_err(|err| RoutingError { + from, + to, + source: err.into(), + })?; let mut tracer = self.tracer(&mesh); let trace = tracer.start(from, 3.0); @@ -135,7 +134,8 @@ impl Router { &mesh, from.into(), &mut RouterAstarStrategy::new(tracer, trace, to.into(), observer), - ).ok_or(RoutingError { + ) + .ok_or(RoutingError { from, to, source: RoutingErrorKind::AStar, diff --git a/src/segbend.rs b/src/segbend.rs index db44c48..fe05227 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -1,5 +1,5 @@ use crate::{ - graph::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex}, + geometry::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex}, layout::Layout, primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot}, }; diff --git a/src/tracer.rs b/src/tracer.rs index c7a6d67..bd62cd0 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -1,10 +1,11 @@ use contracts::debug_ensures; use crate::{ + connectivity::{BandIndex, BandWeight, ConnectivityWeight}, draw::{Draw, DrawException}, - graph::{FixedDotIndex, GetNet, LooseBendIndex}, + geometry::{FixedDotIndex, GetNet, LooseBendIndex}, guide::{BareHead, Head, SegbendHead}, - layout::{Band, Layout, LayoutException}, + layout::{Layout, LayoutException}, mesh::{Mesh, VertexIndex}, rules::Rules, }; @@ -31,10 +32,12 @@ impl<'a> Tracer<'a> { } pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace { - let band = self.layout.bands.insert(Band { - width, - net: self.layout.primitive(from).net(), - }); + let band = BandIndex::new(self.layout.connectivity.add_node(ConnectivityWeight::Band( + BandWeight { + width, + net: self.layout.primitive(from).net(), + }, + ))); Trace { path: vec![from.into()], head: BareHead { dot: from, band }.into(), diff --git a/src/triangulation.rs b/src/triangulation.rs index 08eed16..f89bd5b 100644 --- a/src/triangulation.rs +++ b/src/triangulation.rs @@ -27,7 +27,7 @@ impl + HasPosition