mirror of https://codeberg.org/topola/topola.git
graph,primitive: Split the 3 primitives into 7
`Dot` becomes `FixedDot` and `LooseDot`. `Seg` becomes `FixedSeg`, `HalfLooseSeg`, and `FullyLooseSeg`. `Bend` becomes `FixedBend` and `LooseBend`. The fixed variants differ from the loose variants by being unchangeable for the router (though probably will be pushable in some cases, but that's for later). So typically tey're going to be the initial conditions. For now only the fixed variants are used even if actually loose, to split this change into several commits.
This commit is contained in:
parent
2966df6b2c
commit
a2531b078d
22
src/band.rs
22
src/band.rs
|
|
@ -1,22 +1,22 @@
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{DotIndex, Ends, Index, Interior, Label, MakePrimitive, Weight},
|
graph::{DotIndex, Ends, FixedDotIndex, Index, Interior, Label, MakePrimitive, Weight},
|
||||||
primitive::TaggedPrevTaggedNext,
|
primitive::TaggedPrevTaggedNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Band {
|
pub struct Band {
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
interior: Vec<Index>,
|
interior: Vec<Index>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Band {
|
impl Band {
|
||||||
pub fn from_dot_prev(
|
pub fn from_dot_prev(
|
||||||
dot: DotIndex,
|
dot: FixedDotIndex,
|
||||||
graph: &StableDiGraph<Weight, Label, usize>,
|
graph: &StableDiGraph<Weight, Label, usize>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let mut next_index = Index::Dot(dot);
|
let mut next_index: Index = dot.into();
|
||||||
let mut interior = vec![];
|
let mut interior = vec![];
|
||||||
|
|
||||||
while let Some(index) = next_index.primitive(graph).tagged_prev() {
|
while let Some(index) = next_index.primitive(graph).tagged_prev() {
|
||||||
|
|
@ -28,7 +28,7 @@ impl Band {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Self {
|
Some(Self {
|
||||||
from: interior.pop().unwrap().into_dot().unwrap(),
|
from: interior.pop().unwrap().into_fixed_dot().unwrap(),
|
||||||
to: dot,
|
to: dot,
|
||||||
interior,
|
interior,
|
||||||
})
|
})
|
||||||
|
|
@ -36,10 +36,10 @@ impl Band {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_dot_next(
|
pub fn from_dot_next(
|
||||||
dot: DotIndex,
|
dot: FixedDotIndex,
|
||||||
graph: &StableDiGraph<Weight, Label, usize>,
|
graph: &StableDiGraph<Weight, Label, usize>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let mut prev_index = Index::Dot(dot);
|
let mut prev_index: Index = dot.into();
|
||||||
let mut interior = vec![];
|
let mut interior = vec![];
|
||||||
|
|
||||||
while let Some(index) = prev_index.primitive(graph).tagged_next() {
|
while let Some(index) = prev_index.primitive(graph).tagged_next() {
|
||||||
|
|
@ -52,7 +52,7 @@ impl Band {
|
||||||
} else {
|
} else {
|
||||||
Some(Self {
|
Some(Self {
|
||||||
from: dot,
|
from: dot,
|
||||||
to: interior.pop().unwrap().into_dot().unwrap(),
|
to: interior.pop().unwrap().into_fixed_dot().unwrap(),
|
||||||
interior,
|
interior,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +66,8 @@ impl Interior<Index> for Band {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ends<DotIndex, DotIndex> for Band {
|
impl Ends<FixedDotIndex, FixedDotIndex> for Band {
|
||||||
fn ends(&self) -> (DotIndex, DotIndex) {
|
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
(self.from, self.to)
|
(self.from, self.to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
src/bow.rs
53
src/bow.rs
|
|
@ -1,38 +1,41 @@
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
|
|
||||||
use crate::graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight};
|
use crate::graph::{
|
||||||
use crate::primitive::{Bend, Dot, Seg, TaggedPrevTaggedNext};
|
BendIndex, DotIndex, Ends, FixedBendIndex, FixedDotIndex, FixedSegIndex, Index, Interior,
|
||||||
|
Label, SegIndex, Weight,
|
||||||
|
};
|
||||||
|
use crate::primitive::{FixedBend, FixedDot, FixedSeg, TaggedPrevTaggedNext};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Bow {
|
pub struct Bow {
|
||||||
seg1_dot1: DotIndex,
|
seg1_dot1: FixedDotIndex,
|
||||||
seg1: SegIndex,
|
seg1: FixedSegIndex,
|
||||||
seg1_dot2: DotIndex,
|
seg1_dot2: FixedDotIndex,
|
||||||
bend: BendIndex,
|
bend: FixedBendIndex,
|
||||||
seg2_dot1: DotIndex,
|
seg2_dot1: FixedDotIndex,
|
||||||
seg2: SegIndex,
|
seg2: FixedSegIndex,
|
||||||
seg2_dot2: DotIndex,
|
seg2_dot2: FixedDotIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bow {
|
impl Bow {
|
||||||
pub fn from_bend(index: BendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
|
pub fn from_bend(index: FixedBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
|
||||||
let bend = index;
|
let bend = index;
|
||||||
|
|
||||||
let seg1_dot2 = Bend::new(bend, graph).prev().unwrap();
|
let seg1_dot2 = FixedBend::new(bend, graph).prev().unwrap();
|
||||||
let seg1 = Dot::new(seg1_dot2, graph)
|
let seg1 = FixedDot::new(seg1_dot2, graph)
|
||||||
.tagged_prev()
|
.tagged_prev()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_seg()
|
.into_fixed_seg()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let seg1_dot1 = Seg::new(seg1, graph).prev().unwrap();
|
let seg1_dot1 = FixedSeg::new(seg1, graph).prev().unwrap();
|
||||||
|
|
||||||
let seg2_dot1 = Bend::new(bend, graph).next().unwrap();
|
let seg2_dot1 = FixedBend::new(bend, graph).next().unwrap();
|
||||||
let seg2 = Dot::new(seg2_dot1, graph)
|
let seg2 = FixedDot::new(seg2_dot1, graph)
|
||||||
.tagged_next()
|
.tagged_next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_seg()
|
.into_fixed_seg()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let seg2_dot2 = Seg::new(seg2, graph).next().unwrap();
|
let seg2_dot2 = FixedSeg::new(seg2, graph).next().unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
seg1_dot1,
|
seg1_dot1,
|
||||||
|
|
@ -49,17 +52,17 @@ impl Bow {
|
||||||
impl Interior<Index> for Bow {
|
impl Interior<Index> for Bow {
|
||||||
fn interior(&self) -> Vec<Index> {
|
fn interior(&self) -> Vec<Index> {
|
||||||
vec![
|
vec![
|
||||||
Index::Seg(self.seg1),
|
self.seg1.into(),
|
||||||
Index::Dot(self.seg1_dot2),
|
self.seg1_dot2.into(),
|
||||||
Index::Bend(self.bend),
|
self.bend.into(),
|
||||||
Index::Dot(self.seg2_dot1),
|
self.seg2_dot1.into(),
|
||||||
Index::Seg(self.seg2),
|
self.seg2.into(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ends<DotIndex, DotIndex> for Bow {
|
impl Ends<FixedDotIndex, FixedDotIndex> for Bow {
|
||||||
fn ends(&self) -> (DotIndex, DotIndex) {
|
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
(self.seg1_dot1, self.seg2_dot2)
|
(self.seg1_dot1, self.seg2_dot2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
61
src/draw.rs
61
src/draw.rs
|
|
@ -3,7 +3,10 @@ use enum_dispatch::enum_dispatch;
|
||||||
use geo::{EuclideanLength, Point};
|
use geo::{EuclideanLength, Point};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, SegIndex, SegWeight},
|
graph::{
|
||||||
|
BendIndex, DotIndex, Ends, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
|
||||||
|
FixedSegIndex, FixedSegWeight, Index, SegIndex,
|
||||||
|
},
|
||||||
guide::Guide,
|
guide::Guide,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
math::Circle,
|
math::Circle,
|
||||||
|
|
@ -14,7 +17,7 @@ use crate::{
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait HeadTrait {
|
pub trait HeadTrait {
|
||||||
fn dot(&self) -> DotIndex;
|
fn dot(&self) -> FixedDotIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(HeadTrait)]
|
#[enum_dispatch(HeadTrait)]
|
||||||
|
|
@ -26,23 +29,23 @@ pub enum Head {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct BareHead {
|
pub struct BareHead {
|
||||||
pub dot: DotIndex,
|
pub dot: FixedDotIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeadTrait for BareHead {
|
impl HeadTrait for BareHead {
|
||||||
fn dot(&self) -> DotIndex {
|
fn dot(&self) -> FixedDotIndex {
|
||||||
self.dot
|
self.dot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SegbendHead {
|
pub struct SegbendHead {
|
||||||
pub dot: DotIndex,
|
pub dot: FixedDotIndex,
|
||||||
pub segbend: Segbend,
|
pub segbend: Segbend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeadTrait for SegbendHead {
|
impl HeadTrait for SegbendHead {
|
||||||
fn dot(&self) -> DotIndex {
|
fn dot(&self) -> FixedDotIndex {
|
||||||
self.dot
|
self.dot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,13 +60,13 @@ impl<'a> Draw<'a> {
|
||||||
Self { layout, rules }
|
Self { layout, rules }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self, from: DotIndex) -> Head {
|
pub fn start(&mut self, from: FixedDotIndex) -> Head {
|
||||||
self.prev_head(from)
|
self.prev_head(from)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
||||||
pub fn finish(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> {
|
pub fn finish(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
|
||||||
if let Some(bend) = self.layout.primitive(into).bend() {
|
if let Some(bend) = self.layout.primitive(into).bend() {
|
||||||
self.finish_in_bend(head, bend, into, width)?;
|
self.finish_in_bend(head, bend, into, width)?;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -74,7 +77,7 @@ impl<'a> Draw<'a> {
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))]
|
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))]
|
||||||
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
||||||
fn finish_in_dot(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> {
|
fn finish_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
|
||||||
let tangent = self
|
let tangent = self
|
||||||
.guide(&Default::default())
|
.guide(&Default::default())
|
||||||
.head_into_dot_segment(&head, into, width)?;
|
.head_into_dot_segment(&head, into, width)?;
|
||||||
|
|
@ -82,7 +85,7 @@ impl<'a> Draw<'a> {
|
||||||
|
|
||||||
let net = self.layout.primitive(head.dot()).weight().net;
|
let net = self.layout.primitive(head.dot()).weight().net;
|
||||||
self.layout
|
self.layout
|
||||||
.add_seg(head.dot(), into, SegWeight { net, width })?;
|
.add_seg(head.dot(), into, FixedSegWeight { net, width })?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,8 +94,8 @@ impl<'a> Draw<'a> {
|
||||||
fn finish_in_bend(
|
fn finish_in_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
into_bend: BendIndex,
|
into_bend: FixedBendIndex,
|
||||||
into: DotIndex,
|
into: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let to_head = self.next_head(into);
|
let to_head = self.next_head(into);
|
||||||
|
|
@ -106,7 +109,7 @@ impl<'a> Draw<'a> {
|
||||||
|
|
||||||
let net = self.layout.primitive(head.dot()).weight().net;
|
let net = self.layout.primitive(head.dot()).weight().net;
|
||||||
self.layout
|
self.layout
|
||||||
.add_seg(head.dot(), into, SegWeight { net, width })?;
|
.add_seg(head.dot(), into, FixedSegWeight { net, width })?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +118,7 @@ impl<'a> Draw<'a> {
|
||||||
pub fn segbend_around_dot(
|
pub fn segbend_around_dot(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: DotIndex,
|
around: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let mut tangents = self
|
let mut tangents = self
|
||||||
|
|
@ -134,7 +137,7 @@ impl<'a> Draw<'a> {
|
||||||
.find_map(|(i, tangent)| {
|
.find_map(|(i, tangent)| {
|
||||||
self.segbend_around(
|
self.segbend_around(
|
||||||
head,
|
head,
|
||||||
Index::Dot(around),
|
around.into(),
|
||||||
tangent.start_point(),
|
tangent.start_point(),
|
||||||
tangent.end_point(),
|
tangent.end_point(),
|
||||||
dirs[i],
|
dirs[i],
|
||||||
|
|
@ -150,7 +153,7 @@ impl<'a> Draw<'a> {
|
||||||
pub fn segbend_around_bend(
|
pub fn segbend_around_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: BendIndex,
|
around: FixedBendIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let mut tangents = self
|
let mut tangents = self
|
||||||
|
|
@ -169,7 +172,7 @@ impl<'a> Draw<'a> {
|
||||||
.find_map(|(i, tangent)| {
|
.find_map(|(i, tangent)| {
|
||||||
self.segbend_around(
|
self.segbend_around(
|
||||||
head,
|
head,
|
||||||
Index::Bend(around),
|
around.into(),
|
||||||
tangent.start_point(),
|
tangent.start_point(),
|
||||||
tangent.end_point(),
|
tangent.end_point(),
|
||||||
dirs[i],
|
dirs[i],
|
||||||
|
|
@ -254,9 +257,9 @@ impl<'a> Draw<'a> {
|
||||||
|
|
||||||
let bend = self
|
let bend = self
|
||||||
.layout
|
.layout
|
||||||
.add_bend(head.dot, bend_to, around, BendWeight { net, cw })
|
.add_bend(head.dot, bend_to, around, FixedBendWeight { net, cw })
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
self.layout.remove(Index::Dot(bend_to));
|
self.layout.remove(bend_to.into());
|
||||||
self.undo_seg(head, seg);
|
self.undo_seg(head, seg);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -274,7 +277,7 @@ impl<'a> Draw<'a> {
|
||||||
.prev()
|
.prev()
|
||||||
.map(|prev_dot| {
|
.map(|prev_dot| {
|
||||||
self.layout.remove_interior(&head.segbend);
|
self.layout.remove_interior(&head.segbend);
|
||||||
self.layout.remove(Index::Dot(head.dot()));
|
self.layout.remove(head.dot().into());
|
||||||
|
|
||||||
self.prev_head(prev_dot)
|
self.prev_head(prev_dot)
|
||||||
})
|
})
|
||||||
|
|
@ -283,9 +286,9 @@ impl<'a> Draw<'a> {
|
||||||
#[debug_requires(width <= self.layout.primitive(head.dot()).weight().circle.r * 2.0)]
|
#[debug_requires(width <= self.layout.primitive(head.dot()).weight().circle.r * 2.0)]
|
||||||
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 2))]
|
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 2))]
|
||||||
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
||||||
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(BareHead, SegIndex), ()> {
|
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(BareHead, FixedSegIndex), ()> {
|
||||||
let net = self.layout.primitive(head.dot()).weight().net;
|
let net = self.layout.primitive(head.dot()).weight().net;
|
||||||
let to_index = self.layout.add_dot(DotWeight {
|
let to_index = self.layout.add_dot(FixedDotWeight {
|
||||||
net,
|
net,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: to,
|
pos: to,
|
||||||
|
|
@ -294,21 +297,21 @@ impl<'a> Draw<'a> {
|
||||||
})?;
|
})?;
|
||||||
let seg = self
|
let seg = self
|
||||||
.layout
|
.layout
|
||||||
.add_seg(head.dot(), to_index, SegWeight { net, width })
|
.add_seg(head.dot(), to_index, FixedSegWeight { net, width })
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
self.layout.remove(Index::Dot(to_index));
|
self.layout.remove(to_index.into());
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
Ok((BareHead { dot: to_index }, seg))
|
Ok((BareHead { dot: to_index }, seg))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))]
|
#[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))]
|
||||||
fn undo_seg(&mut self, head: BareHead, seg: SegIndex) {
|
fn undo_seg(&mut self, head: BareHead, seg: FixedSegIndex) {
|
||||||
self.layout.remove(Index::Seg(seg));
|
self.layout.remove(seg.into());
|
||||||
self.layout.remove(Index::Dot(head.dot));
|
self.layout.remove(head.dot.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prev_head(&self, dot: DotIndex) -> Head {
|
fn prev_head(&self, dot: FixedDotIndex) -> Head {
|
||||||
if let Some(segbend) = self.layout.prev_segbend(dot) {
|
if let Some(segbend) = self.layout.prev_segbend(dot) {
|
||||||
Head::from(SegbendHead { dot, segbend })
|
Head::from(SegbendHead { dot, segbend })
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -316,7 +319,7 @@ impl<'a> Draw<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_head(&self, dot: DotIndex) -> Head {
|
fn next_head(&self, dot: FixedDotIndex) -> Head {
|
||||||
if let Some(segbend) = self.layout.next_segbend(dot) {
|
if let Some(segbend) = self.layout.next_segbend(dot) {
|
||||||
Head::from(SegbendHead { dot, segbend })
|
Head::from(SegbendHead { dot, segbend })
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
113
src/graph.rs
113
src/graph.rs
|
|
@ -26,14 +26,6 @@ pub trait GetNet {
|
||||||
fn net(&self) -> i64;
|
fn net(&self) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(Retag, GetNet)]
|
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
|
||||||
pub enum Weight {
|
|
||||||
Dot(DotWeight),
|
|
||||||
Seg(SegWeight),
|
|
||||||
Bend(BendWeight),
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_type {
|
macro_rules! impl_type {
|
||||||
($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => {
|
($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => {
|
||||||
impl Retag for $weight_struct_name {
|
impl Retag for $weight_struct_name {
|
||||||
|
|
@ -64,29 +56,114 @@ macro_rules! impl_type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(Retag, GetNet)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum Weight {
|
||||||
|
FixedDot(FixedDotWeight),
|
||||||
|
LooseDot(LooseDotWeight),
|
||||||
|
FixedSeg(FixedSegWeight),
|
||||||
|
HalfLooseSeg(HalfLooseSegWeight),
|
||||||
|
FullyLooseSeg(FullyLooseSegWeight),
|
||||||
|
FixedBend(FixedBendWeight),
|
||||||
|
LooseBend(LooseBendWeight),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum Index {
|
||||||
|
FixedDot(FixedDotIndex),
|
||||||
|
LooseDot(LooseDotIndex),
|
||||||
|
FixedSeg(FixedSegIndex),
|
||||||
|
HalfLooseSeg(HalfLooseSegIndex),
|
||||||
|
FullyLooseSeg(FullyLooseSegIndex),
|
||||||
|
FixedBend(FixedBendIndex),
|
||||||
|
LooseBend(LooseBendIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum DotIndex {
|
||||||
|
Fixed(FixedDotIndex),
|
||||||
|
Loose(LooseDotIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum SegIndex {
|
||||||
|
Fixed(FixedSegIndex),
|
||||||
|
HalfLoose(HalfLooseSegIndex),
|
||||||
|
FullyLoose(FullyLooseSegIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum LooseSegIndex {
|
||||||
|
Half(HalfLooseSegIndex),
|
||||||
|
Fully(FullyLooseSegIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum BendIndex {
|
||||||
|
Fixed(FixedBendIndex),
|
||||||
|
Loose(LooseBendIndex),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct DotWeight {
|
pub struct FixedDotWeight {
|
||||||
pub net: i64,
|
pub net: i64,
|
||||||
pub circle: Circle,
|
pub circle: Circle,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(DotWeight, Dot, DotIndex);
|
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct SegWeight {
|
pub struct LooseDotWeight {
|
||||||
|
pub net: i64,
|
||||||
|
pub circle: Circle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct FixedSegWeight {
|
||||||
pub net: i64,
|
pub net: i64,
|
||||||
pub width: f64,
|
pub width: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(SegWeight, Seg, SegIndex);
|
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct BendWeight {
|
pub struct HalfLooseSegWeight {
|
||||||
|
pub net: i64,
|
||||||
|
pub width: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct FullyLooseSegWeight {
|
||||||
|
pub net: i64,
|
||||||
|
pub width: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct FixedBendWeight {
|
||||||
pub net: i64,
|
pub net: i64,
|
||||||
pub cw: bool,
|
pub cw: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(BendWeight, Bend, BendIndex);
|
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct LooseBendWeight {
|
||||||
|
pub net: i64,
|
||||||
|
pub cw: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex);
|
||||||
|
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
pub enum Label {
|
pub enum Label {
|
||||||
|
|
@ -105,14 +182,6 @@ pub trait MakePrimitive {
|
||||||
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a>;
|
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
|
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
|
||||||
pub enum Index {
|
|
||||||
Dot(DotIndex),
|
|
||||||
Seg(SegIndex),
|
|
||||||
Bend(BendIndex),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct GenericIndex<W> {
|
pub struct GenericIndex<W> {
|
||||||
node_index: NodeIndex<usize>,
|
node_index: NodeIndex<usize>,
|
||||||
|
|
|
||||||
16
src/guide.rs
16
src/guide.rs
|
|
@ -2,7 +2,7 @@ use geo::Line;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{Head, HeadTrait},
|
draw::{Head, HeadTrait},
|
||||||
graph::{BendIndex, DotIndex},
|
graph::{FixedBendIndex, FixedDotIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
math::{self, Circle},
|
math::{self, Circle},
|
||||||
primitive::{GetWeight, MakeShape},
|
primitive::{GetWeight, MakeShape},
|
||||||
|
|
@ -27,7 +27,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
pub fn head_into_dot_segment(
|
pub fn head_into_dot_segment(
|
||||||
&self,
|
&self,
|
||||||
head: &Head,
|
head: &Head,
|
||||||
into: DotIndex,
|
into: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Line, ()> {
|
) -> Result<Line, ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
|
|
@ -43,7 +43,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
pub fn head_around_dot_segments(
|
pub fn head_around_dot_segments(
|
||||||
&self,
|
&self,
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: DotIndex,
|
around: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<(Line, Line), ()> {
|
) -> Result<(Line, Line), ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
|
|
@ -58,7 +58,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
pub fn head_around_dot_segment(
|
pub fn head_around_dot_segment(
|
||||||
&self,
|
&self,
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: DotIndex,
|
around: FixedDotIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Line, ()> {
|
) -> Result<Line, ()> {
|
||||||
|
|
@ -72,7 +72,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
pub fn head_around_bend_segments(
|
pub fn head_around_bend_segments(
|
||||||
&self,
|
&self,
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: BendIndex,
|
around: FixedBendIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<(Line, Line), ()> {
|
) -> Result<(Line, Line), ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
|
|
@ -87,7 +87,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
pub fn head_around_bend_segment(
|
pub fn head_around_bend_segment(
|
||||||
&self,
|
&self,
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: BendIndex,
|
around: FixedBendIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Line, ()> {
|
) -> Result<Line, ()> {
|
||||||
|
|
@ -132,7 +132,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bend_circle(&self, bend: BendIndex, _width: f64) -> Circle {
|
fn bend_circle(&self, bend: FixedBendIndex, _width: f64) -> Circle {
|
||||||
let mut circle = self
|
let mut circle = self
|
||||||
.layout
|
.layout
|
||||||
.primitive(bend)
|
.primitive(bend)
|
||||||
|
|
@ -144,7 +144,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
circle
|
circle
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dot_circle(&self, dot: DotIndex, width: f64) -> Circle {
|
fn dot_circle(&self, dot: FixedDotIndex, width: f64) -> Circle {
|
||||||
let circle = self.layout.primitive(dot).weight().circle;
|
let circle = self.layout.primitive(dot).weight().circle;
|
||||||
Circle {
|
Circle {
|
||||||
pos: circle.pos,
|
pos: circle.pos,
|
||||||
|
|
|
||||||
139
src/layout.rs
139
src/layout.rs
|
|
@ -9,8 +9,9 @@ use rstar::{RTree, RTreeObject};
|
||||||
use crate::band::Band;
|
use crate::band::Band;
|
||||||
use crate::bow::Bow;
|
use crate::bow::Bow;
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label,
|
BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
|
||||||
MakePrimitive, Retag, SegIndex, SegWeight, Weight,
|
FixedSegIndex, FixedSegWeight, GenericIndex, GetNodeIndex, Index, Interior, Label,
|
||||||
|
MakePrimitive, Retag, SegIndex, Weight,
|
||||||
};
|
};
|
||||||
use crate::primitive::{
|
use crate::primitive::{
|
||||||
GenericPrimitive, GetConnectable, GetWeight, MakeShape, TaggedPrevTaggedNext,
|
GenericPrimitive, GetConnectable, GetWeight, MakeShape, TaggedPrevTaggedNext,
|
||||||
|
|
@ -37,14 +38,22 @@ impl Layout {
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - path.interior().len()))]
|
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - path.interior().len()))]
|
||||||
pub fn remove_interior(&mut self, path: &impl Interior<Index>) {
|
pub fn remove_interior(&mut self, path: &impl Interior<Index>) {
|
||||||
for index in path.interior().into_iter().filter(|index| !index.is_dot()) {
|
for index in path
|
||||||
|
.interior()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|index| !index.is_fixed_dot())
|
||||||
|
{
|
||||||
self.remove(index);
|
self.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must remove the dots only after the segs and bends because we need dots to calculate
|
// We must remove the dots only after the segs and bends because we need dots to calculate
|
||||||
// the shapes, which we need to remove the segs and bends from the R-tree.
|
// the shapes, which we need to remove the segs and bends from the R-tree.
|
||||||
|
|
||||||
for index in path.interior().into_iter().filter(|index| index.is_dot()) {
|
for index in path
|
||||||
|
.interior()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|index| index.is_fixed_dot())
|
||||||
|
{
|
||||||
self.remove(index);
|
self.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,11 +68,11 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||||
pub fn add_dot(&mut self, weight: DotWeight) -> Result<DotIndex, ()> {
|
pub fn add_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> {
|
||||||
let dot = DotIndex::new(self.graph.add_node(Weight::Dot(weight)));
|
let dot = FixedDotIndex::new(self.graph.add_node(Weight::FixedDot(weight)));
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Dot(dot));
|
self.insert_into_rtree(dot.into());
|
||||||
self.fail_and_remove_if_collides_except(Index::Dot(dot), &[])?;
|
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
|
||||||
|
|
||||||
Ok(dot)
|
Ok(dot)
|
||||||
}
|
}
|
||||||
|
|
@ -72,30 +81,30 @@ impl Layout {
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||||
pub fn add_seg(
|
pub fn add_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
weight: SegWeight,
|
weight: FixedSegWeight,
|
||||||
) -> Result<SegIndex, ()> {
|
) -> Result<FixedSegIndex, ()> {
|
||||||
let seg = SegIndex::new(self.graph.add_node(Weight::Seg(weight)));
|
let seg = FixedSegIndex::new(self.graph.add_node(Weight::FixedSeg(weight)));
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(from.node_index(), seg.node_index(), Label::End);
|
.add_edge(from.node_index(), seg.node_index(), Label::End);
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(seg.node_index(), to.node_index(), Label::End);
|
.add_edge(seg.node_index(), to.node_index(), Label::End);
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Seg(seg));
|
self.insert_into_rtree(seg.into());
|
||||||
self.fail_and_remove_if_collides_except(Index::Seg(seg), &[])?;
|
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(from.node_index())
|
.node_weight_mut(from.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_dot_mut()
|
.as_fixed_dot_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.net = weight.net;
|
.net = weight.net;
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(to.node_index())
|
.node_weight_mut(to.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_dot_mut()
|
.as_fixed_dot_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.net = weight.net;
|
.net = weight.net;
|
||||||
|
|
||||||
|
|
@ -106,15 +115,16 @@ impl Layout {
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||||
pub fn add_bend(
|
pub fn add_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
around: Index,
|
around: Index,
|
||||||
weight: BendWeight,
|
weight: FixedBendWeight,
|
||||||
) -> Result<BendIndex, ()> {
|
) -> Result<FixedBendIndex, ()> {
|
||||||
match around {
|
match around {
|
||||||
Index::Dot(core) => self.add_core_bend(from, to, core, weight),
|
Index::FixedDot(core) => self.add_core_bend(from, to, core, weight),
|
||||||
Index::Bend(around) => self.add_outer_bend(from, to, around, weight),
|
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||||
Index::Seg(..) => unreachable!(),
|
Index::FixedSeg(..) => unreachable!(),
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,12 +134,12 @@ impl Layout {
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
pub fn add_core_bend(
|
pub fn add_core_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
core: DotIndex,
|
core: FixedDotIndex,
|
||||||
weight: BendWeight,
|
weight: FixedBendWeight,
|
||||||
) -> Result<BendIndex, ()> {
|
) -> Result<FixedBendIndex, ()> {
|
||||||
let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight)));
|
let bend = FixedBendIndex::new(self.graph.add_node(Weight::FixedBend(weight)));
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(from.node_index(), bend.node_index(), Label::End);
|
.add_edge(from.node_index(), bend.node_index(), Label::End);
|
||||||
|
|
@ -138,8 +148,8 @@ impl Layout {
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(bend.node_index(), core.node_index(), Label::Core);
|
.add_edge(bend.node_index(), core.node_index(), Label::Core);
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Bend(bend));
|
self.insert_into_rtree(bend.into());
|
||||||
self.fail_and_remove_if_collides_except(Index::Bend(bend), &[Index::Dot(core)])?;
|
self.fail_and_remove_if_collides_except(bend.into(), &[core.into()])?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,11 +159,11 @@ impl Layout {
|
||||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
pub fn add_outer_bend(
|
pub fn add_outer_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
inner: BendIndex,
|
inner: FixedBendIndex,
|
||||||
weight: BendWeight,
|
weight: FixedBendWeight,
|
||||||
) -> Result<BendIndex, ()> {
|
) -> Result<FixedBendIndex, ()> {
|
||||||
let core = *self
|
let core = *self
|
||||||
.graph
|
.graph
|
||||||
.neighbors(inner.node_index())
|
.neighbors(inner.node_index())
|
||||||
|
|
@ -163,12 +173,12 @@ impl Layout {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_core()
|
.is_core()
|
||||||
})
|
})
|
||||||
.map(|ni| DotIndex::new(ni))
|
.map(|ni| FixedDotIndex::new(ni))
|
||||||
.collect::<Vec<DotIndex>>()
|
.collect::<Vec<FixedDotIndex>>()
|
||||||
.first()
|
.first()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight)));
|
let bend = FixedBendIndex::new(self.graph.add_node(Weight::FixedBend(weight)));
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(from.node_index(), bend.node_index(), Label::End);
|
.add_edge(from.node_index(), bend.node_index(), Label::End);
|
||||||
|
|
@ -179,16 +189,16 @@ impl Layout {
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
|
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Bend(bend));
|
self.insert_into_rtree(bend.into());
|
||||||
self.fail_and_remove_if_collides_except(Index::Bend(bend), &[Index::Dot(core)])?;
|
self.fail_and_remove_if_collides_except(bend.into(), &[core.into()])?;
|
||||||
Ok(bend)
|
Ok(bend)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[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.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))]
|
||||||
pub fn reattach_bend(&mut self, bend: BendIndex, inner: BendIndex) {
|
pub fn reattach_bend(&mut self, bend: FixedBendIndex, inner: FixedBendIndex) {
|
||||||
self.remove_from_rtree(Index::Bend(bend));
|
self.remove_from_rtree(bend.into());
|
||||||
|
|
||||||
if let Some(old_inner_edge) = self
|
if let Some(old_inner_edge) = self
|
||||||
.graph
|
.graph
|
||||||
|
|
@ -201,46 +211,46 @@ impl Layout {
|
||||||
|
|
||||||
self.graph
|
self.graph
|
||||||
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
|
.add_edge(inner.node_index(), bend.node_index(), Label::Outer);
|
||||||
self.insert_into_rtree(Index::Bend(bend));
|
self.insert_into_rtree(bend.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[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.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
pub fn flip_bend(&mut self, bend: BendIndex) {
|
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
|
||||||
self.remove_from_rtree(Index::Bend(bend));
|
self.remove_from_rtree(bend.into());
|
||||||
let cw = self
|
let cw = self
|
||||||
.graph
|
.graph
|
||||||
.node_weight(bend.node_index())
|
.node_weight(bend.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_bend()
|
.into_fixed_bend()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.cw;
|
.cw;
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(bend.node_index())
|
.node_weight_mut(bend.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bend_mut()
|
.as_fixed_bend_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.cw = !cw;
|
.cw = !cw;
|
||||||
self.insert_into_rtree(Index::Bend(bend));
|
self.insert_into_rtree(bend.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bow(&self, bend: BendIndex) -> Bow {
|
pub fn bow(&self, bend: FixedBendIndex) -> Bow {
|
||||||
Bow::from_bend(bend, &self.graph)
|
Bow::from_bend(bend, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
pub fn prev_segbend(&self, dot: FixedDotIndex) -> Option<Segbend> {
|
||||||
Segbend::from_dot_prev(dot, &self.graph)
|
Segbend::from_dot_prev(dot, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
pub fn next_segbend(&self, dot: FixedDotIndex) -> Option<Segbend> {
|
||||||
Segbend::from_dot_next(dot, &self.graph)
|
Segbend::from_dot_next(dot, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev_band(&self, to: DotIndex) -> Option<Band> {
|
pub fn prev_band(&self, to: FixedDotIndex) -> Option<Band> {
|
||||||
Band::from_dot_prev(to, &self.graph)
|
Band::from_dot_prev(to, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_band(&self, from: DotIndex) -> Option<Band> {
|
pub fn next_band(&self, from: FixedDotIndex) -> Option<Band> {
|
||||||
Band::from_dot_next(from, &self.graph)
|
Band::from_dot_next(from, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,8 +269,9 @@ impl Layout {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
|
pub fn dots(&self) -> impl Iterator<Item = FixedDotIndex> + '_ {
|
||||||
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
|
self.nodes()
|
||||||
|
.filter_map(|ni| ni.as_fixed_dot().map(|di| *di))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||||
|
|
@ -280,26 +291,26 @@ impl Layout {
|
||||||
impl Layout {
|
impl Layout {
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[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.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> {
|
pub fn move_dot(&mut self, dot: FixedDotIndex, to: Point) -> Result<(), ()> {
|
||||||
self.primitive(dot)
|
self.primitive(dot)
|
||||||
.tagged_prev()
|
.tagged_prev()
|
||||||
.map(|prev| self.remove_from_rtree(prev));
|
.map(|prev| self.remove_from_rtree(prev));
|
||||||
self.primitive(dot)
|
self.primitive(dot)
|
||||||
.tagged_next()
|
.tagged_next()
|
||||||
.map(|next| self.remove_from_rtree(next));
|
.map(|next| self.remove_from_rtree(next));
|
||||||
self.remove_from_rtree(Index::Dot(dot));
|
self.remove_from_rtree(dot.into());
|
||||||
|
|
||||||
let mut dot_weight = self.primitive(dot).weight();
|
let mut dot_weight = self.primitive(dot).weight();
|
||||||
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::Dot(dot_weight);
|
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(dot_weight);
|
||||||
|
|
||||||
if let Some(..) = self.detect_collision_except(Index::Dot(dot), &[]) {
|
if let Some(..) = self.detect_collision_except(dot.into(), &[]) {
|
||||||
// Restore original state.
|
// Restore original state.
|
||||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::Dot(old_weight);
|
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(old_weight);
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Dot(dot));
|
self.insert_into_rtree(dot.into());
|
||||||
self.primitive(dot)
|
self.primitive(dot)
|
||||||
.tagged_prev()
|
.tagged_prev()
|
||||||
.map(|prev| self.insert_into_rtree(prev));
|
.map(|prev| self.insert_into_rtree(prev));
|
||||||
|
|
@ -309,7 +320,7 @@ impl Layout {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.insert_into_rtree(Index::Dot(dot));
|
self.insert_into_rtree(dot.into());
|
||||||
self.primitive(dot)
|
self.primitive(dot)
|
||||||
.tagged_prev()
|
.tagged_prev()
|
||||||
.map(|prev| self.insert_into_rtree(prev));
|
.map(|prev| self.insert_into_rtree(prev));
|
||||||
|
|
|
||||||
84
src/main.rs
84
src/main.rs
|
|
@ -2,8 +2,8 @@ extern crate sdl2;
|
||||||
|
|
||||||
macro_rules! dbg_dot {
|
macro_rules! dbg_dot {
|
||||||
($graph:expr) => {
|
($graph:expr) => {
|
||||||
use petgraph::dot::Dot;
|
use petgraph::FixedDot::FixedDot;
|
||||||
println!("{:?}", Dot::new(&$graph));
|
println!("{:?}", FixedDot::new(&$graph));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ mod shape;
|
||||||
mod tracer;
|
mod tracer;
|
||||||
|
|
||||||
use geo::point;
|
use geo::point;
|
||||||
use graph::{DotIndex, SegWeight};
|
use graph::{FixedDotIndex, FixedSegWeight};
|
||||||
use layout::Layout;
|
use layout::Layout;
|
||||||
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
|
|
@ -43,7 +43,7 @@ use shape::Shape;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracer::{Trace, Tracer};
|
use tracer::{Trace, Tracer};
|
||||||
|
|
||||||
use crate::graph::DotWeight;
|
use crate::graph::FixedDotWeight;
|
||||||
use crate::math::Circle;
|
use crate::math::Circle;
|
||||||
use crate::router::Router;
|
use crate::router::Router;
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ fn main() {
|
||||||
|
|
||||||
let dot1 = router
|
let dot1 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 1,
|
net: 1,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (100.5, 400.5).into(),
|
pos: (100.5, 400.5).into(),
|
||||||
|
|
@ -145,7 +145,7 @@ fn main() {
|
||||||
|
|
||||||
let dot2 = router
|
let dot2 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 1,
|
net: 1,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (100.5, 500.5).into(),
|
pos: (100.5, 500.5).into(),
|
||||||
|
|
@ -156,7 +156,7 @@ fn main() {
|
||||||
|
|
||||||
let dot_end = router
|
let dot_end = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 1,
|
net: 1,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (470.5, 350.5).into(),
|
pos: (470.5, 350.5).into(),
|
||||||
|
|
@ -167,7 +167,7 @@ fn main() {
|
||||||
|
|
||||||
let dot1_1 = router
|
let dot1_1 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (200.5, 200.5).into(),
|
pos: (200.5, 200.5).into(),
|
||||||
|
|
@ -178,7 +178,7 @@ fn main() {
|
||||||
|
|
||||||
let dot2_1 = router
|
let dot2_1 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (200.5, 500.5).into(),
|
pos: (200.5, 500.5).into(),
|
||||||
|
|
@ -190,7 +190,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot1_1,
|
dot1_1,
|
||||||
dot2_1,
|
dot2_1,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -198,7 +198,7 @@ fn main() {
|
||||||
|
|
||||||
let dot2_2 = router
|
let dot2_2 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (600.5, 500.5).into(),
|
pos: (600.5, 500.5).into(),
|
||||||
|
|
@ -210,7 +210,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot2_1,
|
dot2_1,
|
||||||
dot2_2,
|
dot2_2,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -218,7 +218,7 @@ fn main() {
|
||||||
|
|
||||||
let dot3 = router
|
let dot3 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (400.5, 200.5).into(),
|
pos: (400.5, 200.5).into(),
|
||||||
|
|
@ -229,7 +229,7 @@ fn main() {
|
||||||
|
|
||||||
let dot4 = router
|
let dot4 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (400.5, 400.5).into(),
|
pos: (400.5, 400.5).into(),
|
||||||
|
|
@ -241,7 +241,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot3,
|
dot3,
|
||||||
dot4,
|
dot4,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -249,7 +249,7 @@ fn main() {
|
||||||
|
|
||||||
let dot5 = router
|
let dot5 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (530.5, 400.5).into(),
|
pos: (530.5, 400.5).into(),
|
||||||
|
|
@ -261,7 +261,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot4,
|
dot4,
|
||||||
dot5,
|
dot5,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -269,7 +269,7 @@ fn main() {
|
||||||
|
|
||||||
let dot1_2 = router
|
let dot1_2 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (600.5, 200.5).into(),
|
pos: (600.5, 200.5).into(),
|
||||||
|
|
@ -281,7 +281,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot3,
|
dot3,
|
||||||
dot1_2,
|
dot1_2,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -290,7 +290,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot1_2,
|
dot1_2,
|
||||||
dot2_2,
|
dot2_2,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -298,7 +298,7 @@ fn main() {
|
||||||
|
|
||||||
let dot6 = router
|
let dot6 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (530.5, 300.5).into(),
|
pos: (530.5, 300.5).into(),
|
||||||
|
|
@ -310,7 +310,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot5,
|
dot5,
|
||||||
dot6,
|
dot6,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -318,7 +318,7 @@ fn main() {
|
||||||
|
|
||||||
/*let dot7 = router
|
/*let dot7 = router
|
||||||
.layout
|
.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: 2,
|
net: 2,
|
||||||
circle: Circle {
|
circle: Circle {
|
||||||
pos: (400.5, 440.5).into(),
|
pos: (400.5, 440.5).into(),
|
||||||
|
|
@ -330,7 +330,7 @@ fn main() {
|
||||||
let _ = router.layout.add_seg(
|
let _ = router.layout.add_seg(
|
||||||
dot4,
|
dot4,
|
||||||
dot7,
|
dot7,
|
||||||
SegWeight {
|
FixedSegWeight {
|
||||||
net: 20,
|
net: 20,
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
},
|
},
|
||||||
|
|
@ -402,8 +402,8 @@ fn render_times(
|
||||||
event_pump: &mut EventPump,
|
event_pump: &mut EventPump,
|
||||||
canvas: &mut Canvas<Window>,
|
canvas: &mut Canvas<Window>,
|
||||||
mut router_or_layout: RouterOrLayout,
|
mut router_or_layout: RouterOrLayout,
|
||||||
from: Option<DotIndex>,
|
from: Option<FixedDotIndex>,
|
||||||
follower: Option<DotIndex>,
|
follower: Option<FixedDotIndex>,
|
||||||
mut mesh: Option<Mesh>,
|
mut mesh: Option<Mesh>,
|
||||||
path: &[VertexIndex],
|
path: &[VertexIndex],
|
||||||
times: i64,
|
times: i64,
|
||||||
|
|
@ -453,27 +453,27 @@ fn render_times(
|
||||||
//let result = panic::catch_unwind(|| {
|
//let result = panic::catch_unwind(|| {
|
||||||
for shape in layout.shapes() {
|
for shape in layout.shapes() {
|
||||||
match shape {
|
match shape {
|
||||||
Shape::Dot(dot) => {
|
Shape::Dot(FixedDot) => {
|
||||||
let _ = canvas.filled_circle(
|
let _ = canvas.filled_circle(
|
||||||
dot.c.pos.x() as i16,
|
FixedDot.c.pos.x() as i16,
|
||||||
dot.c.pos.y() as i16,
|
FixedDot.c.pos.y() as i16,
|
||||||
dot.c.r as i16,
|
FixedDot.c.r as i16,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Shape::Seg(seg) => {
|
Shape::Seg(FixedSeg) => {
|
||||||
let _ = canvas.thick_line(
|
let _ = canvas.thick_line(
|
||||||
seg.from.x() as i16,
|
FixedSeg.from.x() as i16,
|
||||||
seg.from.y() as i16,
|
FixedSeg.from.y() as i16,
|
||||||
seg.to.x() as i16,
|
FixedSeg.to.x() as i16,
|
||||||
seg.to.y() as i16,
|
FixedSeg.to.y() as i16,
|
||||||
seg.width as u8,
|
FixedSeg.width as u8,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Shape::Bend(bend) => {
|
Shape::Bend(FixedBend) => {
|
||||||
let delta1 = bend.from - bend.c.pos;
|
let delta1 = FixedBend.from - FixedBend.c.pos;
|
||||||
let delta2 = bend.to - bend.c.pos;
|
let delta2 = FixedBend.to - FixedBend.c.pos;
|
||||||
|
|
||||||
let angle1 = delta1.y().atan2(delta1.x());
|
let angle1 = delta1.y().atan2(delta1.x());
|
||||||
let angle2 = delta2.y().atan2(delta2.x());
|
let angle2 = delta2.y().atan2(delta2.x());
|
||||||
|
|
@ -482,10 +482,10 @@ fn render_times(
|
||||||
let _ = canvas.arc(
|
let _ = canvas.arc(
|
||||||
//around_circle.pos.x() as i16,
|
//around_circle.pos.x() as i16,
|
||||||
//around_circle.pos.y() as i16,
|
//around_circle.pos.y() as i16,
|
||||||
bend.c.pos.x() as i16,
|
FixedBend.c.pos.x() as i16,
|
||||||
bend.c.pos.y() as i16,
|
FixedBend.c.pos.y() as i16,
|
||||||
//(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16,
|
//(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16,
|
||||||
(bend.circle().r + (d as f64)) as i16,
|
(FixedBend.circle().r + (d as f64)) as i16,
|
||||||
angle1.to_degrees() as i16,
|
angle1.to_degrees() as i16,
|
||||||
angle2.to_degrees() as i16,
|
angle2.to_degrees() as i16,
|
||||||
Color::RGB(200, 52, 52),
|
Color::RGB(200, 52, 52),
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@ use spade::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{DotIndex, GetNodeIndex},
|
graph::{DotIndex, FixedDotIndex, GetNodeIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
};
|
};
|
||||||
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
use crate::{primitive::MakeShape, shape::ShapeTrait};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
dot: DotIndex,
|
dot: FixedDotIndex,
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ impl Mesh {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, vertex: VertexIndex) -> DotIndex {
|
pub fn dot(&self, vertex: VertexIndex) -> FixedDotIndex {
|
||||||
self.triangulation.vertex(vertex.handle).as_ref().dot
|
self.triangulation.vertex(vertex.handle).as_ref().dot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
264
src/primitive.rs
264
src/primitive.rs
|
|
@ -5,8 +5,10 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
||||||
use petgraph::Direction::{Incoming, Outgoing};
|
use petgraph::Direction::{Incoming, Outgoing};
|
||||||
|
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNet, GetNodeIndex, Index,
|
BendIndex, DotIndex, Ends, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
|
||||||
Interior, Label, MakePrimitive, Retag, SegWeight, Weight,
|
FixedSegWeight, FullyLooseSegWeight, GenericIndex, GetNet, GetNodeIndex, HalfLooseSegWeight,
|
||||||
|
Index, Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotWeight, MakePrimitive, Retag,
|
||||||
|
Weight,
|
||||||
};
|
};
|
||||||
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};
|
||||||
|
|
@ -44,9 +46,13 @@ pub trait MakeShape {
|
||||||
|
|
||||||
#[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)]
|
#[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)]
|
||||||
pub enum Primitive<'a> {
|
pub enum Primitive<'a> {
|
||||||
Dot(Dot<'a>),
|
FixedDot(FixedDot<'a>),
|
||||||
Seg(Seg<'a>),
|
LooseDot(LooseDot<'a>),
|
||||||
Bend(Bend<'a>),
|
FixedSeg(FixedSeg<'a>),
|
||||||
|
HalfLooseSeg(HalfLooseSeg<'a>),
|
||||||
|
FullyLooseSeg(FullyLooseSeg<'a>),
|
||||||
|
FixedBend(FixedBend<'a>),
|
||||||
|
LooseBend(LooseBend<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -66,7 +72,7 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
.map(|index| self.graph.node_weight(index).unwrap().retag(index))
|
.map(|index| self.graph.node_weight(index).unwrap().retag(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev_bend(&self) -> Option<BendIndex> {
|
pub fn prev_bend(&self) -> Option<FixedBendIndex> {
|
||||||
let mut prev_index = self.index.node_index();
|
let mut prev_index = self.index.node_index();
|
||||||
|
|
||||||
while let Some(index) = self
|
while let Some(index) = self
|
||||||
|
|
@ -85,8 +91,8 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
{
|
{
|
||||||
let _weight = *self.graph.node_weight(index).unwrap();
|
let _weight = *self.graph.node_weight(index).unwrap();
|
||||||
|
|
||||||
if let Some(Weight::Bend(..)) = self.graph.node_weight(index) {
|
if let Some(Weight::FixedBend(..)) = self.graph.node_weight(index) {
|
||||||
return Some(BendIndex::new(index));
|
return Some(FixedBendIndex::new(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_index = index;
|
prev_index = index;
|
||||||
|
|
@ -107,7 +113,7 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_bend(&self) -> Option<BendIndex> {
|
pub fn next_bend(&self) -> Option<FixedBendIndex> {
|
||||||
let mut prev_index = self.index.node_index();
|
let mut prev_index = self.index.node_index();
|
||||||
|
|
||||||
while let Some(index) = self
|
while let Some(index) = self
|
||||||
|
|
@ -126,8 +132,8 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
{
|
{
|
||||||
let _weight = *self.graph.node_weight(index).unwrap();
|
let _weight = *self.graph.node_weight(index).unwrap();
|
||||||
|
|
||||||
if let Some(Weight::Bend(..)) = self.graph.node_weight(index) {
|
if let Some(Weight::FixedBend(..)) = self.graph.node_weight(index) {
|
||||||
return Some(BendIndex::new(index));
|
return Some(FixedBendIndex::new(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_index = index;
|
prev_index = index;
|
||||||
|
|
@ -148,7 +154,7 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn core(&self) -> Option<DotIndex> {
|
pub fn core(&self) -> Option<FixedDotIndex> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors(self.index.node_index())
|
.neighbors(self.index.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
|
|
@ -157,33 +163,10 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_core()
|
.is_core()
|
||||||
})
|
})
|
||||||
.map(|ni| DotIndex::new(ni))
|
.map(|ni| FixedDotIndex::new(ni))
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*pub fn connectable<WW>(&self, index: GenericIndex<WW>) -> bool {
|
|
||||||
let this = self.net(&self.index);
|
|
||||||
let other = self.net(&index);
|
|
||||||
|
|
||||||
if this == other {
|
|
||||||
true
|
|
||||||
} else if this == -1 || other == -1 {
|
|
||||||
true
|
|
||||||
} else if this == -2 || other == -2 {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
this == other
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn net<WW>(&self, index: &GenericIndex<WW>) -> i64 {
|
|
||||||
match self.graph.node_weight(index.node_index()).unwrap() {
|
|
||||||
Weight::Dot(dot) => dot.net,
|
|
||||||
Weight::Seg(seg) => seg.net,
|
|
||||||
Weight::Bend(bend) => bend.net,
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pub fn tagged_index(&self) -> Index {
|
pub fn tagged_index(&self) -> Index {
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight(self.index.node_index())
|
.node_weight(self.index.node_index())
|
||||||
|
|
@ -206,8 +189,8 @@ impl<'a, W> Interior<Index> for GenericPrimitive<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W> Ends<DotIndex, DotIndex> for GenericPrimitive<'a, W> {
|
impl<'a, W> Ends<FixedDotIndex, FixedDotIndex> for GenericPrimitive<'a, W> {
|
||||||
fn ends(&self) -> (DotIndex, DotIndex) {
|
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||||
let v = self
|
let v = self
|
||||||
.graph
|
.graph
|
||||||
.neighbors_undirected(self.index.node_index())
|
.neighbors_undirected(self.index.node_index())
|
||||||
|
|
@ -222,8 +205,8 @@ impl<'a, W> Ends<DotIndex, DotIndex> for GenericPrimitive<'a, W> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_end()
|
.is_end()
|
||||||
})
|
})
|
||||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_dot())
|
||||||
.map(|ni| DotIndex::new(ni))
|
.map(|ni| FixedDotIndex::new(ni))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
(v[0], v[1])
|
(v[0], v[1])
|
||||||
}
|
}
|
||||||
|
|
@ -261,10 +244,10 @@ impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Dot<'a> = GenericPrimitive<'a, DotWeight>;
|
pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>;
|
||||||
|
|
||||||
impl<'a> Dot<'a> {
|
impl<'a> FixedDot<'a> {
|
||||||
pub fn bend(&self) -> Option<BendIndex> {
|
pub fn bend(&self) -> Option<FixedBendIndex> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors_undirected(self.index.node_index())
|
.neighbors_undirected(self.index.node_index())
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
|
|
@ -278,12 +261,12 @@ impl<'a> Dot<'a> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_end()
|
.is_end()
|
||||||
})
|
})
|
||||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_bend())
|
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_bend())
|
||||||
.map(|ni| BendIndex::new(ni))
|
.map(|ni| FixedBendIndex::new(ni))
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outer(&self) -> Option<BendIndex> {
|
pub fn outer(&self) -> Option<FixedBendIndex> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors_directed(self.index.node_index(), Incoming)
|
.neighbors_directed(self.index.node_index(), Incoming)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
|
|
@ -292,19 +275,19 @@ impl<'a> Dot<'a> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_core()
|
.is_core()
|
||||||
})
|
})
|
||||||
.map(|ni| BendIndex::new(ni))
|
.map(|ni| FixedBendIndex::new(ni))
|
||||||
.filter(|bend| self.primitive(*bend).inner().is_none())
|
.filter(|bend| self.primitive(*bend).inner().is_none())
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetWeight<DotWeight> for Dot<'a> {
|
impl<'a> GetWeight<FixedDotWeight> for FixedDot<'a> {
|
||||||
fn weight(&self) -> DotWeight {
|
fn weight(&self) -> FixedDotWeight {
|
||||||
self.tagged_weight().into_dot().unwrap()
|
self.tagged_weight().into_fixed_dot().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MakeShape for Dot<'a> {
|
impl<'a> MakeShape for FixedDot<'a> {
|
||||||
fn shape(&self) -> Shape {
|
fn shape(&self) -> Shape {
|
||||||
Shape::Dot(DotShape {
|
Shape::Dot(DotShape {
|
||||||
c: self.weight().circle,
|
c: self.weight().circle,
|
||||||
|
|
@ -312,25 +295,41 @@ impl<'a> MakeShape for Dot<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Seg<'a> = GenericPrimitive<'a, SegWeight>;
|
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
|
||||||
|
|
||||||
impl<'a> Seg<'a> {
|
impl<'a> GetWeight<LooseDotWeight> for LooseDot<'a> {
|
||||||
pub fn next(&self) -> Option<DotIndex> {
|
fn weight(&self) -> LooseDotWeight {
|
||||||
self.next_node().map(|ni| DotIndex::new(ni))
|
self.tagged_weight().into_loose_dot().unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev(&self) -> Option<DotIndex> {
|
|
||||||
self.prev_node().map(|ni| DotIndex::new(ni))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetWeight<SegWeight> for Seg<'a> {
|
impl<'a> MakeShape for LooseDot<'a> {
|
||||||
fn weight(&self) -> SegWeight {
|
fn shape(&self) -> Shape {
|
||||||
self.tagged_weight().into_seg().unwrap()
|
Shape::Dot(DotShape {
|
||||||
|
c: self.weight().circle,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MakeShape for Seg<'a> {
|
pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>;
|
||||||
|
|
||||||
|
impl<'a> FixedSeg<'a> {
|
||||||
|
pub fn next(&self) -> Option<FixedDotIndex> {
|
||||||
|
self.next_node().map(|ni| FixedDotIndex::new(ni))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev(&self) -> Option<FixedDotIndex> {
|
||||||
|
self.prev_node().map(|ni| FixedDotIndex::new(ni))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> GetWeight<FixedSegWeight> for FixedSeg<'a> {
|
||||||
|
fn weight(&self) -> FixedSegWeight {
|
||||||
|
self.tagged_weight().into_fixed_seg().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for FixedSeg<'a> {
|
||||||
fn shape(&self) -> Shape {
|
fn shape(&self) -> Shape {
|
||||||
let ends = self.ends();
|
let ends = self.ends();
|
||||||
Shape::Seg(SegShape {
|
Shape::Seg(SegShape {
|
||||||
|
|
@ -341,18 +340,56 @@ impl<'a> MakeShape for Seg<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Bend<'a> = GenericPrimitive<'a, BendWeight>;
|
pub type HalfLooseSeg<'a> = GenericPrimitive<'a, HalfLooseSegWeight>;
|
||||||
|
|
||||||
impl<'a> Bend<'a> {
|
impl<'a> GetWeight<HalfLooseSegWeight> for HalfLooseSeg<'a> {
|
||||||
|
fn weight(&self) -> HalfLooseSegWeight {
|
||||||
|
self.tagged_weight().into_half_loose_seg().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for HalfLooseSeg<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
Shape::Seg(SegShape {
|
||||||
|
from: self.primitive(ends.0).weight().circle.pos,
|
||||||
|
to: self.primitive(ends.1).weight().circle.pos,
|
||||||
|
width: self.weight().width,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FullyLooseSeg<'a> = GenericPrimitive<'a, FullyLooseSegWeight>;
|
||||||
|
|
||||||
|
impl<'a> GetWeight<FullyLooseSegWeight> for FullyLooseSeg<'a> {
|
||||||
|
fn weight(&self) -> FullyLooseSegWeight {
|
||||||
|
self.tagged_weight().into_fully_loose_seg().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for FullyLooseSeg<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
Shape::Seg(SegShape {
|
||||||
|
from: self.primitive(ends.0).weight().circle.pos,
|
||||||
|
to: self.primitive(ends.1).weight().circle.pos,
|
||||||
|
width: self.weight().width,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
|
||||||
|
|
||||||
|
impl<'a> FixedBend<'a> {
|
||||||
pub fn around(&self) -> Index {
|
pub fn around(&self) -> Index {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
Index::Bend(inner)
|
inner.into()
|
||||||
} else {
|
} else {
|
||||||
Index::Dot(self.core().unwrap())
|
self.core().unwrap().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner(&self) -> Option<BendIndex> {
|
pub fn inner(&self) -> Option<FixedBendIndex> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors_directed(self.index.node_index(), Incoming)
|
.neighbors_directed(self.index.node_index(), Incoming)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
|
|
@ -361,11 +398,11 @@ impl<'a> Bend<'a> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_outer()
|
.is_outer()
|
||||||
})
|
})
|
||||||
.map(|ni| BendIndex::new(ni))
|
.map(|ni| FixedBendIndex::new(ni))
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outer(&self) -> Option<BendIndex> {
|
pub fn outer(&self) -> Option<FixedBendIndex> {
|
||||||
self.graph
|
self.graph
|
||||||
.neighbors_directed(self.index.node_index(), Outgoing)
|
.neighbors_directed(self.index.node_index(), Outgoing)
|
||||||
.filter(|ni| {
|
.filter(|ni| {
|
||||||
|
|
@ -374,21 +411,21 @@ impl<'a> Bend<'a> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_outer()
|
.is_outer()
|
||||||
})
|
})
|
||||||
.map(|ni| BendIndex::new(ni))
|
.map(|ni| FixedBendIndex::new(ni))
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> Option<DotIndex> {
|
pub fn next(&self) -> Option<FixedDotIndex> {
|
||||||
self.next_node().map(|ni| DotIndex::new(ni))
|
self.next_node().map(|ni| FixedDotIndex::new(ni))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&self) -> Option<DotIndex> {
|
pub fn prev(&self) -> Option<FixedDotIndex> {
|
||||||
self.prev_node().map(|ni| DotIndex::new(ni))
|
self.prev_node().map(|ni| FixedDotIndex::new(ni))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner_radius(&self) -> f64 {
|
fn inner_radius(&self) -> f64 {
|
||||||
let mut r = 0.0;
|
let mut r = 0.0;
|
||||||
let mut layer = BendIndex::new(self.index.node_index());
|
let mut layer = FixedBendIndex::new(self.index.node_index());
|
||||||
|
|
||||||
while let Some(inner) = self.primitive(layer).inner() {
|
while let Some(inner) = self.primitive(layer).inner() {
|
||||||
r += self.primitive(inner).shape().width();
|
r += self.primitive(inner).shape().width();
|
||||||
|
|
@ -397,7 +434,7 @@ impl<'a> Bend<'a> {
|
||||||
|
|
||||||
let core_circle = self
|
let core_circle = self
|
||||||
.primitive(
|
.primitive(
|
||||||
self.primitive(BendIndex::new(self.index.node_index()))
|
self.primitive(FixedBendIndex::new(self.index.node_index()))
|
||||||
.core()
|
.core()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
|
|
@ -416,13 +453,78 @@ impl<'a> Bend<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GetWeight<BendWeight> for Bend<'a> {
|
impl<'a> GetWeight<FixedBendWeight> for FixedBend<'a> {
|
||||||
fn weight(&self) -> BendWeight {
|
fn weight(&self) -> FixedBendWeight {
|
||||||
self.tagged_weight().into_bend().unwrap()
|
self.tagged_weight().into_fixed_bend().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MakeShape for Bend<'a> {
|
impl<'a> MakeShape for FixedBend<'a> {
|
||||||
|
fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
|
||||||
|
let mut bend_shape = BendShape {
|
||||||
|
from: self.primitive(ends.0).weight().circle.pos,
|
||||||
|
to: self.primitive(ends.1).weight().circle.pos,
|
||||||
|
c: Circle {
|
||||||
|
pos: self.primitive(self.core().unwrap()).weight().circle.pos,
|
||||||
|
r: self.inner_radius(),
|
||||||
|
},
|
||||||
|
width: self.primitive(ends.0).weight().circle.r * 2.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.weight().cw {
|
||||||
|
swap(&mut bend_shape.from, &mut bend_shape.to);
|
||||||
|
}
|
||||||
|
Shape::Bend(bend_shape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>;
|
||||||
|
|
||||||
|
impl<'a> LooseBend<'a> {
|
||||||
|
pub fn inner(&self) -> Option<LooseBendIndex> {
|
||||||
|
self.graph
|
||||||
|
.neighbors_directed(self.index.node_index(), Incoming)
|
||||||
|
.filter(|ni| {
|
||||||
|
self.graph
|
||||||
|
.edge_weight(self.graph.find_edge(*ni, self.index.node_index()).unwrap())
|
||||||
|
.unwrap()
|
||||||
|
.is_outer()
|
||||||
|
})
|
||||||
|
.map(|ni| LooseBendIndex::new(ni))
|
||||||
|
.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner_radius(&self) -> f64 {
|
||||||
|
let mut r = 0.0;
|
||||||
|
let mut layer = LooseBendIndex::new(self.index.node_index());
|
||||||
|
|
||||||
|
while let Some(inner) = self.primitive(layer).inner() {
|
||||||
|
r += self.primitive(inner).shape().width();
|
||||||
|
layer = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
let core_circle = self
|
||||||
|
.primitive(
|
||||||
|
self.primitive(LooseBendIndex::new(self.index.node_index()))
|
||||||
|
.core()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.weight()
|
||||||
|
.circle;
|
||||||
|
|
||||||
|
core_circle.r + r + 3.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> GetWeight<LooseBendWeight> for LooseBend<'a> {
|
||||||
|
fn weight(&self) -> LooseBendWeight {
|
||||||
|
self.tagged_weight().into_loose_bend().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MakeShape for LooseBend<'a> {
|
||||||
fn shape(&self) -> Shape {
|
fn shape(&self) -> Shape {
|
||||||
let ends = self.ends();
|
let ends = self.ends();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use petgraph::visit::EdgeRef;
|
||||||
use spade::InsertionError;
|
use spade::InsertionError;
|
||||||
|
|
||||||
use crate::astar::{astar, AstarStrategy, PathTracker};
|
use crate::astar::{astar, AstarStrategy, PathTracker};
|
||||||
use crate::graph::{DotIndex, DotWeight, Ends};
|
use crate::graph::{DotIndex, Ends, FixedDotIndex, FixedDotWeight};
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
|
|
||||||
use crate::math::Circle;
|
use crate::math::Circle;
|
||||||
|
|
@ -84,8 +84,8 @@ impl Router {
|
||||||
|
|
||||||
pub fn enroute(
|
pub fn enroute(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: DotIndex,
|
to: FixedDotIndex,
|
||||||
observer: &mut impl RouterObserver,
|
observer: &mut impl RouterObserver,
|
||||||
) -> Result<Mesh, InsertionError> {
|
) -> Result<Mesh, InsertionError> {
|
||||||
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
||||||
|
|
@ -95,12 +95,17 @@ impl Router {
|
||||||
mesh.triangulate(&self.layout)?;
|
mesh.triangulate(&self.layout)?;
|
||||||
|
|
||||||
let mut tracer = self.tracer(&mesh);
|
let mut tracer = self.tracer(&mesh);
|
||||||
let trace = tracer.start(mesh.vertex(from));
|
let trace = tracer.start(mesh.vertex(DotIndex::Fixed(from)));
|
||||||
|
|
||||||
let (_cost, _path) = astar(
|
let (_cost, _path) = astar(
|
||||||
&mesh,
|
&mesh,
|
||||||
mesh.vertex(from),
|
mesh.vertex(DotIndex::Fixed(from)),
|
||||||
&mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer),
|
&mut RouterAstarStrategy::new(
|
||||||
|
tracer,
|
||||||
|
trace,
|
||||||
|
mesh.vertex(DotIndex::Fixed(to)),
|
||||||
|
observer,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap(); // TODO.
|
.unwrap(); // TODO.
|
||||||
|
|
||||||
|
|
@ -109,7 +114,7 @@ impl Router {
|
||||||
|
|
||||||
pub fn reroute(
|
pub fn reroute(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: FixedDotIndex,
|
||||||
to: Point,
|
to: Point,
|
||||||
observer: &mut impl RouterObserver,
|
observer: &mut impl RouterObserver,
|
||||||
) -> Result<Mesh, InsertionError> {
|
) -> Result<Mesh, InsertionError> {
|
||||||
|
|
@ -122,7 +127,7 @@ impl Router {
|
||||||
} else {
|
} else {
|
||||||
let from_weight = self.layout.primitive(from).weight();
|
let from_weight = self.layout.primitive(from).weight();
|
||||||
self.layout
|
self.layout
|
||||||
.add_dot(DotWeight {
|
.add_dot(FixedDotWeight {
|
||||||
net: from_weight.net,
|
net: from_weight.net,
|
||||||
circle: Circle { pos: to, r: 2.0 },
|
circle: Circle { pos: to, r: 2.0 },
|
||||||
})
|
})
|
||||||
|
|
@ -135,7 +140,7 @@ impl Router {
|
||||||
/*pub fn squeeze_around_dot(
|
/*pub fn squeeze_around_dot(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: DotIndex,
|
around: FixedDotIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Head, ()> {
|
) -> Result<Head, ()> {
|
||||||
|
|
@ -151,7 +156,7 @@ impl Router {
|
||||||
pub fn squeeze_around_bend(
|
pub fn squeeze_around_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: BendIndex,
|
around: FixedBendIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<Head, ()> {
|
) -> Result<Head, ()> {
|
||||||
|
|
@ -164,7 +169,7 @@ impl Router {
|
||||||
Ok(head)
|
Ok(head)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reroute_outward(&mut self, bend: BendIndex) -> Result<(), ()> {
|
fn reroute_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> {
|
||||||
let mut bows: Vec<Bow> = vec![];
|
let mut bows: Vec<Bow> = vec![];
|
||||||
let cw = self.layout.primitive(bend).weight().cw;
|
let cw = self.layout.primitive(bend).weight().cw;
|
||||||
|
|
||||||
|
|
@ -204,7 +209,7 @@ impl Router {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relax_band(&mut self, bend: BendIndex) {
|
fn relax_band(&mut self, bend: FixedBendIndex) {
|
||||||
let mut prev_bend = bend;
|
let mut prev_bend = bend;
|
||||||
while let Some(cur_bend) = self.layout.primitive(prev_bend).find_prev_akin() {
|
while let Some(cur_bend) = self.layout.primitive(prev_bend).find_prev_akin() {
|
||||||
if self.layout.primitive(cur_bend).cross_product() >= 0. {
|
if self.layout.primitive(cur_bend).cross_product() >= 0. {
|
||||||
|
|
@ -224,7 +229,7 @@ impl Router {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release_bow(&mut self, bend: BendIndex) {
|
fn release_bow(&mut self, bend: FixedBendIndex) {
|
||||||
let bow = self.layout.bow(bend);
|
let bow = self.layout.bow(bend);
|
||||||
let ends = bow.ends();
|
let ends = bow.ends();
|
||||||
|
|
||||||
|
|
@ -234,7 +239,7 @@ impl Router {
|
||||||
let _ = self.draw().finish(head, ends.1, 5.0);
|
let _ = self.draw().finish(head, ends.1, 5.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> {
|
pub fn move_dot(&mut self, dot: FixedDotIndex, to: Point) -> Result<(), ()> {
|
||||||
self.layout.move_dot(dot, to)?;
|
self.layout.move_dot(dot, to)?;
|
||||||
|
|
||||||
if let Some(outer) = self.layout.primitive(dot).outer() {
|
if let Some(outer) = self.layout.primitive(dot).outer() {
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,49 @@
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight},
|
graph::{
|
||||||
primitive::{Bend, Dot, TaggedPrevTaggedNext},
|
BendIndex, DotIndex, Ends, FixedBendIndex, FixedDotIndex, FixedSegIndex, Index, Interior,
|
||||||
|
Label, SegIndex, Weight,
|
||||||
|
},
|
||||||
|
primitive::{FixedBend, FixedDot, TaggedPrevTaggedNext},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Segbend {
|
pub struct Segbend {
|
||||||
pub seg: SegIndex,
|
pub seg: FixedSegIndex,
|
||||||
pub dot: DotIndex,
|
pub dot: FixedDotIndex,
|
||||||
pub bend: BendIndex,
|
pub bend: FixedBendIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Segbend {
|
impl Segbend {
|
||||||
pub fn new(bend: BendIndex, dot: DotIndex, seg: SegIndex) -> Self {
|
pub fn new(bend: FixedBendIndex, dot: FixedDotIndex, seg: FixedSegIndex) -> Self {
|
||||||
Self { seg, dot, bend }
|
Self { seg, dot, bend }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_dot_prev(
|
pub fn from_dot_prev(
|
||||||
dot: DotIndex,
|
dot: FixedDotIndex,
|
||||||
graph: &StableDiGraph<Weight, Label, usize>,
|
graph: &StableDiGraph<Weight, Label, usize>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let bend = *Dot::new(dot, graph).tagged_prev()?.as_bend()?;
|
let bend = *FixedDot::new(dot, graph).tagged_prev()?.as_fixed_bend()?;
|
||||||
let dot = Bend::new(bend, graph).prev().unwrap();
|
let dot = FixedBend::new(bend, graph).prev().unwrap();
|
||||||
let seg = Dot::new(dot, graph)
|
let seg = FixedDot::new(dot, graph)
|
||||||
.tagged_prev()
|
.tagged_prev()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_seg()
|
.into_fixed_seg()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Some(Self { bend, dot, seg })
|
Some(Self { bend, dot, seg })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_dot_next(
|
pub fn from_dot_next(
|
||||||
dot: DotIndex,
|
dot: FixedDotIndex,
|
||||||
graph: &StableDiGraph<Weight, Label, usize>,
|
graph: &StableDiGraph<Weight, Label, usize>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let bend = *Dot::new(dot, graph).tagged_next()?.as_bend()?;
|
let bend = *FixedDot::new(dot, graph).tagged_next()?.as_fixed_bend()?;
|
||||||
let dot = Bend::new(bend, graph).next().unwrap();
|
let dot = FixedBend::new(bend, graph).next().unwrap();
|
||||||
let seg = Dot::new(dot, graph)
|
let seg = FixedDot::new(dot, graph)
|
||||||
.tagged_next()
|
.tagged_next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_seg()
|
.into_fixed_seg()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Some(Self { bend, dot, seg })
|
Some(Self { bend, dot, seg })
|
||||||
}
|
}
|
||||||
|
|
@ -48,16 +51,12 @@ impl Segbend {
|
||||||
|
|
||||||
impl Interior<Index> for Segbend {
|
impl Interior<Index> for Segbend {
|
||||||
fn interior(&self) -> Vec<Index> {
|
fn interior(&self) -> Vec<Index> {
|
||||||
vec![
|
vec![self.bend.into(), self.dot.into(), self.seg.into()]
|
||||||
Index::Bend(self.bend),
|
|
||||||
Index::Dot(self.dot),
|
|
||||||
Index::Seg(self.seg),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ends<SegIndex, BendIndex> for Segbend {
|
impl Ends<FixedSegIndex, FixedBendIndex> for Segbend {
|
||||||
fn ends(&self) -> (SegIndex, BendIndex) {
|
fn ends(&self) -> (FixedSegIndex, FixedBendIndex) {
|
||||||
(self.seg, self.bend)
|
(self.seg, self.bend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use contracts::debug_ensures;
|
||||||
use crate::{
|
use crate::{
|
||||||
bow::Bow,
|
bow::Bow,
|
||||||
draw::{BareHead, Draw, Head, HeadTrait, SegbendHead},
|
draw::{BareHead, Draw, Head, HeadTrait, SegbendHead},
|
||||||
graph::{BendIndex, DotIndex, Ends},
|
graph::{Ends, FixedBendIndex, FixedDotIndex},
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
mesh::{Mesh, VertexIndex},
|
mesh::{Mesh, VertexIndex},
|
||||||
primitive::{GetWeight, MakeShape},
|
primitive::{GetWeight, MakeShape},
|
||||||
|
|
@ -93,7 +93,7 @@ impl<'a> Tracer<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap(&mut self, head: Head, around: DotIndex, width: f64) -> Result<SegbendHead, ()> {
|
fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result<SegbendHead, ()> {
|
||||||
let _around_pos = self.layout.primitive(around).weight().circle.pos;
|
let _around_pos = self.layout.primitive(around).weight().circle.pos;
|
||||||
let _around_primitive = self.layout.primitive(around);
|
let _around_primitive = self.layout.primitive(around);
|
||||||
|
|
||||||
|
|
@ -122,7 +122,12 @@ impl<'a> Tracer<'a> {
|
||||||
self.draw().segbend_around_dot(head, around, width)
|
self.draw().segbend_around_dot(head, around, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_under(&mut self, head: Head, around: DotIndex, layer: BendIndex) -> Option<bool> {
|
fn is_under(
|
||||||
|
&mut self,
|
||||||
|
head: Head,
|
||||||
|
around: FixedDotIndex,
|
||||||
|
layer: FixedBendIndex,
|
||||||
|
) -> Option<bool> {
|
||||||
let around_pos = self.layout.primitive(around).weight().circle.pos;
|
let around_pos = self.layout.primitive(around).weight().circle.pos;
|
||||||
|
|
||||||
if Some(layer) != self.layout.primitive(head.dot()).prev_bend() {
|
if Some(layer) != self.layout.primitive(head.dot()).prev_bend() {
|
||||||
|
|
@ -142,7 +147,7 @@ impl<'a> Tracer<'a> {
|
||||||
fn tuck_around_dot(
|
fn tuck_around_dot(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: DotIndex,
|
around: FixedDotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let outer = self.layout.primitive(around).outer().unwrap();
|
let outer = self.layout.primitive(around).outer().unwrap();
|
||||||
|
|
@ -158,7 +163,7 @@ impl<'a> Tracer<'a> {
|
||||||
fn tuck_around_bend(
|
fn tuck_around_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
around: BendIndex,
|
around: FixedBendIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let outer = self.layout.primitive(around).outer().unwrap();
|
let outer = self.layout.primitive(around).outer().unwrap();
|
||||||
|
|
@ -171,7 +176,7 @@ impl<'a> Tracer<'a> {
|
||||||
Ok(head)
|
Ok(head)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn redraw_outward(&mut self, bend: BendIndex) -> Result<(), ()> {
|
fn redraw_outward(&mut self, bend: FixedBendIndex) -> Result<(), ()> {
|
||||||
let mut bows: Vec<Bow> = vec![];
|
let mut bows: Vec<Bow> = vec![];
|
||||||
|
|
||||||
let mut cur_bend = bend;
|
let mut cur_bend = bend;
|
||||||
|
|
@ -210,7 +215,7 @@ impl<'a> Tracer<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relax_band(&mut self, bend: BendIndex) {
|
fn relax_band(&mut self, bend: FixedBendIndex) {
|
||||||
let mut prev_bend = bend;
|
let mut prev_bend = bend;
|
||||||
while let Some(cur_bend) = self.layout.primitive(prev_bend).prev_bend() {
|
while let Some(cur_bend) = self.layout.primitive(prev_bend).prev_bend() {
|
||||||
if self.layout.primitive(cur_bend).cross_product() >= 0. {
|
if self.layout.primitive(cur_bend).cross_product() >= 0. {
|
||||||
|
|
@ -230,7 +235,7 @@ impl<'a> Tracer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release_bow(&mut self, bend: BendIndex) {
|
fn release_bow(&mut self, bend: FixedBendIndex) {
|
||||||
let bow = self.layout.bow(bend);
|
let bow = self.layout.bow(bend);
|
||||||
let ends = bow.ends();
|
let ends = bow.ends();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue