mirror of https://codeberg.org/topola/topola.git
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:
parent
9a4e8357e7
commit
1af5b96768
|
|
@ -24,9 +24,6 @@ version = "0.11.0"
|
||||||
[dependencies.petgraph]
|
[dependencies.petgraph]
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
|
||||||
[dependencies.slab]
|
|
||||||
version = "0.4.9"
|
|
||||||
|
|
||||||
[dependencies.spade]
|
[dependencies.spade]
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {}
|
||||||
|
|
@ -3,8 +3,8 @@ use geo::{EuclideanLength, Point};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{
|
geometry::{
|
||||||
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBand, GetNet, LooseBendIndex,
|
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetBandIndex, GetNet, LooseBendIndex,
|
||||||
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
|
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
|
||||||
WraparoundableIndex,
|
WraparoundableIndex,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
||||||
|
}
|
||||||
288
src/graph.rs
288
src/graph.rs
|
|
@ -1,298 +1,20 @@
|
||||||
use enum_dispatch::enum_dispatch;
|
|
||||||
use petgraph::stable_graph::NodeIndex;
|
|
||||||
use std::{
|
use std::{
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use enum_dispatch::enum_dispatch;
|
||||||
layout::Layout,
|
use petgraph::stable_graph::NodeIndex;
|
||||||
math::Circle,
|
|
||||||
primitive::{GenericPrimitive, Primitive},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[enum_dispatch]
|
// Due to apparent limitations of enum_dispatch we're forced to import some types backwards.
|
||||||
pub trait Retag {
|
use crate::connectivity::{BandWeight, ComponentWeight, ConnectivityWeight};
|
||||||
fn retag(&self, index: NodeIndex<usize>) -> Index;
|
use crate::geometry::{BendIndex, DotIndex, Index, SegIndex, WraparoundableIndex};
|
||||||
}
|
|
||||||
|
|
||||||
#[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,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait GetNodeIndex {
|
pub trait GetNodeIndex {
|
||||||
fn node_index(&self) -> NodeIndex<usize>;
|
fn node_index(&self) -> NodeIndex<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch]
|
|
||||||
pub trait MakePrimitive {
|
|
||||||
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct GenericIndex<W> {
|
pub struct GenericIndex<W> {
|
||||||
node_index: NodeIndex<usize>,
|
node_index: NodeIndex<usize>,
|
||||||
|
|
|
||||||
15
src/guide.rs
15
src/guide.rs
|
|
@ -2,7 +2,8 @@ use enum_dispatch::enum_dispatch;
|
||||||
use geo::Line;
|
use geo::Line;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{BendIndex, DotIndex, FixedDotIndex, GetBand, LooseDotIndex, MakePrimitive},
|
connectivity::BandIndex,
|
||||||
|
geometry::{BendIndex, DotIndex, FixedDotIndex, GetBandIndex, LooseDotIndex, MakePrimitive},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
math::{self, Circle, NoTangents},
|
math::{self, Circle, NoTangents},
|
||||||
primitive::{GetCore, GetInnerOuter, GetOtherEnd, GetWeight, MakeShape},
|
primitive::{GetCore, GetInnerOuter, GetOtherEnd, GetWeight, MakeShape},
|
||||||
|
|
@ -14,7 +15,7 @@ use crate::{
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait HeadTrait {
|
pub trait HeadTrait {
|
||||||
fn face(&self) -> DotIndex;
|
fn face(&self) -> DotIndex;
|
||||||
fn band(&self) -> usize;
|
fn band(&self) -> BandIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(HeadTrait)]
|
#[enum_dispatch(HeadTrait)]
|
||||||
|
|
@ -27,7 +28,7 @@ pub enum Head {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct BareHead {
|
pub struct BareHead {
|
||||||
pub dot: FixedDotIndex,
|
pub dot: FixedDotIndex,
|
||||||
pub band: usize,
|
pub band: BandIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeadTrait for BareHead {
|
impl HeadTrait for BareHead {
|
||||||
|
|
@ -35,7 +36,7 @@ impl HeadTrait for BareHead {
|
||||||
self.dot.into()
|
self.dot.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn band(&self) -> usize {
|
fn band(&self) -> BandIndex {
|
||||||
self.band
|
self.band
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +45,7 @@ impl HeadTrait for BareHead {
|
||||||
pub struct SegbendHead {
|
pub struct SegbendHead {
|
||||||
pub face: LooseDotIndex,
|
pub face: LooseDotIndex,
|
||||||
pub segbend: Segbend,
|
pub segbend: Segbend,
|
||||||
pub band: usize,
|
pub band: BandIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeadTrait for SegbendHead {
|
impl HeadTrait for SegbendHead {
|
||||||
|
|
@ -52,7 +53,7 @@ impl HeadTrait for SegbendHead {
|
||||||
self.face.into()
|
self.face.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn band(&self) -> usize {
|
fn band(&self) -> BandIndex {
|
||||||
self.band
|
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 {
|
match dot {
|
||||||
DotIndex::Fixed(fixed) => BareHead { dot: fixed, band }.into(),
|
DotIndex::Fixed(fixed) => BareHead { dot: fixed, band }.into(),
|
||||||
DotIndex::Loose(loose) => self.segbend_head(loose).into(),
|
DotIndex::Loose(loose) => self.segbend_head(loose).into(),
|
||||||
|
|
|
||||||
282
src/layout.rs
282
src/layout.rs
|
|
@ -6,15 +6,16 @@ use petgraph::visit::EdgeRef;
|
||||||
use petgraph::Direction::Incoming;
|
use petgraph::Direction::Incoming;
|
||||||
use rstar::primitives::GeomWithData;
|
use rstar::primitives::GeomWithData;
|
||||||
use rstar::{RTree, RTreeObject};
|
use rstar::{RTree, RTreeObject};
|
||||||
use slab::Slab;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::graph::{
|
use crate::connectivity::{BandIndex, ConnectivityLabel, ConnectivityWeight};
|
||||||
|
use crate::geometry::{
|
||||||
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedDotIndex, FixedDotWeight, FixedSegIndex,
|
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,
|
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive,
|
||||||
Retag, SegWeight, Weight, WraparoundableIndex,
|
Retag, SegWeight, WraparoundableIndex,
|
||||||
};
|
};
|
||||||
|
use crate::graph::{GenericIndex, GetNodeIndex};
|
||||||
use crate::guide::Guide;
|
use crate::guide::Guide;
|
||||||
use crate::math::NoTangents;
|
use crate::math::NoTangents;
|
||||||
use crate::primitive::{
|
use crate::primitive::{
|
||||||
|
|
@ -52,31 +53,25 @@ pub struct Collision(pub Shape, pub Index);
|
||||||
#[error("{1:?} is already connected to net {0}")]
|
#[error("{1:?} is already connected to net {0}")]
|
||||||
pub struct AlreadyConnected(pub i64, pub Index);
|
pub struct AlreadyConnected(pub i64, pub Index);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Band {
|
|
||||||
pub net: i64,
|
|
||||||
pub width: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
rtree: RTree<RTreeWrapper>,
|
rtree: RTree<RTreeWrapper>,
|
||||||
pub bands: Slab<Band>,
|
pub connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
|
||||||
pub graph: StableDiGraph<Weight, Label, 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())]
|
#[debug_invariant(self.test_envelopes())]
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Layout {
|
Layout {
|
||||||
rtree: RTree::new(),
|
rtree: RTree::new(),
|
||||||
bands: Slab::new(),
|
connectivity: StableDiGraph::default(),
|
||||||
graph: 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) {
|
pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) {
|
||||||
let maybe_outer = self.primitive(segbend.bend).outer();
|
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) {
|
fn remove(&mut self, index: Index) {
|
||||||
// Unnecessary retag. It should be possible to elide it.
|
// 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.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_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
||||||
self.add_dot_infringably(weight, &[])
|
self.add_dot_infringably(weight, &[])
|
||||||
}
|
}
|
||||||
|
|
@ -122,8 +117,8 @@ impl Layout {
|
||||||
self.add_dot_infringably(weight, &[])
|
self.add_dot_infringably(weight, &[])
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
fn add_dot_infringably<W: DotWeight>(
|
fn add_dot_infringably<W: DotWeight>(
|
||||||
&mut self,
|
&mut self,
|
||||||
weight: W,
|
weight: W,
|
||||||
|
|
@ -132,7 +127,7 @@ impl Layout {
|
||||||
where
|
where
|
||||||
GenericIndex<W>: Into<Index> + Copy,
|
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.insert_into_rtree(dot.into());
|
||||||
self.fail_and_remove_if_infringes_except(dot.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(dot.into(), infringables)?;
|
||||||
|
|
@ -140,10 +135,10 @@ impl Layout {
|
||||||
Ok(dot)
|
Ok(dot)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn add_fixed_seg(
|
pub fn add_fixed_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: FixedDotIndex,
|
||||||
|
|
@ -153,10 +148,10 @@ impl Layout {
|
||||||
self.add_seg_infringably(from, to, weight, &[])
|
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.geometry.node_count() == old(self.geometry.node_count() + 4))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn insert_segbend(
|
pub fn insert_segbend(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
|
|
@ -204,8 +199,8 @@ impl Layout {
|
||||||
Ok::<Segbend, LayoutException>(segbend)
|
Ok::<Segbend, LayoutException>(segbend)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec<Index> {
|
fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec<Index> {
|
||||||
let bend_primitive = self.primitive(bend);
|
let bend_primitive = self.primitive(bend);
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
|
|
@ -224,8 +219,8 @@ impl Layout {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
|
fn inner_bow_and_outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
|
||||||
let bend_primitive = self.primitive(bend);
|
let bend_primitive = self.primitive(bend);
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
|
|
@ -247,8 +242,8 @@ impl Layout {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec<Index> {
|
fn this_and_wraparound_bow(&self, around: WraparoundableIndex) -> Vec<Index> {
|
||||||
match around {
|
match around {
|
||||||
WraparoundableIndex::FixedDot(dot) => {
|
WraparoundableIndex::FixedDot(dot) => {
|
||||||
|
|
@ -276,8 +271,8 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Move this to primitives?
|
// XXX: Move this to primitives?
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn bow(&self, bend: LooseBendIndex) -> Vec<Index> {
|
fn bow(&self, bend: LooseBendIndex) -> Vec<Index> {
|
||||||
let mut bow: Vec<Index> = vec![];
|
let mut bow: Vec<Index> = vec![];
|
||||||
bow.push(bend.into());
|
bow.push(bend.into());
|
||||||
|
|
@ -297,8 +292,8 @@ impl Layout {
|
||||||
bow
|
bow
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
|
fn outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> {
|
||||||
let mut outer_bows = vec![];
|
let mut outer_bows = vec![];
|
||||||
let mut rail = bend;
|
let mut rail = bend;
|
||||||
|
|
@ -344,32 +339,35 @@ impl Layout {
|
||||||
outer_bows*/
|
outer_bows*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count())
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count())
|
||||||
|| self.graph.edge_count() == old(self.graph.edge_count() - 1)
|
|| self.geometry.edge_count() == old(self.geometry.edge_count() - 1)
|
||||||
|| self.graph.edge_count() == old(self.graph.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>) {
|
fn reattach_bend(&mut self, bend: LooseBendIndex, maybe_new_inner: Option<LooseBendIndex>) {
|
||||||
self.remove_from_rtree(bend.into());
|
self.remove_from_rtree(bend.into());
|
||||||
|
|
||||||
if let Some(old_inner_edge) = self
|
if let Some(old_inner_edge) = self
|
||||||
.graph
|
.geometry
|
||||||
.edges_directed(bend.node_index(), Incoming)
|
.edges_directed(bend.node_index(), Incoming)
|
||||||
.filter(|edge| *edge.weight() == Label::Outer)
|
.filter(|edge| *edge.weight() == GeometryLabel::Outer)
|
||||||
.next()
|
.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 {
|
if let Some(new_inner) = maybe_new_inner {
|
||||||
self.graph
|
self.geometry.add_edge(
|
||||||
.add_edge(new_inner.node_index(), bend.node_index(), Label::Outer);
|
new_inner.node_index(),
|
||||||
|
bend.node_index(),
|
||||||
|
GeometryLabel::Outer,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.insert_into_rtree(bend.into());
|
self.insert_into_rtree(bend.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn update_this_and_outward_bows(
|
fn update_this_and_outward_bows(
|
||||||
&mut self,
|
&mut self,
|
||||||
around: LooseBendIndex,
|
around: LooseBendIndex,
|
||||||
|
|
@ -415,10 +413,10 @@ impl Layout {
|
||||||
Ok::<(), LayoutException>(())
|
Ok::<(), LayoutException>(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 4))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 4))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn add_segbend(
|
pub fn add_segbend(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
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.geometry.node_count() == old(self.geometry.node_count() + 4))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() >= old(self.graph.edge_count() + 5))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() >= old(self.geometry.edge_count() + 5))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn add_segbend_infringably(
|
fn add_segbend_infringably(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
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.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn add_loose_seg(
|
pub fn add_loose_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
|
|
@ -494,10 +492,10 @@ impl Layout {
|
||||||
self.add_seg_infringably(from, to, weight, &[])
|
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.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 2))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn add_seg_infringably<W: SegWeight>(
|
fn add_seg_infringably<W: SegWeight>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: impl GetNodeIndex,
|
from: impl GetNodeIndex,
|
||||||
|
|
@ -508,12 +506,12 @@ impl Layout {
|
||||||
where
|
where
|
||||||
GenericIndex<W>: Into<Index> + Copy,
|
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
|
self.geometry
|
||||||
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
.add_edge(from.node_index(), seg.node_index(), GeometryLabel::Adjacent);
|
||||||
self.graph
|
self.geometry
|
||||||
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
|
.add_edge(seg.node_index(), to.node_index(), GeometryLabel::Adjacent);
|
||||||
|
|
||||||
self.insert_into_rtree(seg.into());
|
self.insert_into_rtree(seg.into());
|
||||||
self.fail_and_remove_if_infringes_except(seg.into(), infringables)?;
|
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.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3)
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3)
|
||||||
|| self.graph.edge_count() == old(self.graph.edge_count() + 4))]
|
|| self.geometry.edge_count() == old(self.geometry.edge_count() + 4))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn add_loose_bend_infringably(
|
fn add_loose_bend_infringably(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: LooseDotIndex,
|
from: LooseDotIndex,
|
||||||
|
|
@ -551,13 +549,14 @@ impl Layout {
|
||||||
infringables: &[Index],
|
infringables: &[Index],
|
||||||
) -> 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.bands[weight.band].net;
|
let net = self
|
||||||
|
.connectivity
|
||||||
|
.node_weight(weight.band.node_index())
|
||||||
|
.unwrap()
|
||||||
|
.net();
|
||||||
//
|
//
|
||||||
if net == around.primitive(self).net() {
|
if net == around.primitive(self).net() {
|
||||||
return Err(AlreadyConnected(
|
return Err(AlreadyConnected(net, around.into()).into());
|
||||||
net,
|
|
||||||
around.into(),
|
|
||||||
).into());
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if let Some(wraparound) = match around {
|
if let Some(wraparound) = match around {
|
||||||
|
|
@ -566,10 +565,7 @@ impl Layout {
|
||||||
WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(),
|
WraparoundableIndex::LooseBend(around) => self.primitive(around).wraparound(),
|
||||||
} {
|
} {
|
||||||
if net == wraparound.primitive(self).net() {
|
if net == wraparound.primitive(self).net() {
|
||||||
return Err(AlreadyConnected(
|
return Err(AlreadyConnected(net, wraparound.into()).into());
|
||||||
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_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 3))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn add_core_bend_infringably<W: BendWeight>(
|
fn add_core_bend_infringably<W: BendWeight>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: impl GetNodeIndex,
|
from: impl GetNodeIndex,
|
||||||
|
|
@ -601,24 +597,27 @@ impl Layout {
|
||||||
where
|
where
|
||||||
GenericIndex<W>: Into<Index> + Copy,
|
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
|
self.geometry.add_edge(
|
||||||
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
|
from.node_index(),
|
||||||
self.graph
|
bend.node_index(),
|
||||||
.add_edge(bend.node_index(), to.node_index(), Label::Adjacent);
|
GeometryLabel::Adjacent,
|
||||||
self.graph
|
);
|
||||||
.add_edge(bend.node_index(), core.node_index(), Label::Core);
|
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.insert_into_rtree(bend.into());
|
||||||
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.node_count() == old(self.geometry.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count() + 4))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn add_outer_bend_infringably<W: BendWeight>(
|
fn add_outer_bend_infringably<W: BendWeight>(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: impl GetNodeIndex,
|
from: impl GetNodeIndex,
|
||||||
|
|
@ -628,14 +627,14 @@ impl Layout {
|
||||||
infringables: &[Index],
|
infringables: &[Index],
|
||||||
) -> Result<LooseBendIndex, Infringement> {
|
) -> Result<LooseBendIndex, Infringement> {
|
||||||
let core = *self
|
let core = *self
|
||||||
.graph
|
.geometry
|
||||||
.neighbors(inner.node_index())
|
.neighbors(inner.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.graph
|
self.geometry
|
||||||
.edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap())
|
.edge_weight(self.geometry.find_edge(inner.node_index(), *ni).unwrap())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Core
|
GeometryLabel::Core
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| FixedDotIndex::new(ni))
|
.map(|ni| FixedDotIndex::new(ni))
|
||||||
|
|
@ -643,28 +642,33 @@ impl Layout {
|
||||||
.first()
|
.first()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
|
let bend = LooseBendIndex::new(self.geometry.add_node(weight.into()));
|
||||||
|
|
||||||
self.graph
|
self.geometry.add_edge(
|
||||||
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
|
from.node_index(),
|
||||||
self.graph
|
bend.node_index(),
|
||||||
.add_edge(bend.node_index(), to.node_index(), Label::Adjacent);
|
GeometryLabel::Adjacent,
|
||||||
self.graph
|
);
|
||||||
.add_edge(bend.node_index(), core.node_index(), Label::Core);
|
self.geometry
|
||||||
self.graph
|
.add_edge(bend.node_index(), to.node_index(), GeometryLabel::Adjacent);
|
||||||
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
|
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.insert_into_rtree(bend.into());
|
||||||
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
|
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
|
||||||
self.remove_from_rtree(bend.into());
|
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!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -681,9 +685,9 @@ impl Layout {
|
||||||
Segbend::from_dot(dot, self)
|
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.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_ok() -> self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count() - 1))]
|
#[debug_ensures(ret.is_err() -> self.geometry.node_count() == old(self.geometry.node_count() - 1))]
|
||||||
fn fail_and_remove_if_infringes_except(
|
fn fail_and_remove_if_infringes_except(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: Index,
|
index: Index,
|
||||||
|
|
@ -705,7 +709,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_count(&self) -> usize {
|
pub fn node_count(&self) -> usize {
|
||||||
self.graph.node_count()
|
self.geometry.node_count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_indices(&self) -> impl Iterator<Item = Index> + '_ {
|
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.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn move_dot_infringably(
|
pub fn move_dot_infringably(
|
||||||
&mut self,
|
&mut self,
|
||||||
dot: LooseDotIndex,
|
dot: LooseDotIndex,
|
||||||
|
|
@ -741,11 +745,13 @@ impl Layout {
|
||||||
let old_weight = dot_weight;
|
let old_weight = dot_weight;
|
||||||
|
|
||||||
dot_weight.circle.pos = to;
|
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) {
|
if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) {
|
||||||
// Restore original state.
|
// 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(dot.into());
|
||||||
self.insert_into_rtree(self.primitive(dot).bend().into());
|
self.insert_into_rtree(self.primitive(dot).bend().into());
|
||||||
|
|
@ -764,14 +770,14 @@ impl Layout {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W> {
|
pub fn primitive<W>(&self, index: GenericIndex<W>) -> GenericPrimitive<W> {
|
||||||
GenericPrimitive::new(index, self)
|
GenericPrimitive::new(index, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn detect_infringement_except(&self, index: Index, except: &[Index]) -> Option<Infringement> {
|
fn detect_infringement_except(&self, index: Index, except: &[Index]) -> Option<Infringement> {
|
||||||
let shape = index.primitive(self).shape();
|
let shape = index.primitive(self).shape();
|
||||||
|
|
||||||
|
|
@ -789,8 +795,8 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Collision and infringement are the same for now. Change this.
|
// 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.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn detect_collision(&self, index: Index) -> Option<Collision> {
|
fn detect_collision(&self, index: Index) -> Option<Collision> {
|
||||||
let shape = index.primitive(self).shape();
|
let shape = index.primitive(self).shape();
|
||||||
|
|
||||||
|
|
@ -806,15 +812,15 @@ impl Layout {
|
||||||
.and_then(|collidee| Some(Collision(shape, collidee)))
|
.and_then(|collidee| Some(Collision(shape, collidee)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn insert_into_rtree(&mut self, index: Index) {
|
fn insert_into_rtree(&mut self, index: Index) {
|
||||||
let shape = index.primitive(self).shape();
|
let shape = index.primitive(self).shape();
|
||||||
self.rtree.insert(RTreeWrapper::new(shape, index));
|
self.rtree.insert(RTreeWrapper::new(shape, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.geometry.node_count() == old(self.geometry.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.geometry.edge_count() == old(self.geometry.edge_count()))]
|
||||||
fn remove_from_rtree(&mut self, index: Index) {
|
fn remove_from_rtree(&mut self, index: Index) {
|
||||||
let shape = index.primitive(self).shape();
|
let shape = index.primitive(self).shape();
|
||||||
let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index));
|
let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index));
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,11 @@ macro_rules! dbg_dot {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod graph;
|
|
||||||
mod astar;
|
mod astar;
|
||||||
|
mod connectivity;
|
||||||
mod draw;
|
mod draw;
|
||||||
|
mod geometry;
|
||||||
|
mod graph;
|
||||||
mod guide;
|
mod guide;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod math;
|
mod math;
|
||||||
|
|
@ -26,7 +27,7 @@ mod triangulation;
|
||||||
|
|
||||||
use draw::DrawException;
|
use draw::DrawException;
|
||||||
use geo::point;
|
use geo::point;
|
||||||
use graph::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive};
|
use geometry::{FixedDotIndex, FixedSegWeight, Index, LooseDotIndex, MakePrimitive};
|
||||||
use layout::{Infringement, Layout, LayoutException};
|
use layout::{Infringement, Layout, LayoutException};
|
||||||
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
|
|
@ -54,7 +55,7 @@ use pathfinder_resources::embedded::EmbeddedResourceLoader;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracer::{Trace, Tracer};
|
use tracer::{Trace, Tracer};
|
||||||
|
|
||||||
use crate::graph::FixedDotWeight;
|
use crate::geometry::FixedDotWeight;
|
||||||
use crate::math::Circle;
|
use crate::math::Circle;
|
||||||
use crate::router::Router;
|
use crate::router::Router;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ use spade::{HasPosition, InsertionError, Point2};
|
||||||
use crate::primitive::{GetCore, Primitive};
|
use crate::primitive::{GetCore, Primitive};
|
||||||
use crate::triangulation::TriangulationEdgeReference;
|
use crate::triangulation::TriangulationEdgeReference;
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex, MakePrimitive},
|
geometry::{FixedBendIndex, FixedDotIndex, Index, LooseBendIndex, MakePrimitive},
|
||||||
|
graph::GetNodeIndex,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
primitive::MakeShape,
|
primitive::MakeShape,
|
||||||
shape::ShapeTrait,
|
shape::ShapeTrait,
|
||||||
|
|
@ -74,7 +75,7 @@ impl Mesh {
|
||||||
vertex_to_triangulation_vertex: Vec::new(),
|
vertex_to_triangulation_vertex: Vec::new(),
|
||||||
};
|
};
|
||||||
this.vertex_to_triangulation_vertex
|
this.vertex_to_triangulation_vertex
|
||||||
.resize(layout.graph.node_bound(), None);
|
.resize(layout.geometry.node_bound(), None);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,13 @@ use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::stable_graph::NodeIndex;
|
use petgraph::stable_graph::NodeIndex;
|
||||||
use petgraph::Direction::{Incoming, Outgoing};
|
use petgraph::Direction::{Incoming, Outgoing};
|
||||||
|
|
||||||
use crate::graph::{
|
use crate::geometry::{
|
||||||
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GenericIndex,
|
DotIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegWeight, GeometryLabel,
|
||||||
GetBand, GetNet, GetNodeIndex, GetOffset, GetWidth, Index, Label, LooseBendIndex,
|
GeometryWeight, GetBandIndex, GetNet, GetOffset, GetWidth, Index, LooseBendIndex,
|
||||||
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive,
|
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, MakePrimitive,
|
||||||
Retag, Weight,
|
Retag,
|
||||||
};
|
};
|
||||||
|
use crate::graph::{GenericIndex, GetNodeIndex};
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
use crate::math::{self, Circle};
|
use crate::math::{self, Circle};
|
||||||
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
||||||
|
|
@ -65,20 +66,20 @@ pub trait GetWraparound: GetLayout + GetNodeIndex {
|
||||||
pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
||||||
fn first_rail(&self) -> Option<LooseBendIndex> {
|
fn first_rail(&self) -> Option<LooseBendIndex> {
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_directed(self.node_index(), Incoming)
|
.neighbors_directed(self.node_index(), Incoming)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.find_edge(*ni, self.node_index())
|
.find_edge(*ni, self.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Core
|
GeometryLabel::Core
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| LooseBendIndex::new(ni))
|
.map(|ni| LooseBendIndex::new(ni))
|
||||||
|
|
@ -89,20 +90,20 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex {
|
||||||
pub trait GetCore: GetLayout + GetNodeIndex {
|
pub trait GetCore: GetLayout + GetNodeIndex {
|
||||||
fn core(&self) -> FixedDotIndex {
|
fn core(&self) -> FixedDotIndex {
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.neighbors(self.node_index())
|
.neighbors(self.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.find_edge(self.node_index(), *ni)
|
.find_edge(self.node_index(), *ni)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Core
|
GeometryLabel::Core
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| FixedDotIndex::new(ni))
|
.map(|ni| FixedDotIndex::new(ni))
|
||||||
|
|
@ -114,20 +115,20 @@ pub trait GetCore: GetLayout + GetNodeIndex {
|
||||||
pub trait GetInnerOuter: GetLayout + GetNodeIndex {
|
pub trait GetInnerOuter: GetLayout + GetNodeIndex {
|
||||||
fn inner(&self) -> Option<LooseBendIndex> {
|
fn inner(&self) -> Option<LooseBendIndex> {
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_directed(self.node_index(), Incoming)
|
.neighbors_directed(self.node_index(), Incoming)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.find_edge(*ni, self.node_index())
|
.find_edge(*ni, self.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Outer
|
GeometryLabel::Outer
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| LooseBendIndex::new(ni))
|
.map(|ni| LooseBendIndex::new(ni))
|
||||||
|
|
@ -136,20 +137,20 @@ pub trait GetInnerOuter: GetLayout + GetNodeIndex {
|
||||||
|
|
||||||
fn outer(&self) -> Option<LooseBendIndex> {
|
fn outer(&self) -> Option<LooseBendIndex> {
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_directed(self.node_index(), Outgoing)
|
.neighbors_directed(self.node_index(), Outgoing)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout()
|
self.layout()
|
||||||
.graph
|
.geometry
|
||||||
.find_edge(self.node_index(), *ni)
|
.find_edge(self.node_index(), *ni)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Outer
|
GeometryLabel::Outer
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| LooseBendIndex::new(ni))
|
.map(|ni| LooseBendIndex::new(ni))
|
||||||
|
|
@ -161,7 +162,7 @@ macro_rules! impl_primitive {
|
||||||
($primitive_struct:ident, $weight_struct:ident) => {
|
($primitive_struct:ident, $weight_struct:ident) => {
|
||||||
impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> {
|
impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> {
|
||||||
fn weight(&self) -> $weight_struct {
|
fn weight(&self) -> $weight_struct {
|
||||||
if let Weight::$primitive_struct(weight) = self.tagged_weight() {
|
if let GeometryWeight::$primitive_struct(weight) = self.tagged_weight() {
|
||||||
weight
|
weight
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
@ -189,7 +190,11 @@ macro_rules! impl_loose_primitive {
|
||||||
|
|
||||||
impl<'a> GetNet for $primitive_struct<'a> {
|
impl<'a> GetNet for $primitive_struct<'a> {
|
||||||
fn net(&self) -> i64 {
|
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 }
|
Self { index, layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tagged_weight(&self) -> Weight {
|
fn tagged_weight(&self) -> GeometryWeight {
|
||||||
*self
|
*self
|
||||||
.layout
|
.layout
|
||||||
.graph
|
.geometry
|
||||||
.node_weight(self.index.node_index())
|
.node_weight(self.index.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjacents(&self) -> Vec<NodeIndex<usize>> {
|
fn adjacents(&self) -> Vec<NodeIndex<usize>> {
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_undirected(self.index.node_index())
|
.neighbors_undirected(self.index.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.find_edge_undirected(self.index.node_index(), *ni)
|
.find_edge_undirected(self.index.node_index(), *ni)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0,
|
.0,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Adjacent
|
GeometryLabel::Adjacent
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
@ -303,27 +308,27 @@ impl_loose_primitive!(LooseDot, LooseDotWeight);
|
||||||
impl<'a> LooseDot<'a> {
|
impl<'a> LooseDot<'a> {
|
||||||
pub fn seg(&self) -> Option<LooseSegIndex> {
|
pub fn seg(&self) -> Option<LooseSegIndex> {
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_undirected(self.index.node_index())
|
.neighbors_undirected(self.index.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.find_edge_undirected(self.index.node_index(), *ni)
|
.find_edge_undirected(self.index.node_index(), *ni)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0,
|
.0,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Adjacent
|
GeometryLabel::Adjacent
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout.graph.node_weight(*ni).unwrap(),
|
self.layout.geometry.node_weight(*ni).unwrap(),
|
||||||
Weight::LooseSeg(..)
|
GeometryWeight::LooseSeg(..)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| LooseSegIndex::new(ni))
|
.map(|ni| LooseSegIndex::new(ni))
|
||||||
|
|
@ -332,27 +337,27 @@ impl<'a> LooseDot<'a> {
|
||||||
|
|
||||||
pub fn bend(&self) -> LooseBendIndex {
|
pub fn bend(&self) -> LooseBendIndex {
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.neighbors_undirected(self.index.node_index())
|
.neighbors_undirected(self.index.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.edge_weight(
|
.edge_weight(
|
||||||
self.layout
|
self.layout
|
||||||
.graph
|
.geometry
|
||||||
.find_edge_undirected(self.index.node_index(), *ni)
|
.find_edge_undirected(self.index.node_index(), *ni)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0,
|
.0,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
Label::Adjacent
|
GeometryLabel::Adjacent
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
matches!(
|
matches!(
|
||||||
self.layout.graph.node_weight(*ni).unwrap(),
|
self.layout.geometry.node_weight(*ni).unwrap(),
|
||||||
Weight::LooseBend(..)
|
GeometryWeight::LooseBend(..)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| LooseBendIndex::new(ni))
|
.map(|ni| LooseBendIndex::new(ni))
|
||||||
|
|
@ -418,9 +423,10 @@ impl<'a> GetWidth for LooseSeg<'a> {
|
||||||
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
|
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
|
||||||
fn ends(&self) -> (DotIndex, LooseDotIndex) {
|
fn ends(&self) -> (DotIndex, LooseDotIndex) {
|
||||||
let v = self.adjacents();
|
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]))
|
(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]))
|
(FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0]))
|
||||||
} else {
|
} else {
|
||||||
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::astar::{astar, AstarStrategy, PathTracker};
|
use crate::astar::{astar, AstarStrategy, PathTracker};
|
||||||
use crate::draw::DrawException;
|
use crate::draw::DrawException;
|
||||||
use crate::graph::FixedDotIndex;
|
use crate::geometry::FixedDotIndex;
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
|
|
||||||
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||||
|
|
@ -121,12 +121,11 @@ impl Router {
|
||||||
// right.
|
// right.
|
||||||
//self.mesh.triangulate(&self.layout)?;
|
//self.mesh.triangulate(&self.layout)?;
|
||||||
let mut mesh = Mesh::new(&self.layout);
|
let mut mesh = Mesh::new(&self.layout);
|
||||||
mesh.generate(&self.layout)
|
mesh.generate(&self.layout).map_err(|err| RoutingError {
|
||||||
.map_err(|err| RoutingError {
|
from,
|
||||||
from,
|
to,
|
||||||
to,
|
source: err.into(),
|
||||||
source: err.into(),
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let mut tracer = self.tracer(&mesh);
|
let mut tracer = self.tracer(&mesh);
|
||||||
let trace = tracer.start(from, 3.0);
|
let trace = tracer.start(from, 3.0);
|
||||||
|
|
@ -135,7 +134,8 @@ impl Router {
|
||||||
&mesh,
|
&mesh,
|
||||||
from.into(),
|
from.into(),
|
||||||
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
|
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
|
||||||
).ok_or(RoutingError {
|
)
|
||||||
|
.ok_or(RoutingError {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
source: RoutingErrorKind::AStar,
|
source: RoutingErrorKind::AStar,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex},
|
geometry::{Index, LooseBendIndex, LooseDotIndex, LooseSegIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot},
|
primitive::{GetEnds, GetInterior, GetOtherEnd, LooseBend, LooseDot},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use contracts::debug_ensures;
|
use contracts::debug_ensures;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
connectivity::{BandIndex, BandWeight, ConnectivityWeight},
|
||||||
draw::{Draw, DrawException},
|
draw::{Draw, DrawException},
|
||||||
graph::{FixedDotIndex, GetNet, LooseBendIndex},
|
geometry::{FixedDotIndex, GetNet, LooseBendIndex},
|
||||||
guide::{BareHead, Head, SegbendHead},
|
guide::{BareHead, Head, SegbendHead},
|
||||||
layout::{Band, Layout, LayoutException},
|
layout::{Layout, LayoutException},
|
||||||
mesh::{Mesh, VertexIndex},
|
mesh::{Mesh, VertexIndex},
|
||||||
rules::Rules,
|
rules::Rules,
|
||||||
};
|
};
|
||||||
|
|
@ -31,10 +32,12 @@ impl<'a> Tracer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
||||||
let band = self.layout.bands.insert(Band {
|
let band = BandIndex::new(self.layout.connectivity.add_node(ConnectivityWeight::Band(
|
||||||
width,
|
BandWeight {
|
||||||
net: self.layout.primitive(from).net(),
|
width,
|
||||||
});
|
net: self.layout.primitive(from).net(),
|
||||||
|
},
|
||||||
|
)));
|
||||||
Trace {
|
Trace {
|
||||||
path: vec![from.into()],
|
path: vec![from.into()],
|
||||||
head: BareHead { dot: from, band }.into(),
|
head: BareHead { dot: from, band }.into(),
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
|
||||||
index_marker: PhantomData,
|
index_marker: PhantomData,
|
||||||
};
|
};
|
||||||
this.vertex_to_handle
|
this.vertex_to_handle
|
||||||
.resize(layout.graph.node_bound(), None);
|
.resize(layout.geometry.node_bound(), None);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue