deps,graph: split out to new geometry and connectivity graph modules

The geometry graph is where the layout's dots, segs, and bends are
stored. The connectivity graph is where information about connected
components and relations between tem (e.g. which ones are connected with
bands) and information common to all band primitives are stored.

This removes dependency on the Slab library. We may go back to it
sometime in the future if we decide to phase out usage of Petgraph's
`StableDiGraph`.
This commit is contained in:
Mikolaj Wielgus 2024-01-13 20:36:25 +00:00
parent 9a4e8357e7
commit 1af5b96768
14 changed files with 563 additions and 497 deletions

View File

@ -24,9 +24,6 @@ version = "0.11.0"
[dependencies.petgraph]
version = "0.6.3"
[dependencies.slab]
version = "0.4.9"
[dependencies.spade]
version = "2.2.0"

42
src/connectivity.rs Normal file
View File

@ -0,0 +1,42 @@
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::StableDiGraph;
use crate::{geometry::GetNet, graph::GenericIndex};
pub type ConnectivityGraph = StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>;
#[enum_dispatch(GetNet)]
#[derive(Debug, Clone, Copy)]
pub enum ConnectivityWeight {
Component(ComponentWeight),
Band(BandWeight),
}
#[derive(Debug, Clone, Copy)]
pub struct ComponentWeight {
pub net: i64,
}
impl GetNet for ComponentWeight {
fn net(&self) -> i64 {
self.net
}
}
#[derive(Debug, Clone, Copy)]
pub struct BandWeight {
pub net: i64,
pub width: f64,
}
impl GetNet for BandWeight {
fn net(&self) -> i64 {
self.net
}
}
pub type BandIndex = GenericIndex<BandWeight>;
#[enum_dispatch]
#[derive(Debug, Clone, Copy)]
pub enum ConnectivityLabel {}

View File

