From a2531b078df9372aa77ef1df9b887790c42775ff Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 22 Oct 2023 02:05:22 +0000 Subject: [PATCH] graph,primitive: Split the 3 primitives into 7 `Dot` becomes `FixedDot` and `LooseDot`. `Seg` becomes `FixedSeg`, `HalfLooseSeg`, and `FullyLooseSeg`. `Bend` becomes `FixedBend` and `LooseBend`. The fixed variants differ from the loose variants by being unchangeable for the router (though probably will be pushable in some cases, but that's for later). So typically tey're going to be the initial conditions. For now only the fixed variants are used even if actually loose, to split this change into several commits. --- src/band.rs | 22 ++-- src/bow.rs | 53 +++++----- src/draw.rs | 61 +++++------ src/graph.rs | 113 ++++++++++++++++---- src/guide.rs | 16 +-- src/layout.rs | 139 +++++++++++++------------ src/main.rs | 84 +++++++-------- src/mesh.rs | 6 +- src/primitive.rs | 264 ++++++++++++++++++++++++++++++++--------------- src/router.rs | 33 +++--- src/segbend.rs | 45 ++++---- src/tracer.rs | 21 ++-- 12 files changed, 527 insertions(+), 330 deletions(-) diff --git a/src/band.rs b/src/band.rs index b6dc0ad..ab4d64c 100644 --- a/src/band.rs +++ b/src/band.rs @@ -1,22 +1,22 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ - graph::{DotIndex, Ends, Index, Interior, Label, MakePrimitive, Weight}, + graph::{DotIndex, Ends, FixedDotIndex, Index, Interior, Label, MakePrimitive, Weight}, primitive::TaggedPrevTaggedNext, }; pub struct Band { - from: DotIndex, - to: DotIndex, + from: FixedDotIndex, + to: FixedDotIndex, interior: Vec, } impl Band { pub fn from_dot_prev( - dot: DotIndex, + dot: FixedDotIndex, graph: &StableDiGraph, ) -> Option { - let mut next_index = Index::Dot(dot); + let mut next_index: Index = dot.into(); let mut interior = vec![]; while let Some(index) = next_index.primitive(graph).tagged_prev() { @@ -28,7 +28,7 @@ impl Band { None } else { Some(Self { - from: interior.pop().unwrap().into_dot().unwrap(), + from: interior.pop().unwrap().into_fixed_dot().unwrap(), to: dot, interior, }) @@ -36,10 +36,10 @@ impl Band { } pub fn from_dot_next( - dot: DotIndex, + dot: FixedDotIndex, graph: &StableDiGraph, ) -> Option { - let mut prev_index = Index::Dot(dot); + let mut prev_index: Index = dot.into(); let mut interior = vec![]; while let Some(index) = prev_index.primitive(graph).tagged_next() { @@ -52,7 +52,7 @@ impl Band { } else { Some(Self { from: dot, - to: interior.pop().unwrap().into_dot().unwrap(), + to: interior.pop().unwrap().into_fixed_dot().unwrap(), interior, }) } @@ -66,8 +66,8 @@ impl Interior for Band { } } -impl Ends for Band { - fn ends(&self) -> (DotIndex, DotIndex) { +impl Ends for Band { + fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { (self.from, self.to) } } diff --git a/src/bow.rs b/src/bow.rs index eb8f92f..d54c5cd 100644 --- a/src/bow.rs +++ b/src/bow.rs @@ -1,38 +1,41 @@ use petgraph::stable_graph::StableDiGraph; -use crate::graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}; -use crate::primitive::{Bend, Dot, Seg, TaggedPrevTaggedNext}; +use crate::graph::{ + BendIndex, DotIndex, Ends, FixedBendIndex, FixedDotIndex, FixedSegIndex, Index, Interior, + Label, SegIndex, Weight, +}; +use crate::primitive::{FixedBend, FixedDot, FixedSeg, TaggedPrevTaggedNext}; #[derive(Debug, Clone, Copy)] pub struct Bow { - seg1_dot1: DotIndex, - seg1: SegIndex, - seg1_dot2: DotIndex, - bend: BendIndex, - seg2_dot1: DotIndex, - seg2: SegIndex, - seg2_dot2: DotIndex, + seg1_dot1: FixedDotIndex, + seg1: FixedSegIndex, + seg1_dot2: FixedDotIndex, + bend: FixedBendIndex, + seg2_dot1: FixedDotIndex, + seg2: FixedSegIndex, + seg2_dot2: FixedDotIndex, } impl Bow { - pub fn from_bend(index: BendIndex, graph: &StableDiGraph) -> Self { + pub fn from_bend(index: FixedBendIndex, graph: &StableDiGraph) -> Self { let bend = index; - let seg1_dot2 = Bend::new(bend, graph).prev().unwrap(); - let seg1 = Dot::new(seg1_dot2, graph) + let seg1_dot2 = FixedBend::new(bend, graph).prev().unwrap(); + let seg1 = FixedDot::new(seg1_dot2, graph) .tagged_prev() .unwrap() - .into_seg() + .into_fixed_seg() .unwrap(); - let seg1_dot1 = Seg::new(seg1, graph).prev().unwrap(); + let seg1_dot1 = FixedSeg::new(seg1, graph).prev().unwrap(); - let seg2_dot1 = Bend::new(bend, graph).next().unwrap(); - let seg2 = Dot::new(seg2_dot1, graph) + let seg2_dot1 = FixedBend::new(bend, graph).next().unwrap(); + let seg2 = FixedDot::new(seg2_dot1, graph) .tagged_next() .unwrap() - .into_seg() + .into_fixed_seg() .unwrap(); - let seg2_dot2 = Seg::new(seg2, graph).next().unwrap(); + let seg2_dot2 = FixedSeg::new(seg2, graph).next().unwrap(); Self { seg1_dot1, @@ -49,17 +52,17 @@ impl Bow { impl Interior for Bow { fn interior(&self) -> Vec { vec![ - Index::Seg(self.seg1), - Index::Dot(self.seg1_dot2), - Index::Bend(self.bend), - Index::Dot(self.seg2_dot1), - Index::Seg(self.seg2), + self.seg1.into(), + self.seg1_dot2.into(), + self.bend.into(), + self.seg2_dot1.into(), + self.seg2.into(), ] } } -impl Ends for Bow { - fn ends(&self) -> (DotIndex, DotIndex) { +impl Ends for Bow { + fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { (self.seg1_dot1, self.seg2_dot2) } } diff --git a/src/draw.rs b/src/draw.rs index 258d1de..c1f7046 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -3,7 +3,10 @@ use enum_dispatch::enum_dispatch; use geo::{EuclideanLength, Point}; use crate::{ - graph::{BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, SegIndex, SegWeight}, + graph::{ + BendIndex, DotIndex, Ends, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, + FixedSegIndex, FixedSegWeight, Index, SegIndex, + }, guide::Guide, layout::Layout, math::Circle, @@ -14,7 +17,7 @@ use crate::{ #[enum_dispatch] pub trait HeadTrait { - fn dot(&self) -> DotIndex; + fn dot(&self) -> FixedDotIndex; } #[enum_dispatch(HeadTrait)] @@ -26,23 +29,23 @@ pub enum Head { #[derive(Debug, Clone, Copy)] pub struct BareHead { - pub dot: DotIndex, + pub dot: FixedDotIndex, } impl HeadTrait for BareHead { - fn dot(&self) -> DotIndex { + fn dot(&self) -> FixedDotIndex { self.dot } } #[derive(Debug, Clone, Copy)] pub struct SegbendHead { - pub dot: DotIndex, + pub dot: FixedDotIndex, pub segbend: Segbend, } impl HeadTrait for SegbendHead { - fn dot(&self) -> DotIndex { + fn dot(&self) -> FixedDotIndex { self.dot } } @@ -57,13 +60,13 @@ impl<'a> Draw<'a> { Self { layout, rules } } - pub fn start(&mut self, from: DotIndex) -> Head { + pub fn start(&mut self, from: FixedDotIndex) -> Head { self.prev_head(from) } #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] - pub fn finish(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> { + pub fn finish(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> { if let Some(bend) = self.layout.primitive(into).bend() { self.finish_in_bend(head, bend, into, width)?; } else { @@ -74,7 +77,7 @@ impl<'a> Draw<'a> { #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] - fn finish_in_dot(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> { + fn finish_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> { let tangent = self .guide(&Default::default()) .head_into_dot_segment(&head, into, width)?; @@ -82,7 +85,7 @@ impl<'a> Draw<'a> { let net = self.layout.primitive(head.dot()).weight().net; self.layout - .add_seg(head.dot(), into, SegWeight { net, width })?; + .add_seg(head.dot(), into, FixedSegWeight { net, width })?; Ok(()) } @@ -91,8 +94,8 @@ impl<'a> Draw<'a> { fn finish_in_bend( &mut self, head: Head, - into_bend: BendIndex, - into: DotIndex, + into_bend: FixedBendIndex, + into: FixedDotIndex, width: f64, ) -> Result<(), ()> { let to_head = self.next_head(into); @@ -106,7 +109,7 @@ impl<'a> Draw<'a> { let net = self.layout.primitive(head.dot()).weight().net; self.layout - .add_seg(head.dot(), into, SegWeight { net, width })?; + .add_seg(head.dot(), into, FixedSegWeight { net, width })?; Ok(()) } @@ -115,7 +118,7 @@ impl<'a> Draw<'a> { pub fn segbend_around_dot( &mut self, head: Head, - around: DotIndex, + around: FixedDotIndex, width: f64, ) -> Result { let mut tangents = self @@ -134,7 +137,7 @@ impl<'a> Draw<'a> { .find_map(|(i, tangent)| { self.segbend_around( head, - Index::Dot(around), + around.into(), tangent.start_point(), tangent.end_point(), dirs[i], @@ -150,7 +153,7 @@ impl<'a> Draw<'a> { pub fn segbend_around_bend( &mut self, head: Head, - around: BendIndex, + around: FixedBendIndex, width: f64, ) -> Result { let mut tangents = self @@ -169,7 +172,7 @@ impl<'a> Draw<'a> { .find_map(|(i, tangent)| { self.segbend_around( head, - Index::Bend(around), + around.into(), tangent.start_point(), tangent.end_point(), dirs[i], @@ -254,9 +257,9 @@ impl<'a> Draw<'a> { let bend = self .layout - .add_bend(head.dot, bend_to, around, BendWeight { net, cw }) + .add_bend(head.dot, bend_to, around, FixedBendWeight { net, cw }) .map_err(|err| { - self.layout.remove(Index::Dot(bend_to)); + self.layout.remove(bend_to.into()); self.undo_seg(head, seg); err })?; @@ -274,7 +277,7 @@ impl<'a> Draw<'a> { .prev() .map(|prev_dot| { self.layout.remove_interior(&head.segbend); - self.layout.remove(Index::Dot(head.dot())); + self.layout.remove(head.dot().into()); self.prev_head(prev_dot) }) @@ -283,9 +286,9 @@ impl<'a> Draw<'a> { #[debug_requires(width <= self.layout.primitive(head.dot()).weight().circle.r * 2.0)] #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 2))] #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] - fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(BareHead, SegIndex), ()> { + fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(BareHead, FixedSegIndex), ()> { let net = self.layout.primitive(head.dot()).weight().net; - let to_index = self.layout.add_dot(DotWeight { + let to_index = self.layout.add_dot(FixedDotWeight { net, circle: Circle { pos: to, @@ -294,21 +297,21 @@ impl<'a> Draw<'a> { })?; let seg = self .layout - .add_seg(head.dot(), to_index, SegWeight { net, width }) + .add_seg(head.dot(), to_index, FixedSegWeight { net, width }) .map_err(|err| { - self.layout.remove(Index::Dot(to_index)); + self.layout.remove(to_index.into()); err })?; Ok((BareHead { dot: to_index }, seg)) } #[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))] - fn undo_seg(&mut self, head: BareHead, seg: SegIndex) { - self.layout.remove(Index::Seg(seg)); - self.layout.remove(Index::Dot(head.dot)); + fn undo_seg(&mut self, head: BareHead, seg: FixedSegIndex) { + self.layout.remove(seg.into()); + self.layout.remove(head.dot.into()); } - fn prev_head(&self, dot: DotIndex) -> Head { + fn prev_head(&self, dot: FixedDotIndex) -> Head { if let Some(segbend) = self.layout.prev_segbend(dot) { Head::from(SegbendHead { dot, segbend }) } else { @@ -316,7 +319,7 @@ impl<'a> Draw<'a> { } } - fn next_head(&self, dot: DotIndex) -> Head { + fn next_head(&self, dot: FixedDotIndex) -> Head { if let Some(segbend) = self.layout.next_segbend(dot) { Head::from(SegbendHead { dot, segbend }) } else { diff --git a/src/graph.rs b/src/graph.rs index 703a055..f71c1d0 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -26,14 +26,6 @@ pub trait GetNet { fn net(&self) -> i64; } -#[enum_dispatch(Retag, GetNet)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] -pub enum Weight { - Dot(DotWeight), - Seg(SegWeight), - Bend(BendWeight), -} - macro_rules! impl_type { ($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => { impl Retag for $weight_struct_name { @@ -64,29 +56,114 @@ macro_rules! impl_type { }; } +#[enum_dispatch(Retag, GetNet)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum Weight { + FixedDot(FixedDotWeight), + LooseDot(LooseDotWeight), + FixedSeg(FixedSegWeight), + HalfLooseSeg(HalfLooseSegWeight), + FullyLooseSeg(FullyLooseSegWeight), + FixedBend(FixedBendWeight), + LooseBend(LooseBendWeight), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum Index { + FixedDot(FixedDotIndex), + LooseDot(LooseDotIndex), + FixedSeg(FixedSegIndex), + HalfLooseSeg(HalfLooseSegIndex), + FullyLooseSeg(FullyLooseSegIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum DotIndex { + Fixed(FixedDotIndex), + Loose(LooseDotIndex), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum SegIndex { + Fixed(FixedSegIndex), + HalfLoose(HalfLooseSegIndex), + FullyLoose(FullyLooseSegIndex), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum LooseSegIndex { + Half(HalfLooseSegIndex), + Fully(FullyLooseSegIndex), +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +pub enum BendIndex { + Fixed(FixedBendIndex), + Loose(LooseBendIndex), +} + #[derive(Debug, Clone, Copy, PartialEq)] -pub struct DotWeight { +pub struct FixedDotWeight { pub net: i64, pub circle: Circle, } -impl_type!(DotWeight, Dot, DotIndex); +impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); #[derive(Debug, Clone, Copy, PartialEq)] -pub struct SegWeight { +pub struct LooseDotWeight { + pub net: i64, + pub circle: Circle, +} + +impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FixedSegWeight { pub net: i64, pub width: f64, } -impl_type!(SegWeight, Seg, SegIndex); +impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); #[derive(Debug, Clone, Copy, PartialEq)] -pub struct BendWeight { +pub struct HalfLooseSegWeight { + pub net: i64, + pub width: f64, +} + +impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex); + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FullyLooseSegWeight { + pub net: i64, + pub width: f64, +} + +impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex); + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct FixedBendWeight { pub net: i64, pub cw: bool, } -impl_type!(BendWeight, Bend, BendIndex); +impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct LooseBendWeight { + pub net: i64, + pub cw: bool, +} + +impl_type!(LooseBendWeight, LooseBend, LooseBendIndex); #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Label { @@ -105,14 +182,6 @@ pub trait MakePrimitive { fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a>; } -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] -pub enum Index { - Dot(DotIndex), - Seg(SegIndex), - Bend(BendIndex), -} - #[derive(Debug, Clone, Copy, PartialEq)] pub struct GenericIndex { node_index: NodeIndex, diff --git a/src/guide.rs b/src/guide.rs index da0087c..ae8630f 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -2,7 +2,7 @@ use geo::Line; use crate::{ draw::{Head, HeadTrait}, - graph::{BendIndex, DotIndex}, + graph::{FixedBendIndex, FixedDotIndex}, layout::Layout, math::{self, Circle}, primitive::{GetWeight, MakeShape}, @@ -27,7 +27,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn head_into_dot_segment( &self, head: &Head, - into: DotIndex, + into: FixedDotIndex, width: f64, ) -> Result { let from_circle = self.head_circle(head, width); @@ -43,7 +43,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn head_around_dot_segments( &self, head: &Head, - around: DotIndex, + around: FixedDotIndex, width: f64, ) -> Result<(Line, Line), ()> { let from_circle = self.head_circle(head, width); @@ -58,7 +58,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn head_around_dot_segment( &self, head: &Head, - around: DotIndex, + around: FixedDotIndex, cw: bool, width: f64, ) -> Result { @@ -72,7 +72,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn head_around_bend_segments( &self, head: &Head, - around: BendIndex, + around: FixedBendIndex, width: f64, ) -> Result<(Line, Line), ()> { let from_circle = self.head_circle(head, width); @@ -87,7 +87,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn head_around_bend_segment( &self, head: &Head, - around: BendIndex, + around: FixedBendIndex, cw: bool, width: f64, ) -> Result { @@ -132,7 +132,7 @@ impl<'a, 'b> Guide<'a, 'b> { } } - fn bend_circle(&self, bend: BendIndex, _width: f64) -> Circle { + fn bend_circle(&self, bend: FixedBendIndex, _width: f64) -> Circle { let mut circle = self .layout .primitive(bend) @@ -144,7 +144,7 @@ impl<'a, 'b> Guide<'a, 'b> { circle } - fn dot_circle(&self, dot: DotIndex, width: f64) -> Circle { + fn dot_circle(&self, dot: FixedDotIndex, width: f64) -> Circle { let circle = self.layout.primitive(dot).weight().circle; Circle { pos: circle.pos, diff --git a/src/layout.rs b/src/layout.rs index 8e86a77..2d907c4 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -9,8 +9,9 @@ use rstar::{RTree, RTreeObject}; use crate::band::Band; use crate::bow::Bow; use crate::graph::{ - BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, - MakePrimitive, Retag, SegIndex, SegWeight, Weight, + BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, + FixedSegIndex, FixedSegWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, + MakePrimitive, Retag, SegIndex, Weight, }; use crate::primitive::{ GenericPrimitive, GetConnectable, GetWeight, MakeShape, TaggedPrevTaggedNext, @@ -37,14 +38,22 @@ impl Layout { #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - path.interior().len()))] pub fn remove_interior(&mut self, path: &impl Interior) { - for index in path.interior().into_iter().filter(|index| !index.is_dot()) { + for index in path + .interior() + .into_iter() + .filter(|index| !index.is_fixed_dot()) + { self.remove(index); } // We must remove the dots only after the segs and bends because we need dots to calculate // the shapes, which we need to remove the segs and bends from the R-tree. - for index in path.interior().into_iter().filter(|index| index.is_dot()) { + for index in path + .interior() + .into_iter() + .filter(|index| index.is_fixed_dot()) + { self.remove(index); } } @@ -59,11 +68,11 @@ impl Layout { } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - pub fn add_dot(&mut self, weight: DotWeight) -> Result { - let dot = DotIndex::new(self.graph.add_node(Weight::Dot(weight))); + pub fn add_dot(&mut self, weight: FixedDotWeight) -> Result { + let dot = FixedDotIndex::new(self.graph.add_node(Weight::FixedDot(weight))); - self.insert_into_rtree(Index::Dot(dot)); - self.fail_and_remove_if_collides_except(Index::Dot(dot), &[])?; + self.insert_into_rtree(dot.into()); + self.fail_and_remove_if_collides_except(dot.into(), &[])?; Ok(dot) } @@ -72,30 +81,30 @@ impl Layout { #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] pub fn add_seg( &mut self, - from: DotIndex, - to: DotIndex, - weight: SegWeight, - ) -> Result { - let seg = SegIndex::new(self.graph.add_node(Weight::Seg(weight))); + from: FixedDotIndex, + to: FixedDotIndex, + weight: FixedSegWeight, + ) -> Result { + let seg = FixedSegIndex::new(self.graph.add_node(Weight::FixedSeg(weight))); self.graph .add_edge(from.node_index(), seg.node_index(), Label::End); self.graph .add_edge(seg.node_index(), to.node_index(), Label::End); - self.insert_into_rtree(Index::Seg(seg)); - self.fail_and_remove_if_collides_except(Index::Seg(seg), &[])?; + self.insert_into_rtree(seg.into()); + self.fail_and_remove_if_collides_except(seg.into(), &[])?; self.graph .node_weight_mut(from.node_index()) .unwrap() - .as_dot_mut() + .as_fixed_dot_mut() .unwrap() .net = weight.net; self.graph .node_weight_mut(to.node_index()) .unwrap() - .as_dot_mut() + .as_fixed_dot_mut() .unwrap() .net = weight.net; @@ -106,15 +115,16 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] pub fn add_bend( &mut self, - from: DotIndex, - to: DotIndex, + from: FixedDotIndex, + to: FixedDotIndex, around: Index, - weight: BendWeight, - ) -> Result { + weight: FixedBendWeight, + ) -> Result { match around { - Index::Dot(core) => self.add_core_bend(from, to, core, weight), - Index::Bend(around) => self.add_outer_bend(from, to, around, weight), - Index::Seg(..) => unreachable!(), + Index::FixedDot(core) => self.add_core_bend(from, to, core, weight), + Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), + Index::FixedSeg(..) => unreachable!(), + _ => unreachable!(), } } @@ -124,12 +134,12 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_core_bend( &mut self, - from: DotIndex, - to: DotIndex, - core: DotIndex, - weight: BendWeight, - ) -> Result { - let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); + from: FixedDotIndex, + to: FixedDotIndex, + core: FixedDotIndex, + weight: FixedBendWeight, + ) -> Result { + let bend = FixedBendIndex::new(self.graph.add_node(Weight::FixedBend(weight))); self.graph .add_edge(from.node_index(), bend.node_index(), Label::End); @@ -138,8 +148,8 @@ impl Layout { self.graph .add_edge(bend.node_index(), core.node_index(), Label::Core); - self.insert_into_rtree(Index::Bend(bend)); - self.fail_and_remove_if_collides_except(Index::Bend(bend), &[Index::Dot(core)])?; + self.insert_into_rtree(bend.into()); + self.fail_and_remove_if_collides_except(bend.into(), &[core.into()])?; Ok(bend) } @@ -149,11 +159,11 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_outer_bend( &mut self, - from: DotIndex, - to: DotIndex, - inner: BendIndex, - weight: BendWeight, - ) -> Result { + from: FixedDotIndex, + to: FixedDotIndex, + inner: FixedBendIndex, + weight: FixedBendWeight, + ) -> Result { let core = *self .graph .neighbors(inner.node_index()) @@ -163,12 +173,12 @@ impl Layout { .unwrap() .is_core() }) - .map(|ni| DotIndex::new(ni)) - .collect::>() + .map(|ni| FixedDotIndex::new(ni)) + .collect::>() .first() .unwrap(); - let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); + let bend = FixedBendIndex::new(self.graph.add_node(Weight::FixedBend(weight))); self.graph .add_edge(from.node_index(), bend.node_index(), Label::End); @@ -179,16 +189,16 @@ impl Layout { self.graph .add_edge(inner.node_index(), bend.node_index(), Label::Outer); - self.insert_into_rtree(Index::Bend(bend)); - self.fail_and_remove_if_collides_except(Index::Bend(bend), &[Index::Dot(core)])?; + self.insert_into_rtree(bend.into()); + self.fail_and_remove_if_collides_except(bend.into(), &[core.into()])?; Ok(bend) } #[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))] - pub fn reattach_bend(&mut self, bend: BendIndex, inner: BendIndex) { - self.remove_from_rtree(Index::Bend(bend)); + pub fn reattach_bend(&mut self, bend: FixedBendIndex, inner: FixedBendIndex) { + self.remove_from_rtree(bend.into()); if let Some(old_inner_edge) = self .graph @@ -201,46 +211,46 @@ impl Layout { self.graph .add_edge(inner.node_index(), bend.node_index(), Label::Outer); - self.insert_into_rtree(Index::Bend(bend)); + 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()))] - pub fn flip_bend(&mut self, bend: BendIndex) { - self.remove_from_rtree(Index::Bend(bend)); + pub fn flip_bend(&mut self, bend: FixedBendIndex) { + self.remove_from_rtree(bend.into()); let cw = self .graph .node_weight(bend.node_index()) .unwrap() - .into_bend() + .into_fixed_bend() .unwrap() .cw; self.graph .node_weight_mut(bend.node_index()) .unwrap() - .as_bend_mut() + .as_fixed_bend_mut() .unwrap() .cw = !cw; - self.insert_into_rtree(Index::Bend(bend)); + self.insert_into_rtree(bend.into()); } - pub fn bow(&self, bend: BendIndex) -> Bow { + pub fn bow(&self, bend: FixedBendIndex) -> Bow { Bow::from_bend(bend, &self.graph) } - pub fn prev_segbend(&self, dot: DotIndex) -> Option { + pub fn prev_segbend(&self, dot: FixedDotIndex) -> Option { Segbend::from_dot_prev(dot, &self.graph) } - pub fn next_segbend(&self, dot: DotIndex) -> Option { + pub fn next_segbend(&self, dot: FixedDotIndex) -> Option { Segbend::from_dot_next(dot, &self.graph) } - pub fn prev_band(&self, to: DotIndex) -> Option { + pub fn prev_band(&self, to: FixedDotIndex) -> Option { Band::from_dot_prev(to, &self.graph) } - pub fn next_band(&self, from: DotIndex) -> Option { + pub fn next_band(&self, from: FixedDotIndex) -> Option { Band::from_dot_next(from, &self.graph) } @@ -259,8 +269,9 @@ impl Layout { Ok(()) } - pub fn dots(&self) -> impl Iterator + '_ { - self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di)) + pub fn dots(&self) -> impl Iterator + '_ { + self.nodes() + .filter_map(|ni| ni.as_fixed_dot().map(|di| *di)) } pub fn shapes(&self) -> impl Iterator + '_ { @@ -280,26 +291,26 @@ impl Layout { impl Layout { #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] - pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> { + pub fn move_dot(&mut self, dot: FixedDotIndex, to: Point) -> Result<(), ()> { self.primitive(dot) .tagged_prev() .map(|prev| self.remove_from_rtree(prev)); self.primitive(dot) .tagged_next() .map(|next| self.remove_from_rtree(next)); - self.remove_from_rtree(Index::Dot(dot)); + self.remove_from_rtree(dot.into()); let mut dot_weight = self.primitive(dot).weight(); let old_weight = dot_weight; dot_weight.circle.pos = to; - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::Dot(dot_weight); + *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(dot_weight); - if let Some(..) = self.detect_collision_except(Index::Dot(dot), &[]) { + if let Some(..) = self.detect_collision_except(dot.into(), &[]) { // Restore original state. - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::Dot(old_weight); + *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(old_weight); - self.insert_into_rtree(Index::Dot(dot)); + self.insert_into_rtree(dot.into()); self.primitive(dot) .tagged_prev() .map(|prev| self.insert_into_rtree(prev)); @@ -309,7 +320,7 @@ impl Layout { return Err(()); } - self.insert_into_rtree(Index::Dot(dot)); + self.insert_into_rtree(dot.into()); self.primitive(dot) .tagged_prev() .map(|prev| self.insert_into_rtree(prev)); diff --git a/src/main.rs b/src/main.rs index 94df4ff..4789790 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ extern crate sdl2; macro_rules! dbg_dot { ($graph:expr) => { - use petgraph::dot::Dot; - println!("{:?}", Dot::new(&$graph)); + use petgraph::FixedDot::FixedDot; + println!("{:?}", FixedDot::new(&$graph)); }; } @@ -25,7 +25,7 @@ mod shape; mod tracer; use geo::point; -use graph::{DotIndex, SegWeight}; +use graph::{FixedDotIndex, FixedSegWeight}; use layout::Layout; use mesh::{Mesh, MeshEdgeReference, VertexIndex}; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; @@ -43,7 +43,7 @@ use shape::Shape; use std::time::Duration; use tracer::{Trace, Tracer}; -use crate::graph::DotWeight; +use crate::graph::FixedDotWeight; use crate::math::Circle; use crate::router::Router; @@ -134,7 +134,7 @@ fn main() { let dot1 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 1, circle: Circle { pos: (100.5, 400.5).into(), @@ -145,7 +145,7 @@ fn main() { let dot2 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 1, circle: Circle { pos: (100.5, 500.5).into(), @@ -156,7 +156,7 @@ fn main() { let dot_end = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 1, circle: Circle { pos: (470.5, 350.5).into(), @@ -167,7 +167,7 @@ fn main() { let dot1_1 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (200.5, 200.5).into(), @@ -178,7 +178,7 @@ fn main() { let dot2_1 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (200.5, 500.5).into(), @@ -190,7 +190,7 @@ fn main() { let _ = router.layout.add_seg( dot1_1, dot2_1, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -198,7 +198,7 @@ fn main() { let dot2_2 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (600.5, 500.5).into(), @@ -210,7 +210,7 @@ fn main() { let _ = router.layout.add_seg( dot2_1, dot2_2, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -218,7 +218,7 @@ fn main() { let dot3 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (400.5, 200.5).into(), @@ -229,7 +229,7 @@ fn main() { let dot4 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (400.5, 400.5).into(), @@ -241,7 +241,7 @@ fn main() { let _ = router.layout.add_seg( dot3, dot4, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -249,7 +249,7 @@ fn main() { let dot5 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (530.5, 400.5).into(), @@ -261,7 +261,7 @@ fn main() { let _ = router.layout.add_seg( dot4, dot5, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -269,7 +269,7 @@ fn main() { let dot1_2 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (600.5, 200.5).into(), @@ -281,7 +281,7 @@ fn main() { let _ = router.layout.add_seg( dot3, dot1_2, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -290,7 +290,7 @@ fn main() { let _ = router.layout.add_seg( dot1_2, dot2_2, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -298,7 +298,7 @@ fn main() { let dot6 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (530.5, 300.5).into(), @@ -310,7 +310,7 @@ fn main() { let _ = router.layout.add_seg( dot5, dot6, - SegWeight { + FixedSegWeight { net: 2, width: 16.0, }, @@ -318,7 +318,7 @@ fn main() { /*let dot7 = router .layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: 2, circle: Circle { pos: (400.5, 440.5).into(), @@ -330,7 +330,7 @@ fn main() { let _ = router.layout.add_seg( dot4, dot7, - SegWeight { + FixedSegWeight { net: 20, width: 16.0, }, @@ -402,8 +402,8 @@ fn render_times( event_pump: &mut EventPump, canvas: &mut Canvas, mut router_or_layout: RouterOrLayout, - from: Option, - follower: Option, + from: Option, + follower: Option, mut mesh: Option, path: &[VertexIndex], times: i64, @@ -453,27 +453,27 @@ fn render_times( //let result = panic::catch_unwind(|| { for shape in layout.shapes() { match shape { - Shape::Dot(dot) => { + Shape::Dot(FixedDot) => { let _ = canvas.filled_circle( - dot.c.pos.x() as i16, - dot.c.pos.y() as i16, - dot.c.r as i16, + FixedDot.c.pos.x() as i16, + FixedDot.c.pos.y() as i16, + FixedDot.c.r as i16, Color::RGB(200, 52, 52), ); } - Shape::Seg(seg) => { + Shape::Seg(FixedSeg) => { let _ = canvas.thick_line( - seg.from.x() as i16, - seg.from.y() as i16, - seg.to.x() as i16, - seg.to.y() as i16, - seg.width as u8, + FixedSeg.from.x() as i16, + FixedSeg.from.y() as i16, + FixedSeg.to.x() as i16, + FixedSeg.to.y() as i16, + FixedSeg.width as u8, Color::RGB(200, 52, 52), ); } - Shape::Bend(bend) => { - let delta1 = bend.from - bend.c.pos; - let delta2 = bend.to - bend.c.pos; + Shape::Bend(FixedBend) => { + let delta1 = FixedBend.from - FixedBend.c.pos; + let delta2 = FixedBend.to - FixedBend.c.pos; let angle1 = delta1.y().atan2(delta1.x()); let angle2 = delta2.y().atan2(delta2.x()); @@ -482,10 +482,10 @@ fn render_times( let _ = canvas.arc( //around_circle.pos.x() as i16, //around_circle.pos.y() as i16, - bend.c.pos.x() as i16, - bend.c.pos.y() as i16, + FixedBend.c.pos.x() as i16, + FixedBend.c.pos.y() as i16, //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, - (bend.circle().r + (d as f64)) as i16, + (FixedBend.circle().r + (d as f64)) as i16, angle1.to_degrees() as i16, angle2.to_degrees() as i16, Color::RGB(200, 52, 52), diff --git a/src/mesh.rs b/src/mesh.rs index 717542b..65c9fa1 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -8,14 +8,14 @@ use spade::{ }; use crate::{ - graph::{DotIndex, GetNodeIndex}, + graph::{DotIndex, FixedDotIndex, GetNodeIndex}, layout::Layout, }; use crate::{primitive::MakeShape, shape::ShapeTrait}; #[derive(Debug, Clone)] struct Vertex { - dot: DotIndex, + dot: FixedDotIndex, x: f64, y: f64, } @@ -66,7 +66,7 @@ impl Mesh { Ok(()) } - pub fn dot(&self, vertex: VertexIndex) -> DotIndex { + pub fn dot(&self, vertex: VertexIndex) -> FixedDotIndex { self.triangulation.vertex(vertex.handle).as_ref().dot } diff --git a/src/primitive.rs b/src/primitive.rs index e4580db..07c2cec 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -5,8 +5,10 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::Direction::{Incoming, Outgoing}; use crate::graph::{ - BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNet, GetNodeIndex, Index, - Interior, Label, MakePrimitive, Retag, SegWeight, Weight, + BendIndex, DotIndex, Ends, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, + FixedSegWeight, FullyLooseSegWeight, GenericIndex, GetNet, GetNodeIndex, HalfLooseSegWeight, + Index, Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotWeight, MakePrimitive, Retag, + Weight, }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; @@ -44,9 +46,13 @@ pub trait MakeShape { #[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)] pub enum Primitive<'a> { - Dot(Dot<'a>), - Seg(Seg<'a>), - Bend(Bend<'a>), + FixedDot(FixedDot<'a>), + LooseDot(LooseDot<'a>), + FixedSeg(FixedSeg<'a>), + HalfLooseSeg(HalfLooseSeg<'a>), + FullyLooseSeg(FullyLooseSeg<'a>), + FixedBend(FixedBend<'a>), + LooseBend(LooseBend<'a>), } #[derive(Debug)] @@ -66,7 +72,7 @@ impl<'a, W> GenericPrimitive<'a, W> { .map(|index| self.graph.node_weight(index).unwrap().retag(index)) } - pub fn prev_bend(&self) -> Option { + pub fn prev_bend(&self) -> Option { let mut prev_index = self.index.node_index(); while let Some(index) = self @@ -85,8 +91,8 @@ impl<'a, W> GenericPrimitive<'a, W> { { let _weight = *self.graph.node_weight(index).unwrap(); - if let Some(Weight::Bend(..)) = self.graph.node_weight(index) { - return Some(BendIndex::new(index)); + if let Some(Weight::FixedBend(..)) = self.graph.node_weight(index) { + return Some(FixedBendIndex::new(index)); } prev_index = index; @@ -107,7 +113,7 @@ impl<'a, W> GenericPrimitive<'a, W> { .next() } - pub fn next_bend(&self) -> Option { + pub fn next_bend(&self) -> Option { let mut prev_index = self.index.node_index(); while let Some(index) = self @@ -126,8 +132,8 @@ impl<'a, W> GenericPrimitive<'a, W> { { let _weight = *self.graph.node_weight(index).unwrap(); - if let Some(Weight::Bend(..)) = self.graph.node_weight(index) { - return Some(BendIndex::new(index)); + if let Some(Weight::FixedBend(..)) = self.graph.node_weight(index) { + return Some(FixedBendIndex::new(index)); } prev_index = index; @@ -148,7 +154,7 @@ impl<'a, W> GenericPrimitive<'a, W> { .next() } - pub fn core(&self) -> Option { + pub fn core(&self) -> Option { self.graph .neighbors(self.index.node_index()) .filter(|ni| { @@ -157,33 +163,10 @@ impl<'a, W> GenericPrimitive<'a, W> { .unwrap() .is_core() }) - .map(|ni| DotIndex::new(ni)) + .map(|ni| FixedDotIndex::new(ni)) .next() } - /*pub fn connectable(&self, index: GenericIndex) -> bool { - let this = self.net(&self.index); - let other = self.net(&index); - - if this == other { - true - } else if this == -1 || other == -1 { - true - } else if this == -2 || other == -2 { - false - } else { - this == other - } - } - - fn net(&self, index: &GenericIndex) -> i64 { - match self.graph.node_weight(index.node_index()).unwrap() { - Weight::Dot(dot) => dot.net, - Weight::Seg(seg) => seg.net, - Weight::Bend(bend) => bend.net, - } - }*/ - pub fn tagged_index(&self) -> Index { self.graph .node_weight(self.index.node_index()) @@ -206,8 +189,8 @@ impl<'a, W> Interior for GenericPrimitive<'a, W> { } } -impl<'a, W> Ends for GenericPrimitive<'a, W> { - fn ends(&self) -> (DotIndex, DotIndex) { +impl<'a, W> Ends for GenericPrimitive<'a, W> { + fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { let v = self .graph .neighbors_undirected(self.index.node_index()) @@ -222,8 +205,8 @@ impl<'a, W> Ends for GenericPrimitive<'a, W> { .unwrap() .is_end() }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot()) - .map(|ni| DotIndex::new(ni)) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_dot()) + .map(|ni| FixedDotIndex::new(ni)) .collect::>(); (v[0], v[1]) } @@ -261,10 +244,10 @@ impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> { } } -pub type Dot<'a> = GenericPrimitive<'a, DotWeight>; +pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; -impl<'a> Dot<'a> { - pub fn bend(&self) -> Option { +impl<'a> FixedDot<'a> { + pub fn bend(&self) -> Option { self.graph .neighbors_undirected(self.index.node_index()) .filter(|ni| { @@ -278,12 +261,12 @@ impl<'a> Dot<'a> { .unwrap() .is_end() }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_bend()) - .map(|ni| BendIndex::new(ni)) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_bend()) + .map(|ni| FixedBendIndex::new(ni)) .next() } - pub fn outer(&self) -> Option { + pub fn outer(&self) -> Option { self.graph .neighbors_directed(self.index.node_index(), Incoming) .filter(|ni| { @@ -292,19 +275,19 @@ impl<'a> Dot<'a> { .unwrap() .is_core() }) - .map(|ni| BendIndex::new(ni)) + .map(|ni| FixedBendIndex::new(ni)) .filter(|bend| self.primitive(*bend).inner().is_none()) .next() } } -impl<'a> GetWeight for Dot<'a> { - fn weight(&self) -> DotWeight { - self.tagged_weight().into_dot().unwrap() +impl<'a> GetWeight for FixedDot<'a> { + fn weight(&self) -> FixedDotWeight { + self.tagged_weight().into_fixed_dot().unwrap() } } -impl<'a> MakeShape for Dot<'a> { +impl<'a> MakeShape for FixedDot<'a> { fn shape(&self) -> Shape { Shape::Dot(DotShape { c: self.weight().circle, @@ -312,25 +295,41 @@ impl<'a> MakeShape for Dot<'a> { } } -pub type Seg<'a> = GenericPrimitive<'a, SegWeight>; +pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; -impl<'a> Seg<'a> { - pub fn next(&self) -> Option { - self.next_node().map(|ni| DotIndex::new(ni)) - } - - pub fn prev(&self) -> Option { - self.prev_node().map(|ni| DotIndex::new(ni)) +impl<'a> GetWeight for LooseDot<'a> { + fn weight(&self) -> LooseDotWeight { + self.tagged_weight().into_loose_dot().unwrap() } } -impl<'a> GetWeight for Seg<'a> { - fn weight(&self) -> SegWeight { - self.tagged_weight().into_seg().unwrap() +impl<'a> MakeShape for LooseDot<'a> { + fn shape(&self) -> Shape { + Shape::Dot(DotShape { + c: self.weight().circle, + }) } } -impl<'a> MakeShape for Seg<'a> { +pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; + +impl<'a> FixedSeg<'a> { + pub fn next(&self) -> Option { + self.next_node().map(|ni| FixedDotIndex::new(ni)) + } + + pub fn prev(&self) -> Option { + self.prev_node().map(|ni| FixedDotIndex::new(ni)) + } +} + +impl<'a> GetWeight for FixedSeg<'a> { + fn weight(&self) -> FixedSegWeight { + self.tagged_weight().into_fixed_seg().unwrap() + } +} + +impl<'a> MakeShape for FixedSeg<'a> { fn shape(&self) -> Shape { let ends = self.ends(); Shape::Seg(SegShape { @@ -341,18 +340,56 @@ impl<'a> MakeShape for Seg<'a> { } } -pub type Bend<'a> = GenericPrimitive<'a, BendWeight>; +pub type HalfLooseSeg<'a> = GenericPrimitive<'a, HalfLooseSegWeight>; -impl<'a> Bend<'a> { +impl<'a> GetWeight for HalfLooseSeg<'a> { + fn weight(&self) -> HalfLooseSegWeight { + self.tagged_weight().into_half_loose_seg().unwrap() + } +} + +impl<'a> MakeShape for HalfLooseSeg<'a> { + fn shape(&self) -> Shape { + let ends = self.ends(); + Shape::Seg(SegShape { + from: self.primitive(ends.0).weight().circle.pos, + to: self.primitive(ends.1).weight().circle.pos, + width: self.weight().width, + }) + } +} + +pub type FullyLooseSeg<'a> = GenericPrimitive<'a, FullyLooseSegWeight>; + +impl<'a> GetWeight for FullyLooseSeg<'a> { + fn weight(&self) -> FullyLooseSegWeight { + self.tagged_weight().into_fully_loose_seg().unwrap() + } +} + +impl<'a> MakeShape for FullyLooseSeg<'a> { + fn shape(&self) -> Shape { + let ends = self.ends(); + Shape::Seg(SegShape { + from: self.primitive(ends.0).weight().circle.pos, + to: self.primitive(ends.1).weight().circle.pos, + width: self.weight().width, + }) + } +} + +pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; + +impl<'a> FixedBend<'a> { pub fn around(&self) -> Index { if let Some(inner) = self.inner() { - Index::Bend(inner) + inner.into() } else { - Index::Dot(self.core().unwrap()) + self.core().unwrap().into() } } - pub fn inner(&self) -> Option { + pub fn inner(&self) -> Option { self.graph .neighbors_directed(self.index.node_index(), Incoming) .filter(|ni| { @@ -361,11 +398,11 @@ impl<'a> Bend<'a> { .unwrap() .is_outer() }) - .map(|ni| BendIndex::new(ni)) + .map(|ni| FixedBendIndex::new(ni)) .next() } - pub fn outer(&self) -> Option { + pub fn outer(&self) -> Option { self.graph .neighbors_directed(self.index.node_index(), Outgoing) .filter(|ni| { @@ -374,21 +411,21 @@ impl<'a> Bend<'a> { .unwrap() .is_outer() }) - .map(|ni| BendIndex::new(ni)) + .map(|ni| FixedBendIndex::new(ni)) .next() } - pub fn next(&self) -> Option { - self.next_node().map(|ni| DotIndex::new(ni)) + pub fn next(&self) -> Option { + self.next_node().map(|ni| FixedDotIndex::new(ni)) } - pub fn prev(&self) -> Option { - self.prev_node().map(|ni| DotIndex::new(ni)) + pub fn prev(&self) -> Option { + self.prev_node().map(|ni| FixedDotIndex::new(ni)) } fn inner_radius(&self) -> f64 { let mut r = 0.0; - let mut layer = BendIndex::new(self.index.node_index()); + let mut layer = FixedBendIndex::new(self.index.node_index()); while let Some(inner) = self.primitive(layer).inner() { r += self.primitive(inner).shape().width(); @@ -397,7 +434,7 @@ impl<'a> Bend<'a> { let core_circle = self .primitive( - self.primitive(BendIndex::new(self.index.node_index())) + self.primitive(FixedBendIndex::new(self.index.node_index())) .core() .unwrap(), ) @@ -416,13 +453,78 @@ impl<'a> Bend<'a> { } } -impl<'a> GetWeight for Bend<'a> { - fn weight(&self) -> BendWeight { - self.tagged_weight().into_bend().unwrap() +impl<'a> GetWeight for FixedBend<'a> { + fn weight(&self) -> FixedBendWeight { + self.tagged_weight().into_fixed_bend().unwrap() } } -impl<'a> MakeShape for Bend<'a> { +impl<'a> MakeShape for FixedBend<'a> { + fn shape(&self) -> Shape { + let ends = self.ends(); + + let mut bend_shape = BendShape { + from: self.primitive(ends.0).weight().circle.pos, + to: self.primitive(ends.1).weight().circle.pos, + c: Circle { + pos: self.primitive(self.core().unwrap()).weight().circle.pos, + r: self.inner_radius(), + }, + width: self.primitive(ends.0).weight().circle.r * 2.0, + }; + + if self.weight().cw { + swap(&mut bend_shape.from, &mut bend_shape.to); + } + Shape::Bend(bend_shape) + } +} + +pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; + +impl<'a> LooseBend<'a> { + pub fn inner(&self) -> Option { + self.graph + .neighbors_directed(self.index.node_index(), Incoming) + .filter(|ni| { + self.graph + .edge_weight(self.graph.find_edge(*ni, self.index.node_index()).unwrap()) + .unwrap() + .is_outer() + }) + .map(|ni| LooseBendIndex::new(ni)) + .next() + } + + fn inner_radius(&self) -> f64 { + let mut r = 0.0; + let mut layer = LooseBendIndex::new(self.index.node_index()); + + while let Some(inner) = self.primitive(layer).inner() { + r += self.primitive(inner).shape().width(); + layer = inner; + } + + let core_circle = self + .primitive( + self.primitive(LooseBendIndex::new(self.index.node_index())) + .core() + .unwrap(), + ) + .weight() + .circle; + + core_circle.r + r + 3.0 + } +} + +impl<'a> GetWeight for LooseBend<'a> { + fn weight(&self) -> LooseBendWeight { + self.tagged_weight().into_loose_bend().unwrap() + } +} + +impl<'a> MakeShape for LooseBend<'a> { fn shape(&self) -> Shape { let ends = self.ends(); diff --git a/src/router.rs b/src/router.rs index fa126a7..af23450 100644 --- a/src/router.rs +++ b/src/router.rs @@ -3,7 +3,7 @@ use petgraph::visit::EdgeRef; use spade::InsertionError; use crate::astar::{astar, AstarStrategy, PathTracker}; -use crate::graph::{DotIndex, DotWeight, Ends}; +use crate::graph::{DotIndex, Ends, FixedDotIndex, FixedDotWeight}; use crate::layout::Layout; use crate::math::Circle; @@ -84,8 +84,8 @@ impl Router { pub fn enroute( &mut self, - from: DotIndex, - to: DotIndex, + from: FixedDotIndex, + to: FixedDotIndex, observer: &mut impl RouterObserver, ) -> Result { // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look @@ -95,12 +95,17 @@ impl Router { mesh.triangulate(&self.layout)?; let mut tracer = self.tracer(&mesh); - let trace = tracer.start(mesh.vertex(from)); + let trace = tracer.start(mesh.vertex(DotIndex::Fixed(from))); let (_cost, _path) = astar( &mesh, - mesh.vertex(from), - &mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer), + mesh.vertex(DotIndex::Fixed(from)), + &mut RouterAstarStrategy::new( + tracer, + trace, + mesh.vertex(DotIndex::Fixed(to)), + observer, + ), ) .unwrap(); // TODO. @@ -109,7 +114,7 @@ impl Router { pub fn reroute( &mut self, - from: DotIndex, + from: FixedDotIndex, to: Point, observer: &mut impl RouterObserver, ) -> Result { @@ -122,7 +127,7 @@ impl Router { } else { let from_weight = self.layout.primitive(from).weight(); self.layout - .add_dot(DotWeight { + .add_dot(FixedDotWeight { net: from_weight.net, circle: Circle { pos: to, r: 2.0 }, }) @@ -135,7 +140,7 @@ impl Router { /*pub fn squeeze_around_dot( &mut self, head: Head, - around: DotIndex, + around: FixedDotIndex, cw: bool, width: f64, ) -> Result { @@ -151,7 +156,7 @@ impl Router { pub fn squeeze_around_bend( &mut self, head: Head, - around: BendIndex, + around: FixedBendIndex, cw: bool, width: f64, ) -> Result { @@ -164,7 +169,7 @@ impl Router { Ok(head) } - fn reroute_outward(&mut self, bend: BendIndex) -> Result<(), ()> { + fn reroute_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> { let mut bows: Vec = vec![]; let cw = self.layout.primitive(bend).weight().cw; @@ -204,7 +209,7 @@ impl Router { Ok(()) } - fn relax_band(&mut self, bend: BendIndex) { + fn relax_band(&mut self, bend: FixedBendIndex) { let mut prev_bend = bend; while let Some(cur_bend) = self.layout.primitive(prev_bend).find_prev_akin() { if self.layout.primitive(cur_bend).cross_product() >= 0. { @@ -224,7 +229,7 @@ impl Router { } } - fn release_bow(&mut self, bend: BendIndex) { + fn release_bow(&mut self, bend: FixedBendIndex) { let bow = self.layout.bow(bend); let ends = bow.ends(); @@ -234,7 +239,7 @@ impl Router { let _ = self.draw().finish(head, ends.1, 5.0); } - pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> { + pub fn move_dot(&mut self, dot: FixedDotIndex, to: Point) -> Result<(), ()> { self.layout.move_dot(dot, to)?; if let Some(outer) = self.layout.primitive(dot).outer() { diff --git a/src/segbend.rs b/src/segbend.rs index 1ddf35b..c630baa 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -1,46 +1,49 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ - graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}, - primitive::{Bend, Dot, TaggedPrevTaggedNext}, + graph::{ + BendIndex, DotIndex, Ends, FixedBendIndex, FixedDotIndex, FixedSegIndex, Index, Interior, + Label, SegIndex, Weight, + }, + primitive::{FixedBend, FixedDot, TaggedPrevTaggedNext}, }; #[derive(Debug, Clone, Copy)] pub struct Segbend { - pub seg: SegIndex, - pub dot: DotIndex, - pub bend: BendIndex, + pub seg: FixedSegIndex, + pub dot: FixedDotIndex, + pub bend: FixedBendIndex, } impl Segbend { - pub fn new(bend: BendIndex, dot: DotIndex, seg: SegIndex) -> Self { + pub fn new(bend: FixedBendIndex, dot: FixedDotIndex, seg: FixedSegIndex) -> Self { Self { seg, dot, bend } } pub fn from_dot_prev( - dot: DotIndex, + dot: FixedDotIndex, graph: &StableDiGraph, ) -> Option { - let bend = *Dot::new(dot, graph).tagged_prev()?.as_bend()?; - let dot = Bend::new(bend, graph).prev().unwrap(); - let seg = Dot::new(dot, graph) + let bend = *FixedDot::new(dot, graph).tagged_prev()?.as_fixed_bend()?; + let dot = FixedBend::new(bend, graph).prev().unwrap(); + let seg = FixedDot::new(dot, graph) .tagged_prev() .unwrap() - .into_seg() + .into_fixed_seg() .unwrap(); Some(Self { bend, dot, seg }) } pub fn from_dot_next( - dot: DotIndex, + dot: FixedDotIndex, graph: &StableDiGraph, ) -> Option { - let bend = *Dot::new(dot, graph).tagged_next()?.as_bend()?; - let dot = Bend::new(bend, graph).next().unwrap(); - let seg = Dot::new(dot, graph) + let bend = *FixedDot::new(dot, graph).tagged_next()?.as_fixed_bend()?; + let dot = FixedBend::new(bend, graph).next().unwrap(); + let seg = FixedDot::new(dot, graph) .tagged_next() .unwrap() - .into_seg() + .into_fixed_seg() .unwrap(); Some(Self { bend, dot, seg }) } @@ -48,16 +51,12 @@ impl Segbend { impl Interior for Segbend { fn interior(&self) -> Vec { - vec![ - Index::Bend(self.bend), - Index::Dot(self.dot), - Index::Seg(self.seg), - ] + vec![self.bend.into(), self.dot.into(), self.seg.into()] } } -impl Ends for Segbend { - fn ends(&self) -> (SegIndex, BendIndex) { +impl Ends for Segbend { + fn ends(&self) -> (FixedSegIndex, FixedBendIndex) { (self.seg, self.bend) } } diff --git a/src/tracer.rs b/src/tracer.rs index 07b5bd1..36667a6 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -3,7 +3,7 @@ use contracts::debug_ensures; use crate::{ bow::Bow, draw::{BareHead, Draw, Head, HeadTrait, SegbendHead}, - graph::{BendIndex, DotIndex, Ends}, + graph::{Ends, FixedBendIndex, FixedDotIndex}, layout::Layout, mesh::{Mesh, VertexIndex}, primitive::{GetWeight, MakeShape}, @@ -93,7 +93,7 @@ impl<'a> Tracer<'a> { Ok(()) } - fn wrap(&mut self, head: Head, around: DotIndex, width: f64) -> Result { + fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result { let _around_pos = self.layout.primitive(around).weight().circle.pos; let _around_primitive = self.layout.primitive(around); @@ -122,7 +122,12 @@ impl<'a> Tracer<'a> { self.draw().segbend_around_dot(head, around, width) } - fn is_under(&mut self, head: Head, around: DotIndex, layer: BendIndex) -> Option { + fn is_under( + &mut self, + head: Head, + around: FixedDotIndex, + layer: FixedBendIndex, + ) -> Option { let around_pos = self.layout.primitive(around).weight().circle.pos; if Some(layer) != self.layout.primitive(head.dot()).prev_bend() { @@ -142,7 +147,7 @@ impl<'a> Tracer<'a> { fn tuck_around_dot( &mut self, head: Head, - around: DotIndex, + around: FixedDotIndex, width: f64, ) -> Result { let outer = self.layout.primitive(around).outer().unwrap(); @@ -158,7 +163,7 @@ impl<'a> Tracer<'a> { fn tuck_around_bend( &mut self, head: Head, - around: BendIndex, + around: FixedBendIndex, width: f64, ) -> Result { let outer = self.layout.primitive(around).outer().unwrap(); @@ -171,7 +176,7 @@ impl<'a> Tracer<'a> { Ok(head) } - fn redraw_outward(&mut self, bend: BendIndex) -> Result<(), ()> { + fn redraw_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> { let mut bows: Vec = vec![]; let mut cur_bend = bend; @@ -210,7 +215,7 @@ impl<'a> Tracer<'a> { Ok(()) } - fn relax_band(&mut self, bend: BendIndex) { + fn relax_band(&mut self, bend: FixedBendIndex) { let mut prev_bend = bend; while let Some(cur_bend) = self.layout.primitive(prev_bend).prev_bend() { if self.layout.primitive(cur_bend).cross_product() >= 0. { @@ -230,7 +235,7 @@ impl<'a> Tracer<'a> { } } - fn release_bow(&mut self, bend: BendIndex) { + fn release_bow(&mut self, bend: FixedBendIndex) { let bow = self.layout.bow(bend); let ends = bow.ends();