mirror of https://codeberg.org/topola/topola.git
graph,layout,primitive: Use loose primitive variants for traces
This commit is contained in:
parent
4b46b2174b
commit
c163716a6a
40
src/bow.rs
40
src/bow.rs
|
|
@ -1,32 +1,32 @@
|
|||
use petgraph::stable_graph::StableDiGraph;
|
||||
|
||||
use crate::graph::{
|
||||
FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label, Weight,
|
||||
GetEnds, Index, Interior, Label, LooseBendIndex, LooseDotIndex, LooseSegIndex, Weight,
|
||||
};
|
||||
use crate::primitive::{FixedBend, FixedDot, FixedSeg};
|
||||
use crate::primitive::{GetOtherEnd, LooseBend, LooseDot, LooseSeg};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Bow {
|
||||
seg1_dot1: FixedDotIndex,
|
||||
seg1: FixedSegIndex,
|
||||
seg1_dot2: FixedDotIndex,
|
||||
bend: FixedBendIndex,
|
||||
seg2_dot1: FixedDotIndex,
|
||||
seg2: FixedSegIndex,
|
||||
seg2_dot2: FixedDotIndex,
|
||||
seg1_dot1: LooseDotIndex,
|
||||
seg1: LooseSegIndex,
|
||||
seg1_dot2: LooseDotIndex,
|
||||
bend: LooseBendIndex,
|
||||
seg2_dot1: LooseDotIndex,
|
||||
seg2: LooseSegIndex,
|
||||
seg2_dot2: LooseDotIndex,
|
||||
}
|
||||
|
||||
impl Bow {
|
||||
pub fn from_bend(index: FixedBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
|
||||
/*impl Bow {
|
||||
pub fn from_bend(index: LooseBendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
|
||||
let bend = index;
|
||||
|
||||
let seg1_dot2 = FixedBend::new(bend, graph).ends().0;
|
||||
let seg1 = FixedDot::new(seg1_dot2, graph).seg().unwrap();
|
||||
let seg1_dot1 = FixedSeg::new(seg1, graph).other_end(seg1_dot2);
|
||||
let seg1_dot2 = LooseBend::new(bend, graph).ends().0;
|
||||
let seg1 = LooseDot::new(seg1_dot2, graph).seg().unwrap();
|
||||
let seg1_dot1 = LooseSeg::new(seg1, graph).other_end(seg1_dot2);
|
||||
|
||||
let seg2_dot1 = FixedBend::new(bend, graph).ends().1;
|
||||
let seg2 = FixedDot::new(seg2_dot1, graph).seg().unwrap();
|
||||
let seg2_dot2 = FixedSeg::new(seg2, graph).other_end(seg2_dot1);
|
||||
let seg2_dot1 = LooseBend::new(bend, graph).ends().1;
|
||||
let seg2 = LooseDot::new(seg2_dot1, graph).seg().unwrap();
|
||||
let seg2_dot2 = LooseSeg::new(seg2, graph).other_end(seg2_dot1);
|
||||
|
||||
Self {
|
||||
seg1_dot1,
|
||||
|
|
@ -38,7 +38,7 @@ impl Bow {
|
|||
seg2_dot2,
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
impl Interior<Index> for Bow {
|
||||
fn interior(&self) -> Vec<Index> {
|
||||
|
|
@ -52,8 +52,8 @@ impl Interior<Index> for Bow {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetEnds<FixedDotIndex, FixedDotIndex> for Bow {
|
||||
fn ends(&self) -> (FixedDotIndex, FixedDotIndex) {
|
||||
impl GetEnds<LooseDotIndex, LooseDotIndex> for Bow {
|
||||
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||
(self.seg1_dot1, self.seg2_dot2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
117
src/draw.rs
117
src/draw.rs
|
|
@ -4,20 +4,21 @@ use geo::{EuclideanLength, Point};
|
|||
|
||||
use crate::{
|
||||
graph::{
|
||||
BendIndex, DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
|
||||
FixedSegIndex, FixedSegWeight, Index,
|
||||
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex,
|
||||
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
|
||||
MakePrimitive,
|
||||
},
|
||||
guide::Guide,
|
||||
layout::Layout,
|
||||
math::Circle,
|
||||
primitive::GetWeight,
|
||||
primitive::{GetOtherEnd, GetWeight},
|
||||
rules::{Conditions, Rules},
|
||||
segbend::Segbend,
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait HeadTrait {
|
||||
fn dot(&self) -> FixedDotIndex;
|
||||
fn dot(&self) -> DotIndex;
|
||||
}
|
||||
|
||||
#[enum_dispatch(HeadTrait)]
|
||||
|
|
@ -33,20 +34,20 @@ pub struct BareHead {
|
|||
}
|
||||
|
||||
impl HeadTrait for BareHead {
|
||||
fn dot(&self) -> FixedDotIndex {
|
||||
self.dot
|
||||
fn dot(&self) -> DotIndex {
|
||||
self.dot.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SegbendHead {
|
||||
pub dot: FixedDotIndex,
|
||||
pub dot: LooseDotIndex,
|
||||
pub segbend: Segbend,
|
||||
}
|
||||
|
||||
impl HeadTrait for SegbendHead {
|
||||
fn dot(&self) -> FixedDotIndex {
|
||||
self.dot
|
||||
fn dot(&self) -> DotIndex {
|
||||
self.dot.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,45 +61,54 @@ impl<'a> Draw<'a> {
|
|||
Self { layout, rules }
|
||||
}
|
||||
|
||||
pub fn start(&mut self, from: FixedDotIndex) -> Head {
|
||||
self.head(from)
|
||||
pub fn start(&mut self, from: LooseDotIndex) -> Head {
|
||||
self.head(from.into())
|
||||
}
|
||||
|
||||
#[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()))]
|
||||
pub fn finish(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
|
||||
pub fn finish(&mut self, head: Head, into: LooseDotIndex, width: f64) -> Result<(), ()> {
|
||||
if let Some(bend) = self.layout.primitive(into).bend() {
|
||||
self.finish_in_bend(head, bend, into, width)?;
|
||||
} else {
|
||||
self.finish_in_dot(head, into, width)?;
|
||||
self.finish_in_dot(head, into.into(), width)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}*/
|
||||
|
||||
#[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()))]
|
||||
fn finish_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
|
||||
pub fn finish_in_dot(&mut self, head: Head, into: FixedDotIndex, width: f64) -> Result<(), ()> {
|
||||
let tangent = self
|
||||
.guide(&Default::default())
|
||||
.head_into_dot_segment(&head, into, width)?;
|
||||
let head = self.extend_head(head, tangent.start_point())?;
|
||||
|
||||
let net = self.layout.primitive(head.dot()).weight().net;
|
||||
let net = head.dot().primitive(&self.layout.graph).net();
|
||||
|
||||
match head.dot() {
|
||||
DotIndex::Fixed(dot) => {
|
||||
self.layout
|
||||
.add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?;
|
||||
.add_fixed_seg(into.into(), dot, FixedSegWeight { net, width })?;
|
||||
}
|
||||
DotIndex::Loose(dot) => {
|
||||
self.layout
|
||||
.add_loose_seg(into.into(), dot, LooseSegWeight { net })?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[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()))]
|
||||
fn finish_in_bend(
|
||||
pub fn finish_in_bend(
|
||||
&mut self,
|
||||
head: Head,
|
||||
into_bend: FixedBendIndex,
|
||||
into: FixedDotIndex,
|
||||
into_bend: LooseBendIndex,
|
||||
into: LooseDotIndex,
|
||||
width: f64,
|
||||
) -> Result<(), ()> {
|
||||
let to_head = self.head(into);
|
||||
let to_head = self.head(into.into());
|
||||
let to_cw = self.guide(&Default::default()).head_cw(&to_head).unwrap();
|
||||
let tangent = self.guide(&Default::default()).head_around_bend_segment(
|
||||
&head,
|
||||
|
|
@ -110,9 +120,9 @@ impl<'a> Draw<'a> {
|
|||
let head = self.extend_head(head, tangent.start_point())?;
|
||||
let _to_head = self.extend_head(to_head, tangent.end_point())?;
|
||||
|
||||
let net = self.layout.primitive(head.dot()).weight().net;
|
||||
let net = head.dot().primitive(&self.layout.graph).net();
|
||||
self.layout
|
||||
.add_fixed_seg(head.dot(), into, FixedSegWeight { net, width })?;
|
||||
.add_loose_seg(head.dot(), into.into(), LooseSegWeight { net })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -248,34 +258,27 @@ impl<'a> Draw<'a> {
|
|||
cw: bool,
|
||||
width: f64,
|
||||
) -> Result<SegbendHead, ()> {
|
||||
let (head, seg) = self.seg(head, to, width)?;
|
||||
let dot = head.dot;
|
||||
let (seg, dot) = self.seg(head, to, width)?;
|
||||
let net = head.dot().primitive(&self.layout.graph).net();
|
||||
let bend_to = self
|
||||
.layout
|
||||
.add_fixed_dot(self.layout.primitive(head.dot).weight())
|
||||
.add_loose_dot(self.layout.primitive(dot).weight())
|
||||
.map_err(|err| {
|
||||
self.undo_seg(head, seg);
|
||||
self.undo_seg(seg, dot);
|
||||
err
|
||||
})?;
|
||||
|
||||
let net = self.layout.primitive(head.dot).weight().net;
|
||||
|
||||
let bend = self
|
||||
.layout
|
||||
.add_fixed_bend(
|
||||
head.dot,
|
||||
bend_to,
|
||||
around,
|
||||
FixedBendWeight { net, width, cw },
|
||||
)
|
||||
.add_loose_bend(dot, bend_to, around, LooseBendWeight { net, cw })
|
||||
.map_err(|err| {
|
||||
self.layout.remove(bend_to.into());
|
||||
self.undo_seg(head, seg);
|
||||
self.undo_seg(seg, dot);
|
||||
err
|
||||
})?;
|
||||
Ok(SegbendHead {
|
||||
dot: bend_to,
|
||||
segbend: Segbend { bend, dot, seg },
|
||||
segbend: Segbend { seg, dot, bend },
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -285,20 +288,25 @@ impl<'a> Draw<'a> {
|
|||
let prev_dot = self
|
||||
.layout
|
||||
.primitive(head.segbend.seg)
|
||||
.other_end(head.segbend.dot);
|
||||
.other_end(head.segbend.dot.into());
|
||||
|
||||
self.layout.remove_interior(&head.segbend);
|
||||
self.layout.remove(head.dot().into());
|
||||
|
||||
Some(self.head(prev_dot))
|
||||
Some(self.head(prev_dot.into()))
|
||||
}
|
||||
|
||||
#[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_err() -> self.layout.node_count() == old(self.layout.node_count()))]
|
||||
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(BareHead, FixedSegIndex), ()> {
|
||||
let net = self.layout.primitive(head.dot()).weight().net;
|
||||
let to_index = self.layout.add_fixed_dot(FixedDotWeight {
|
||||
fn seg(
|
||||
&mut self,
|
||||
head: Head,
|
||||
to: Point,
|
||||
width: f64,
|
||||
) -> Result<(LooseSegIndex, LooseDotIndex), ()> {
|
||||
let net = head.dot().primitive(&self.layout.graph).net();
|
||||
let to_index = self.layout.add_loose_dot(LooseDotWeight {
|
||||
net,
|
||||
circle: Circle {
|
||||
pos: to,
|
||||
|
|
@ -307,25 +315,28 @@ impl<'a> Draw<'a> {
|
|||
})?;
|
||||
let seg = self
|
||||
.layout
|
||||
.add_fixed_seg(head.dot(), to_index, FixedSegWeight { net, width })
|
||||
.add_loose_seg(head.dot(), to_index, LooseSegWeight { net })
|
||||
.map_err(|err| {
|
||||
self.layout.remove(to_index.into());
|
||||
err
|
||||
})?;
|
||||
Ok((BareHead { dot: to_index }, seg))
|
||||
Ok((seg, to_index))
|
||||
}
|
||||
|
||||
#[debug_ensures(self.layout.node_count() == old(self.layout.node_count() - 2))]
|
||||
fn undo_seg(&mut self, head: BareHead, seg: FixedSegIndex) {
|
||||
fn undo_seg(&mut self, seg: LooseSegIndex, dot: LooseDotIndex) {
|
||||
self.layout.remove(seg.into());
|
||||
self.layout.remove(head.dot.into());
|
||||
self.layout.remove(dot.into());
|
||||
}
|
||||
|
||||
fn head(&self, dot: FixedDotIndex) -> Head {
|
||||
if let Some(segbend) = self.layout.segbend(dot) {
|
||||
SegbendHead { dot, segbend }.into()
|
||||
} else {
|
||||
BareHead { dot }.into()
|
||||
fn head(&self, dot: DotIndex) -> Head {
|
||||
match dot {
|
||||
DotIndex::Fixed(loose) => BareHead { dot: loose }.into(),
|
||||
DotIndex::Loose(fixed) => SegbendHead {
|
||||
dot: fixed,
|
||||
segbend: self.layout.segbend(fixed).unwrap(),
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
21
src/graph.rs
21
src/graph.rs
|
|
@ -26,6 +26,11 @@ pub trait GetNet {
|
|||
fn net(&self) -> i64;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetNetMut {
|
||||
fn net_mut(&mut self) -> &mut i64;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait GetWidth {
|
||||
fn width(&self) -> f64;
|
||||
|
|
@ -48,6 +53,12 @@ macro_rules! impl_type {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetNetMut for $weight_struct {
|
||||
fn net_mut(&mut self) -> &mut i64 {
|
||||
&mut self.net
|
||||
}
|
||||
}
|
||||
|
||||
pub type $index_struct = GenericIndex<$weight_struct>;
|
||||
|
||||
impl MakePrimitive for $index_struct {
|
||||
|
|
@ -61,7 +72,7 @@ macro_rules! impl_type {
|
|||
};
|
||||
}
|
||||
|
||||
#[enum_dispatch(Retag, GetNet)]
|
||||
#[enum_dispatch(Retag, GetNet, GetNetMut)]
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Weight {
|
||||
FixedDot(FixedDotWeight),
|
||||
|
|
@ -109,8 +120,8 @@ pub enum SegIndex {
|
|||
impl From<SegIndex> for Index {
|
||||
fn from(seg: SegIndex) -> Self {
|
||||
match seg {
|
||||
SegIndex::Fixed(fixed) => Index::FixedSeg(fixed),
|
||||
SegIndex::Loose(fully_loose) => Index::LooseSeg(fully_loose),
|
||||
SegIndex::Fixed(seg) => Index::FixedSeg(seg),
|
||||
SegIndex::Loose(seg) => Index::LooseSeg(seg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,8 +136,8 @@ pub enum BendIndex {
|
|||
impl From<BendIndex> for Index {
|
||||
fn from(bend: BendIndex) -> Self {
|
||||
match bend {
|
||||
BendIndex::Fixed(fixed) => Index::FixedBend(fixed),
|
||||
BendIndex::Loose(loose) => Index::LooseBend(loose),
|
||||
BendIndex::Fixed(bend) => Index::FixedBend(bend),
|
||||
BendIndex::Loose(bend) => Index::LooseBend(bend),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
|
||||
match *head {
|
||||
Head::Bare(head) => Circle {
|
||||
pos: self.layout.primitive(head.dot()).weight().circle.pos,
|
||||
pos: head.dot().primitive(&self.layout.graph).shape().center(), // TODO.
|
||||
r: 0.0,
|
||||
},
|
||||
Head::Segbend(head) => {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject};
|
|||
|
||||
use crate::bow::Bow;
|
||||
use crate::graph::{
|
||||
BendWeight, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight,
|
||||
FixedSegIndex, FixedSegWeight, GenericIndex, GetNodeIndex, Index, Interior, Label,
|
||||
LooseDotIndex, LooseSegIndex, LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight,
|
||||
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex,
|
||||
FixedDotWeight, FixedSegIndex, FixedSegWeight, GenericIndex, GetNetMut, GetNodeIndex, Index,
|
||||
Interior, Label, LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex,
|
||||
LooseSegWeight, MakePrimitive, Retag, SegWeight, Weight,
|
||||
};
|
||||
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
|
||||
use crate::segbend::Segbend;
|
||||
|
|
@ -38,7 +39,7 @@ impl Layout {
|
|||
for index in path
|
||||
.interior()
|
||||
.into_iter()
|
||||
.filter(|index| !index.is_fixed_dot())
|
||||
.filter(|index| !index.is_loose_dot())
|
||||
{
|
||||
self.remove(index);
|
||||
}
|
||||
|
|
@ -49,7 +50,7 @@ impl Layout {
|
|||
for index in path
|
||||
.interior()
|
||||
.into_iter()
|
||||
.filter(|index| index.is_fixed_dot())
|
||||
.filter(|index| index.is_loose_dot())
|
||||
{
|
||||
self.remove(index);
|
||||
}
|
||||
|
|
@ -65,10 +66,20 @@ impl Layout {
|
|||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> {
|
||||
self.add_dot(weight)
|
||||
}
|
||||
|
||||
// TODO: Remove.
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result<LooseDotIndex, ()> {
|
||||
self.add_dot(weight)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()>
|
||||
where
|
||||
|
|
@ -101,7 +112,7 @@ impl Layout {
|
|||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_loose_seg(
|
||||
&mut self,
|
||||
from: LooseDotIndex,
|
||||
from: DotIndex,
|
||||
to: LooseDotIndex,
|
||||
weight: LooseSegWeight,
|
||||
) -> Result<LooseSegIndex, ()> {
|
||||
|
|
@ -131,23 +142,21 @@ impl Layout {
|
|||
self.insert_into_rtree(seg.into());
|
||||
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
|
||||
|
||||
self.graph
|
||||
*self
|
||||
.graph
|
||||
.node_weight_mut(from.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net();
|
||||
self.graph
|
||||
.net_mut() = weight.net();
|
||||
*self
|
||||
.graph
|
||||
.node_weight_mut(to.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net();
|
||||
.net_mut() = weight.net();
|
||||
|
||||
Ok(seg)
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
/*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
pub fn add_fixed_bend(
|
||||
&mut self,
|
||||
|
|
@ -161,7 +170,7 @@ impl Layout {
|
|||
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
|
|
@ -170,8 +179,8 @@ impl Layout {
|
|||
from: LooseDotIndex,
|
||||
to: LooseDotIndex,
|
||||
around: Index,
|
||||
weight: FixedBendWeight,
|
||||
) -> Result<FixedBendIndex, ()> {
|
||||
weight: LooseBendWeight,
|
||||
) -> Result<LooseBendIndex, ()> {
|
||||
match around {
|
||||
Index::FixedDot(core) => self.add_core_bend(from, to, core, weight),
|
||||
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||
|
|
@ -189,11 +198,11 @@ impl Layout {
|
|||
to: impl GetNodeIndex,
|
||||
core: FixedDotIndex,
|
||||
weight: W,
|
||||
) -> Result<FixedBendIndex, ()>
|
||||
) -> Result<LooseBendIndex, ()>
|
||||
where
|
||||
GenericIndex<W>: Into<Index> + Copy,
|
||||
{
|
||||
let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
|
||||
let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
|
||||
|
|
@ -217,7 +226,7 @@ impl Layout {
|
|||
to: impl GetNodeIndex,
|
||||
inner: impl GetNodeIndex,
|
||||
weight: W,
|
||||
) -> Result<FixedBendIndex, ()> {
|
||||
) -> Result<LooseBendIndex, ()> {
|
||||
let core = *self
|
||||
.graph
|
||||
.neighbors(inner.node_index())
|
||||
|
|
@ -232,7 +241,7 @@ impl Layout {
|
|||
.first()
|
||||
.unwrap();
|
||||
|
||||
let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
|
||||
let bend = LooseBendIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.add_edge(from.node_index(), bend.node_index(), Label::Adjacent);
|
||||
|
|
@ -288,11 +297,11 @@ impl Layout {
|
|||
self.insert_into_rtree(bend.into());
|
||||
}
|
||||
|
||||
pub fn bow(&self, bend: FixedBendIndex) -> Bow {
|
||||
/*pub fn bow(&self, bend: LooseBendIndex) -> Bow {
|
||||
Bow::from_bend(bend, &self.graph)
|
||||
}
|
||||
}*/
|
||||
|
||||
pub fn segbend(&self, dot: FixedDotIndex) -> Option<Segbend> {
|
||||
pub fn segbend(&self, dot: LooseDotIndex) -> Option<Segbend> {
|
||||
Segbend::from_dot(dot, &self.graph)
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +342,7 @@ impl Layout {
|
|||
impl Layout {
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn move_dot(&mut self, dot: FixedDotIndex, to: Point) -> Result<(), ()> {
|
||||
pub fn move_dot(&mut self, dot: LooseDotIndex, to: Point) -> Result<(), ()> {
|
||||
self.primitive(dot)
|
||||
.seg()
|
||||
.map(|seg| self.remove_from_rtree(seg.into()));
|
||||
|
|
@ -346,11 +355,11 @@ impl Layout {
|
|||
let old_weight = dot_weight;
|
||||
|
||||
dot_weight.circle.pos = to;
|
||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(dot_weight);
|
||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight);
|
||||
|
||||
if let Some(..) = self.detect_collision_except(dot.into(), &[]) {
|
||||
// Restore original state.
|
||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::FixedDot(old_weight);
|
||||
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight);
|
||||
|
||||
self.insert_into_rtree(dot.into());
|
||||
self.primitive(dot)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ extern crate sdl2;
|
|||
|
||||
macro_rules! dbg_dot {
|
||||
($graph:expr) => {
|
||||
use petgraph::FixedDot::FixedDot;
|
||||
println!("{:?}", FixedDot::new(&$graph));
|
||||
use petgraph::dot::Dot;
|
||||
println!("{:?}", Dot::new(&$graph));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ mod shape;
|
|||
mod tracer;
|
||||
|
||||
use geo::point;
|
||||
use graph::{FixedDotIndex, FixedSegWeight};
|
||||
use graph::{FixedDotIndex, FixedSegWeight, LooseDotIndex};
|
||||
use layout::Layout;
|
||||
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||
|
|
@ -403,7 +403,7 @@ fn render_times(
|
|||
canvas: &mut Canvas<Window>,
|
||||
mut router_or_layout: RouterOrLayout,
|
||||
from: Option<FixedDotIndex>,
|
||||
follower: Option<FixedDotIndex>,
|
||||
follower: Option<LooseDotIndex>,
|
||||
mut mesh: Option<Mesh>,
|
||||
path: &[VertexIndex],
|
||||
times: i64,
|
||||
|
|
|
|||
148
src/primitive.rs
148
src/primitive.rs
|
|
@ -5,9 +5,10 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
|||
use petgraph::Direction::{Incoming, Outgoing};
|
||||
|
||||
use crate::graph::{
|
||||
FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight,
|
||||
GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label, LooseBendIndex,
|
||||
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, Retag, Weight,
|
||||
DotIndex, FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex,
|
||||
FixedSegWeight, GenericIndex, GetEnds, GetNet, GetNodeIndex, GetWidth, Index, Interior, Label,
|
||||
LooseBendIndex, LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
|
||||
MakePrimitive, Retag, Weight,
|
||||
};
|
||||
use crate::math::{self, Circle};
|
||||
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
||||
|
|
@ -37,14 +38,18 @@ pub trait MakeShape {
|
|||
fn shape(&self) -> Shape;
|
||||
}
|
||||
|
||||
#[enum_dispatch(
|
||||
GetNet,
|
||||
GetWidth,
|
||||
GetGraph,
|
||||
GetConnectable,
|
||||
TaggedPrevTaggedNext,
|
||||
MakeShape
|
||||
)]
|
||||
pub trait GetOtherEnd<F: GetNodeIndex, T: GetNodeIndex + Into<F>>: GetEnds<F, T> {
|
||||
fn other_end(&self, end: F) -> F {
|
||||
let ends = self.ends();
|
||||
if ends.0.node_index() != end.node_index() {
|
||||
ends.0
|
||||
} else {
|
||||
ends.1.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)]
|
||||
pub enum Primitive<'a> {
|
||||
FixedDot(FixedDot<'a>),
|
||||
LooseDot(LooseDot<'a>),
|
||||
|
|
@ -148,44 +153,6 @@ where
|
|||
pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>;
|
||||
|
||||
impl<'a> FixedDot<'a> {
|
||||
pub fn seg(&self) -> Option<FixedSegIndex> {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.node_index())
|
||||
.filter(|ni| {
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(self.index.node_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap()
|
||||
.is_adjacent()
|
||||
})
|
||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_seg())
|
||||
.map(|ni| FixedSegIndex::new(ni))
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn bend(&self) -> Option<FixedBendIndex> {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.node_index())
|
||||
.filter(|ni| {
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(self.index.node_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap()
|
||||
.is_adjacent()
|
||||
})
|
||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_fixed_bend())
|
||||
.map(|ni| FixedBendIndex::new(ni))
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn outer(&self) -> Option<FixedBendIndex> {
|
||||
self.graph
|
||||
.neighbors_directed(self.index.node_index(), Incoming)
|
||||
|
|
@ -217,6 +184,46 @@ impl<'a> MakeShape for FixedDot<'a> {
|
|||
|
||||
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
|
||||
|
||||
impl<'a> LooseDot<'a> {
|
||||
pub fn seg(&self) -> Option<LooseSegIndex> {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.node_index())
|
||||
.filter(|ni| {
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(self.index.node_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap()
|
||||
.is_adjacent()
|
||||
})
|
||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_seg())
|
||||
.map(|ni| LooseSegIndex::new(ni))
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn bend(&self) -> Option<LooseBendIndex> {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.node_index())
|
||||
.filter(|ni| {
|
||||
self.graph
|
||||
.edge_weight(
|
||||
self.graph
|
||||
.find_edge_undirected(self.index.node_index(), *ni)
|
||||
.unwrap()
|
||||
.0,
|
||||
)
|
||||
.unwrap()
|
||||
.is_adjacent()
|
||||
})
|
||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_bend())
|
||||
.map(|ni| LooseBendIndex::new(ni))
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetWeight<LooseDotWeight> for LooseDot<'a> {
|
||||
fn weight(&self) -> LooseDotWeight {
|
||||
self.tagged_weight().into_loose_dot().unwrap()
|
||||
|
|
@ -233,16 +240,6 @@ impl<'a> MakeShape for LooseDot<'a> {
|
|||
|
||||
pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>;
|
||||
|
||||
impl<'a> FixedSeg<'a> {
|
||||
pub fn other_end(&self, dot: FixedDotIndex) -> FixedDotIndex {
|
||||
let ends = self.ends();
|
||||
[ends.0, ends.1]
|
||||
.into_iter()
|
||||
.find(|end| end.node_index() != dot.node_index())
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetWeight<FixedSegWeight> for FixedSeg<'a> {
|
||||
fn weight(&self) -> FixedSegWeight {
|
||||
self.tagged_weight().into_fixed_seg().unwrap()
|
||||
|
|
@ -267,6 +264,8 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
|
||||
|
||||
pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>;
|
||||
|
||||
impl<'a> GetWeight<LooseSegWeight> for LooseSeg<'a> {
|
||||
|
|
@ -279,7 +278,10 @@ impl<'a> MakeShape for LooseSeg<'a> {
|
|||
fn shape(&self) -> Shape {
|
||||
let ends = self.ends();
|
||||
Shape::Seg(SegShape {
|
||||
from: self.primitive(ends.0).weight().circle.pos,
|
||||
from: match ends.0 {
|
||||
DotIndex::Fixed(dot) => self.primitive(dot).weight().circle.pos,
|
||||
DotIndex::Loose(dot) => self.primitive(dot).weight().circle.pos,
|
||||
},
|
||||
to: self.primitive(ends.1).weight().circle.pos,
|
||||
width: self.width(),
|
||||
})
|
||||
|
|
@ -292,12 +294,20 @@ impl<'a> GetWidth for LooseSeg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseSeg<'a> {
|
||||
fn ends(&self) -> (LooseDotIndex, LooseDotIndex) {
|
||||
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
|
||||
fn ends(&self) -> (DotIndex, LooseDotIndex) {
|
||||
let v = self.adjacents();
|
||||
(LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1]))
|
||||
if self.graph.node_weight(v[0]).unwrap().is_fixed_dot() {
|
||||
(FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
||||
} else if self.graph.node_weight(v[1]).unwrap().is_fixed_dot() {
|
||||
(FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0]))
|
||||
} else {
|
||||
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for LooseSeg<'a> {}
|
||||
|
||||
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
|
||||
|
||||
|
|
@ -336,14 +346,6 @@ impl<'a> FixedBend<'a> {
|
|||
.next()
|
||||
}
|
||||
|
||||
pub fn other_end(&self, dot: FixedDotIndex) -> FixedDotIndex {
|
||||
let ends = self.ends();
|
||||
[ends.0, ends.1]
|
||||
.into_iter()
|
||||
.find(|end| end.node_index() != dot.node_index())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn inner_radius(&self) -> f64 {
|
||||
let mut r = 0.0;
|
||||
let mut layer = FixedBendIndex::new(self.index.node_index());
|
||||
|
|
@ -408,6 +410,8 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedBend<'a> {}
|
||||
|
||||
pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>;
|
||||
|
||||
impl<'a> LooseBend<'a> {
|
||||
|
|
@ -485,3 +489,5 @@ impl<'a> GetEnds<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {
|
|||
(LooseDotIndex::new(v[0]), LooseDotIndex::new(v[1]))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetOtherEnd<LooseDotIndex, LooseDotIndex> for LooseBend<'a> {}
|
||||
|
|
|
|||
|
|
@ -2,26 +2,27 @@ use petgraph::stable_graph::StableDiGraph;
|
|||
|
||||
use crate::{
|
||||
graph::{
|
||||
FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label, Weight,
|
||||
FixedBendIndex, FixedDotIndex, FixedSegIndex, GetEnds, Index, Interior, Label,
|
||||
LooseBendIndex, LooseDotIndex, LooseSegIndex, Weight,
|
||||
},
|
||||
primitive::{FixedBend, FixedDot},
|
||||
primitive::{FixedBend, FixedDot, GetOtherEnd, LooseBend, LooseDot},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Segbend {
|
||||
pub seg: FixedSegIndex,
|
||||
pub dot: FixedDotIndex,
|
||||
pub bend: FixedBendIndex,
|
||||
pub seg: LooseSegIndex,
|
||||
pub dot: LooseDotIndex,
|
||||
pub bend: LooseBendIndex,
|
||||
}
|
||||
|
||||
impl Segbend {
|
||||
pub fn from_dot(
|
||||
dot: FixedDotIndex,
|
||||
dot: LooseDotIndex,
|
||||
graph: &StableDiGraph<Weight, Label, usize>,
|
||||
) -> Option<Self> {
|
||||
let bend = FixedDot::new(dot, graph).bend()?;
|
||||
let dot = FixedBend::new(bend, graph).other_end(dot);
|
||||
let seg = FixedDot::new(dot, graph).seg()?;
|
||||
let bend = LooseDot::new(dot, graph).bend()?;
|
||||
let dot = LooseBend::new(bend, graph).other_end(dot);
|
||||
let seg = LooseDot::new(dot, graph).seg()?;
|
||||
Some(Self { bend, dot, seg })
|
||||
}
|
||||
}
|
||||
|
|
@ -32,8 +33,8 @@ impl Interior<Index> for Segbend {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetEnds<FixedSegIndex, FixedBendIndex> for Segbend {
|
||||
fn ends(&self) -> (FixedSegIndex, FixedBendIndex) {
|
||||
impl GetEnds<LooseSegIndex, LooseBendIndex> for Segbend {
|
||||
fn ends(&self) -> (LooseSegIndex, LooseBendIndex) {
|
||||
(self.seg, self.bend)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ impl<'a> Tracer<'a> {
|
|||
|
||||
pub fn finish(&mut self, trace: &mut Trace, into: VertexIndex, width: f64) -> Result<(), ()> {
|
||||
let into_dot = self.mesh.dot(into);
|
||||
self.draw().finish(trace.head, into_dot, width)
|
||||
self.draw().finish_in_dot(trace.head, into_dot, width)
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())]
|
||||
|
|
@ -87,14 +87,14 @@ impl<'a> Tracer<'a> {
|
|||
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]
|
||||
pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> {
|
||||
let to_dot = self.mesh.dot(to);
|
||||
trace.head = Head::from(self.wrap(trace.head, to_dot, width)?);
|
||||
trace.head = self.wrap(trace.head, to_dot, width)?.into();
|
||||
|
||||
trace.path.push(to);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
'blk: {
|
||||
|
|
@ -117,12 +117,12 @@ impl<'a> Tracer<'a> {
|
|||
|
||||
return self.draw().segbend_around_bend(head, layer.into(), width);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
self.draw().segbend_around_dot(head, around.into(), width)
|
||||
}
|
||||
|
||||
fn is_under(
|
||||
/*fn is_under(
|
||||
&mut self,
|
||||
_head: Head,
|
||||
around: FixedDotIndex,
|
||||
|
|
@ -142,9 +142,9 @@ impl<'a> Tracer<'a> {
|
|||
} else {*/
|
||||
None
|
||||
//}
|
||||
}
|
||||
}*/
|
||||
|
||||
fn tuck_around_dot(
|
||||
/*fn tuck_around_dot(
|
||||
&mut self,
|
||||
head: Head,
|
||||
around: FixedDotIndex,
|
||||
|
|
@ -213,7 +213,7 @@ impl<'a> Tracer<'a> {
|
|||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}*/
|
||||
|
||||
/*fn relax_band(&mut self, bend: FixedBendIndex) {
|
||||
let mut prev_bend = bend;
|
||||
|
|
@ -235,15 +235,16 @@ impl<'a> Tracer<'a> {
|
|||
}
|
||||
}*/
|
||||
|
||||
fn release_bow(&mut self, bend: FixedBendIndex) {
|
||||
/*fn release_bow(&mut self, bend: FixedBendIndex) {
|
||||
let bow = self.layout.bow(bend);
|
||||
let ends = bow.ends();
|
||||
|
||||
self.layout.remove_interior(&bow);
|
||||
|
||||
let head = self.draw().start(ends.0);
|
||||
|
||||
let _ = self.draw().finish(head, ends.1, 5.0);
|
||||
}
|
||||
}*/
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() - 1))]
|
||||
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]
|
||||
|
|
|
|||
Loading…
Reference in New Issue