From 26112724c78685ec87d8ecae41024784bf5549f7 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 14 Jul 2023 12:40:30 +0200 Subject: [PATCH] Make bends nodes This is necessary because bends may have more than two neighbors: apart from the ends, there's also the node around which the bend is wrapped (not yet made a neighbor, will be done in subsequent commits). --- src/layout.rs | 2 +- src/main.rs | 3 ++- src/mesh.rs | 49 ++++++++++++++++++++++++++++++++++++------------ src/primitive.rs | 3 +++ src/weight.rs | 10 ++++++++++ 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index ebc10c6..a024b5d 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -137,7 +137,7 @@ impl Layout { match self.mesh.weight(head_around) { Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions), Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions), - Weight::Seg(..) => unreachable!(), + Weight::Seg(..) | Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(), } }, None => Circle { diff --git a/src/main.rs b/src/main.rs index efcf2d3..3b4e47e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,7 +133,7 @@ fn main() { let mut angle1 = delta1.y().atan2(delta1.x()); let mut angle2 = delta2.y().atan2(delta2.x()); - if !primitive.weight.as_bend().unwrap().cw { + if primitive.weight.as_bend().unwrap().cw { swap(&mut angle1, &mut angle2); } @@ -151,6 +151,7 @@ fn main() { } }, + Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(), } } diff --git a/src/mesh.rs b/src/mesh.rs index 9880142..673a229 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -6,7 +6,7 @@ use rstar::{RTree, RTreeObject, AABB}; use rstar::primitives::GeomWithData; use crate::primitive::Primitive; -use crate::weight::{Weight, DotWeight, SegWeight, BendWeight}; +use crate::weight::{Weight, DotWeight, SegWeight, BendWeight, EndRefWeight, AroundRefWeight}; #[derive(Debug, Copy, Clone, PartialEq)] @@ -44,7 +44,7 @@ impl Tag for SegIndex { } } -pub type BendIndex = Index, BendWeight>; +pub type BendIndex = Index, BendWeight>; impl Tag for BendIndex { fn tag(&self) -> TaggedIndex { @@ -52,11 +52,29 @@ impl Tag for BendIndex { } } +pub type EndRefIndex = Index, EndRefWeight>; + +impl Tag for EndRefIndex { + fn tag(&self) -> TaggedIndex { + TaggedIndex::EndRef(*self) + } +} + +pub type AroundRefIndex = Index, AroundRefWeight>; + +impl Tag for AroundRefIndex { + fn tag(&self) -> TaggedIndex { + TaggedIndex::AroundRef(*self) + } +} + #[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)] pub enum TaggedIndex { Dot(DotIndex), Seg(SegIndex), Bend(BendIndex), + EndRef(EndRefIndex), + AroundRef(AroundRefIndex), } pub type RTreeWrapper = GeomWithData; @@ -99,7 +117,10 @@ impl Mesh { } pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, weight: BendWeight) -> BendIndex { - let bend_index = BendIndex::new(self.graph.add_edge(from.index, to.index, Weight::Bend(weight))); + let bend_index = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); + self.graph.add_edge(from.index, bend_index.index, Weight::EndRef(EndRefWeight {})); + self.graph.add_edge(bend_index.index, to.index, Weight::EndRef(EndRefWeight {})); + let index = TaggedIndex::Bend(bend_index); self.rtree.insert(RTreeWrapper::new(self.primitive(index), index)); bend_index @@ -107,7 +128,7 @@ impl Mesh { pub fn remove_bend(&mut self, bend: BendIndex) { self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend))); - self.graph.remove_edge(bend.index); + self.graph.remove_node(bend.index); } pub fn primitives(&self) -> Box + '_> { @@ -143,15 +164,18 @@ impl Mesh { pub fn neighboring_dots(&self, index: TaggedIndex) -> Vec { match index { - TaggedIndex::Dot(DotIndex {index: node_index, ..}) => + TaggedIndex::Dot(DotIndex {index: node_index, ..}) + | TaggedIndex::Bend(BendIndex {index: node_index, ..}) => return self.graph.neighbors(node_index) - .map(|ni| TaggedIndex::Dot(Index::new(ni))).collect(), - TaggedIndex::Seg(SegIndex {index: edge_index, ..}) - | TaggedIndex::Bend(BendIndex {index: edge_index, ..}) => { + .filter(|ni| self.graph.node_weight(*ni).unwrap().as_dot().is_some()) + .map(|ni| TaggedIndex::Dot(Index::new(ni))) + .collect(), + TaggedIndex::Seg(SegIndex {index: edge_index, ..}) => { let endpoints = self.graph.edge_endpoints(edge_index).unwrap(); return vec![TaggedIndex::Dot(DotIndex::new(endpoints.0)), TaggedIndex::Dot(DotIndex::new(endpoints.1))] - } + }, + TaggedIndex::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(), } } @@ -169,11 +193,12 @@ impl Mesh { pub fn weight(&self, index: TaggedIndex) -> Weight { match index { - TaggedIndex::Dot(DotIndex {index: node_index, ..}) => + TaggedIndex::Dot(DotIndex {index: node_index, ..}) + | TaggedIndex::Bend(BendIndex {index: node_index, ..}) => *self.graph.node_weight(node_index).unwrap(), - TaggedIndex::Seg(SegIndex {index: edge_index, ..}) - | TaggedIndex::Bend(BendIndex {index: edge_index, ..}) => + TaggedIndex::Seg(SegIndex {index: edge_index, ..}) => *self.graph.edge_weight(edge_index).unwrap(), + TaggedIndex::EndRef(..) | TaggedIndex::AroundRef(..) => unreachable!(), } } } diff --git a/src/primitive.rs b/src/primitive.rs index 213249d..ce78d09 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -28,6 +28,7 @@ impl Primitive { .collect(); return AABB::<[f64; 2]>::from_points(&points); }, + Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(), } } @@ -42,6 +43,7 @@ impl Primitive { r, }) } + Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(), } } @@ -50,6 +52,7 @@ impl Primitive { Weight::Dot(dot) => dot.circle.r * 2.0, Weight::Seg(seg) => seg.width, Weight::Bend(bend) => self.dot_neighbor_weights[0].circle.r * 2.0, + Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(), } } diff --git a/src/weight.rs b/src/weight.rs index 9ef720c..9f2573c 100644 --- a/src/weight.rs +++ b/src/weight.rs @@ -21,9 +21,19 @@ pub struct SegWeight { pub width: f64, } +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct EndRefWeight { +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct AroundRefWeight { +} + #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Weight { Dot(DotWeight), Seg(SegWeight), Bend(BendWeight), + EndRef(EndRefWeight), + AroundRef(AroundRefWeight), }