graph,layout,primitive: Use loose primitive variants for traces

This commit is contained in:
Mikolaj Wielgus 2023-10-28 13:18:55 +00:00
parent 4b46b2174b
commit c163716a6a
9 changed files with 252 additions and 213 deletions

View File

@ -1,32 +1,32 @@
use petgraph::stable_graph::StableDiGraph; use petgraph::stable_graph::StableDiGraph;
use crate::graph::{ 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)] #[derive(Debug, Clone, Copy)]
pub struct Bow { pub struct Bow {
seg1_dot1: FixedDotIndex, seg1_dot1: LooseDotIndex,
seg1: FixedSegIndex, seg1: LooseSegIndex,
seg1_dot2: FixedDotIndex, seg1_dot2: LooseDotIndex,
bend: FixedBendIndex, bend: LooseBendIndex,
seg2_dot1: FixedDotIndex, seg2_dot1: LooseDotIndex,
seg2: FixedSegIndex, seg2: LooseSegIndex,
seg2_dot2: FixedDotIndex, seg2_dot2: LooseDotIndex,
} }
impl Bow { /*impl Bow {
pub fn from_bend(index: FixedBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self { pub fn from_bend(index: LooseBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
let bend = index; let bend = index;
let seg1_dot2 = FixedBend::new(bend, graph).ends().0; let seg1_dot2 = LooseBend::new(bend, graph).ends().0;
let seg1 = FixedDot::new(seg1_dot2, graph).seg().unwrap(); let seg1 = LooseDot::new(seg1_dot2, graph).seg().unwrap();
let seg1_dot1 = FixedSeg::new(seg1, graph).other_end(seg1_dot2); let seg1_dot1 = LooseSeg::new(seg1, graph).other_end(seg1_dot2);
let seg2_dot1 = FixedBend::new(bend, graph).ends().1; let seg2_dot1 = LooseBend::new(bend, graph).ends().1;
let seg2 = FixedDot::new(seg2_dot1, graph).seg().unwrap(); let seg2 = LooseDot::new(seg2_dot1, graph).seg().unwrap();
let seg2_dot2 = FixedSeg::new(seg2, graph).other_end(seg2_dot1); let seg2_dot2 = LooseSeg::new(seg2, graph).other_end(seg2_dot1);
Self { Self {
seg1_dot1, seg1_dot1,
@ -38,7 +38,7 @@ impl Bow {
seg2_dot2, seg2_dot2,
} }
} }
} }*/
impl Interior<Index> for Bow { impl Interior<Index> for Bow {
fn interior(&self) -> Vec<Index> { fn interior(&self) -> Vec<Index> {
@ -52,8 +52,8 @@ impl Interior<Index> for Bow {
} }
} }
impl GetEnds<FixedDotIndex, FixedDotIndex> for Bow { impl GetEnds<LooseDotIndex, LooseDotIndex> for Bow {
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
(self.seg1_dot1, self.seg2_dot2) (self.seg1_dot1, self.seg2_dot2)
} }
} }

View File

