From dea65a3b434328fce31ad5b14b347883360dfdcf Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 21 Jul 2023 23:31:26 +0200 Subject: [PATCH] Add `untag!` macro, move `.shape()` to `Primitive` --- src/layout.rs | 11 ++----- src/main.rs | 2 +- src/mesh.rs | 75 ++++++++++++------------------------------------ src/primitive.rs | 61 +++++++++++++++++++++++++++++++++------ 4 files changed, 75 insertions(+), 74 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 1becf9c..9d780bf 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -9,7 +9,6 @@ use crate::shape::Shape; use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight}; use crate::math; - pub struct Layout { mesh: Mesh, rules: Rules, @@ -54,10 +53,6 @@ impl Layout { self.add_seg(head.dot, to, width); } - /*pub fn shove_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head { - - }*/ - pub fn route_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head { let from_circle = self.head_guidecircle(&head, width); @@ -163,7 +158,7 @@ impl Layout { let mut layer = bend; while let Some(inner) = self.mesh.primitive(layer).inner() { - r += 5.0 + self.mesh.shape(inner.tag()).width(); + r += 5.0 + self.mesh.primitive(inner).shape().width(); layer = inner; } @@ -225,7 +220,7 @@ impl Layout { self.mesh.add_seg(from, to, SegWeight {net, width}) } - pub fn shapes(&self) -> Box + '_> { - self.mesh.shapes() + pub fn shapes(&self) -> impl Iterator + '_ { + self.mesh.nodes().map(|ni| untag!(ni, self.mesh.primitive(ni).shape())) } } diff --git a/src/main.rs b/src/main.rs index a1b6991..124be40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ extern crate sdl2; +#[macro_use] mod mesh; mod layout; mod rules; -mod mesh; mod primitive; mod shape; mod weight; diff --git a/src/mesh.rs b/src/mesh.rs index c172d16..3d559b2 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -30,6 +30,16 @@ pub trait Tag { fn tag(&self) -> TaggedIndex; } +macro_rules! untag { + ($index:ident, $expr:expr) => { + match $index { + TaggedIndex::Dot($index) => $expr, + TaggedIndex::Seg($index) => $expr, + TaggedIndex::Bend($index) => $expr, + } + } +} + pub type DotIndex = Index; impl Tag for DotIndex { @@ -78,13 +88,12 @@ impl Mesh { pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex { let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight))); - let index = TaggedIndex::Dot(dot); - self.rtree.insert(RTreeWrapper::new(self.shape(index), index)); + self.rtree.insert(RTreeWrapper::new(self.primitive(dot).shape(), TaggedIndex::Dot(dot))); dot } pub fn remove_dot(&mut self, dot: DotIndex) { - self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Dot(dot)), TaggedIndex::Dot(dot))); + self.rtree.remove(&RTreeWrapper::new(self.primitive(dot).shape(), TaggedIndex::Dot(dot))); self.graph.remove_node(dot.index); } @@ -93,14 +102,12 @@ impl Mesh { self.graph.add_edge(seg.index, from.index, Label::End); self.graph.add_edge(seg.index, to.index, Label::End); - let index = TaggedIndex::Seg(seg); - self.rtree.insert(RTreeWrapper::new(self.shape(index), index)); + self.rtree.insert(RTreeWrapper::new(self.primitive(seg).shape(), TaggedIndex::Seg(seg))); seg - } pub fn remove_seg(&mut self, seg: SegIndex) { - self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Seg(seg)), TaggedIndex::Seg(seg))); + self.rtree.remove(&RTreeWrapper::new(self.primitive(seg).shape(), TaggedIndex::Seg(seg))); self.graph.remove_node(seg.index); } @@ -120,8 +127,7 @@ impl Mesh { self.graph.add_edge(bend.index, to.index, Label::End); self.graph.add_edge(bend.index, core.index, Label::Core); - let index = TaggedIndex::Bend(bend); - self.rtree.insert(RTreeWrapper::new(self.shape(index), index)); + self.rtree.insert(RTreeWrapper::new(self.primitive(bend).shape(), TaggedIndex::Bend(bend))); bend } @@ -138,60 +144,15 @@ impl Mesh { } pub fn remove_bend(&mut self, bend: BendIndex) { - self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend))); + self.rtree.remove(&RTreeWrapper::new(self.primitive(bend).shape(), TaggedIndex::Bend(bend))); self.graph.remove_node(bend.index); } - pub fn shapes(&self) -> Box + '_> { - Box::new(self.rtree.iter().map(|wrapper| self.shape(wrapper.data))) - } - - pub fn shape(&self, index: TaggedIndex) -> Shape { - Shape { - weight: match index { - TaggedIndex::Dot(index) => self.primitive(index).tagged_weight(), - TaggedIndex::Seg(index) => self.primitive(index).tagged_weight(), - TaggedIndex::Bend(index) => self.primitive(index).tagged_weight(), - }, - dot_neighbor_weights: match index { - TaggedIndex::Dot(index) => { - self.primitive(index).ends() - .into_iter() - .map(|index| self.primitive(index).weight()) - .collect() - }, - TaggedIndex::Seg(index) => { - self.primitive(index).ends() - .into_iter() - .map(|index| self.primitive(index).weight()) - .collect() - }, - TaggedIndex::Bend(index) => { - self.primitive(index).ends() - .into_iter() - .map(|index| self.primitive(index).weight()) - .collect() - }, - }, - core_pos: match index { - TaggedIndex::Bend(bend) => { - Some(self.primitive(self.primitive(bend).core()).weight().circle.pos) - }, - _ => None, - }, - } + pub fn nodes(&self) -> impl Iterator + '_ { + self.rtree.iter().map(|wrapper| wrapper.data) } pub fn primitive(&self, index: Index) -> Primitive { Primitive::new(index, &self.graph) } - - /*pub fn tagged_weight(&self, index: TaggedIndex) -> Weight { - match index { - TaggedIndex::Dot(DotIndex {index: node, ..}) - | TaggedIndex::Seg(SegIndex {index: node, ..}) - | TaggedIndex::Bend(BendIndex {index: node, ..}) => - *self.graph.node_weight(node).unwrap(), - } - }*/ } diff --git a/src/primitive.rs b/src/primitive.rs index a699179..1267585 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -2,6 +2,7 @@ use petgraph::Direction::{Outgoing, Incoming}; use petgraph::stable_graph::StableDiGraph; use crate::{mesh::{DotIndex, SegIndex, BendIndex, TaggedIndex, Mesh, Tag, Index}, weight::{DotWeight, SegWeight, BendWeight, TaggedWeight, Label}}; +use crate::shape::Shape; pub struct Primitive<'a, Weight> { index: Index, @@ -13,17 +14,13 @@ impl<'a, Weight> Primitive<'a, Weight> { Primitive:: {index, graph} } - pub fn ends(&self) -> Vec { - self.graph.neighbors(self.index.index) - .filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end()) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot()) - .map(|ni| DotIndex::new(ni)) - .collect() - } - pub fn tagged_weight(&self) -> TaggedWeight { *self.graph.node_weight(self.index.index).unwrap() } + + fn primitive(&self, index: Index) -> Primitive { + Primitive::new(index, &self.graph) + } } type Dot<'a> = Primitive<'a, DotWeight>; @@ -31,18 +28,66 @@ type Seg<'a> = Primitive<'a, SegWeight>; type Bend<'a> = Primitive<'a, BendWeight>; impl<'a> Dot<'a> { + pub fn shape(&self) -> Shape { + Shape { + weight: self.tagged_weight(), + dot_neighbor_weights: vec![], + core_pos: None, + } + } + pub fn weight(&self) -> DotWeight { *self.tagged_weight().as_dot().unwrap() } } impl<'a> Seg<'a> { + pub fn shape(&self) -> Shape { + Shape { + weight: self.tagged_weight(), + dot_neighbor_weights: + self.ends() + .into_iter() + .map(|index| self.primitive(index).weight()) + .collect(), + core_pos: None, + } + } + + pub fn ends(&self) -> Vec { + self.graph.neighbors(self.index.index) + .filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end()) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot()) + .map(|ni| DotIndex::new(ni)) + .collect() + } + pub fn weight(&self) -> SegWeight { *self.tagged_weight().as_seg().unwrap() } } impl<'a> Bend<'a> { + pub fn shape(&self) -> Shape { + Shape { + weight: self.tagged_weight(), + dot_neighbor_weights: + self.ends() + .into_iter() + .map(|index| self.primitive(index).weight()) + .collect(), + core_pos: Some(self.primitive(self.core()).weight().circle.pos), + } + } + + pub fn ends(&self) -> Vec { + self.graph.neighbors(self.index.index) + .filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end()) + .filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot()) + .map(|ni| DotIndex::new(ni)) + .collect() + } + pub fn around(&self) -> TaggedIndex { if let Some(inner) = self.inner() { TaggedIndex::Bend(inner)