Move Delaunay triangulation to a new `Mesh` struct

This commit is contained in:
Mikolaj Wielgus 2023-08-24 21:23:37 +02:00
parent 8456259b38
commit 658bb112c2
5 changed files with 90 additions and 31 deletions

View File

@ -40,7 +40,6 @@ pub enum Label {
End,
Outer,
Core,
Peer,
}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]

View File

@ -56,7 +56,6 @@ impl Layout {
self.fail_and_remove_if_collides_except(dot, &[])?;
self.insert_into_rtree(dot.tag());
self.triangulate();
Ok(dot)
}
@ -120,7 +119,6 @@ impl Layout {
self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
self.insert_into_rtree(bend.tag());
self.triangulate();
Ok(bend)
}
@ -165,7 +163,6 @@ impl Layout {
self.remove_from_rtree(bend.tag());
self.move_dot(dot, to)?;
self.insert_into_rtree(bend.tag());
self.triangulate();
Ok(())
}
@ -198,7 +195,6 @@ impl Layout {
}
self.insert_into_rtree(dot.tag());
self.triangulate();
let mut cur_bend = self.primitive(dot).outer();
loop {
@ -214,27 +210,6 @@ impl Layout {
Ok(())
}
pub fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
self.rtree.iter().map(|wrapper| wrapper.data)
}
pub fn edges(&self) -> impl Iterator<Item = (TaggedIndex, TaggedIndex)> + '_ {
self.graph.edge_indices().map(|edge| {
let endpoints = self.graph.edge_endpoints(edge).unwrap();
(
Index::<Label>::new(endpoints.0)
.retag(self.graph.node_weight(endpoints.0).unwrap()),
Index::<Label>::new(endpoints.1)
.retag(self.graph.node_weight(endpoints.1).unwrap()),
)
})
}
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
self.nodes()
.map(|ni| untag!(ni, self.primitive(ni).shape()))
}
pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
Primitive::new(index, &self.graph)
}
@ -243,7 +218,7 @@ impl Layout {
Bow::new(bend, &self.graph)
}
fn triangulate(&mut self) {
/*fn triangulate(&mut self) {
let peer_edge_indices: Vec<EdgeIndex<usize>> = self
.graph
.edge_indices()
@ -292,7 +267,7 @@ impl Layout {
let to = edge.to().as_ref().index;
self.graph.add_edge(from, to, Label::Peer);
}
}
}*/
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
&mut self,
@ -335,4 +310,30 @@ impl Layout {
let shape = untag!(index, self.primitive(index).shape());
self.rtree.remove(&RTreeWrapper::new(shape, index));
}
/*pub fn edges(&self) -> impl Iterator<Item = (TaggedIndex, TaggedIndex)> + '_ {
self.graph.edge_indices().map(|edge| {
let endpoints = self.graph.edge_endpoints(edge).unwrap();
(
Index::<Label>::new(endpoints.0)
.retag(self.graph.node_weight(endpoints.0).unwrap()),
Index::<Label>::new(endpoints.1)
.retag(self.graph.node_weight(endpoints.1).unwrap()),
)
})
}*/
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
self.nodes()
.filter_map(|ni| ni.as_dot().and_then(|di| Some(*di)))
}
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
self.nodes()
.map(|ni| untag!(ni, self.primitive(ni).shape()))
}
fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
self.rtree.iter().map(|wrapper| wrapper.data)
}
}

View File

@ -13,6 +13,7 @@ mod bow;
mod guide;
mod layout;
mod math;
mod mesh;
mod primitive;
mod router;
mod rules;

50
src/mesh.rs Normal file
View File

@ -0,0 +1,50 @@
use petgraph::stable_graph::NodeIndex;
use spade::{DelaunayTriangulation, HasPosition, Point2, Triangulation};
use crate::{graph::DotIndex, layout::Layout, router::Router};
struct TriangulationVertex {
pub index: DotIndex,
x: f64,
y: f64,
}
impl HasPosition for TriangulationVertex {
type Scalar = f64;
fn position(&self) -> Point2<Self::Scalar> {
Point2::new(self.x, self.y)
}
}
pub struct Mesh {
triangulation: DelaunayTriangulation<TriangulationVertex>,
}
impl Mesh {
pub fn new() -> Self {
Self {
triangulation: DelaunayTriangulation::new(),
}
}
pub fn triangulate(&mut self, layout: &Layout) {
self.triangulation.clear();
for dot in layout.dots() {
let center = layout.primitive(dot).shape().center();
self.triangulation
.insert(TriangulationVertex {
index: dot,
x: center.x(),
y: center.y(),
})
.unwrap(); // TODO.
}
}
pub fn edges(&self) -> impl Iterator<Item = (DotIndex, DotIndex)> + '_ {
self.triangulation
.directed_edges()
.map(|edge| (edge.from().as_ref().index, edge.to().as_ref().index))
}
}

View File

@ -8,11 +8,13 @@ use crate::guide::Guide;
use crate::layout::Layout;
use crate::math;
use crate::math::Circle;
use crate::mesh::Mesh;
use crate::rules::{Conditions, Rules};
use crate::shape::Shape;
pub struct Router {
pub layout: Layout,
mesh: Mesh,
rules: Rules,
}
@ -25,6 +27,7 @@ impl Router {
pub fn new() -> Self {
Router {
layout: Layout::new(),
mesh: Mesh::new(),
rules: Rules::new(),
}
}
@ -53,6 +56,7 @@ impl Router {
let net = self.layout.primitive(head.dot).weight().net;
self.layout
.add_seg(head.dot, into, SegWeight { net, width })?;
self.mesh.triangulate(&self.layout);
Ok(())
}
@ -78,6 +82,7 @@ impl Router {
let net = self.layout.primitive(head.dot).weight().net;
self.layout
.add_seg(head.dot, into, SegWeight { net, width })?;
self.mesh.triangulate(&self.layout);
Ok(())
}
@ -170,6 +175,7 @@ impl Router {
let bend = self
.layout
.add_bend(head.dot, bend_to, around, BendWeight { net, cw })?;
self.mesh.triangulate(&self.layout);
Ok(Head {
dot: bend_to,
bend: Some(bend),
@ -232,6 +238,7 @@ impl Router {
})?;
self.layout
.add_seg(head.dot, to_index, SegWeight { net, width })?;
self.mesh.triangulate(&self.layout);
Ok(Head {
dot: to_index,
bend: None,
@ -275,6 +282,7 @@ impl Router {
self.reroute_outward(outer)?;
}
self.mesh.triangulate(&self.layout);
Ok(())
}
@ -300,12 +308,12 @@ impl Router {
}
pub fn routeedges(&self) -> impl Iterator<Item = (Point, Point)> + '_ {
self.layout.edges().map(|endpoints| {
self.mesh.edges().map(|endpoints| {
let index0 = endpoints.0;
let index1 = endpoints.1;
(
untag!(index0, self.layout.primitive(index0).shape().center()),
untag!(index1, self.layout.primitive(index1).shape().center()),
self.layout.primitive(index0).shape().center(),
self.layout.primitive(index1).shape().center(),
)
})
}