From 16e6162b74a6c0c347f76aecc9be410693cb8fb6 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 18 Jan 2024 19:14:08 +0000 Subject: [PATCH] layout: hide band weights, split out to new band module --- src/band.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/layout.rs | 27 +++++++++------------ src/main.rs | 1 + 3 files changed, 77 insertions(+), 16 deletions(-) create mode 100644 src/band.rs diff --git a/src/band.rs b/src/band.rs new file mode 100644 index 0000000..9ec4279 --- /dev/null +++ b/src/band.rs @@ -0,0 +1,65 @@ +use crate::{ + connectivity::{BandIndex, BandWeight, ConnectivityWeight, GetNet}, + geometry::{DotIndex, FixedDotIndex}, + graph::GetNodeIndex, + layout::Layout, + loose::{GetNextLoose, LooseIndex}, + primitive::GetEnds, +}; + +pub struct Band<'a> { + pub index: BandIndex, + layout: &'a Layout, +} + +impl<'a> Band<'a> { + pub fn new(index: BandIndex, layout: &'a Layout) -> Self { + Self { index, layout } + } + + fn weight(&self) -> BandWeight { + if let Some(ConnectivityWeight::Band(weight)) = self + .layout + .connectivity() + .node_weight(self.index.node_index()) + { + *weight + } else { + unreachable!() + } + } + + pub fn from(&self) -> FixedDotIndex { + self.weight().from + } + + pub fn to(&self) -> Option { + // For now, we do full traversal. Later on, we may want to store the target fixed dot + // somewhere. + + let mut maybe_loose = self.layout.primitive(self.from()).first_loose(self.index); + let mut prev = None; + + while let Some(loose) = maybe_loose { + let prev_prev = prev; + prev = maybe_loose; + maybe_loose = self.layout.loose(loose).next_loose(prev_prev); + } + + if let Some(LooseIndex::SeqSeg(seg)) = maybe_loose { + if let DotIndex::Fixed(dot) = self.layout.primitive(seg).ends().0 { + Some(dot) + } else { + unreachable!() + } + } else { + None + } + } +} + +impl<'a> GetNet for Band<'a> { + fn net(&self) -> i64 { + self.weight().net + } +} diff --git a/src/layout.rs b/src/layout.rs index c9d4f3a..7d10e16 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -8,6 +8,7 @@ use rstar::primitives::GeomWithData; use rstar::{RTree, RTreeObject}; use thiserror::Error; +use crate::band::Band; use crate::connectivity::{ BandIndex, BandWeight, ComponentIndex, ComponentWeight, ConnectivityGraph, ConnectivityWeight, GetNet, @@ -82,7 +83,7 @@ impl Layout { let mut bends = vec![]; let mut outers = vec![]; - let from = self.band_weight(band).from; + let from = self.band(band).from(); let mut maybe_loose = self.primitive(from).first_loose(band); let mut prev = None; @@ -605,7 +606,7 @@ impl Layout { infringables: &[GeometryIndex], ) -> Result { // It makes no sense to wrap something around or under one of its connectables. - let net = self.band_weight(weight.band).net(); + let net = self.band(weight.band).net(); // if net == around.primitive(self).net() { return Err(AlreadyConnected(net, around.into()).into()); @@ -889,32 +890,26 @@ impl Layout { #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] - pub fn primitive(&self, node: GenericIndex) -> GenericPrimitive { - GenericPrimitive::new(node, self) + pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { + GenericPrimitive::new(index, self) } #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] - fn wraparoundable(&self, node: WraparoundableIndex) -> Wraparoundable { - Wraparoundable::new(node, self) + pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable { + Wraparoundable::new(index, self) } #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] - fn loose(&self, node: LooseIndex) -> Loose { - Loose::new(node, self) + pub fn loose(&self, index: LooseIndex) -> Loose { + Loose::new(index, self) } #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] - fn band_weight(&self, band: BandIndex) -> BandWeight { - if let Some(ConnectivityWeight::Band(band_weight)) = - self.connectivity.node_weight(band.node_index()) - { - *band_weight - } else { - unreachable!() - } + pub fn band(&self, index: BandIndex) -> Band { + Band::new(index, self) } fn test_envelopes(&self) -> bool { diff --git a/src/main.rs b/src/main.rs index e41aa4f..6fcd42e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ macro_rules! dbg_dot { } mod astar; +mod band; mod connectivity; mod draw; mod geometry;