@ -3,8 +3,8 @@ use geo::{EuclideanLength, Point};
use thiserror::Error;
use crate::{
graph::{
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBand, GetNet, LooseBendIndex,
geometry::{
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetNet, LooseBendIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
WraparoundableIndex,
},

287
src/geometry.rs Normal file
View File

@ -0,0 +1,287 @@
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use std::marker::PhantomData;
use crate::{
connectivity::{BandIndex, BandWeight, ComponentWeight, ConnectivityWeight},
graph::{GenericIndex, GetNodeIndex},
layout::Layout,
math::Circle,
primitive::{GenericPrimitive, Primitive},
};
#[enum_dispatch]
pub trait Retag {
fn retag(&self, index: NodeIndex<usize>) -> Index;
}
#[enum_dispatch]
pub trait GetNet {
fn net(&self) -> i64;
}
pub trait GetNetMut {
fn net_mut(&mut self) -> &mut i64;
}
pub trait GetBandIndex {
fn band(&self) -> BandIndex;
}
#[enum_dispatch]
pub trait GetWidth {
fn width(&self) -> f64;
}
pub trait GetOffset {
fn offset(&self) -> f64;
}
macro_rules! impl_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl Retag for $weight_struct {
fn retag(&self, index: NodeIndex<usize>) -> Index {
Index::$weight_variant($index_struct::new(index))
}
}
pub type $index_struct = GenericIndex<$weight_struct>;
impl MakePrimitive for $index_struct {
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a> {
Primitive::$weight_variant(GenericPrimitive::new(*self, layout))
}
}
};
}
macro_rules! impl_fixed_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl_weight!($weight_struct, $weight_variant, $index_struct);
impl GetNet for $weight_struct {
fn net(&self) -> i64 {
self.net
}
}
impl GetNetMut for $weight_struct {
fn net_mut(&mut self) -> &mut i64 {
&mut self.net
}
}
};
}
macro_rules! impl_loose_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl_weight!($weight_struct, $weight_variant, $index_struct);
impl GetBandIndex for $weight_struct {
fn band(&self) -> BandIndex {
self.band
}
}
};
}
pub type GeometryGraph = StableDiGraph<GeometryWeight, GeometryLabel, usize>;
#[enum_dispatch(Retag)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GeometryWeight {
FixedDot(FixedDotWeight),
LooseDot(LooseDotWeight),
FixedSeg(FixedSegWeight),
LooseSeg(LooseSegWeight),
FixedBend(FixedBendWeight),
LooseBend(LooseBendWeight),
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Index {
FixedDot(FixedDotIndex),
LooseDot(LooseDotIndex),
FixedSeg(FixedSegIndex),
LooseSeg(LooseSegIndex),
FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex),
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DotIndex {
Fixed(FixedDotIndex),
Loose(LooseDotIndex),
}
impl From<DotIndex> for Index {
fn from(dot: DotIndex) -> Self {
match dot {
DotIndex::Fixed(fixed) => Index::FixedDot(fixed),
DotIndex::Loose(loose) => Index::LooseDot(loose),
}
}
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SegIndex {
Fixed(FixedSegIndex),
Loose(LooseSegIndex),
}
impl From<SegIndex> for Index {
fn from(seg: SegIndex) -> Self {
match seg {
SegIndex::Fixed(seg) => Index::FixedSeg(seg),
SegIndex::Loose(seg) => Index::LooseSeg(seg),
}
}
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BendIndex {
Fixed(FixedBendIndex),
Loose(LooseBendIndex),
}
impl From<BendIndex> for Index {
fn from(bend: BendIndex) -> Self {
match bend {
BendIndex::Fixed(bend) => Index::FixedBend(bend),
BendIndex::Loose(bend) => Index::LooseBend(bend),
}
}
}
impl From<BendIndex> 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<WraparoundableIndex> for Index {
fn from(wraparoundable: WraparoundableIndex) -> Self {
match wraparoundable {
WraparoundableIndex::FixedDot(dot) => Index::FixedDot(dot),
WraparoundableIndex::FixedBend(bend) => Index::FixedBend(bend),
WraparoundableIndex::LooseBend(bend) => Index::LooseBend(bend),
}
}
}
pub trait DotWeight: GetWidth + Into<GeometryWeight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedDotWeight {
pub net: i64,
pub circle: Circle,
}
impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex);
impl DotWeight for FixedDotWeight {}
impl GetWidth for FixedDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseDotWeight {
pub band: BandIndex,
pub circle: Circle,
}
impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex);
impl DotWeight for LooseDotWeight {}
impl GetWidth for LooseDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0
}
}
pub trait SegWeight: Into<GeometryWeight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedSegWeight {
pub net: i64,
pub width: f64,
}
impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex);
impl SegWeight for FixedSegWeight {}
impl GetWidth for FixedSegWeight {
fn width(&self) -> f64 {
self.width
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseSegWeight {
pub band: BandIndex,
}
impl_loose_weight!(LooseSegWeight, LooseSeg, LooseSegIndex);
impl SegWeight for LooseSegWeight {}
pub trait BendWeight: Into<GeometryWeight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedBendWeight {
pub net: i64,
pub width: f64,
pub cw: bool,
}
impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex);
impl BendWeight for FixedBendWeight {}
impl GetWidth for FixedBendWeight {
fn width(&self) -> f64 {
self.width
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseBendWeight {
pub band: BandIndex,
pub offset: f64,
pub cw: bool,
}
impl GetOffset for LooseBendWeight {
fn offset(&self) -> f64 {
self.offset
}
}
impl_loose_weight!(LooseBendWeight, LooseBend, LooseBendIndex);
impl BendWeight for LooseBendWeight {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GeometryLabel {
Adjacent,
Outer,
Core,
}
#[enum_dispatch]
pub trait MakePrimitive {
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>;
}

View File

@ -1,298 +1,20 @@
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use std::{
hash::{Hash, Hasher},
marker::PhantomData,
};
use crate::{
layout::Layout,
math::Circle,
primitive::{GenericPrimitive, Primitive},
};
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
#[enum_dispatch]
pub trait Retag {
fn retag(&self, index: NodeIndex<usize>) -> Index;
}
#[enum_dispatch]
pub trait GetNet {
fn net(&self) -> i64;
}
pub trait GetNetMut {
fn net_mut(&mut self) -> &mut i64;
}
pub trait GetBand {
fn band(&self) -> usize;
}
#[enum_dispatch]
pub trait GetWidth {
fn width(&self) -> f64;
}
pub trait GetOffset {
fn offset(&self) -> f64;
}
macro_rules! impl_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl Retag for $weight_struct {
fn retag(&self, index: NodeIndex<usize>) -> Index {
Index::$weight_variant($index_struct {
node_index: index,
marker: PhantomData,
})
}
}
pub type $index_struct = GenericIndex<$weight_struct>;
impl MakePrimitive for $index_struct {
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a> {
Primitive::$weight_variant(GenericPrimitive::new(*self, layout))
}
}
};
}
macro_rules! impl_fixed_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl_weight!($weight_struct, $weight_variant, $index_struct);
impl GetNet for $weight_struct {
fn net(&self) -> i64 {
self.net
}
}
impl GetNetMut for $weight_struct {
fn net_mut(&mut self) -> &mut i64 {
&mut self.net
}
}
};
}
macro_rules! impl_loose_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl_weight!($weight_struct, $weight_variant, $index_struct);
impl GetBand for $weight_struct {
fn band(&self) -> usize {
self.band
}
}
};
}
#[enum_dispatch(Retag)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Weight {
FixedDot(FixedDotWeight),
LooseDot(LooseDotWeight),
FixedSeg(FixedSegWeight),
LooseSeg(LooseSegWeight),
FixedBend(FixedBendWeight),
LooseBend(LooseBendWeight),
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Index {
FixedDot(FixedDotIndex),
LooseDot(LooseDotIndex),
FixedSeg(FixedSegIndex),
LooseSeg(LooseSegIndex),
FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex),
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DotIndex {
Fixed(FixedDotIndex),
Loose(LooseDotIndex),
}
impl From<DotIndex> for Index {
fn from(dot: DotIndex) -> Self {
match dot {
DotIndex::Fixed(fixed) => Index::FixedDot(fixed),
DotIndex::Loose(loose) => Index::LooseDot(loose),
}
}
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum SegIndex {
Fixed(FixedSegIndex),
Loose(LooseSegIndex),
}
impl From<SegIndex> for Index {
fn from(seg: SegIndex) -> Self {
match seg {
SegIndex::Fixed(seg) => Index::FixedSeg(seg),
SegIndex::Loose(seg) => Index::LooseSeg(seg),
}
}
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BendIndex {
Fixed(FixedBendIndex),
Loose(LooseBendIndex),
}
impl From<BendIndex> for Index {
fn from(bend: BendIndex) -> Self {
match bend {
BendIndex::Fixed(bend) => Index::FixedBend(bend),
BendIndex::Loose(bend) => Index::LooseBend(bend),
}
}
}
impl From<BendIndex> 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<WraparoundableIndex> for Index {
fn from(wraparoundable: WraparoundableIndex) -> Self {
match wraparoundable {
WraparoundableIndex::FixedDot(dot) => Index::FixedDot(dot),
WraparoundableIndex::FixedBend(bend) => Index::FixedBend(bend),
WraparoundableIndex::LooseBend(bend) => Index::LooseBend(bend),
}
}
}
pub trait DotWeight: GetWidth + Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedDotWeight {
pub net: i64,
pub circle: Circle,
}
impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex);
impl DotWeight for FixedDotWeight {}
impl GetWidth for FixedDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseDotWeight {
pub band: usize,
pub circle: Circle,
}
impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex);
impl DotWeight for LooseDotWeight {}
impl GetWidth for LooseDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0
}
}
pub trait SegWeight: Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedSegWeight {
pub net: i64,
pub width: f64,
}
impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex);
impl SegWeight for FixedSegWeight {}
impl GetWidth for FixedSegWeight {
fn width(&self) -> f64 {
self.width
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseSegWeight {
pub band: usize,
}
impl_loose_weight!(LooseSegWeight, LooseSeg, LooseSegIndex);
impl SegWeight for LooseSegWeight {}
pub trait BendWeight: Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedBendWeight {
pub net: i64,
pub width: f64,
pub cw: bool,
}
impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex);
impl BendWeight for FixedBendWeight {}
impl GetWidth for FixedBendWeight {
fn width(&self) -> f64 {
self.width
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseBendWeight {
pub band: usize,
pub offset: f64,
pub cw: bool,
}
impl GetOffset for LooseBendWeight {
fn offset(&self) -> f64 {
self.offset
}
}
impl_loose_weight!(LooseBendWeight, LooseBend, LooseBendIndex);
impl BendWeight for LooseBendWeight {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Label {
Adjacent,
Outer,
Core,
}
// Due to apparent limitations of enum_dispatch we're forced to import some types backwards.
use crate::connectivity::{BandWeight, ComponentWeight, ConnectivityWeight};
use crate::geometry::{BendIndex, DotIndex, Index, SegIndex, WraparoundableIndex};
#[enum_dispatch]
pub trait GetNodeIndex {
fn node_index(&self) -> NodeIndex<usize>;
}
#[enum_dispatch]
pub trait MakePrimitive {
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>;
}
#[derive(Debug, Clone, Copy)]
pub struct GenericIndex<W> {
node_index: NodeIndex<usize>,

View File

@ -2,7 +2,8 @@ use enum_dispatch::enum_dispatch;
use geo::Line;
use crate::{
graph::{BendIndex, DotIndex, FixedDotIndex, GetBand, LooseDotIndex, MakePrimitive},
connectivity::BandIndex,
geometry::{BendIndex, DotIndex, FixedDotIndex, GetBandIndex, LooseDotIndex, MakePrimitive},
layout::Layout,
math::{self, Circle, NoTangents},
primitive::{GetCore, GetInnerOuter, GetOtherEnd, GetWeight, MakeShape},
@ -14,7 +15,7 @@ use crate::{
#[enum_dispatch]
pub trait HeadTrait {
fn face(&self) -> DotIndex;
fn band(&self) -> usize;
fn band(&self) -> BandIndex;
}
#[enum_dispatch(HeadTrait)]
@ -27,7 +28,7 @@ pub enum Head {
#[derive(Debug, Clone, Copy)]
pub struct BareHead {
pub dot: FixedDotIndex,
pub band: usize,
pub band: BandIndex,
}
impl HeadTrait for BareHead {
@ -35,7 +36,7 @@ impl HeadTrait for BareHead {
self.dot.into()
}
fn band(&self) -> usize {
fn band(&self) -> BandIndex {
self.band
}
}
@ -44,7 +45,7 @@ impl HeadTrait for BareHead {
pub struct SegbendHead {
pub face: LooseDotIndex,
pub segbend: Segbend,
pub band: usize,
pub band: BandIndex,
}
impl HeadTrait for SegbendHead {
@ -52,7 +53,7 @@ impl HeadTrait for SegbendHead {
self.face.into()
}
fn band(&self) -> usize {
fn band(&self) -> BandIndex {
self.band
}
}
@ -215,7 +216,7 @@ impl<'a, 'b> Guide<'a, 'b> {
)
}
pub fn head(&self, dot: DotIndex, band: usize) -> Head {
pub fn head(&self, dot: DotIndex, band: BandIndex) -> Head {
match dot {
DotIndex::Fixed(fixed) => BareHead { dot: fixed, band }.into(),
DotIndex::Loose(loose) => self.segbend_head(loose).into(),

View File

@ -6,15 +6,16 @@ use petgraph::visit::EdgeRef;
use petgraph::Direction::Incoming;
use rstar::primitives::GeomWithData;
use rstar::{RTree, RTreeObject};
use slab::Slab;
use thiserror::Error;
use crate::graph::{
use crate::connectivity::{BandIndex, ConnectivityLabel, ConnectivityWeight};
use crate::geometry::{
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex,
FixedSegWeight, GenericIndex, GetNet, GetNodeIndex, Index, Label, LooseBendIndex,
FixedSegWeight, GeometryGraph, GeometryLabel, GeometryWeight, GetNet, Index, LooseBendIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive,
Retag, SegWeight, Weight, WraparoundableIndex,
Retag, SegWeight, WraparoundableIndex,
};
use crate::graph::{GenericIndex, GetNodeIndex};
use crate::guide::Guide;
use crate::math::NoTangents;
use crate::primitive::{
@ -52,31 +53,25 @@ pub struct Collision(pub Shape, pub Index);
#[error("{1:?} is already connected to net {0}")]
pub struct AlreadyConnected(pub i64, pub Index);
#[derive(Debug, Clone, Copy)]
pub struct Band {
pub net: i64,
pub width: f64,
}
#[derive(Debug)]
pub struct Layout {
rtree: RTree<RTreeWrapper>,
pub bands: Slab<Band>,
pub graph: StableDiGraph<Weight, Label, usize>,
pub connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
pub geometry: GeometryGraph,
}
#[debug_invariant(self.graph.node_count() == self.rtree.size())]
#[debug_invariant(self.geometry.node_count() == self.rtree.size())]
#[debug_invariant(self.test_envelopes())]
impl Layout {
pub fn new() -> Self {
Layout {
rtree: RTree::new(),
bands: Slab::new(),
graph: StableDiGraph::default(),
connectivity: StableDiGraph::default(),
geometry: StableDiGraph::default(),
}
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 4))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count() - 4))]
pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) {
let maybe_outer = self.primitive(segbend.bend).outer();
@ -99,18 +94,18 @@ impl Layout {
}
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count() - 1))]
fn remove(&mut self, index: Index) {
// Unnecessary retag. It should be possible to elide it.
let weight = *self.graph.node_weight(index.node_index()).unwrap();
let weight = *self.geometry.node_weight(index.node_index()).unwrap();
self.remove_from_rtree(weight.retag(index.node_index()));
self.graph.remove_node(index.node_index());
self.geometry.remove_node(index.node_index());
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
self.add_dot_infringably(weight, &[])
}
@ -122,8 +117,8 @@ impl Layout {
self.add_dot_infringably(weight, &[])
}*/
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
fn add_dot_infringably<W: DotWeight>(
&mut self,
weight: W,
@ -132,7 +127,7 @@ impl Layout {
where
GenericIndex<W>: Into<Index> + Copy,
{
let dot = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
let dot = GenericIndex::<W>::new(self.geometry.add_node(weight.into()));
self.insert_into_rtree(dot.into());
self.fail_and_remove_if_infringes_except(dot.into(), infringables)?;
@ -140,10 +135,10 @@ impl Layout {
Ok(dot)
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_fixed_seg(
&mut self,
from: FixedDotIndex,
@ -153,10 +148,10 @@ impl Layout {
self.add_seg_infringably(from, to, weight, &[])
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn insert_segbend(
&mut self,
from: DotIndex,
@ -204,8 +199,8 @@ impl Layout {
Ok::<Segbend, LayoutException>(segbend)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec<Index> {
let bend_primitive = self.primitive(bend);
let mut v = vec![];
@ -224,8 +219,8 @@ impl Layout {
v
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
let bend_primitive = self.primitive(bend);
let mut v = vec![];
@ -247,8 +242,8 @@ impl Layout {
v
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[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<Index> {
match around {
WraparoundableIndex::FixedDot(dot) => {
@ -276,8 +271,8 @@ impl Layout {
}
// XXX: Move this to primitives?
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn bow(&self, bend: LooseBendIndex) -> Vec<Index> {
let mut bow: Vec<Index> = vec![];
bow.push(bend.into());
@ -297,8 +292,8 @@ impl Layout {
bow
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
let mut outer_bows = vec![];
let mut rail = bend;
@ -344,32 +339,35 @@ impl Layout {
outer_bows*/
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count())
|| self.graph.edge_count() == old(self.graph.edge_count() - 1)
|| self.graph.edge_count() == old(self.graph.edge_count() + 1))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count())
|| self.geometry.edge_count() == old(self.geometry.edge_count() - 1)
|| self.geometry.edge_count() == old(self.geometry.edge_count() + 1))]
fn reattach_bend(&mut self, bend: LooseBendIndex, maybe_new_inner: Option<LooseBendIndex>) {
self.remove_from_rtree(bend.into());
if let Some(old_inner_edge) = self
.graph
.geometry
.edges_directed(bend.node_index(), Incoming)
.filter(|edge| *edge.weight() == Label::Outer)
.filter(|edge| *edge.weight() == GeometryLabel::Outer)
.next()
{
self.graph.remove_edge(old_inner_edge.id());
self.geometry.remove_edge(old_inner_edge.id());
}
if let Some(new_inner) = maybe_new_inner {
self.graph
.add_edge(new_inner.node_index(), bend.node_index(), Label::Outer);
self.geometry.add_edge(
new_inner.node_index(),
bend.node_index(),
GeometryLabel::Outer,
);
}
self.insert_into_rtree(bend.into());
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn update_this_and_outward_bows(
&mut self,
around: LooseBendIndex,
@ -415,10 +413,10 @@ impl Layout {
Ok::<(), LayoutException>(())
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_segbend(
&mut self,
from: DotIndex,
@ -437,10 +435,10 @@ impl Layout {
)
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn add_segbend_infringably(
&mut self,
from: DotIndex,
@ -481,10 +479,10 @@ impl Layout {
})
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn add_loose_seg(
&mut self,
from: DotIndex,
@ -494,10 +492,10 @@ impl Layout {
self.add_seg_infringably(from, to, weight, &[])
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn add_seg_infringably<W: SegWeight>(
&mut self,
from: impl GetNodeIndex,
@ -508,12 +506,12 @@ impl Layout {
where
GenericIndex<W>: Into<Index> + Copy,
{
let seg = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
let seg = GenericIndex::<W>::new(self.geometry.add_node(weight.into()));
self.graph
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
self.graph
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
self.geometry
.add_edge(from.node_index(), seg.node_index(), GeometryLabel::Adjacent);
self.geometry
.add_edge(seg.node_index(), to.node_index(), GeometryLabel::Adjacent);
self.insert_into_rtree(seg.into());
self.fail_and_remove_if_infringes_except(seg.into(), infringables)?;
@ -537,11 +535,11 @@ impl Layout {
}
}*/
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3)
|| self.graph.edge_count() == old(self.graph.edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3)
|| self.geometry.edge_count() == old(self.geometry.edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn add_loose_bend_infringably(
&mut self,
from: LooseDotIndex,
@ -551,13 +549,14 @@ impl Layout {
infringables: &[Index],
) -> Result<LooseBendIndex, LayoutException> {
// It makes no sense to wrap something around or under one of its connectables.
let net = self.bands[weight.band].net;
let net = self
.connectivity
.node_weight(weight.band.node_index())
.unwrap()
.net();
//
if net == around.primitive(self).net() {
return Err(AlreadyConnected(
net,
around.into(),
).into());
return Err(AlreadyConnected(net, around.into()).into());
}
//
if let Some(wraparound) = match around {
@ -566,10 +565,7 @@ impl Layout {
WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(),
} {
if net == wraparound.primitive(self).net() {
return Err(AlreadyConnected(
net,
wraparound.into(),
).into());
return Err(AlreadyConnected(net, wraparound.into()).into());
}
}
@ -586,10 +582,10 @@ impl Layout {
}
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn add_core_bend_infringably<W: BendWeight>(
&mut self,
from: impl GetNodeIndex,
@ -601,24 +597,27 @@ impl Layout {
where
GenericIndex<W>: Into<Index> + Copy,
{
let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
let bend = LooseBendIndex::new(self.geometry.add_node(weight.into()));
self.graph
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
self.graph
.add_edge(bend.node_index(), to.node_index(), Label::Adjacent);
self.graph
.add_edge(bend.node_index(), core.node_index(), Label::Core);
self.geometry.add_edge(
from.node_index(),
bend.node_index(),
GeometryLabel::Adjacent,
);
self.geometry
.add_edge(bend.node_index(), to.node_index(), GeometryLabel::Adjacent);
self.geometry
.add_edge(bend.node_index(), core.node_index(), GeometryLabel::Core);
self.insert_into_rtree(bend.into());
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
Ok(bend)
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn add_outer_bend_infringably<W: BendWeight>(
&mut self,
from: impl GetNodeIndex,
@ -628,14 +627,14 @@ impl Layout {
infringables: &[Index],
) -> Result<LooseBendIndex, Infringement> {
let core = *self
.graph
.geometry
.neighbors(inner.node_index())
.filter(|ni| {
matches!(
self.graph
.edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap())
self.geometry
.edge_weight(self.geometry.find_edge(inner.node_index(), *ni).unwrap())
.unwrap(),
Label::Core
GeometryLabel::Core
)
})
.map(|ni| FixedDotIndex::new(ni))
@ -643,28 +642,33 @@ impl Layout {
.first()
.unwrap();
let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
let bend = LooseBendIndex::new(self.geometry.add_node(weight.into()));
self.graph
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
self.graph
.add_edge(bend.node_index(), to.node_index(), Label::Adjacent);
self.graph
.add_edge(bend.node_index(), core.node_index(), Label::Core);
self.graph
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
self.geometry.add_edge(
from.node_index(),
bend.node_index(),
GeometryLabel::Adjacent,
);
self.geometry
.add_edge(bend.node_index(), to.node_index(), GeometryLabel::Adjacent);
self.geometry
.add_edge(bend.node_index(), core.node_index(), GeometryLabel::Core);
self.geometry
.add_edge(inner.node_index(), bend.node_index(), GeometryLabel::Outer);
self.insert_into_rtree(bend.into());
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
Ok(bend)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
self.remove_from_rtree(bend.into());
let Some(Weight::FixedBend(weight)) = self.graph.node_weight_mut(bend.node_index()) else {
let Some(GeometryWeight::FixedBend(weight)) =
self.geometry.node_weight_mut(bend.node_index())
else {
unreachable!();
};
@ -681,9 +685,9 @@ impl Layout {
Segbend::from_dot(dot, self)
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count() - 1))]
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count() - 1))]
fn fail_and_remove_if_infringes_except(
&mut self,
index: Index,
@ -705,7 +709,7 @@ impl Layout {
}
pub fn node_count(&self) -> usize {
self.graph.node_count()
self.geometry.node_count()
}
fn node_indices(&self) -> impl Iterator<Item = Index> + '_ {
@ -723,8 +727,8 @@ impl Layout {
)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
pub fn move_dot_infringably(
&mut self,
dot: LooseDotIndex,
@ -741,11 +745,13 @@ impl Layout {
let old_weight = dot_weight;
dot_weight.circle.pos = to;
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight);
*self.geometry.node_weight_mut(dot.node_index()).unwrap() =
GeometryWeight::LooseDot(dot_weight);
if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) {
// Restore original state.
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight);
*self.geometry.node_weight_mut(dot.node_index()).unwrap() =
GeometryWeight::LooseDot(old_weight);
self.insert_into_rtree(dot.into());
self.insert_into_rtree(self.primitive(dot).bend().into());
@ -764,14 +770,14 @@ impl Layout {
Ok(())
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[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<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W> {
GenericPrimitive::new(index, self)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn detect_infringement_except(&self, index: Index, except: &[Index]) -> Option<Infringement> {
let shape = index.primitive(self).shape();
@ -789,8 +795,8 @@ impl Layout {
}
// TODO: Collision and infringement are the same for now. Change this.
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn detect_collision(&self, index: Index) -> Option<Collision> {
let shape = index.primitive(self).shape();
@ -806,15 +812,15 @@ impl Layout {
.and_then(|collidee| Some(Collision(shape, collidee)))
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn insert_into_rtree(&mut self, index: Index) {
let shape = index.primitive(self).shape();
self.rtree.insert(RTreeWrapper::new(shape, index));
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
fn remove_from_rtree(&mut self, index: Index) {
let shape = index.primitive(self).shape();
let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index));

View File

@ -8,10 +8,11 @@ macro_rules! dbg_dot {
};
}
#[macro_use]
mod graph;
mod astar;
mod connectivity;
mod draw;
mod geometry;
mod graph;
mod guide;
mod layout;
mod math;
@ -26,7 +27,7 @@ mod triangulation;
use draw::DrawException;
use geo::point;
use graph::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive};
use geometry::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive};
use layout::{Infringement, Layout, LayoutException};
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
@ -54,7 +55,7 @@ use pathfinder_resources::embedded::EmbeddedResourceLoader;
use std::time::Duration;
use tracer::{Trace, Tracer};
use crate::graph::FixedDotWeight;
use crate::geometry::FixedDotWeight;
use crate::math::Circle;
use crate::router::Router;

View File

@ -10,7 +10,8 @@ use spade::{HasPosition, InsertionError, Point2};
use crate::primitive::{GetCore, Primitive};
use crate::triangulation::TriangulationEdgeReference;
use crate::{
graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex, MakePrimitive},
geometry::{FixedBendIndex, FixedDotIndex, Index, LooseBendIndex, MakePrimitive},
graph::GetNodeIndex,
layout::Layout,
primitive::MakeShape,
shape::ShapeTrait,
@ -74,7 +75,7 @@ impl Mesh {
vertex_to_triangulation_vertex: Vec::new(),
};
this.vertex_to_triangulation_vertex
.resize(layout.graph.node_bound(), None);
.resize(layout.geometry.node_bound(), None);
this
}

View File

@ -4,12 +4,13 @@ use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use petgraph::Direction::{Incoming, Outgoing};
use crate::graph::{
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GenericIndex,
GetBand, GetNet, GetNodeIndex, GetOffset, GetWidth, Index, Label, LooseBendIndex,
use crate::geometry::{
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryLabel,
GeometryWeight, GetBandIndex, GetNet, GetOffset, GetWidth, Index, LooseBendIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive,
Retag, Weight,
Retag,
};
use crate::graph::{GenericIndex, GetNodeIndex};
use crate::layout::Layout;
use crate::math::{self, Circle};
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
@ -65,20 +66,20 @@ pub trait GetWraparound: GetLayout + GetNodeIndex {
pub trait GetFirstRail: GetLayout + GetNodeIndex {
fn first_rail(&self) -> Option<LooseBendIndex> {
self.layout()
.graph
.geometry
.neighbors_directed(self.node_index(), Incoming)
.filter(|ni| {
matches!(
self.layout()
.graph
.geometry
.edge_weight(
self.layout()
.graph
.geometry
.find_edge(*ni, self.node_index())
.unwrap()
)
.unwrap(),
Label::Core
GeometryLabel::Core
)
})
.map(|ni| LooseBendIndex::new(ni))
@ -89,20 +90,20 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex {
pub trait GetCore: GetLayout + GetNodeIndex {
fn core(&self) -> FixedDotIndex {
self.layout()
.graph
.geometry
.neighbors(self.node_index())
.filter(|ni| {
matches!(
self.layout()
.graph
.geometry
.edge_weight(
self.layout()
.graph
.geometry
.find_edge(self.node_index(), *ni)
.unwrap()
)
.unwrap(),
Label::Core
GeometryLabel::Core
)
})
.map(|ni| FixedDotIndex::new(ni))
@ -114,20 +115,20 @@ pub trait GetCore: GetLayout + GetNodeIndex {
pub trait GetInnerOuter: GetLayout + GetNodeIndex {
fn inner(&self) -> Option<LooseBendIndex> {
self.layout()
.graph
.geometry
.neighbors_directed(self.node_index(), Incoming)
.filter(|ni| {
matches!(
self.layout()
.graph
.geometry
.edge_weight(
self.layout()
.graph
.geometry
.find_edge(*ni, self.node_index())
.unwrap()
)
.unwrap(),
Label::Outer
GeometryLabel::Outer
)
})
.map(|ni| LooseBendIndex::new(ni))
@ -136,20 +137,20 @@ pub trait GetInnerOuter: GetLayout + GetNodeIndex {
fn outer(&self) -> Option<LooseBendIndex> {
self.layout()
.graph
.geometry
.neighbors_directed(self.node_index(), Outgoing)
.filter(|ni| {
matches!(
self.layout()
.graph
.geometry
.edge_weight(
self.layout()
.graph
.geometry
.find_edge(self.node_index(), *ni)
.unwrap()
)
.unwrap(),
Label::Outer
GeometryLabel::Outer
)
})
.map(|ni| LooseBendIndex::new(ni))
@ -161,7 +162,7 @@ macro_rules! impl_primitive {
($primitive_struct:ident, $weight_struct:ident) => {
impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> {
fn weight(&self) -> $weight_struct {
if let Weight::$primitive_struct(weight) = self.tagged_weight() {
if let GeometryWeight::$primitive_struct(weight) = self.tagged_weight() {
weight
} else {
unreachable!()
@ -189,7 +190,11 @@ macro_rules! impl_loose_primitive {
impl<'a> GetNet for $primitive_struct<'a> {
fn net(&self) -> i64 {
self.layout().bands[self.weight().band()].net
self.layout()
.connectivity
.node_weight(self.weight().band().node_index())
.unwrap()
.net()
}
}
};
@ -216,31 +221,31 @@ impl<'a, W> GenericPrimitive<'a, W> {
Self { index, layout }
}
fn tagged_weight(&self) -> Weight {
fn tagged_weight(&self) -> GeometryWeight {
*self
.layout
.graph
.geometry
.node_weight(self.index.node_index())
.unwrap()
}
fn adjacents(&self) -> Vec<NodeIndex<usize>> {
self.layout
.graph
.geometry
.neighbors_undirected(self.index.node_index())
.filter(|ni| {
matches!(
self.layout
.graph
.geometry
.edge_weight(
self.layout
.graph
.geometry
.find_edge_undirected(self.index.node_index(), *ni)
.unwrap()
.0,
)
.unwrap(),
Label::Adjacent
GeometryLabel::Adjacent
)
})
.collect()
@ -303,27 +308,27 @@ impl_loose_primitive!(LooseDot, LooseDotWeight);
impl<'a> LooseDot<'a> {
pub fn seg(&self) -> Option<LooseSegIndex> {
self.layout
.graph
.geometry
.neighbors_undirected(self.index.node_index())
.filter(|ni| {
matches!(
self.layout
.graph
.geometry
.edge_weight(
self.layout
.graph
.geometry
.find_edge_undirected(self.index.node_index(), *ni)
.unwrap()
.0,
)
.unwrap(),
Label::Adjacent
GeometryLabel::Adjacent
)
})
.filter(|ni| {
matches!(
self.layout.graph.node_weight(*ni).unwrap(),
Weight::LooseSeg(..)
self.layout.geometry.node_weight(*ni).unwrap(),
GeometryWeight::LooseSeg(..)
)
})
.map(|ni| LooseSegIndex::new(ni))
@ -332,27 +337,27 @@ impl<'a> LooseDot<'a> {
pub fn bend(&self) -> LooseBendIndex {
self.layout
.graph
.geometry
.neighbors_undirected(self.index.node_index())
.filter(|ni| {
matches!(
self.layout
.graph
.geometry
.edge_weight(
self.layout
.graph
.geometry
.find_edge_undirected(self.index.node_index(), *ni)
.unwrap()
.0,
)
.unwrap(),
Label::Adjacent
GeometryLabel::Adjacent
)
})
.filter(|ni| {
matches!(
self.layout.graph.node_weight(*ni).unwrap(),
Weight::LooseBend(..)
self.layout.geometry.node_weight(*ni).unwrap(),
GeometryWeight::LooseBend(..)
)
})
.map(|ni| LooseBendIndex::new(ni))
@ -418,9 +423,10 @@ impl<'a> GetWidth for LooseSeg<'a> {
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
fn ends(&self) -> (DotIndex, LooseDotIndex) {
let v = self.adjacents();
if let Weight::FixedDot(..) = self.layout.graph.node_weight(v[0]).unwrap() {
if let GeometryWeight::FixedDot(..) = self.layout.geometry.node_weight(v[0]).unwrap() {
(FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
} else if let Weight::FixedDot(..) = self.layout.graph.node_weight(v[1]).unwrap() {
} else if let GeometryWeight::FixedDot(..) = self.layout.geometry.node_weight(v[1]).unwrap()
{
(FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0]))
} else {
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))

View File

@ -5,7 +5,7 @@ use thiserror::Error;
use crate::astar::{astar, AstarStrategy, PathTracker};
use crate::draw::DrawException;
use crate::graph::FixedDotIndex;
use crate::geometry::FixedDotIndex;
use crate::layout::Layout;
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
@ -121,12 +121,11 @@ impl Router {
// right.
//self.mesh.triangulate(&self.layout)?;
let mut mesh = Mesh::new(&self.layout);
mesh.generate(&self.layout)
.map_err(|err| RoutingError {
from,
to,
source: err.into(),
})?;
mesh.generate(&self.layout).map_err(|err| RoutingError {
from,
to,
source: err.into(),
})?;
let mut tracer = self.tracer(&mesh);
let trace = tracer.start(from, 3.0);
@ -135,7 +134,8 @@ impl Router {
&mesh,
from.into(),
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
).ok_or(RoutingError {
)
.ok_or(RoutingError {
from,
to,
source: RoutingErrorKind::AStar,

View File

@ -1,5 +1,5 @@
use crate::{
graph::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex},
geometry::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex},
layout::Layout,
primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot},
};

View File

@ -1,10 +1,11 @@
use contracts::debug_ensures;
use crate::{
connectivity::{BandIndex, BandWeight, ConnectivityWeight},
draw::{Draw, DrawException},
graph::{FixedDotIndex, GetNet, LooseBendIndex},
geometry::{FixedDotIndex, GetNet, LooseBendIndex},
guide::{BareHead, Head, SegbendHead},
layout::{Band, Layout, LayoutException},
layout::{Layout, LayoutException},
mesh::{Mesh, VertexIndex},
rules::Rules,
};
@ -31,10 +32,12 @@ impl<'a> Tracer<'a> {
}
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
let band = self.layout.bands.insert(Band {
width,
net: self.layout.primitive(from).net(),
});
let band = BandIndex::new(self.layout.connectivity.add_node(ConnectivityWeight::Band(
BandWeight {
width,
net: self.layout.primitive(from).net(),
},
)));
Trace {
path: vec![from.into()],
head: BareHead { dot: from, band }.into(),

View File

@ -27,7 +27,7 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
index_marker: PhantomData,
};
this.vertex_to_handle
.resize(layout.graph.node_bound(), None);
.resize(layout.geometry.node_bound(), None);
this
}