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 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<Weight, Label, usize>) -> Self {
/*impl Bow {
pub fn from_bend(index: LooseBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> 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<Index> for Bow {
fn interior(&self) -> Vec<Index> {
@ -52,8 +52,8 @@ impl Interior<Index> for Bow {
}
}
impl GetEnds<FixedDotIndex, FixedDotIndex> for Bow {
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
impl GetEnds<LooseDotIndex, LooseDotIndex> for Bow {
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
(self.seg1_dot1, self.seg2_dot2)
}
}

View File

@ -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()))]
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
.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;
let net = head.dot().primitive(&self.layout.graph).net();
match head.dot() {
DotIndex::Fixed(dot) => {
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(())
}
#[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<SegbendHead, ()> {
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(),
}
}

View File

@ -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<SegIndex> 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<BendIndex> 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),
}
}
}

View File

@ -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) => {

View File

@ -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<FixedDotIndex, ()> {
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))]
fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()>
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<LooseSegIndex, ()> {
@ -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<FixedBendIndex, ()> {
weight: LooseBendWeight,
) -> Result<LooseBendIndex, ()> {
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<FixedBendIndex, ()>
) -> Result<LooseBendIndex, ()>
where
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
.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<FixedBendIndex, ()> {
) -> Result<LooseBendIndex, ()> {
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<Segbend> {
pub fn segbend(&self, dot: LooseDotIndex) -> Option<Segbend> {
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)

View File

@ -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<Window>,
mut router_or_layout: RouterOrLayout,
from: Option<FixedDotIndex>,
follower: Option<FixedDotIndex>,
follower: Option<LooseDotIndex>,
mut mesh: Option<Mesh>,
path: &[VertexIndex],
times: i64,

View File

@ -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<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetEnds<F, T> {
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<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> {
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<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> {
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<FixedSegWeight> for FixedSeg<'a> {
fn weight(&self) -> FixedSegWeight {
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>;
impl<'a> GetWeight<LooseSegWeight> 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<LooseDotIndex, LooseDotIndex> for LooseSeg<'a> {
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
impl<'a> GetEnds<DotIndex, LooseDotIndex> 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<DotIndex, LooseDotIndex> 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<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
}
}
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>;
impl<'a> LooseBend<'a> {
@ -485,3 +489,5 @@ impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
(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::{
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<Weight, Label, usize>,
) -> Option<Self> {
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<Index> for Segbend {
}
}
impl GetEnds<FixedSegIndex, FixedBendIndex> for Segbend {
fn ends(&self) -> (FixedSegIndex, FixedBendIndex) {
impl GetEnds<LooseSegIndex, LooseBendIndex> for Segbend {
fn ends(&self) -> (LooseSegIndex, LooseBendIndex) {
(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<(), ()> {
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<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);
'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()))]