diff --git a/src/layout.rs b/src/layout.rs index 3028a31..048c0be 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -22,12 +22,12 @@ use crate::graph::{GenericIndex, GetNodeIndex}; use crate::guide::Guide; use crate::math::NoTangents; use crate::primitive::{ - GenericPrimitive, GetConnectable, GetCore, GetEnds, GetFirstRail, GetInnerOuter, GetOtherEnd, - GetWeight, GetWraparound, MakeShape, + GenericPrimitive, GetConnectable, GetCore, GetEnds, GetInnerOuter, GetOtherEnd, GetWeight, + MakeShape, }; use crate::segbend::Segbend; use crate::shape::{Shape, ShapeTrait}; -use crate::wraparoundable::{Wraparoundable, WraparoundableIndex}; +use crate::wraparoundable::{GetWraparound, Wraparoundable, WraparoundableIndex}; pub type RTreeWrapper = GeomWithData; diff --git a/src/loose.rs b/src/loose.rs new file mode 100644 index 0000000..052b6eb --- /dev/null +++ b/src/loose.rs @@ -0,0 +1,98 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::NodeIndex; + +use crate::{ + geometry::{ + DotIndex, GeometryIndex, LoneLooseSegIndex, LooseBendIndex, LooseDotIndex, MakePrimitive, + SeqLooseSegIndex, + }, + graph::GetNodeIndex, + layout::Layout, + primitive::{GetEnds, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg}, +}; + +pub trait GetNextLoose { + fn next(&self, prev: GeometryIndex) -> Option; +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum LooseIndex { + Dot(LooseDotIndex), + LoneSeg(LoneLooseSegIndex), + SeqSeg(SeqLooseSegIndex), + Bend(LooseBendIndex), +} + +impl From for GeometryIndex { + fn from(loose: LooseIndex) -> Self { + match loose { + LooseIndex::Dot(dot) => GeometryIndex::LooseDot(dot), + LooseIndex::LoneSeg(seg) => GeometryIndex::LoneLooseSeg(seg), + LooseIndex::SeqSeg(seg) => GeometryIndex::SeqLooseSeg(seg), + LooseIndex::Bend(bend) => GeometryIndex::LooseBend(bend), + } + } +} + +#[enum_dispatch(GetNextLoose, GetLayout, GetNodeIndex)] +pub enum Loose<'a> { + Dot(LooseDot<'a>), + LoneSeg(LoneLooseSeg<'a>), + SeqSeg(SeqLooseSeg<'a>), + Bend(LooseBend<'a>), +} + +impl<'a> Loose<'a> { + pub fn new(index: LooseIndex, layout: &'a Layout) -> Self { + match index { + LooseIndex::Dot(dot) => layout.primitive(dot).into(), + LooseIndex::LoneSeg(seg) => layout.primitive(seg).into(), + LooseIndex::SeqSeg(seg) => layout.primitive(seg).into(), + LooseIndex::Bend(bend) => layout.primitive(bend).into(), + } + } +} + +impl<'a> GetNextLoose for LooseDot<'a> { + fn next(&self, prev: GeometryIndex) -> Option { + let bend = self.bend(); + + if bend.node_index() != prev.node_index() { + self.seg().map(Into::into) + } else { + Some(bend.into()) + } + } +} + +impl<'a> GetNextLoose for LoneLooseSeg<'a> { + fn next(&self, _prev: GeometryIndex) -> Option { + None + } +} + +impl<'a> GetNextLoose for SeqLooseSeg<'a> { + fn next(&self, prev: GeometryIndex) -> Option { + let ends = self.ends(); + if ends.0.node_index() != prev.node_index() { + match ends.0 { + DotIndex::Fixed(..) => None, + DotIndex::Loose(dot) => Some(dot.into()), + } + } else { + Some(ends.1.into()) + } + } +} + +impl<'a> GetNextLoose for LooseBend<'a> { + fn next(&self, prev: GeometryIndex) -> Option { + let ends = self.ends(); + if ends.0.node_index() != prev.node_index() { + Some(ends.0.into()) + } else { + Some(ends.1.into()) + } + } +} diff --git a/src/main.rs b/src/main.rs index 42055e5..6c870dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ mod geometry; mod graph; mod guide; mod layout; +mod loose; mod math; mod mesh; mod primitive; diff --git a/src/primitive.rs b/src/primitive.rs index 01f8d03..8a4a250 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -13,6 +13,7 @@ use crate::geometry::{ }; use crate::graph::{GenericIndex, GetNodeIndex}; use crate::layout::Layout; +use crate::loose::Loose; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; @@ -60,11 +61,6 @@ pub trait GetEnds { fn ends(&self) -> (F, T); } -#[enum_dispatch] -pub trait GetWraparound: GetLayout + GetNodeIndex { - fn wraparound(&self) -> Option; -} - pub trait GetFirstRail: GetLayout + GetNodeIndex { fn first_rail(&self) -> Option { self.layout() @@ -303,11 +299,6 @@ impl<'a> MakeShape for FixedDot<'a> { } } impl<'a> GetFirstRail for FixedDot<'a> {} -impl<'a> GetWraparound for FixedDot<'a> { - fn wraparound(&self) -> Option { - self.first_rail() - } -} pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; impl_loose_primitive!(LooseDot, LooseDotWeight); @@ -520,11 +511,6 @@ impl<'a> GetEnds for FixedBend<'a> { impl<'a> GetOtherEnd for FixedBend<'a> {} impl<'a> GetFirstRail for FixedBend<'a> {} -impl<'a> GetWraparound for FixedBend<'a> { - fn wraparound(&self) -> Option { - self.first_rail() - } -} impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actually. //impl<'a> GetInnerOuter for FixedBend<'a> {} @@ -595,11 +581,5 @@ impl<'a> GetEnds for LooseBend<'a> { } impl<'a> GetOtherEnd for LooseBend<'a> {} -impl<'a> GetWraparound for LooseBend<'a> { - fn wraparound(&self) -> Option { - self.outer() - } -} - impl<'a> GetCore for LooseBend<'a> {} impl<'a> GetInnerOuter for LooseBend<'a> {} diff --git a/src/wraparoundable.rs b/src/wraparoundable.rs index e9103fe..35a42e7 100644 --- a/src/wraparoundable.rs +++ b/src/wraparoundable.rs @@ -7,9 +7,16 @@ use crate::{ }, graph::GetNodeIndex, layout::Layout, - primitive::{FixedBend, FixedDot, GetLayout, GetWraparound, LooseBend, Primitive}, + primitive::{ + FixedBend, FixedDot, GetFirstRail, GetInnerOuter, GetLayout, LooseBend, Primitive, + }, }; +#[enum_dispatch] +pub trait GetWraparound: GetLayout + GetNodeIndex { + fn wraparound(&self) -> Option; +} + #[enum_dispatch(GetNodeIndex, MakePrimitive)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum WraparoundableIndex { @@ -53,3 +60,21 @@ impl<'a> Wraparoundable<'a> { } } } + +impl<'a> GetWraparound for FixedDot<'a> { + fn wraparound(&self) -> Option { + self.first_rail() + } +} + +impl<'a> GetWraparound for LooseBend<'a> { + fn wraparound(&self) -> Option { + self.outer() + } +} + +impl<'a> GetWraparound for FixedBend<'a> { + fn wraparound(&self) -> Option { + self.first_rail() + } +}