From e1f3d3ede4eacf02d5304c88614df70f36a6b764 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 13 Feb 2024 00:46:12 +0000 Subject: [PATCH] layout: move neighborhood-collecting code to a new collect module --- src/layout/collect.rs | 128 ++++++++++++++++++++++++++++++++++ src/layout/layout.rs | 157 ++++++++---------------------------------- src/layout/mod.rs | 1 + 3 files changed, 157 insertions(+), 129 deletions(-) create mode 100644 src/layout/collect.rs diff --git a/src/layout/collect.rs b/src/layout/collect.rs new file mode 100644 index 0000000..01206e7 --- /dev/null +++ b/src/layout/collect.rs @@ -0,0 +1,128 @@ +use crate::wraparoundable::{GetWraparound, WraparoundableIndex}; + +use super::{ + bend::LooseBendIndex, + dot::DotIndex, + graph::GeometryIndex, + primitive::{GetCore, GetInnerOuter, GetJoints}, + rules::RulesTrait, + Layout, +}; + +#[derive(Debug)] +pub struct Collect<'a, R: RulesTrait> { + layout: &'a Layout, +} + +impl<'a, R: RulesTrait> Collect<'a, R> { + pub fn new(layout: &'a Layout) -> Self { + Self { layout } + } + + pub fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec { + let bend_primitive = self.layout.primitive(bend); + let mut v = vec![]; + + if let Some(inner) = bend_primitive.inner() { + v.append(&mut self.bow(inner.into())); + } else { + let core = bend_primitive.core(); + v.push(core.into()); + } + + if let Some(outer) = bend_primitive.outer() { + v.append(&mut self.bow(outer.into())); + } + + v + } + + pub fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec { + let bend_primitive = self.layout.primitive(bend); + let mut v = vec![]; + + if let Some(inner) = bend_primitive.inner() { + v.append(&mut self.bow(inner.into())); + } else { + let core = bend_primitive.core(); + v.push(core.into()); + } + + let mut rail = bend; + + while let Some(outer) = self.layout.primitive(rail).outer() { + v.append(&mut self.bow(outer.into())); + rail = outer; + } + + v + } + + pub fn segbend_inner_and_outer_bibows( + &self, + from: DotIndex, + around: WraparoundableIndex, + ) -> Vec { + let mut v = match from { + DotIndex::Fixed(..) => vec![], + DotIndex::Loose(dot) => { + self.inner_bow_and_outer_bow(self.layout.primitive(dot).bend().into()) + } + }; + v.append(&mut self.this_and_wraparound_bow(around)); + v + } + + pub fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec { + 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.layout.wraparoundable(around).wraparound() { + v.append(&mut self.bow(wraparound)); + } + v + } + + pub fn bow(&self, bend: LooseBendIndex) -> Vec { + let mut v: Vec = vec![]; + v.push(bend.into()); + + let ends = self.layout.primitive(bend).joints(); + v.push(ends.0.into()); + v.push(ends.1.into()); + + if let Some(seg0) = self.layout.primitive(ends.0).seg() { + v.push(seg0.into()); + } + + if let Some(seg1) = self.layout.primitive(ends.1).seg() { + v.push(seg1.into()); + } + + v + } + + pub fn outer_bows(&self, bend: LooseBendIndex) -> Vec { + let mut v = vec![]; + let mut rail = bend; + + while let Some(outer) = self.layout.primitive(rail).outer() { + let primitive = self.layout.primitive(outer); + + v.push(outer.into()); + + let ends = primitive.joints(); + v.push(ends.0.into()); + v.push(ends.1.into()); + + v.push(self.layout.primitive(ends.0).seg().unwrap().into()); + v.push(self.layout.primitive(ends.1).seg().unwrap().into()); + + rail = outer; + } + + v + } +} diff --git a/src/layout/layout.rs b/src/layout/layout.rs index ec69466..c8a383b 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -18,6 +18,7 @@ use super::rules::RulesTrait; use super::segbend::Segbend; use crate::graph::{GenericIndex, GetNodeIndex}; use crate::layout::bend::BendIndex; +use crate::layout::collect::Collect; use crate::layout::dot::DotWeight; use crate::layout::geometry::{ BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetOffset, GetPos, GetWidth, @@ -259,10 +260,10 @@ impl Layout { cw: bool, ) -> Result { let maybe_wraparound = self.wraparoundable(around).wraparound(); - let mut infringables = self.segbend_inner_and_outer_bibows(from, around); + let mut infringables = self.collect().segbend_inner_and_outer_bibows(from, around); if let Some(wraparound) = maybe_wraparound { - infringables.append(&mut self.outer_bows(wraparound)); + infringables.append(&mut self.collect().outer_bows(wraparound)); } let segbend = self.add_segbend_infringably( @@ -293,124 +294,6 @@ impl Layout { Ok::(segbend) } - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec { - let bend_primitive = self.primitive(bend); - let mut v = vec![]; - - if let Some(inner) = bend_primitive.inner() { - v.append(&mut self.bow(inner.into())); - } else { - let core = bend_primitive.core(); - v.push(core.into()); - } - - if let Some(outer) = bend_primitive.outer() { - v.append(&mut self.bow(outer.into())); - } - - v - } - - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec { - let bend_primitive = self.primitive(bend); - let mut v = vec![]; - - if let Some(inner) = bend_primitive.inner() { - v.append(&mut self.bow(inner.into())); - } else { - let core = bend_primitive.core(); - v.push(core.into()); - } - - let mut rail = bend; - - while let Some(outer) = self.primitive(rail).outer() { - v.append(&mut self.bow(outer.into())); - rail = outer; - } - - v - } - - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn segbend_inner_and_outer_bibows( - &self, - from: DotIndex, - around: WraparoundableIndex, - ) -> Vec { - let mut v = match from { - DotIndex::Fixed(..) => vec![], - DotIndex::Loose(dot) => self.inner_bow_and_outer_bow(self.primitive(dot).bend().into()), - }; - v.append(&mut self.this_and_wraparound_bow(around)); - v - } - - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec { - 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? - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn bow(&self, bend: LooseBendIndex) -> Vec { - let mut bow: Vec = vec![]; - bow.push(bend.into()); - - let ends = self.primitive(bend).joints(); - bow.push(ends.0.into()); - bow.push(ends.1.into()); - - if let Some(seg0) = self.primitive(ends.0).seg() { - bow.push(seg0.into()); - } - - if let Some(seg1) = self.primitive(ends.1).seg() { - bow.push(seg1.into()); - } - - bow - } - - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] - fn outer_bows(&self, bend: LooseBendIndex) -> Vec { - let mut outer_bows = vec![]; - let mut rail = bend; - - while let Some(outer) = self.primitive(rail).outer() { - let primitive = self.primitive(outer); - - outer_bows.push(outer.into()); - - let ends = primitive.joints(); - outer_bows.push(ends.0.into()); - outer_bows.push(ends.1.into()); - - outer_bows.push(self.primitive(ends.0).seg().unwrap().into()); - outer_bows.push(self.primitive(ends.1).seg().unwrap().into()); - - rail = outer; - } - - outer_bows - } - #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()) || self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() - 1) @@ -462,18 +345,18 @@ impl Layout { self.move_dot_infringably( joints.0.into(), from, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; self.move_dot_infringably( joints.1.into(), to, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; self.shift_bend_infringably( rail.into(), offset, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; // Update offsets in case the rule conditions changed. @@ -504,18 +387,18 @@ impl Layout { self.move_dot_infringably( joints.0.into(), from, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; self.move_dot_infringably( joints.1.into(), to, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; self.shift_bend_infringably( rail.into(), offset, - &self.inner_bow_and_outer_bows(rail), + &self.collect().inner_bow_and_outer_bows(rail), )?; } @@ -545,7 +428,7 @@ impl Layout { seg_weight, bend_weight, cw, - &self.segbend_inner_and_outer_bibows(from, around), + &self.collect().segbend_inner_and_outer_bibows(from, around), ) } @@ -637,7 +520,9 @@ impl Layout { from, to.into(), weight, - &self.inner_bow_and_outer_bow(self.primitive(to).bend().into()), + &self + .collect() + .inner_bow_and_outer_bow(self.primitive(to).bend().into()), )?; if let DotIndex::Fixed(dot) = from { @@ -857,7 +742,9 @@ impl Layout { DotIndex::Loose(loose) => self.move_dot_infringably( dot, to, - &self.inner_bow_and_outer_bow(self.primitive(loose).bend()), + &self + .collect() + .inner_bow_and_outer_bow(self.primitive(loose).bend()), ), } } @@ -1003,6 +890,18 @@ impl Layout { &self.rules } + #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] + #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] + pub fn guide(&self) -> Guide { + Guide::new(self) + } + + #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] + #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] + pub fn collect(&self) -> Collect { + Collect::new(self) + } + #[debug_ensures(self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))] pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index f8d1766..a7ece63 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -2,6 +2,7 @@ pub mod graph; pub mod band; pub mod bend; +pub mod collect; pub mod connectivity; pub mod dot; pub mod geometry;