Add `untag!` macro, move `.shape()` to `Primitive`

This commit is contained in:
Mikolaj Wielgus 2023-07-21 23:31:26 +02:00
parent 8b5cfb3686
commit dea65a3b43
4 changed files with 75 additions and 74 deletions

View File

@ -9,7 +9,6 @@ use crate::shape::Shape;
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight}; use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight};
use crate::math; use crate::math;
pub struct Layout { pub struct Layout {
mesh: Mesh, mesh: Mesh,
rules: Rules, rules: Rules,
@ -54,10 +53,6 @@ impl Layout {
self.add_seg(head.dot, to, width); 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 { pub fn route_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head {
let from_circle = self.head_guidecircle(&head, width); let from_circle = self.head_guidecircle(&head, width);
@ -163,7 +158,7 @@ impl Layout {
let mut layer = bend; let mut layer = bend;
while let Some(inner) = self.mesh.primitive(layer).inner() { 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; layer = inner;
} }
@ -225,7 +220,7 @@ impl Layout {
self.mesh.add_seg(from, to, SegWeight {net, width}) self.mesh.add_seg(from, to, SegWeight {net, width})
} }
pub fn shapes(&self) -> Box<dyn Iterator<Item=Shape> + '_> { pub fn shapes(&self) -> impl Iterator<Item=Shape> + '_ {
self.mesh.shapes() self.mesh.nodes().map(|ni| untag!(ni, self.mesh.primitive(ni).shape()))
} }
} }

View File

@ -1,8 +1,8 @@
extern crate sdl2; extern crate sdl2;
#[macro_use] mod mesh;
mod layout; mod layout;
mod rules; mod rules;
mod mesh;
mod primitive; mod primitive;
mod shape; mod shape;
mod weight; mod weight;

View File

@ -30,6 +30,16 @@ pub trait Tag {
fn tag(&self) -> TaggedIndex; 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<DotWeight>; pub type DotIndex = Index<DotWeight>;
impl Tag for DotIndex { impl Tag for DotIndex {
@ -78,13 +88,12 @@ impl Mesh {
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex { pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight))); let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
let index = TaggedIndex::Dot(dot); self.rtree.insert(RTreeWrapper::new(self.primitive(dot).shape(), TaggedIndex::Dot(dot)));
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
dot dot
} }
pub fn remove_dot(&mut self, dot: DotIndex) { 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); 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, from.index, Label::End);
self.graph.add_edge(seg.index, to.index, Label::End); self.graph.add_edge(seg.index, to.index, Label::End);
let index = TaggedIndex::Seg(seg); self.rtree.insert(RTreeWrapper::new(self.primitive(seg).shape(), TaggedIndex::Seg(seg)));
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
seg seg
} }
pub fn remove_seg(&mut self, seg: SegIndex) { 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); 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, to.index, Label::End);
self.graph.add_edge(bend.index, core.index, Label::Core); self.graph.add_edge(bend.index, core.index, Label::Core);
let index = TaggedIndex::Bend(bend); self.rtree.insert(RTreeWrapper::new(self.primitive(bend).shape(), TaggedIndex::Bend(bend)));
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
bend bend
} }
@ -138,60 +144,15 @@ impl Mesh {
} }
pub fn remove_bend(&mut self, bend: BendIndex) { 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); self.graph.remove_node(bend.index);
} }
pub fn shapes(&self) -> Box<dyn Iterator<Item=Shape> + '_> { pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
Box::new(self.rtree.iter().map(|wrapper| self.shape(wrapper.data))) self.rtree.iter().map(|wrapper| 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 primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> { pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
Primitive::new(index, &self.graph) 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(),
}
}*/
} }

View File

@ -2,6 +2,7 @@ use petgraph::Direction::{Outgoing, Incoming};
use petgraph::stable_graph::StableDiGraph; use petgraph::stable_graph::StableDiGraph;
use crate::{mesh::{DotIndex, SegIndex, BendIndex, TaggedIndex, Mesh, Tag, Index}, weight::{DotWeight, SegWeight, BendWeight, TaggedWeight, Label}}; 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> { pub struct Primitive<'a, Weight> {
index: Index<Weight>, index: Index<Weight>,
@ -13,17 +14,13 @@ impl<'a, Weight> Primitive<'a, Weight> {
Primitive::<Weight> {index, graph} Primitive::<Weight> {index, graph}
} }
pub fn ends(&self) -> Vec<DotIndex> {
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 { pub fn tagged_weight(&self) -> TaggedWeight {
*self.graph.node_weight(self.index.index).unwrap() *self.graph.node_weight(self.index.index).unwrap()
} }
fn primitive<W>(&self, index: Index<W>) -> Primitive<W> {
Primitive::new(index, &self.graph)
}
} }
type Dot<'a> = Primitive<'a, DotWeight>; type Dot<'a> = Primitive<'a, DotWeight>;
@ -31,18 +28,66 @@ type Seg<'a> = Primitive<'a, SegWeight>;
type Bend<'a> = Primitive<'a, BendWeight>; type Bend<'a> = Primitive<'a, BendWeight>;
impl<'a> Dot<'a> { 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 { pub fn weight(&self) -> DotWeight {
*self.tagged_weight().as_dot().unwrap() *self.tagged_weight().as_dot().unwrap()
} }
} }
impl<'a> Seg<'a> { 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<DotIndex> {
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 { pub fn weight(&self) -> SegWeight {
*self.tagged_weight().as_seg().unwrap() *self.tagged_weight().as_seg().unwrap()
} }
} }
impl<'a> Bend<'a> { 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<DotIndex> {
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 { pub fn around(&self) -> TaggedIndex {
if let Some(inner) = self.inner() { if let Some(inner) = self.inner() {
TaggedIndex::Bend(inner) TaggedIndex::Bend(inner)