mirror of https://codeberg.org/topola/topola.git
Make segs nodes instead of edges
This simplifies logic. Nodes store data as weights, while edges now only describe relations between nodes with dataless enums -- labels.
This commit is contained in:
parent
b5f85068df
commit
16990517b2
|
|
@ -136,8 +136,8 @@ impl Layout {
|
||||||
|
|
||||||
match self.mesh.weight(head_around) {
|
match self.mesh.weight(head_around) {
|
||||||
Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions),
|
Weight::Dot(..) => self.dot_guidecircle(*head_around.as_dot().unwrap(), width + 5.0, conditions),
|
||||||
|
Weight::Seg(..) => unreachable!(),
|
||||||
Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions),
|
Weight::Bend(..) => self.bend_guidecircle(*head_around.as_bend().unwrap(), width, conditions),
|
||||||
Weight::Seg(..) | Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Circle {
|
None => Circle {
|
||||||
|
|
@ -196,10 +196,10 @@ impl Layout {
|
||||||
let bend_weight = self.mesh.bend_weight(bend);
|
let bend_weight = self.mesh.bend_weight(bend);
|
||||||
let around = self.mesh.around(bend);
|
let around = self.mesh.around(bend);
|
||||||
|
|
||||||
let fixed_dot: TaggedIndex = self.mesh.ends(TaggedIndex::Bend(bend))
|
let fixed_dot: DotIndex = self.mesh.ends(TaggedIndex::Bend(bend))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|neighbor| *neighbor != TaggedIndex::Dot(head.dot))
|
.filter(|neighbor| {*neighbor != head.dot})
|
||||||
.collect::<Vec<TaggedIndex>>()[0];
|
.collect::<Vec<DotIndex>>()[0];
|
||||||
|
|
||||||
self.mesh.remove_bend(bend);
|
self.mesh.remove_bend(bend);
|
||||||
self.mesh.remove_dot(head.dot);
|
self.mesh.remove_dot(head.dot);
|
||||||
|
|
@ -212,7 +212,7 @@ impl Layout {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, around, bend_weight);
|
self.mesh.add_bend(fixed_dot, new_dot, around, bend_weight);
|
||||||
head
|
head
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
94
src/mesh.rs
94
src/mesh.rs
|
|
@ -1,12 +1,12 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
use petgraph::stable_graph::{StableUnGraph, NodeIndex, EdgeIndex};
|
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
||||||
use petgraph::visit::EdgeRef;
|
use petgraph::visit::EdgeRef;
|
||||||
use rstar::{RTree, RTreeObject, AABB};
|
use rstar::{RTree, RTreeObject, AABB};
|
||||||
use rstar::primitives::GeomWithData;
|
use rstar::primitives::GeomWithData;
|
||||||
|
|
||||||
use crate::primitive::Primitive;
|
use crate::primitive::Primitive;
|
||||||
use crate::weight::{Weight, DotWeight, SegWeight, BendWeight, EndRefWeight, AroundRefWeight};
|
use crate::weight::{Weight, DotWeight, SegWeight, BendWeight, Label};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
|
@ -36,7 +36,7 @@ impl Tag for DotIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SegIndex = Index<EdgeIndex<usize>, SegWeight>;
|
pub type SegIndex = Index<NodeIndex<usize>, SegWeight>;
|
||||||
|
|
||||||
impl Tag for SegIndex {
|
impl Tag for SegIndex {
|
||||||
fn tag(&self) -> TaggedIndex {
|
fn tag(&self) -> TaggedIndex {
|
||||||
|
|
@ -52,51 +52,33 @@ impl Tag for BendIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type EndRefIndex = Index<EdgeIndex<usize>, EndRefWeight>;
|
|
||||||
|
|
||||||
impl Tag for EndRefIndex {
|
|
||||||
fn tag(&self) -> TaggedIndex {
|
|
||||||
TaggedIndex::EndRef(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type AroundRefIndex = Index<EdgeIndex<usize>, AroundRefWeight>;
|
|
||||||
|
|
||||||
impl Tag for AroundRefIndex {
|
|
||||||
fn tag(&self) -> TaggedIndex {
|
|
||||||
TaggedIndex::AroundRef(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
|
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
|
||||||
pub enum TaggedIndex {
|
pub enum TaggedIndex {
|
||||||
Dot(DotIndex),
|
Dot(DotIndex),
|
||||||
Seg(SegIndex),
|
Seg(SegIndex),
|
||||||
Bend(BendIndex),
|
Bend(BendIndex),
|
||||||
EndRef(EndRefIndex),
|
|
||||||
AroundRef(AroundRefIndex),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RTreeWrapper = GeomWithData<Primitive, TaggedIndex>;
|
pub type RTreeWrapper = GeomWithData<Primitive, TaggedIndex>;
|
||||||
|
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
pub rtree: RTree<RTreeWrapper>,
|
pub rtree: RTree<RTreeWrapper>,
|
||||||
pub graph: StableUnGraph<Weight, Weight, usize>,
|
pub graph: StableDiGraph<Weight, Label, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
return Mesh {
|
return Mesh {
|
||||||
rtree: RTree::new(),
|
rtree: RTree::new(),
|
||||||
graph: StableUnGraph::default(),
|
graph: StableDiGraph::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
|
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
|
||||||
let dot_index = DotIndex::new(self.graph.add_node(Weight::Dot(weight)));
|
let dot = DotIndex::new(self.graph.add_node(Weight::Dot(weight)));
|
||||||
let index = TaggedIndex::Dot(dot_index);
|
let index = TaggedIndex::Dot(dot);
|
||||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
||||||
dot_index
|
dot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_dot(&mut self, dot: DotIndex) {
|
pub fn remove_dot(&mut self, dot: DotIndex) {
|
||||||
|
|
@ -105,33 +87,34 @@ impl Mesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_seg(&mut self, from: DotIndex, to: DotIndex, weight: SegWeight) -> SegIndex {
|
pub fn add_seg(&mut self, from: DotIndex, to: DotIndex, weight: SegWeight) -> SegIndex {
|
||||||
let seg_index = SegIndex::new(self.graph.add_edge(from.index, to.index, Weight::Seg(weight)));
|
let seg = SegIndex::new(self.graph.add_node(Weight::Seg(weight)));
|
||||||
let index = TaggedIndex::Seg(seg_index);
|
self.graph.add_edge(seg.index, from.index, Label::End);
|
||||||
|
self.graph.add_edge(seg.index, to.index, Label::End);
|
||||||
|
|
||||||
|
let index = TaggedIndex::Seg(seg);
|
||||||
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
self.rtree.insert(RTreeWrapper::new(self.primitive(index), index));
|
||||||
seg_index
|
seg
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_seg(&mut self, seg: SegIndex) {
|
pub fn remove_seg(&mut self, seg: SegIndex) {
|
||||||
self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Seg(seg)), TaggedIndex::Seg(seg)));
|
self.rtree.remove(&RTreeWrapper::new(self.primitive(TaggedIndex::Seg(seg)), TaggedIndex::Seg(seg)));
|
||||||
self.graph.remove_edge(seg.index);
|
self.graph.remove_node(seg.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, around: TaggedIndex, weight: BendWeight) -> BendIndex {
|
pub fn add_bend(&mut self, from: DotIndex, to: DotIndex, around: TaggedIndex, weight: BendWeight) -> BendIndex {
|
||||||
let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight)));
|
let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight)));
|
||||||
self.graph.add_edge(from.index, bend.index, Weight::EndRef(EndRefWeight {}));
|
self.graph.add_edge(bend.index, from.index, Label::End);
|
||||||
self.graph.add_edge(bend.index, to.index, Weight::EndRef(EndRefWeight {}));
|
self.graph.add_edge(bend.index, to.index, Label::End);
|
||||||
|
|
||||||
match around {
|
match around {
|
||||||
TaggedIndex::Dot(DotIndex {index: around_index, ..}) => {
|
TaggedIndex::Dot(DotIndex {index: around_index, ..}) => {
|
||||||
self.graph.add_edge(bend.index, around_index, Weight::AroundRef(AroundRefWeight {}));
|
self.graph.add_edge(bend.index, around_index, Label::Around);
|
||||||
},
|
},
|
||||||
|
TaggedIndex::Seg(..) => unreachable!(),
|
||||||
TaggedIndex::Bend(BendIndex {index: around_index, ..}) => {
|
TaggedIndex::Bend(BendIndex {index: around_index, ..}) => {
|
||||||
self.graph.add_edge(bend.index, around_index, Weight::AroundRef(AroundRefWeight {}));
|
self.graph.add_edge(bend.index, around_index, Label::Around);
|
||||||
},
|
},
|
||||||
TaggedIndex::Seg(..)
|
|
||||||
| TaggedIndex::EndRef(..)
|
|
||||||
| TaggedIndex::AroundRef(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = TaggedIndex::Bend(bend);
|
let index = TaggedIndex::Bend(bend);
|
||||||
|
|
@ -154,7 +137,7 @@ impl Mesh {
|
||||||
dot_neighbor_weights:
|
dot_neighbor_weights:
|
||||||
self.ends(index)
|
self.ends(index)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|index| *self.weight(index).as_dot().unwrap())
|
.map(|index| self.dot_weight(index))
|
||||||
.collect(),
|
.collect(),
|
||||||
around_weight: match index {
|
around_weight: match index {
|
||||||
TaggedIndex::Bend(bend) => Some(self.weight(self.around(bend))),
|
TaggedIndex::Bend(bend) => Some(self.weight(self.around(bend))),
|
||||||
|
|
@ -186,37 +169,28 @@ impl Mesh {
|
||||||
for neighbor in self.graph.neighbors(bend.index) {
|
for neighbor in self.graph.neighbors(bend.index) {
|
||||||
let edge = self.graph.find_edge(bend.index, neighbor).unwrap();
|
let edge = self.graph.find_edge(bend.index, neighbor).unwrap();
|
||||||
|
|
||||||
if self.graph.edge_weight(edge).unwrap().is_around_ref() {
|
if self.graph.edge_weight(edge).unwrap().is_around() {
|
||||||
return match self.graph.node_weight(neighbor).unwrap() {
|
return match self.graph.node_weight(neighbor).unwrap() {
|
||||||
Weight::Dot(dot) => DotIndex::new(neighbor).tag(),
|
Weight::Dot(dot) => DotIndex::new(neighbor).tag(),
|
||||||
Weight::Bend(bend) => BendIndex::new(neighbor).tag(),
|
Weight::Bend(bend) => BendIndex::new(neighbor).tag(),
|
||||||
Weight::Seg(..)
|
Weight::Seg(seg) => SegIndex::new(neighbor).tag(),
|
||||||
| Weight::EndRef(..)
|
|
||||||
| Weight::AroundRef(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ends(&self, index: TaggedIndex) -> Vec<TaggedIndex> {
|
pub fn ends(&self, index: TaggedIndex) -> Vec<DotIndex> {
|
||||||
match index {
|
match index {
|
||||||
TaggedIndex::Dot(DotIndex {index: node, ..})
|
TaggedIndex::Dot(DotIndex {index: node, ..})
|
||||||
| TaggedIndex::Bend(BendIndex {index: node, ..}) =>
|
| TaggedIndex::Seg(SegIndex {index: node, ..})
|
||||||
|
| TaggedIndex::Bend(BendIndex {index: node, ..}) => {
|
||||||
self.graph.neighbors(node)
|
self.graph.neighbors(node)
|
||||||
|
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(node, *ni).unwrap()).unwrap().is_end())
|
||||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
||||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(node, *ni).unwrap()).unwrap().is_end_ref())
|
.map(|ni| DotIndex::new(ni))
|
||||||
.map(|ni| TaggedIndex::Dot(Index::new(ni)))
|
.collect()
|
||||||
.collect(),
|
}
|
||||||
TaggedIndex::Seg(SegIndex {index: edge, ..}) => {
|
|
||||||
let endpoints = self.graph.edge_endpoints(edge).unwrap();
|
|
||||||
vec![TaggedIndex::Dot(DotIndex::new(endpoints.0)),
|
|
||||||
TaggedIndex::Dot(DotIndex::new(endpoints.1))]
|
|
||||||
},
|
|
||||||
TaggedIndex::EndRef(..)
|
|
||||||
| TaggedIndex::AroundRef(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,13 +209,9 @@ impl Mesh {
|
||||||
pub fn weight(&self, index: TaggedIndex) -> Weight {
|
pub fn weight(&self, index: TaggedIndex) -> Weight {
|
||||||
match index {
|
match index {
|
||||||
TaggedIndex::Dot(DotIndex {index: node, ..})
|
TaggedIndex::Dot(DotIndex {index: node, ..})
|
||||||
|
| TaggedIndex::Seg(SegIndex {index: node, ..})
|
||||||
| TaggedIndex::Bend(BendIndex {index: node, ..}) =>
|
| TaggedIndex::Bend(BendIndex {index: node, ..}) =>
|
||||||
*self.graph.node_weight(node).unwrap(),
|
*self.graph.node_weight(node).unwrap(),
|
||||||
TaggedIndex::Seg(SegIndex {index: edge, ..}) =>
|
|
||||||
*self.graph.edge_weight(edge).unwrap(),
|
|
||||||
TaggedIndex::EndRef(..)
|
|
||||||
| TaggedIndex::AroundRef(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ impl Primitive {
|
||||||
.collect();
|
.collect();
|
||||||
return AABB::<[f64; 2]>::from_points(&points);
|
return AABB::<[f64; 2]>::from_points(&points);
|
||||||
},
|
},
|
||||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +42,6 @@ impl Primitive {
|
||||||
r,
|
r,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +50,6 @@ impl Primitive {
|
||||||
Weight::Dot(dot) => dot.circle.r * 2.0,
|
Weight::Dot(dot) => dot.circle.r * 2.0,
|
||||||
Weight::Seg(seg) => seg.width,
|
Weight::Seg(seg) => seg.width,
|
||||||
Weight::Bend(bend) => self.dot_neighbor_weights[0].circle.r * 2.0,
|
Weight::Bend(bend) => self.dot_neighbor_weights[0].circle.r * 2.0,
|
||||||
Weight::EndRef(..) | Weight::AroundRef(..) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
use crate::{math::Circle, mesh::{DotIndex, TaggedIndex}};
|
use crate::math::Circle;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct DotWeight {
|
pub struct DotWeight {
|
||||||
|
|
@ -19,19 +19,15 @@ pub struct SegWeight {
|
||||||
pub width: f64,
|
pub width: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub struct EndRefWeight {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub struct AroundRefWeight {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
pub enum Weight {
|
pub enum Weight {
|
||||||
Dot(DotWeight),
|
Dot(DotWeight),
|
||||||
Seg(SegWeight),
|
Seg(SegWeight),
|
||||||
Bend(BendWeight),
|
Bend(BendWeight),
|
||||||
EndRef(EndRefWeight),
|
}
|
||||||
AroundRef(AroundRefWeight),
|
|
||||||
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
|
pub enum Label {
|
||||||
|
End,
|
||||||
|
Around,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue