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();