From c163716a6a65e9c43180f2255bcf88e707b73ce2 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 28 Oct 2023 13:18:55 +0000 Subject: [PATCH] graph,layout,primitive: Use loose primitive variants for traces --- src/bow.rs | 40 ++++++------- src/draw.rs | 137 +++++++++++++++++++++++-------------------- src/graph.rs | 21 +++++-- src/guide.rs | 2 +- src/layout.rs | 65 ++++++++++++--------- src/main.rs | 8 +-- src/primitive.rs | 148 ++++++++++++++++++++++++----------------------- src/segbend.rs | 23 ++++---- src/tracer.rs | 21 +++---- 9 files changed, 252 insertions(+), 213 deletions(-) diff --git a/src/bow.rs b/src/bow.rs index 925a308..0044c94 100644 --- a/src/bow.rs +++ b/src/bow.rs @@ -1,32 +1,32 @@ use petgraph::stable_graph::StableDiGraph; use crate::graph::{ - FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label, Weight, + GetEnds, Index, Interior, Label, LooseBendIndex, LooseDotIndex, LooseSegIndex, Weight, }; -use crate::primitive::{FixedBend, FixedDot, FixedSeg}; +use crate::primitive::{GetOtherEnd, LooseBend, LooseDot, LooseSeg}; #[derive(Debug, Clone, Copy)] pub struct Bow { - seg1_dot1: FixedDotIndex, - seg1: FixedSegIndex, - seg1_dot2: FixedDotIndex, - bend: FixedBendIndex, - seg2_dot1: FixedDotIndex, - seg2: FixedSegIndex, - seg2_dot2: FixedDotIndex, + seg1_dot1: LooseDotIndex, + seg1: LooseSegIndex, + seg1_dot2: LooseDotIndex, + bend: LooseBendIndex, + seg2_dot1: LooseDotIndex, + seg2: LooseSegIndex, + seg2_dot2: LooseDotIndex, } -impl Bow { - pub fn from_bend(index: FixedBendIndex, graph: &StableDiGraph) -> Self { +/*impl Bow { + pub fn from_bend(index: LooseBendIndex, graph: &StableDiGraph) -> Self { let bend = index; - let seg1_dot2 = FixedBend::new(bend, graph).ends().0; - let seg1 = FixedDot::new(seg1_dot2, graph).seg().unwrap(); - let seg1_dot1 = FixedSeg::new(seg1, graph).other_end(seg1_dot2); + let seg1_dot2 = LooseBend::new(bend, graph).ends().0; + let seg1 = LooseDot::new(seg1_dot2, graph).seg().unwrap(); + let seg1_dot1 = LooseSeg::new(seg1, graph).other_end(seg1_dot2); - let seg2_dot1 = FixedBend::new(bend, graph).ends().1; - let seg2 = FixedDot::new(seg2_dot1, graph).seg().unwrap(); - let seg2_dot2 = FixedSeg::new(seg2, graph).other_end(seg2_dot1); + let seg2_dot1 = LooseBend::new(bend, graph).ends().1; + let seg2 = LooseDot::new(seg2_dot1, graph).seg().unwrap(); + let seg2_dot2 = LooseSeg::new(seg2, graph).other_end(seg2_dot1); Self { seg1_dot1, @@ -38,7 +38,7 @@ impl Bow { seg2_dot2, } } -} +}*/ impl Interior for Bow { fn interior(&self) -> Vec { @@ -52,8 +52,8 @@ impl Interior for Bow { } } -impl GetEnds for Bow { - fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { +impl GetEnds for Bow { + fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { (self.seg1_dot1, self.seg2_dot2) } } diff --git a/src/draw.rs b/src/draw.rs index 2d1953d..31c35b3 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -4,20 +4,21 @@ use geo::{EuclideanLength, Point}; use crate::{ graph::{ - BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, - FixedSegIndex, FixedSegWeight, Index, + BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex, + LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, + MakePrimitive, }, guide::Guide, layout::Layout, math::Circle, - primitive::GetWeight, + primitive::{GetOtherEnd, GetWeight}, rules::{Conditions, Rules}, segbend::Segbend, }; #[enum_dispatch] pub trait HeadTrait { - fn dot(&self) -> FixedDotIndex; + fn dot(&self) -> DotIndex; } #[enum_dispatch(HeadTrait)] @@ -33,20 +34,20 @@ pub struct BareHead { } impl HeadTrait for BareHead { - fn dot(&self) -> FixedDotIndex { - self.dot + fn dot(&self) -> DotIndex { + self.dot.into() } } #[derive(Debug, Clone, Copy)] pub struct SegbendHead { - pub dot: FixedDotIndex, + pub dot: LooseDotIndex, pub segbend: Segbend, } impl HeadTrait for SegbendHead { - fn dot(&self) -> FixedDotIndex { - self.dot + fn dot(&self) -> DotIndex { + self.dot.into() } } @@ -60,45 +61,54 @@ impl<'a> Draw<'a> { Self { layout, rules } } - pub fn start(&mut self, from: FixedDotIndex) -> Head { - self.head(from) + pub fn start(&mut self, from: LooseDotIndex) -> Head { + self.head(from.into()) } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))] + /*#[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: FixedDotIndex, width: f64) -> Result<(), ()> { + pub fn finish(&mut self, head: Head, into: LooseDotIndex, width: f64) -> Result<(), ()> { if let Some(bend) = self.layout.primitive(into).bend() { self.finish_in_bend(head, bend, into, width)?; } else { - self.finish_in_dot(head, into, width)?; + self.finish_in_dot(head, into.into(), width)?; + } + Ok(()) + }*/ + + #[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_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> { + let tangent = self + .guide(&Default::default()) + .head_into_dot_segment(&head, into, width)?; + let head = self.extend_head(head, tangent.start_point())?; + + let net = head.dot().primitive(&self.layout.graph).net(); + + match head.dot() { + DotIndex::Fixed(dot) => { + self.layout + .add_fixed_seg(into.into(), dot, FixedSegWeight { net, width })?; + } + DotIndex::Loose(dot) => { + self.layout + .add_loose_seg(into.into(), dot, LooseSegWeight { net })?; + } } Ok(()) } #[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: FixedDotIndex, width: f64) -> Result<(), ()> { - let tangent = self - .guide(&Default::default()) - .head_into_dot_segment(&head, into, width)?; - let head = self.extend_head(head, tangent.start_point())?; - - let net = self.layout.primitive(head.dot()).weight().net; - self.layout - .add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?; - Ok(()) - } - - #[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_bend( + pub fn finish_in_bend( &mut self, head: Head, - into_bend: FixedBendIndex, - into: FixedDotIndex, + into_bend: LooseBendIndex, + into: LooseDotIndex, width: f64, ) -> Result<(), ()> { - let to_head = self.head(into); + let to_head = self.head(into.into()); let to_cw = self.guide(&Default::default()).head_cw(&to_head).unwrap(); let tangent = self.guide(&Default::default()).head_around_bend_segment( &head, @@ -110,9 +120,9 @@ impl<'a> Draw<'a> { let head = self.extend_head(head, tangent.start_point())?; let _to_head = self.extend_head(to_head, tangent.end_point())?; - let net = self.layout.primitive(head.dot()).weight().net; + let net = head.dot().primitive(&self.layout.graph).net(); self.layout - .add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?; + .add_loose_seg(head.dot(), into.into(), LooseSegWeight { net })?; Ok(()) } @@ -248,34 +258,27 @@ impl<'a> Draw<'a> { cw: bool, width: f64, ) -> Result { - let (head, seg) = self.seg(head, to, width)?; - let dot = head.dot; + let (seg, dot) = self.seg(head, to, width)?; + let net = head.dot().primitive(&self.layout.graph).net(); let bend_to = self .layout - .add_fixed_dot(self.layout.primitive(head.dot).weight()) + .add_loose_dot(self.layout.primitive(dot).weight()) .map_err(|err| { - self.undo_seg(head, seg); + self.undo_seg(seg, dot); err })?; - let net = self.layout.primitive(head.dot).weight().net; - let bend = self .layout - .add_fixed_bend( - head.dot, - bend_to, - around, - FixedBendWeight { net, width, cw }, - ) + .add_loose_bend(dot, bend_to, around, LooseBendWeight { net, cw }) .map_err(|err| { self.layout.remove(bend_to.into()); - self.undo_seg(head, seg); + self.undo_seg(seg, dot); err })?; Ok(SegbendHead { dot: bend_to, - segbend: Segbend { bend, dot, seg }, + segbend: Segbend { seg, dot, bend }, }) } @@ -285,20 +288,25 @@ impl<'a> Draw<'a> { let prev_dot = self .layout .primitive(head.segbend.seg) - .other_end(head.segbend.dot); + .other_end(head.segbend.dot.into()); self.layout.remove_interior(&head.segbend); self.layout.remove(head.dot().into()); - Some(self.head(prev_dot)) + Some(self.head(prev_dot.into())) } - #[debug_requires(width <= self.layout.primitive(head.dot()).weight().circle.r * 2.0)] + //#[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, FixedSegIndex), ()> { - let net = self.layout.primitive(head.dot()).weight().net; - let to_index = self.layout.add_fixed_dot(FixedDotWeight { + fn seg( + &mut self, + head: Head, + to: Point, + width: f64, + ) -> Result<(LooseSegIndex, LooseDotIndex), ()> { + let net = head.dot().primitive(&self.layout.graph).net(); + let to_index = self.layout.add_loose_dot(LooseDotWeight { net, circle: Circle { pos: to, @@ -307,25 +315,28 @@ impl<'a> Draw<'a> { })?; let seg = self .layout - .add_fixed_seg(head.dot(), to_index, FixedSegWeight { net, width }) + .add_loose_seg(head.dot(), to_index, LooseSegWeight { net }) .map_err(|err| { self.layout.remove(to_index.into()); err })?; - Ok((BareHead { dot: to_index }, seg)) + Ok((seg, to_index)) } #[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))] - fn undo_seg(&mut self, head: BareHead, seg: FixedSegIndex) { + fn undo_seg(&mut self, seg: LooseSegIndex, dot: LooseDotIndex) { self.layout.remove(seg.into()); - self.layout.remove(head.dot.into()); + self.layout.remove(dot.into()); } - fn head(&self, dot: FixedDotIndex) -> Head { - if let Some(segbend) = self.layout.segbend(dot) { - SegbendHead { dot, segbend }.into() - } else { - BareHead { dot }.into() + fn head(&self, dot: DotIndex) -> Head { + match dot { + DotIndex::Fixed(loose) => BareHead { dot: loose }.into(), + DotIndex::Loose(fixed) => SegbendHead { + dot: fixed, + segbend: self.layout.segbend(fixed).unwrap(), + } + .into(), } } diff --git a/src/graph.rs b/src/graph.rs index 8171348..a61853e 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -26,6 +26,11 @@ pub trait GetNet { fn net(&self) -> i64; } +#[enum_dispatch] +pub trait GetNetMut { + fn net_mut(&mut self) -> &mut i64; +} + #[enum_dispatch] pub trait GetWidth { fn width(&self) -> f64; @@ -48,6 +53,12 @@ macro_rules! impl_type { } } + impl GetNetMut for $weight_struct { + fn net_mut(&mut self) -> &mut i64 { + &mut self.net + } + } + pub type $index_struct = GenericIndex<$weight_struct>; impl MakePrimitive for $index_struct { @@ -61,7 +72,7 @@ macro_rules! impl_type { }; } -#[enum_dispatch(Retag, GetNet)] +#[enum_dispatch(Retag, GetNet, GetNetMut)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Weight { FixedDot(FixedDotWeight), @@ -109,8 +120,8 @@ pub enum SegIndex { impl From for Index { fn from(seg: SegIndex) -> Self { match seg { - SegIndex::Fixed(fixed) => Index::FixedSeg(fixed), - SegIndex::Loose(fully_loose) => Index::LooseSeg(fully_loose), + SegIndex::Fixed(seg) => Index::FixedSeg(seg), + SegIndex::Loose(seg) => Index::LooseSeg(seg), } } } @@ -125,8 +136,8 @@ pub enum BendIndex { impl From for Index { fn from(bend: BendIndex) -> Self { match bend { - BendIndex::Fixed(fixed) => Index::FixedBend(fixed), - BendIndex::Loose(loose) => Index::LooseBend(loose), + BendIndex::Fixed(bend) => Index::FixedBend(bend), + BendIndex::Loose(bend) => Index::LooseBend(bend), } } } diff --git a/src/guide.rs b/src/guide.rs index f861398..4dd3151 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -117,7 +117,7 @@ impl<'a, 'b> Guide<'a, 'b> { match *head { Head::Bare(head) => Circle { - pos: self.layout.primitive(head.dot()).weight().circle.pos, + pos: head.dot().primitive(&self.layout.graph).shape().center(), // TODO. r: 0.0, }, Head::Segbend(head) => { diff --git a/src/layout.rs b/src/layout.rs index 52483c4..ba319ba 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject}; use crate::bow::Bow; use crate::graph::{ - BendWeight, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, - FixedSegIndex, FixedSegWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, - LooseDotIndex, LooseSegIndex, LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight, + BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex, + FixedDotWeight, FixedSegIndex, FixedSegWeight, GenericIndex, GetNetMut, GetNodeIndex, Index, + Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, + LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight, }; use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape}; use crate::segbend::Segbend; @@ -38,7 +39,7 @@ impl Layout { for index in path .interior() .into_iter() - .filter(|index| !index.is_fixed_dot()) + .filter(|index| !index.is_loose_dot()) { self.remove(index); } @@ -49,7 +50,7 @@ impl Layout { for index in path .interior() .into_iter() - .filter(|index| index.is_fixed_dot()) + .filter(|index| index.is_loose_dot()) { self.remove(index); } @@ -65,10 +66,20 @@ impl Layout { } #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result { self.add_dot(weight) } + // TODO: Remove. + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] + pub fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result { + self.add_dot(weight) + } + #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] fn add_dot(&mut self, weight: W) -> Result, ()> where @@ -101,7 +112,7 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_loose_seg( &mut self, - from: LooseDotIndex, + from: DotIndex, to: LooseDotIndex, weight: LooseSegWeight, ) -> Result { @@ -131,23 +142,21 @@ impl Layout { self.insert_into_rtree(seg.into()); self.fail_and_remove_if_collides_except(seg.into(), &[])?; - self.graph + *self + .graph .node_weight_mut(from.node_index()) .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net(); - self.graph + .net_mut() = weight.net(); + *self + .graph .node_weight_mut(to.node_index()) .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net(); + .net_mut() = weight.net(); Ok(seg) } - #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + /*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] pub fn add_fixed_bend( &mut self, @@ -161,7 +170,7 @@ impl Layout { Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), _ => unreachable!(), } - } + }*/ #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] @@ -170,8 +179,8 @@ impl Layout { from: LooseDotIndex, to: LooseDotIndex, around: Index, - weight: FixedBendWeight, - ) -> Result { + weight: LooseBendWeight, + ) -> Result { match around { Index::FixedDot(core) => self.add_core_bend(from, to, core, weight), Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), @@ -189,11 +198,11 @@ impl Layout { to: impl GetNodeIndex, core: FixedDotIndex, weight: W, - ) -> Result + ) -> Result where GenericIndex: Into + Copy, { - let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); + let bend = LooseBendIndex::new(self.graph.add_node(weight.into())); self.graph .add_edge(from.node_index(), bend.node_index(), Label::Adjacent); @@ -217,7 +226,7 @@ impl Layout { to: impl GetNodeIndex, inner: impl GetNodeIndex, weight: W, - ) -> Result { + ) -> Result { let core = *self .graph .neighbors(inner.node_index()) @@ -232,7 +241,7 @@ impl Layout { .first() .unwrap(); - let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); + let bend = LooseBendIndex::new(self.graph.add_node(weight.into())); self.graph .add_edge(from.node_index(), bend.node_index(), Label::Adjacent); @@ -288,11 +297,11 @@ impl Layout { self.insert_into_rtree(bend.into()); } - pub fn bow(&self, bend: FixedBendIndex) -> Bow { + /*pub fn bow(&self, bend: LooseBendIndex) -> Bow { Bow::from_bend(bend, &self.graph) - } + }*/ - pub fn segbend(&self, dot: FixedDotIndex) -> Option { + pub fn segbend(&self, dot: LooseDotIndex) -> Option { Segbend::from_dot(dot, &self.graph) } @@ -333,7 +342,7 @@ 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: FixedDotIndex, to: Point) -> Result<(), ()> { + pub fn move_dot(&mut self, dot: LooseDotIndex, to: Point) -> Result<(), ()> { self.primitive(dot) .seg() .map(|seg| self.remove_from_rtree(seg.into())); @@ -346,11 +355,11 @@ impl Layout { let old_weight = dot_weight; dot_weight.circle.pos = to; - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(dot_weight); + *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight); if let Some(..) = self.detect_collision_except(dot.into(), &[]) { // Restore original state. - *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(old_weight); + *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight); self.insert_into_rtree(dot.into()); self.primitive(dot) diff --git a/src/main.rs b/src/main.rs index bea4c5d..8ff4c85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ extern crate sdl2; macro_rules! dbg_dot { ($graph:expr) => { - use petgraph::FixedDot::FixedDot; - println!("{:?}", FixedDot::new(&$graph)); + use petgraph::dot::Dot; + println!("{:?}", Dot::new(&$graph)); }; } @@ -25,7 +25,7 @@ mod shape; mod tracer; use geo::point; -use graph::{FixedDotIndex, FixedSegWeight}; +use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex}; use layout::Layout; use mesh::{Mesh, MeshEdgeReference, VertexIndex}; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; @@ -403,7 +403,7 @@ fn render_times( canvas: &mut Canvas, mut router_or_layout: RouterOrLayout, from: Option, - follower: Option, + follower: Option, mut mesh: Option, path: &[VertexIndex], times: i64, diff --git a/src/primitive.rs b/src/primitive.rs index a04b23b..d5ca60f 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -5,9 +5,10 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::Direction::{Incoming, Outgoing}; use crate::graph::{ - FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, - GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label, LooseBendIndex, - LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, Retag, Weight, + DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, + FixedSegWeight, GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label, + LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, + MakePrimitive, Retag, Weight, }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; @@ -37,14 +38,18 @@ pub trait MakeShape { fn shape(&self) -> Shape; } -#[enum_dispatch( - GetNet, - GetWidth, - GetGraph, - GetConnectable, - TaggedPrevTaggedNext, - MakeShape -)] +pub trait GetOtherEnd>: GetEnds { + fn other_end(&self, end: F) -> F { + let ends = self.ends(); + if ends.0.node_index() != end.node_index() { + ends.0 + } else { + ends.1.into() + } + } +} + +#[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)] pub enum Primitive<'a> { FixedDot(FixedDot<'a>), LooseDot(LooseDot<'a>), @@ -148,44 +153,6 @@ where pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; impl<'a> FixedDot<'a> { - pub fn seg(&self) -> Option { - self.graph - .neighbors_undirected(self.index.node_index()) - .filter(|ni| { - self.graph - .edge_weight( - self.graph - .find_edge_undirected(self.index.node_index(), *ni) - .unwrap() - .0, - ) - .unwrap() - .is_adjacent() - }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_seg()) - .map(|ni| FixedSegIndex::new(ni)) - .next() - } - - pub fn bend(&self) -> Option { - self.graph - .neighbors_undirected(self.index.node_index()) - .filter(|ni| { - self.graph - .edge_weight( - self.graph - .find_edge_undirected(self.index.node_index(), *ni) - .unwrap() - .0, - ) - .unwrap() - .is_adjacent() - }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_bend()) - .map(|ni| FixedBendIndex::new(ni)) - .next() - } - pub fn outer(&self) -> Option { self.graph .neighbors_directed(self.index.node_index(), Incoming) @@ -217,6 +184,46 @@ impl<'a> MakeShape for FixedDot<'a> { pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; +impl<'a> LooseDot<'a> { + pub fn seg(&self) -> Option { + self.graph + .neighbors_undirected(self.index.node_index()) + .filter(|ni| { + self.graph + .edge_weight( + self.graph + .find_edge_undirected(self.index.node_index(), *ni) + .unwrap() + .0, + ) + .unwrap() + .is_adjacent() + }) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_seg()) + .map(|ni| LooseSegIndex::new(ni)) + .next() + } + + pub fn bend(&self) -> Option { + self.graph + .neighbors_undirected(self.index.node_index()) + .filter(|ni| { + self.graph + .edge_weight( + self.graph + .find_edge_undirected(self.index.node_index(), *ni) + .unwrap() + .0, + ) + .unwrap() + .is_adjacent() + }) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_bend()) + .map(|ni| LooseBendIndex::new(ni)) + .next() + } +} + impl<'a> GetWeight for LooseDot<'a> { fn weight(&self) -> LooseDotWeight { self.tagged_weight().into_loose_dot().unwrap() @@ -233,16 +240,6 @@ impl<'a> MakeShape for LooseDot<'a> { pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; -impl<'a> FixedSeg<'a> { - pub fn other_end(&self, dot: FixedDotIndex) -> FixedDotIndex { - let ends = self.ends(); - [ends.0, ends.1] - .into_iter() - .find(|end| end.node_index() != dot.node_index()) - .unwrap() - } -} - impl<'a> GetWeight for FixedSeg<'a> { fn weight(&self) -> FixedSegWeight { self.tagged_weight().into_fixed_seg().unwrap() @@ -267,6 +264,8 @@ impl<'a> GetEnds for FixedSeg<'a> { } } +impl<'a> GetOtherEnd for FixedSeg<'a> {} + pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>; impl<'a> GetWeight for LooseSeg<'a> { @@ -279,7 +278,10 @@ impl<'a> MakeShape for LooseSeg<'a> { fn shape(&self) -> Shape { let ends = self.ends(); Shape::Seg(SegShape { - from: self.primitive(ends.0).weight().circle.pos, + from: match ends.0 { + DotIndex::Fixed(dot) => self.primitive(dot).weight().circle.pos, + DotIndex::Loose(dot) => self.primitive(dot).weight().circle.pos, + }, to: self.primitive(ends.1).weight().circle.pos, width: self.width(), }) @@ -292,13 +294,21 @@ impl<'a> GetWidth for LooseSeg<'a> { } } -impl<'a> GetEnds for LooseSeg<'a> { - fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { +impl<'a> GetEnds for LooseSeg<'a> { + fn ends(&self) -> (DotIndex, LooseDotIndex) { let v = self.adjacents(); - (LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1])) + if self.graph.node_weight(v[0]).unwrap().is_fixed_dot() { + (FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) + } else if self.graph.node_weight(v[1]).unwrap().is_fixed_dot() { + (FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0])) + } else { + (LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) + } } } +impl<'a> GetOtherEnd for LooseSeg<'a> {} + pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; impl<'a> FixedBend<'a> { @@ -336,14 +346,6 @@ impl<'a> FixedBend<'a> { .next() } - pub fn other_end(&self, dot: FixedDotIndex) -> FixedDotIndex { - let ends = self.ends(); - [ends.0, ends.1] - .into_iter() - .find(|end| end.node_index() != dot.node_index()) - .unwrap() - } - fn inner_radius(&self) -> f64 { let mut r = 0.0; let mut layer = FixedBendIndex::new(self.index.node_index()); @@ -408,6 +410,8 @@ impl<'a> GetEnds for FixedBend<'a> { } } +impl<'a> GetOtherEnd for FixedBend<'a> {} + pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; impl<'a> LooseBend<'a> { @@ -485,3 +489,5 @@ impl<'a> GetEnds for LooseBend<'a> { (LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1])) } } + +impl<'a> GetOtherEnd for LooseBend<'a> {} diff --git a/src/segbend.rs b/src/segbend.rs index d6c0c7f..81881b6 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -2,26 +2,27 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ graph::{ - FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label, Weight, + FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label, + LooseBendIndex, LooseDotIndex, LooseSegIndex, Weight, }, - primitive::{FixedBend, FixedDot}, + primitive::{FixedBend, FixedDot, GetOtherEnd, LooseBend, LooseDot}, }; #[derive(Debug, Clone, Copy)] pub struct Segbend { - pub seg: FixedSegIndex, - pub dot: FixedDotIndex, - pub bend: FixedBendIndex, + pub seg: LooseSegIndex, + pub dot: LooseDotIndex, + pub bend: LooseBendIndex, } impl Segbend { pub fn from_dot( - dot: FixedDotIndex, + dot: LooseDotIndex, graph: &StableDiGraph, ) -> Option { - let bend = FixedDot::new(dot, graph).bend()?; - let dot = FixedBend::new(bend, graph).other_end(dot); - let seg = FixedDot::new(dot, graph).seg()?; + let bend = LooseDot::new(dot, graph).bend()?; + let dot = LooseBend::new(bend, graph).other_end(dot); + let seg = LooseDot::new(dot, graph).seg()?; Some(Self { bend, dot, seg }) } } @@ -32,8 +33,8 @@ impl Interior for Segbend { } } -impl GetEnds for Segbend { - fn ends(&self) -> (FixedSegIndex, FixedBendIndex) { +impl GetEnds for Segbend { + fn ends(&self) -> (LooseSegIndex, LooseBendIndex) { (self.seg, self.bend) } } diff --git a/src/tracer.rs b/src/tracer.rs index ecbe0bb..d7930de 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -42,7 +42,7 @@ impl<'a> Tracer<'a> { pub fn finish(&mut self, trace: &mut Trace, into: VertexIndex, width: f64) -> Result<(), ()> { let into_dot = self.mesh.dot(into); - self.draw().finish(trace.head, into_dot, width) + self.draw().finish_in_dot(trace.head, into_dot, width) } #[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())] @@ -87,14 +87,14 @@ impl<'a> Tracer<'a> { #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))] pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> { let to_dot = self.mesh.dot(to); - trace.head = Head::from(self.wrap(trace.head, to_dot, width)?); + trace.head = self.wrap(trace.head, to_dot, width)?.into(); trace.path.push(to); Ok(()) } fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result { - let _around_pos = self.layout.primitive(around).weight().circle.pos; + /*let _around_pos = self.layout.primitive(around).weight().circle.pos; let _around_primitive = self.layout.primitive(around); 'blk: { @@ -117,12 +117,12 @@ impl<'a> Tracer<'a> { return self.draw().segbend_around_bend(head, layer.into(), width); } - } + }*/ self.draw().segbend_around_dot(head, around.into(), width) } - fn is_under( + /*fn is_under( &mut self, _head: Head, around: FixedDotIndex, @@ -142,9 +142,9 @@ impl<'a> Tracer<'a> { } else {*/ None //} - } + }*/ - fn tuck_around_dot( + /*fn tuck_around_dot( &mut self, head: Head, around: FixedDotIndex, @@ -213,7 +213,7 @@ impl<'a> Tracer<'a> { } Ok(()) - } + }*/ /*fn relax_band(&mut self, bend: FixedBendIndex) { let mut prev_bend = bend; @@ -235,15 +235,16 @@ impl<'a> Tracer<'a> { } }*/ - fn release_bow(&mut self, bend: FixedBendIndex) { + /*fn release_bow(&mut self, bend: FixedBendIndex) { let bow = self.layout.bow(bend); let ends = bow.ends(); self.layout.remove_interior(&bow); let head = self.draw().start(ends.0); + let _ = self.draw().finish(head, ends.1, 5.0); - } + }*/ #[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() - 1))] #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]