diff --git a/src/band.rs b/src/band.rs deleted file mode 100644 index 0239e62..0000000 --- a/src/band.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::graph::{FixedDotIndex, GetEnds, Index, Interior}; - -pub struct Band { - from: FixedDotIndex, - to: FixedDotIndex, - interior: Vec, -} - -/*impl Band { - pub fn from_dot_prev( - dot: FixedDotIndex, - graph: &StableDiGraph, - ) -> Option { - let mut next_index: Index = dot.into(); - let mut interior = vec![]; - - while let Some(index) = next_index.primitive(graph).tagged_prev() { - interior.push(index); - next_index = index; - } - - if interior.is_empty() { - None - } else { - Some(Self { - from: interior.pop().unwrap().into_fixed_dot().unwrap(), - to: dot, - interior, - }) - } - } - - pub fn from_dot_next( - dot: FixedDotIndex, - graph: &StableDiGraph, - ) -> Option { - let mut prev_index: Index = dot.into(); - let mut interior = vec![]; - - while let Some(index) = prev_index.primitive(graph).tagged_next() { - interior.push(index); - prev_index = index; - } - - if interior.is_empty() { - None - } else { - Some(Self { - from: dot, - to: interior.pop().unwrap().into_fixed_dot().unwrap(), - interior, - }) - } - } -}*/ - -impl Interior for Band { - fn interior(&self) -> Vec { - // FIXME: Unnecessary clone. There should be a better way to do it. - self.interior.clone() - } -} - -impl GetEnds for Band { - fn ends(&self) -> (FixedDotIndex, FixedDotIndex) { - (self.from, self.to) - } -} diff --git a/src/bow.rs b/src/bow.rs deleted file mode 100644 index 4a535ec..0000000 --- a/src/bow.rs +++ /dev/null @@ -1,54 +0,0 @@ -use crate::graph::{GetEnds, Index, Interior, LooseBendIndex, LooseDotIndex, LooseSegIndex}; - -#[derive(Debug, Clone, Copy)] -pub struct Bow { - 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: LooseBendIndex, graph: &StableDiGraph) -> Self { - let bend = index; - - 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 = 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, - seg1, - seg1_dot2, - bend, - seg2_dot1, - seg2, - seg2_dot2, - } - } -}*/ - -impl Interior for Bow { - fn interior(&self) -> Vec { - vec![ - self.seg1.into(), - self.seg1_dot2.into(), - self.bend.into(), - self.seg2_dot1.into(), - self.seg2.into(), - ] - } -} - -impl GetEnds for Bow { - fn ends(&self) -> (LooseDotIndex, LooseDotIndex) { - (self.seg1_dot1, self.seg2_dot2) - } -} diff --git a/src/main.rs b/src/main.rs index 9710677..bec9084 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,8 +11,6 @@ macro_rules! dbg_dot { #[macro_use] mod graph; mod astar; -mod band; -mod bow; mod draw; mod guide; mod layout; @@ -24,6 +22,7 @@ mod rules; mod segbend; mod shape; mod tracer; +mod traverser; use geo::point; use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex}; diff --git a/src/mesh.rs b/src/mesh.rs index ba89fd0..4102270 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -4,9 +4,8 @@ use geo::{point, Point}; use petgraph::stable_graph::NodeIndex; use petgraph::visit::{self, NodeIndexable}; use spade::{ - handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle}, - iterators::DirectedEdgeIterator, - DelaunayTriangulation, HasPosition, InsertionError, Point2, Triangulation, + handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, InsertionError, Point2, + Triangulation, }; use crate::{ diff --git a/src/primitive.rs b/src/primitive.rs index f533c01..ef18f77 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -12,6 +12,7 @@ use crate::graph::{ }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; +use crate::traverser::OutwardLayerTraverser; #[enum_dispatch] pub trait GetGraph { @@ -49,6 +50,42 @@ pub trait GetOtherEnd>: GetEnds } } +pub trait TraverseOutward: GetFirstLayer { + fn traverse_outward(&self) -> OutwardLayerTraverser { + OutwardLayerTraverser::new(self.first_layer(), self.graph()) + } +} + +pub trait GetFirstLayer: GetGraph + GetNodeIndex { + fn first_layer(&self) -> Option { + self.graph() + .neighbors_directed(self.node_index(), Incoming) + .filter(|ni| { + self.graph() + .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) + .unwrap() + .is_core() + }) + .map(|ni| LooseBendIndex::new(ni)) + .next() + } +} + +pub trait GetOuter: GetGraph + GetNodeIndex { + fn outer(&self) -> Option { + self.graph() + .neighbors_directed(self.node_index(), Outgoing) + .filter(|ni| { + self.graph() + .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) + .unwrap() + .is_outer() + }) + .map(|ni| LooseBendIndex::new(ni)) + .next() + } +} + #[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)] pub enum Primitive<'a> { FixedDot(FixedDot<'a>), @@ -70,12 +107,6 @@ impl<'a, W> GenericPrimitive<'a, W> { Self { index, graph } } - pub fn neighbors(&self) -> impl Iterator + '_ { - self.graph - .neighbors_undirected(self.index.node_index()) - .map(|index| self.graph.node_weight(index).unwrap().retag(index)) - } - pub fn core(&self) -> Option { self.graph .neighbors(self.index.node_index()) @@ -127,6 +158,12 @@ impl<'a, W> GetGraph for GenericPrimitive<'a, W> { } } +impl<'a, W> GetNodeIndex for GenericPrimitive<'a, W> { + fn node_index(&self) -> NodeIndex { + self.index.node_index() + } +} + impl<'a, W: GetNet> GetConnectable for GenericPrimitive<'a, W> where GenericPrimitive<'a, W>: GetWeight { @@ -152,22 +189,6 @@ where pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; -impl<'a> FixedDot<'a> { - pub fn outer(&self) -> Option { - self.graph - .neighbors_directed(self.index.node_index(), Incoming) - .filter(|ni| { - self.graph - .edge_weight(self.graph.find_edge(*ni, self.index.node_index()).unwrap()) - .unwrap() - .is_core() - }) - .map(|ni| FixedBendIndex::new(ni)) - .filter(|bend| self.primitive(*bend).inner().is_none()) - .next() - } -} - impl<'a> GetWeight for FixedDot<'a> { fn weight(&self) -> FixedDotWeight { self.tagged_weight().into_fixed_dot().unwrap() @@ -182,6 +203,10 @@ impl<'a> MakeShape for FixedDot<'a> { } } +impl<'a> TraverseOutward for FixedDot<'a> {} + +impl<'a> GetFirstLayer for FixedDot<'a> {} + pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; impl<'a> LooseDot<'a> { @@ -334,19 +359,6 @@ impl<'a> FixedBend<'a> { .next() } - pub fn outer(&self) -> Option { - self.graph - .neighbors_directed(self.index.node_index(), Outgoing) - .filter(|ni| { - self.graph - .edge_weight(self.graph.find_edge(self.index.node_index(), *ni).unwrap()) - .unwrap() - .is_outer() - }) - .map(|ni| FixedBendIndex::new(ni)) - .next() - } - fn inner_radius(&self) -> f64 { let mut r = 0.0; let mut layer = FixedBendIndex::new(self.index.node_index()); @@ -413,6 +425,12 @@ impl<'a> GetEnds for FixedBend<'a> { impl<'a> GetOtherEnd for FixedBend<'a> {} +impl<'a> TraverseOutward for FixedBend<'a> {} + +impl<'a> GetFirstLayer for FixedBend<'a> {} + +impl<'a> GetOuter for FixedBend<'a> {} + pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; impl<'a> LooseBend<'a> { @@ -492,3 +510,5 @@ impl<'a> GetEnds for LooseBend<'a> { } impl<'a> GetOtherEnd for LooseBend<'a> {} + +impl<'a> GetOuter for LooseBend<'a> {} diff --git a/src/traverser.rs b/src/traverser.rs new file mode 100644 index 0000000..ea91d52 --- /dev/null +++ b/src/traverser.rs @@ -0,0 +1,31 @@ +use petgraph::stable_graph::StableDiGraph; + +use crate::{ + graph::{Label, LooseBendIndex, Weight}, + primitive::{GenericPrimitive, GetOuter}, +}; + +pub struct OutwardLayerTraverser<'a> { + layer: Option, + graph: &'a StableDiGraph, +} + +impl<'a> OutwardLayerTraverser<'a> { + pub fn new( + layer: Option, + graph: &'a StableDiGraph, + ) -> Self { + Self { layer, graph } + } +} + +impl<'a> Iterator for OutwardLayerTraverser<'a> { + type Item = LooseBendIndex; + + fn next(&mut self) -> Option { + self.layer.map(|layer| { + self.layer = GenericPrimitive::new(layer, self.graph).outer(); + layer + }) + } +}