layout: hide band weights, split out to new band module

This commit is contained in:
Mikolaj Wielgus 2024-01-18 19:14:08 +00:00
parent afe4c586b5
commit 16e6162b74
3 changed files with 77 additions and 16 deletions

65
src/band.rs Normal file
View File

@ -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<FixedDotIndex> {
// 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
}
}

View File

@ -8,6 +8,7 @@ use rstar::primitives::GeomWithData;
use rstar::{RTree, RTreeObject}; use rstar::{RTree, RTreeObject};
use thiserror::Error; use thiserror::Error;
use crate::band::Band;
use crate::connectivity::{ use crate::connectivity::{
BandIndex, BandWeight, ComponentIndex, ComponentWeight, ConnectivityGraph, ConnectivityWeight, BandIndex, BandWeight, ComponentIndex, ComponentWeight, ConnectivityGraph, ConnectivityWeight,
GetNet, GetNet,
@ -82,7 +83,7 @@ impl Layout {
let mut bends = vec![]; let mut bends = vec![];
let mut outers = 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 maybe_loose = self.primitive(from).first_loose(band);
let mut prev = None; let mut prev = None;
@ -605,7 +606,7 @@ impl Layout {
infringables: &[GeometryIndex], infringables: &[GeometryIndex],
) -> Result<LooseBendIndex, LayoutException> { ) -> Result<LooseBendIndex, LayoutException> {
// It makes no sense to wrap something around or under one of its connectables. // 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() { if net == around.primitive(self).net() {
return Err(AlreadyConnected(net, around.into()).into()); 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.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn primitive<W>(&self, node: GenericIndex<W>) -> GenericPrimitive<W> { pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W> {
GenericPrimitive::new(node, self) GenericPrimitive::new(index, self)
} }
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn wraparoundable(&self, node: WraparoundableIndex) -> Wraparoundable { pub fn wraparoundable(&self, index: WraparoundableIndex) -> Wraparoundable {
Wraparoundable::new(node, self) Wraparoundable::new(index, self)
} }
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn loose(&self, node: LooseIndex) -> Loose { pub fn loose(&self, index: LooseIndex) -> Loose {
Loose::new(node, self) Loose::new(index, self)
} }
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))] #[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))] #[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn band_weight(&self, band: BandIndex) -> BandWeight { pub fn band(&self, index: BandIndex) -> Band {
if let Some(ConnectivityWeight::Band(band_weight)) = Band::new(index, self)
self.connectivity.node_weight(band.node_index())
{
*band_weight
} else {
unreachable!()
}
} }
fn test_envelopes(&self) -> bool { fn test_envelopes(&self) -> bool {

View File

@ -9,6 +9,7 @@ macro_rules! dbg_dot {
} }
mod astar; mod astar;
mod band;
mod connectivity; mod connectivity;
mod draw; mod draw;
mod geometry; mod geometry;