diff --git a/src/draw.rs b/src/draw.rs index 00429f3..a411442 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -5,13 +5,14 @@ use thiserror::Error; use crate::{ geometry::{ BendIndex, DotIndex, FixedDotIndex, GetBandIndex, LoneLooseSegWeight, LooseBendWeight, - LooseDotIndex, LooseDotWeight, MakePrimitive, SeqLooseSegWeight, WraparoundableIndex, + LooseDotIndex, LooseDotWeight, MakePrimitive, SeqLooseSegWeight, }, guide::{Guide, Head, HeadTrait, SegbendHead}, layout::{Infringement, Layout, LayoutException}, math::{Circle, NoTangents}, primitive::GetOtherEnd, rules::{Conditions, Rules}, + wraparoundable::WraparoundableIndex, }; #[derive(Error, Debug, Clone, Copy)] diff --git a/src/geometry.rs b/src/geometry.rs index 2e834a8..2aadd58 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -160,32 +160,6 @@ impl From for GeometryIndex { } } -impl From for WraparoundableIndex { - fn from(bend: BendIndex) -> Self { - match bend { - BendIndex::Fixed(bend) => WraparoundableIndex::FixedBend(bend), - BendIndex::Loose(bend) => WraparoundableIndex::LooseBend(bend), - } - } -} - -#[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum WraparoundableIndex { - FixedDot(FixedDotIndex), - FixedBend(FixedBendIndex), - LooseBend(LooseBendIndex), -} - -impl From for GeometryIndex { - fn from(wraparoundable: WraparoundableIndex) -> Self { - match wraparoundable { - WraparoundableIndex::FixedDot(dot) => GeometryIndex::FixedDot(dot), - WraparoundableIndex::FixedBend(bend) => GeometryIndex::FixedBend(bend), - WraparoundableIndex::LooseBend(bend) => GeometryIndex::LooseBend(bend), - } - } -} pub trait DotWeight: GetWidth + Into + Copy {} #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/src/graph.rs b/src/graph.rs index a68dbe2..e564872 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -8,7 +8,7 @@ use petgraph::stable_graph::NodeIndex; // Due to apparent limitations of enum_dispatch we're forced to import some types backwards. -use crate::geometry::{BendIndex, DotIndex, GeometryIndex, SegIndex, WraparoundableIndex}; +use crate::geometry::{BendIndex, DotIndex, GeometryIndex, SegIndex}; #[enum_dispatch] pub trait GetNodeIndex { diff --git a/src/layout.rs b/src/layout.rs index f2c66df..3028a31 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -16,7 +16,7 @@ use crate::geometry::{ BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, GeometryGraph, GeometryIndex, GeometryLabel, GeometryWeight, LoneLooseSegIndex, LoneLooseSegWeight, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, - MakePrimitive, Retag, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, WraparoundableIndex, + MakePrimitive, Retag, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }; use crate::graph::{GenericIndex, GetNodeIndex}; use crate::guide::Guide; @@ -27,6 +27,7 @@ use crate::primitive::{ }; use crate::segbend::Segbend; use crate::shape::{Shape, ShapeTrait}; +use crate::wraparoundable::{Wraparoundable, WraparoundableIndex}; pub type RTreeWrapper = GeomWithData; @@ -186,12 +187,7 @@ impl Layout { seg_weight: SeqLooseSegWeight, bend_weight: LooseBendWeight, ) -> Result { - let maybe_wraparound = match around { - WraparoundableIndex::FixedDot(around) => self.primitive(around).wraparound(), - WraparoundableIndex::FixedBend(around) => self.primitive(around).wraparound(), - WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(), - }; - + let maybe_wraparound = self.wraparoundable(around).wraparound(); let mut infringables = self.this_and_wraparound_bow(around); if let Some(wraparound) = maybe_wraparound { @@ -271,29 +267,15 @@ impl Layout { #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec { - match around { - WraparoundableIndex::FixedDot(dot) => { - let mut v = vec![around.into()]; - if let Some(first_rail) = self.primitive(dot).first_rail() { - v.append(&mut self.bow(first_rail)); - } - v - } - WraparoundableIndex::FixedBend(bend) => { - let mut v = vec![around.into()]; - if let Some(first_rail) = self.primitive(bend).first_rail() { - v.append(&mut self.bow(first_rail)); - } - v - } - WraparoundableIndex::LooseBend(bend) => { - let mut v = self.bow(bend); - if let Some(outer) = self.primitive(bend).outer() { - v.append(&mut self.bow(outer)); - } - v - } + let mut v = match around { + WraparoundableIndex::FixedDot(..) => vec![around.into()], + WraparoundableIndex::FixedBend(..) => vec![around.into()], + WraparoundableIndex::LooseBend(bend) => self.bow(bend), + }; + if let Some(wraparound) = self.wraparoundable(around).wraparound() { + v.append(&mut self.bow(wraparound)); } + v } // XXX: Move this to primitives? @@ -340,29 +322,6 @@ impl Layout { } outer_bows - - /*let mut outer_bows = vec![]; - - // XXX: Ugly all-same match. - let mut maybe_rail = match around { - WraparoundableIndex::FixedDot(around) => self.primitive(around).wraparound(), - WraparoundableIndex::FixedBend(around) => self.primitive(around).wraparound(), - WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(), - }; - - while let Some(rail) = maybe_rail { - let primitive = self.primitive(rail); - outer_bows.push(rail.into()); - - let ends = primitive.ends(); - outer_bows.push(ends.0.into()); - outer_bows.push(ends.1.into()); - - outer_bows.push(self.primitive(ends.0).seg().unwrap().into()); - maybe_rail = primitive.outer(); - } - - outer_bows*/ } #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] @@ -598,11 +557,7 @@ impl Layout { return Err(AlreadyConnected(net, around.into()).into()); } // - if let Some(wraparound) = match around { - WraparoundableIndex::FixedDot(around) => self.primitive(around).wraparound(), - WraparoundableIndex::FixedBend(around) => self.primitive(around).wraparound(), - WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(), - } { + if let Some(wraparound) = self.wraparoundable(around).wraparound() { if net == wraparound.primitive(self).net() { return Err(AlreadyConnected(net, wraparound.into()).into()); } @@ -884,6 +839,12 @@ impl Layout { GenericPrimitive::new(node, self) } + #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] + #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] + pub fn wraparoundable(&self, node: WraparoundableIndex) -> Wraparoundable { + Wraparoundable::new(node, self) + } + fn test_envelopes(&self) -> bool { !self.rtree.iter().any(|wrapper| { let node = wrapper.data; diff --git a/src/main.rs b/src/main.rs index 97726bd..42055e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ mod segbend; mod shape; mod tracer; mod triangulation; +mod wraparoundable; use draw::DrawException; use geo::point; diff --git a/src/primitive.rs b/src/primitive.rs index 7378dc6..01f8d03 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -60,6 +60,7 @@ pub trait GetEnds { fn ends(&self) -> (F, T); } +#[enum_dispatch] pub trait GetWraparound: GetLayout + GetNodeIndex { fn wraparound(&self) -> Option; } diff --git a/src/wraparoundable.rs b/src/wraparoundable.rs new file mode 100644 index 0000000..e9103fe --- /dev/null +++ b/src/wraparoundable.rs @@ -0,0 +1,55 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::NodeIndex; + +use crate::{ + geometry::{ + BendIndex, FixedBendIndex, FixedDotIndex, GeometryIndex, LooseBendIndex, MakePrimitive, + }, + graph::GetNodeIndex, + layout::Layout, + primitive::{FixedBend, FixedDot, GetLayout, GetWraparound, LooseBend, Primitive}, +}; + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum WraparoundableIndex { + FixedDot(FixedDotIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + +impl From for GeometryIndex { + fn from(wraparoundable: WraparoundableIndex) -> Self { + match wraparoundable { + WraparoundableIndex::FixedDot(dot) => GeometryIndex::FixedDot(dot), + WraparoundableIndex::FixedBend(bend) => GeometryIndex::FixedBend(bend), + WraparoundableIndex::LooseBend(bend) => GeometryIndex::LooseBend(bend), + } + } +} + +impl From for WraparoundableIndex { + fn from(bend: BendIndex) -> Self { + match bend { + BendIndex::Fixed(bend) => WraparoundableIndex::FixedBend(bend), + BendIndex::Loose(bend) => WraparoundableIndex::LooseBend(bend), + } + } +} + +#[enum_dispatch(GetWraparound, GetLayout, GetNodeIndex)] +pub enum Wraparoundable<'a> { + FixedDot(FixedDot<'a>), + FixedBend(FixedBend<'a>), + LooseBend(LooseBend<'a>), +} + +impl<'a> Wraparoundable<'a> { + pub fn new(index: WraparoundableIndex, layout: &'a Layout) -> Self { + match index { + WraparoundableIndex::FixedDot(dot) => layout.primitive(dot).into(), + WraparoundableIndex::FixedBend(bend) => layout.primitive(bend).into(), + WraparoundableIndex::LooseBend(bend) => layout.primitive(bend).into(), + } + } +}