layout: move neighborhood-collecting code to a new collect module

This commit is contained in:
Mikolaj Wielgus 2024-02-13 00:46:12 +00:00
parent 12af34d492
commit e1f3d3ede4
3 changed files with 157 additions and 129 deletions

128
src/layout/collect.rs Normal file
View File

@ -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<R>,
}
impl<'a, R: RulesTrait> Collect<'a, R> {
pub fn new(layout: &'a Layout<R>) -> Self {
Self { layout }
}
pub fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
let mut v: Vec<GeometryIndex> = 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<GeometryIndex> {
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
}
}

View File

@ -18,6 +18,7 @@ use super::rules::RulesTrait;
use super::segbend::Segbend; use super::segbend::Segbend;
use crate::graph::{GenericIndex, GetNodeIndex}; use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::bend::BendIndex; use crate::layout::bend::BendIndex;
use crate::layout::collect::Collect;
use crate::layout::dot::DotWeight; use crate::layout::dot::DotWeight;
use crate::layout::geometry::{ use crate::layout::geometry::{
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetOffset, GetPos, GetWidth, BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetOffset, GetPos, GetWidth,
@ -259,10 +260,10 @@ impl<R: RulesTrait> Layout<R> {
cw: bool, cw: bool,
) -> Result<Segbend, LayoutException> { ) -> Result<Segbend, LayoutException> {
let maybe_wraparound = self.wraparoundable(around).wraparound(); 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 { 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( let segbend = self.add_segbend_infringably(
@ -293,124 +294,6 @@ impl<R: RulesTrait> Layout<R> {
Ok::<Segbend, LayoutException>(segbend) Ok::<Segbend, LayoutException>(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<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
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<GeometryIndex> {
let mut bow: Vec<GeometryIndex> = 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<GeometryIndex> {
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().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()) #[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) || self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count() - 1)
@ -462,18 +345,18 @@ impl<R: RulesTrait> Layout<R> {
self.move_dot_infringably( self.move_dot_infringably(
joints.0.into(), joints.0.into(),
from, from,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
self.move_dot_infringably( self.move_dot_infringably(
joints.1.into(), joints.1.into(),
to, to,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
self.shift_bend_infringably( self.shift_bend_infringably(
rail.into(), rail.into(),
offset, offset,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
// Update offsets in case the rule conditions changed. // Update offsets in case the rule conditions changed.
@ -504,18 +387,18 @@ impl<R: RulesTrait> Layout<R> {
self.move_dot_infringably( self.move_dot_infringably(
joints.0.into(), joints.0.into(),
from, from,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
self.move_dot_infringably( self.move_dot_infringably(
joints.1.into(), joints.1.into(),
to, to,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
self.shift_bend_infringably( self.shift_bend_infringably(
rail.into(), rail.into(),
offset, offset,
&self.inner_bow_and_outer_bows(rail), &self.collect().inner_bow_and_outer_bows(rail),
)?; )?;
} }
@ -545,7 +428,7 @@ impl<R: RulesTrait> Layout<R> {
seg_weight, seg_weight,
bend_weight, bend_weight,
cw, cw,
&self.segbend_inner_and_outer_bibows(from, around), &self.collect().segbend_inner_and_outer_bibows(from, around),
) )
} }
@ -637,7 +520,9 @@ impl<R: RulesTrait> Layout<R> {
from, from,
to.into(), to.into(),
weight, 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 { if let DotIndex::Fixed(dot) = from {
@ -857,7 +742,9 @@ impl<R: RulesTrait> Layout<R> {
DotIndex::Loose(loose) => self.move_dot_infringably( DotIndex::Loose(loose) => self.move_dot_infringably(
dot, dot,
to, 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<R: RulesTrait> Layout<R> {
&self.rules &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<R> {
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<R> {
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().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()))] #[debug_ensures(self.geometry_with_rtree.graph().edge_count() == old(self.geometry_with_rtree.graph().edge_count()))]
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W, R> { pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W, R> {

View File

@ -2,6 +2,7 @@
pub mod graph; pub mod graph;
pub mod band; pub mod band;
pub mod bend; pub mod bend;
pub mod collect;
pub mod connectivity; pub mod connectivity;
pub mod dot; pub mod dot;
pub mod geometry; pub mod geometry;