@ -4,20 +4,21 @@ use geo::{EuclideanLength, Point};
use crate::{ use crate::{
graph::{ graph::{
BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex,
FixedSegIndex, FixedSegWeight, Index, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
MakePrimitive,
}, },
guide::Guide, guide::Guide,
layout::Layout, layout::Layout,
math::Circle, math::Circle,
primitive::GetWeight, primitive::{GetOtherEnd, GetWeight},
rules::{Conditions, Rules}, rules::{Conditions, Rules},
segbend::Segbend, segbend::Segbend,
}; };
#[enum_dispatch] #[enum_dispatch]
pub trait HeadTrait { pub trait HeadTrait {
fn dot(&self) -> FixedDotIndex; fn dot(&self) -> DotIndex;
} }
#[enum_dispatch(HeadTrait)] #[enum_dispatch(HeadTrait)]
@ -33,20 +34,20 @@ pub struct BareHead {
} }
impl HeadTrait for BareHead { impl HeadTrait for BareHead {
fn dot(&self) -> FixedDotIndex { fn dot(&self) -> DotIndex {
self.dot self.dot.into()
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct SegbendHead { pub struct SegbendHead {
pub dot: FixedDotIndex, pub dot: LooseDotIndex,
pub segbend: Segbend, pub segbend: Segbend,
} }
impl HeadTrait for SegbendHead { impl HeadTrait for SegbendHead {
fn dot(&self) -> FixedDotIndex { fn dot(&self) -> DotIndex {
self.dot self.dot.into()
} }
} }
@ -60,45 +61,54 @@ impl<'a> Draw<'a> {
Self { layout, rules } Self { layout, rules }
} }
pub fn start(&mut self, from: FixedDotIndex) -> Head { pub fn start(&mut self, from: LooseDotIndex) -> Head {
self.head(from) 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()))] #[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() { if let Some(bend) = self.layout.primitive(into).bend() {
self.finish_in_bend(head, bend, into, width)?; self.finish_in_bend(head, bend, into, width)?;
} else { } else {
self.finish_in_dot(head, into, width)?; self.finish_in_dot(head, into.into(), width)?;
} }
Ok(()) Ok(())
} }*/
#[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()))] #[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<(), ()> { pub fn finish_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
let tangent = self let tangent = self
.guide(&Default::default()) .guide(&Default::default())
.head_into_dot_segment(&head, into, width)?; .head_into_dot_segment(&head, into, width)?;
let head = self.extend_head(head, tangent.start_point())?; let head = self.extend_head(head, tangent.start_point())?;
let net = self.layout.primitive(head.dot()).weight().net; let net = head.dot().primitive(&self.layout.graph).net();
match head.dot() {
DotIndex::Fixed(dot) => {
self.layout self.layout
.add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?; .add_fixed_seg(into.into(), dot, FixedSegWeight { net, width })?;
}
DotIndex::Loose(dot) => {
self.layout
.add_loose_seg(into.into(), dot, LooseSegWeight { net })?;
}
}
Ok(()) Ok(())
} }
#[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()))] #[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, &mut self,
head: Head, head: Head,
into_bend: FixedBendIndex, into_bend: LooseBendIndex,
into: FixedDotIndex, into: LooseDotIndex,
width: f64, width: f64,
) -> Result<(), ()> { ) -> 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 to_cw = self.guide(&Default::default()).head_cw(&to_head).unwrap();
let tangent = self.guide(&Default::default()).head_around_bend_segment( let tangent = self.guide(&Default::default()).head_around_bend_segment(
&head, &head,
@ -110,9 +120,9 @@ impl<'a> Draw<'a> {
let head = self.extend_head(head, tangent.start_point())?; let head = self.extend_head(head, tangent.start_point())?;
let _to_head = self.extend_head(to_head, tangent.end_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 self.layout
.add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?; .add_loose_seg(head.dot(), into.into(), LooseSegWeight { net })?;
Ok(()) Ok(())
} }
@ -248,34 +258,27 @@ impl<'a> Draw<'a> {
cw: bool, cw: bool,
width: f64, width: f64,
) -> Result<SegbendHead, ()> { ) -> Result<SegbendHead, ()> {
let (head, seg) = self.seg(head, to, width)?; let (seg, dot) = self.seg(head, to, width)?;
let dot = head.dot; let net = head.dot().primitive(&self.layout.graph).net();
let bend_to = self let bend_to = self
.layout .layout
.add_fixed_dot(self.layout.primitive(head.dot).weight()) .add_loose_dot(self.layout.primitive(dot).weight())
.map_err(|err| { .map_err(|err| {
self.undo_seg(head, seg); self.undo_seg(seg, dot);
err err
})?; })?;
let net = self.layout.primitive(head.dot).weight().net;
let bend = self let bend = self
.layout .layout
.add_fixed_bend( .add_loose_bend(dot, bend_to, around, LooseBendWeight { net, cw })
head.dot,
bend_to,
around,
FixedBendWeight { net, width, cw },
)
.map_err(|err| { .map_err(|err| {
self.layout.remove(bend_to.into()); self.layout.remove(bend_to.into());
self.undo_seg(head, seg); self.undo_seg(seg, dot);
err err
})?; })?;
Ok(SegbendHead { Ok(SegbendHead {
dot: bend_to, 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 let prev_dot = self
.layout .layout
.primitive(head.segbend.seg) .primitive(head.segbend.seg)
.other_end(head.segbend.dot); .other_end(head.segbend.dot.into());
self.layout.remove_interior(&head.segbend); self.layout.remove_interior(&head.segbend);
self.layout.remove(head.dot().into()); 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_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()))] #[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), ()> { fn seg(
let net = self.layout.primitive(head.dot()).weight().net; &mut self,
let to_index = self.layout.add_fixed_dot(FixedDotWeight { 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, net,
circle: Circle { circle: Circle {
pos: to, pos: to,
@ -307,25 +315,28 @@ impl<'a> Draw<'a> {
})?; })?;
let seg = self let seg = self
.layout .layout
.add_fixed_seg(head.dot(), to_index, FixedSegWeight { net, width }) .add_loose_seg(head.dot(), to_index, LooseSegWeight { net })
.map_err(|err| { .map_err(|err| {
self.layout.remove(to_index.into()); self.layout.remove(to_index.into());
err err
})?; })?;
Ok((BareHead { dot: to_index }, seg)) Ok((seg, to_index))
} }
#[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))] #[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(seg.into());
self.layout.remove(head.dot.into()); self.layout.remove(dot.into());
} }
fn head(&self, dot: FixedDotIndex) -> Head { fn head(&self, dot: DotIndex) -> Head {
if let Some(segbend) = self.layout.segbend(dot) { match dot {
SegbendHead { dot, segbend }.into() DotIndex::Fixed(loose) => BareHead { dot: loose }.into(),
} else { DotIndex::Loose(fixed) => SegbendHead {
BareHead { dot }.into() dot: fixed,
segbend: self.layout.segbend(fixed).unwrap(),
}
.into(),
} }
} }

View File

@ -26,6 +26,11 @@ pub trait GetNet {
fn net(&self) -> i64; fn net(&self) -> i64;
} }
#[enum_dispatch]
pub trait GetNetMut {
fn net_mut(&mut self) -> &mut i64;
}
#[enum_dispatch] #[enum_dispatch]
pub trait GetWidth { pub trait GetWidth {
fn width(&self) -> f64; 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>; pub type $index_struct = GenericIndex<$weight_struct>;
impl MakePrimitive for $index_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)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Weight { pub enum Weight {
FixedDot(FixedDotWeight), FixedDot(FixedDotWeight),
@ -109,8 +120,8 @@ pub enum SegIndex {
impl From<SegIndex> for Index { impl From<SegIndex> for Index {
fn from(seg: SegIndex) -> Self { fn from(seg: SegIndex) -> Self {
match seg { match seg {
SegIndex::Fixed(fixed) => Index::FixedSeg(fixed), SegIndex::Fixed(seg) => Index::FixedSeg(seg),
SegIndex::Loose(fully_loose) => Index::LooseSeg(fully_loose), SegIndex::Loose(seg) => Index::LooseSeg(seg),
} }
} }
} }
@ -125,8 +136,8 @@ pub enum BendIndex {
impl From<BendIndex> for Index { impl From<BendIndex> for Index {
fn from(bend: BendIndex) -> Self { fn from(bend: BendIndex) -> Self {
match bend { match bend {
BendIndex::Fixed(fixed) => Index::FixedBend(fixed), BendIndex::Fixed(bend) => Index::FixedBend(bend),
BendIndex::Loose(loose) => Index::LooseBend(loose), BendIndex::Loose(bend) => Index::LooseBend(bend),
} }
} }
} }

View File

@ -117,7 +117,7 @@ impl<'a, 'b> Guide<'a, 'b> {
match *head { match *head {
Head::Bare(head) => Circle { 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, r: 0.0,
}, },
Head::Segbend(head) => { Head::Segbend(head) => {

View File

@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject};
use crate::bow::Bow; use crate::bow::Bow;
use crate::graph::{ use crate::graph::{
BendWeight, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex,
FixedSegIndex, FixedSegWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, FixedDotWeight, FixedSegIndex, FixedSegWeight, GenericIndex, GetNetMut, GetNodeIndex, Index,
LooseDotIndex, LooseSegIndex, LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight, Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex,
LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight,
}; };
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape}; use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
use crate::segbend::Segbend; use crate::segbend::Segbend;
@ -38,7 +39,7 @@ impl Layout {
for index in path for index in path
.interior() .interior()
.into_iter() .into_iter()
.filter(|index| !index.is_fixed_dot()) .filter(|index| !index.is_loose_dot())
{ {
self.remove(index); self.remove(index);
} }
@ -49,7 +50,7 @@ impl Layout {
for index in path for index in path
.interior() .interior()
.into_iter() .into_iter()
.filter(|index| index.is_fixed_dot()) .filter(|index| index.is_loose_dot())
{ {
self.remove(index); 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_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<FixedDotIndex, ()> { pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> {
self.add_dot(weight) 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<LooseDotIndex, ()> {
self.add_dot(weight)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()> fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()>
where where
@ -101,7 +112,7 @@ impl Layout {
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn add_loose_seg( pub fn add_loose_seg(
&mut self, &mut self,
from: LooseDotIndex, from: DotIndex,
to: LooseDotIndex, to: LooseDotIndex,
weight: LooseSegWeight, weight: LooseSegWeight,
) -> Result<LooseSegIndex, ()> { ) -> Result<LooseSegIndex, ()> {
@ -131,23 +142,21 @@ impl Layout {
self.insert_into_rtree(seg.into()); self.insert_into_rtree(seg.into());
self.fail_and_remove_if_collides_except(seg.into(), &[])?; self.fail_and_remove_if_collides_except(seg.into(), &[])?;
self.graph *self
.graph
.node_weight_mut(from.node_index()) .node_weight_mut(from.node_index())
.unwrap() .unwrap()
.as_fixed_dot_mut() .net_mut() = weight.net();
.unwrap() *self
.net = weight.net(); .graph
self.graph
.node_weight_mut(to.node_index()) .node_weight_mut(to.node_index())
.unwrap() .unwrap()
.as_fixed_dot_mut() .net_mut() = weight.net();
.unwrap()
.net = weight.net();
Ok(seg) 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()))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
pub fn add_fixed_bend( pub fn add_fixed_bend(
&mut self, &mut self,
@ -161,7 +170,7 @@ impl Layout {
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
_ => unreachable!(), _ => unreachable!(),
} }
} }*/
#[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()))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
@ -170,8 +179,8 @@ impl Layout {
from: LooseDotIndex, from: LooseDotIndex,
to: LooseDotIndex, to: LooseDotIndex,
around: Index, around: Index,
weight: FixedBendWeight, weight: LooseBendWeight,
) -> Result<FixedBendIndex, ()> { ) -> Result<LooseBendIndex, ()> {
match around { match around {
Index::FixedDot(core) => self.add_core_bend(from, to, core, weight), Index::FixedDot(core) => self.add_core_bend(from, to, core, weight),
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
@ -189,11 +198,11 @@ impl Layout {
to: impl GetNodeIndex, to: impl GetNodeIndex,
core: FixedDotIndex, core: FixedDotIndex,
weight: W, weight: W,
) -> Result<FixedBendIndex, ()> ) -> Result<LooseBendIndex, ()>
where where
GenericIndex<W>: Into<Index> + Copy, GenericIndex<W>: Into<Index> + Copy,
{ {
let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
self.graph self.graph
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent); .add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
@ -217,7 +226,7 @@ impl Layout {
to: impl GetNodeIndex, to: impl GetNodeIndex,
inner: impl GetNodeIndex, inner: impl GetNodeIndex,
weight: W, weight: W,
) -> Result<FixedBendIndex, ()> { ) -> Result<LooseBendIndex, ()> {
let core = *self let core = *self
.graph .graph
.neighbors(inner.node_index()) .neighbors(inner.node_index())
@ -232,7 +241,7 @@ impl Layout {
.first() .first()
.unwrap(); .unwrap();
let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
self.graph self.graph
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent); .add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
@ -288,11 +297,11 @@ impl Layout {
self.insert_into_rtree(bend.into()); 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) Bow::from_bend(bend, &self.graph)
} }*/
pub fn segbend(&self, dot: FixedDotIndex) -> Option<Segbend> { pub fn segbend(&self, dot: LooseDotIndex) -> Option<Segbend> {
Segbend::from_dot(dot, &self.graph) Segbend::from_dot(dot, &self.graph)
} }
@ -333,7 +342,7 @@ impl Layout {
impl Layout { impl Layout {
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(self.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) self.primitive(dot)
.seg() .seg()
.map(|seg| self.remove_from_rtree(seg.into())); .map(|seg| self.remove_from_rtree(seg.into()));
@ -346,11 +355,11 @@ impl Layout {
let old_weight = dot_weight; let old_weight = dot_weight;
dot_weight.circle.pos = to; 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(), &[]) { if let Some(..) = self.detect_collision_except(dot.into(), &[]) {
// Restore original state. // 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.insert_into_rtree(dot.into());
self.primitive(dot) self.primitive(dot)

View File

@ -2,8 +2,8 @@ extern crate sdl2;
macro_rules! dbg_dot { macro_rules! dbg_dot {
($graph:expr) => { ($graph:expr) => {
use petgraph::FixedDot::FixedDot; use petgraph::dot::Dot;
println!("{:?}", FixedDot::new(&$graph)); println!("{:?}", Dot::new(&$graph));
}; };
} }
@ -25,7 +25,7 @@ mod shape;
mod tracer; mod tracer;
use geo::point; use geo::point;
use graph::{FixedDotIndex, FixedSegWeight}; use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex};
use layout::Layout; use layout::Layout;
use mesh::{Mesh, MeshEdgeReference, VertexIndex}; use mesh::{Mesh, MeshEdgeReference, VertexIndex};
use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use petgraph::visit::{EdgeRef, IntoEdgeReferences};
@ -403,7 +403,7 @@ fn render_times(
canvas: &mut Canvas<Window>, canvas: &mut Canvas<Window>,
mut router_or_layout: RouterOrLayout, mut router_or_layout: RouterOrLayout,
from: Option<FixedDotIndex>, from: Option<FixedDotIndex>,
follower: Option<FixedDotIndex>, follower: Option<LooseDotIndex>,
mut mesh: Option<Mesh>, mut mesh: Option<Mesh>,
path: &[VertexIndex], path: &[VertexIndex],
times: i64, times: i64,

View File

@ -5,9 +5,10 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use petgraph::Direction::{Incoming, Outgoing}; use petgraph::Direction::{Incoming, Outgoing};
use crate::graph::{ use crate::graph::{
FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex,
GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label, LooseBendIndex, FixedSegWeight, GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, Retag, Weight, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
MakePrimitive, Retag, Weight,
}; };
use crate::math::{self, Circle}; use crate::math::{self, Circle};
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
@ -37,14 +38,18 @@ pub trait MakeShape {
fn shape(&self) -> Shape; fn shape(&self) -> Shape;
} }
#[enum_dispatch( pub trait GetOtherEnd<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetEnds<F, T> {
GetNet, fn other_end(&self, end: F) -> F {
GetWidth, let ends = self.ends();
GetGraph, if ends.0.node_index() != end.node_index() {
GetConnectable, ends.0
TaggedPrevTaggedNext, } else {
MakeShape ends.1.into()
)] }
}
}
#[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)]
pub enum Primitive<'a> { pub enum Primitive<'a> {
FixedDot(FixedDot<'a>), FixedDot(FixedDot<'a>),
LooseDot(LooseDot<'a>), LooseDot(LooseDot<'a>),
@ -148,44 +153,6 @@ where
pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>;
impl<'a> FixedDot<'a> { impl<'a> FixedDot<'a> {
pub fn seg(&self) -> Option<FixedSegIndex> {
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<FixedBendIndex> {
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<FixedBendIndex> { pub fn outer(&self) -> Option<FixedBendIndex> {
self.graph self.graph
.neighbors_directed(self.index.node_index(), Incoming) .neighbors_directed(self.index.node_index(), Incoming)
@ -217,6 +184,46 @@ impl<'a> MakeShape for FixedDot<'a> {
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
impl<'a> LooseDot<'a> {
pub fn seg(&self) -> Option<LooseSegIndex> {
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<LooseBendIndex> {
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<LooseDotWeight> for LooseDot<'a> { impl<'a> GetWeight<LooseDotWeight> for LooseDot<'a> {
fn weight(&self) -> LooseDotWeight { fn weight(&self) -> LooseDotWeight {
self.tagged_weight().into_loose_dot().unwrap() self.tagged_weight().into_loose_dot().unwrap()
@ -233,16 +240,6 @@ impl<'a> MakeShape for LooseDot<'a> {
pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; 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<FixedSegWeight> for FixedSeg<'a> { impl<'a> GetWeight<FixedSegWeight> for FixedSeg<'a> {
fn weight(&self) -> FixedSegWeight { fn weight(&self) -> FixedSegWeight {
self.tagged_weight().into_fixed_seg().unwrap() self.tagged_weight().into_fixed_seg().unwrap()
@ -267,6 +264,8 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
} }
} }
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>; pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>;
impl<'a> GetWeight<LooseSegWeight> for LooseSeg<'a> { impl<'a> GetWeight<LooseSegWeight> for LooseSeg<'a> {
@ -279,7 +278,10 @@ impl<'a> MakeShape for LooseSeg<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
let ends = self.ends(); let ends = self.ends();
Shape::Seg(SegShape { 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, to: self.primitive(ends.1).weight().circle.pos,
width: self.width(), width: self.width(),
}) })
@ -292,13 +294,21 @@ impl<'a> GetWidth for LooseSeg<'a> {
} }
} }
impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseSeg<'a> { impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { fn ends(&self) -> (DotIndex, LooseDotIndex) {
let v = self.adjacents(); 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<DotIndex, LooseDotIndex> for LooseSeg<'a> {}
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
impl<'a> FixedBend<'a> { impl<'a> FixedBend<'a> {
@ -336,14 +346,6 @@ impl<'a> FixedBend<'a> {
.next() .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 { fn inner_radius(&self) -> f64 {
let mut r = 0.0; let mut r = 0.0;
let mut layer = FixedBendIndex::new(self.index.node_index()); let mut layer = FixedBendIndex::new(self.index.node_index());
@ -408,6 +410,8 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
} }
} }
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>;
impl<'a> LooseBend<'a> { impl<'a> LooseBend<'a> {
@ -485,3 +489,5 @@ impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
(LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1])) (LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1]))
} }
} }
impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}

View File

@ -2,26 +2,27 @@ use petgraph::stable_graph::StableDiGraph;
use crate::{ use crate::{
graph::{ 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)] #[derive(Debug, Clone, Copy)]
pub struct Segbend { pub struct Segbend {
pub seg: FixedSegIndex, pub seg: LooseSegIndex,
pub dot: FixedDotIndex, pub dot: LooseDotIndex,
pub bend: FixedBendIndex, pub bend: LooseBendIndex,
} }
impl Segbend { impl Segbend {
pub fn from_dot( pub fn from_dot(
dot: FixedDotIndex, dot: LooseDotIndex,
graph: &StableDiGraph<Weight, Label, usize>, graph: &StableDiGraph<Weight, Label, usize>,
) -> Option<Self> { ) -> Option<Self> {
let bend = FixedDot::new(dot, graph).bend()?; let bend = LooseDot::new(dot, graph).bend()?;
let dot = FixedBend::new(bend, graph).other_end(dot); let dot = LooseBend::new(bend, graph).other_end(dot);
let seg = FixedDot::new(dot, graph).seg()?; let seg = LooseDot::new(dot, graph).seg()?;
Some(Self { bend, dot, seg }) Some(Self { bend, dot, seg })
} }
} }
@ -32,8 +33,8 @@ impl Interior<Index> for Segbend {
} }
} }
impl GetEnds<FixedSegIndex, FixedBendIndex> for Segbend { impl GetEnds<LooseSegIndex, LooseBendIndex> for Segbend {
fn ends(&self) -> (FixedSegIndex, FixedBendIndex) { fn ends(&self) -> (LooseSegIndex, LooseBendIndex) {
(self.seg, self.bend) (self.seg, self.bend)
} }
} }

View File

@ -42,7 +42,7 @@ impl<'a> Tracer<'a> {
pub fn finish(&mut self, trace: &mut Trace, into: VertexIndex, width: f64) -> Result<(), ()> { pub fn finish(&mut self, trace: &mut Trace, into: VertexIndex, width: f64) -> Result<(), ()> {
let into_dot = self.mesh.dot(into); 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())] #[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()))] #[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<(), ()> { pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> {
let to_dot = self.mesh.dot(to); 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); trace.path.push(to);
Ok(()) Ok(())
} }
fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result<SegbendHead, ()> { fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result<SegbendHead, ()> {
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); let _around_primitive = self.layout.primitive(around);
'blk: { 'blk: {
@ -117,12 +117,12 @@ impl<'a> Tracer<'a> {
return self.draw().segbend_around_bend(head, layer.into(), width); return self.draw().segbend_around_bend(head, layer.into(), width);
} }
} }*/
self.draw().segbend_around_dot(head, around.into(), width) self.draw().segbend_around_dot(head, around.into(), width)
} }
fn is_under( /*fn is_under(
&mut self, &mut self,
_head: Head, _head: Head,
around: FixedDotIndex, around: FixedDotIndex,
@ -142,9 +142,9 @@ impl<'a> Tracer<'a> {
} else {*/ } else {*/
None None
//} //}
} }*/
fn tuck_around_dot( /*fn tuck_around_dot(
&mut self, &mut self,
head: Head, head: Head,
around: FixedDotIndex, around: FixedDotIndex,
@ -213,7 +213,7 @@ impl<'a> Tracer<'a> {
} }
Ok(()) Ok(())
} }*/
/*fn relax_band(&mut self, bend: FixedBendIndex) { /*fn relax_band(&mut self, bend: FixedBendIndex) {
let mut prev_bend = bend; 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 bow = self.layout.bow(bend);
let ends = bow.ends(); let ends = bow.ends();
self.layout.remove_interior(&bow); self.layout.remove_interior(&bow);
let head = self.draw().start(ends.0); let head = self.draw().start(ends.0);
let _ = self.draw().finish(head, ends.1, 5.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_ok() -> trace.path.len() == old(trace.path.len() - 1))]
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))] #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]