mesh: Use a tagged graph index as vertex index instead of a Spade handle

This commit is contained in:
Mikolaj Wielgus 2023-11-03 00:31:01 +00:00
parent a6481cb839
commit 13e38c6889
4 changed files with 54 additions and 65 deletions

View File

@ -1,7 +1,10 @@
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use std::marker::PhantomData; use std::{
hash::{Hash, Hasher},
marker::PhantomData,
};
use crate::{ use crate::{
math::Circle, math::Circle,
@ -243,7 +246,7 @@ 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>;
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy)]
pub struct GenericIndex<W> { pub struct GenericIndex<W> {
node_index: NodeIndex<usize>, node_index: NodeIndex<usize>,
marker: PhantomData<W>, marker: PhantomData<W>,
@ -258,6 +261,20 @@ impl<W> GenericIndex<W> {
} }
} }
impl<W> Hash for GenericIndex<W> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.node_index.hash(state)
}
}
impl<W> PartialEq for GenericIndex<W> {
fn eq(&self, other: &Self) -> bool {
self.node_index == other.node_index
}
}
impl<W> Eq for GenericIndex<W> {}
impl<W> GetNodeIndex for GenericIndex<W> { impl<W> GetNodeIndex for GenericIndex<W> {
fn node_index(&self) -> NodeIndex<usize> { fn node_index(&self) -> NodeIndex<usize> {
self.node_index self.node_index

View File

@ -16,24 +16,19 @@ use crate::{primitive::MakeShape, shape::ShapeTrait};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Vertex { struct Vertex {
graph_index: VertexGraphIndex, graph_index: VertexIndex,
x: f64, x: f64,
y: f64, y: f64,
} }
#[enum_dispatch(GetNodeIndex)] #[enum_dispatch(GetNodeIndex)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub enum VertexGraphIndex { pub enum VertexIndex {
FixedDot(FixedDotIndex), FixedDot(FixedDotIndex),
FixedBend(FixedBendIndex), FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex), LooseBend(LooseBendIndex),
} }
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub struct VertexIndex {
handle: FixedVertexHandle,
}
impl HasPosition for Vertex { impl HasPosition for Vertex {
type Scalar = f64; type Scalar = f64;
fn position(&self) -> Point2<Self::Scalar> { fn position(&self) -> Point2<Self::Scalar> {
@ -44,53 +39,49 @@ impl HasPosition for Vertex {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Mesh { pub struct Mesh {
triangulation: DelaunayTriangulation<Vertex>, triangulation: DelaunayTriangulation<Vertex>,
graph_index_to_vertex: Vec<Option<VertexIndex>>, vertex_to_handle: Vec<Option<FixedVertexHandle>>,
} }
impl Mesh { impl Mesh {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
triangulation: DelaunayTriangulation::new(), triangulation: DelaunayTriangulation::new(),
graph_index_to_vertex: Vec::new(), vertex_to_handle: Vec::new(),
} }
} }
pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> { pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> {
self.triangulation.clear(); self.triangulation.clear();
self.graph_index_to_vertex = Vec::new(); self.vertex_to_handle = Vec::new();
self.graph_index_to_vertex self.vertex_to_handle
.resize(layout.graph.node_bound(), None); .resize(layout.graph.node_bound(), None);
for node in layout.nodes() { for node in layout.nodes() {
if let Index::FixedDot(dot) = node { if let Index::FixedDot(dot) = node {
let center = layout.primitive(dot).shape().center(); let center = layout.primitive(dot).shape().center();
self.graph_index_to_vertex[dot.node_index().index()] = Some(VertexIndex { self.vertex_to_handle[dot.node_index().index()] =
handle: self.triangulation.insert(Vertex { Some(self.triangulation.insert(Vertex {
graph_index: dot.into(), graph_index: dot.into(),
x: center.x(), x: center.x(),
y: center.y(), y: center.y(),
})?, })?);
});
} }
} }
Ok(()) Ok(())
} }
pub fn graph_index(&self, vertex: VertexIndex) -> VertexGraphIndex { pub fn vertex(&self, handle: FixedVertexHandle) -> VertexIndex {
self.triangulation self.triangulation.vertex(handle).as_ref().graph_index
.vertex(vertex.handle)
.as_ref()
.graph_index
} }
pub fn vertex(&self, graph_index: VertexGraphIndex) -> VertexIndex { pub fn handle(&self, graph_index: VertexIndex) -> FixedVertexHandle {
self.graph_index_to_vertex[graph_index.node_index().index()].unwrap() self.vertex_to_handle[graph_index.node_index().index()].unwrap()
} }
pub fn position(&self, vertex: VertexIndex) -> Point { pub fn position(&self, vertex: VertexIndex) -> Point {
let position = self.triangulation.vertex(vertex.handle).position(); let position = self.triangulation.vertex(self.handle(vertex)).position();
point! {x: position.x, y: position.y} point! {x: position.x, y: position.y}
} }
} }
@ -120,23 +111,13 @@ impl MeshVisitMap {
} }
} }
pub trait IndexHolder { impl<T: GetNodeIndex> visit::VisitMap<T> for MeshVisitMap {
fn index(&self) -> usize;
}
impl IndexHolder for VertexIndex {
fn index(&self) -> usize {
self.handle.index()
}
}
impl<T: IndexHolder> visit::VisitMap<T> for MeshVisitMap {
fn visit(&mut self, a: T) -> bool { fn visit(&mut self, a: T) -> bool {
!self.fixedbitset.put(a.index()) !self.fixedbitset.put(a.node_index().index())
} }
fn is_visited(&self, a: &T) -> bool { fn is_visited(&self, a: &T) -> bool {
self.fixedbitset.contains(a.index()) self.fixedbitset.contains(a.node_index().index())
} }
} }
@ -144,6 +125,7 @@ impl visit::Visitable for Mesh {
type Map = MeshVisitMap; type Map = MeshVisitMap;
fn visit_map(&self) -> Self::Map { fn visit_map(&self) -> Self::Map {
// FIXME: This seems wrong, but pathfinding works for some reason. Investigate.
MeshVisitMap::with_capacity(self.triangulation.num_vertices()) MeshVisitMap::with_capacity(self.triangulation.num_vertices())
} }
@ -195,12 +177,8 @@ impl<'a> visit::IntoEdgeReferences for &'a Mesh {
self.triangulation self.triangulation
.directed_edges() .directed_edges()
.map(|edge| MeshEdgeReference { .map(|edge| MeshEdgeReference {
from: VertexIndex { from: self.vertex(edge.from().fix()),
handle: edge.from().fix(), to: self.vertex(edge.to().fix()),
},
to: VertexIndex {
handle: edge.to().fix(),
},
}), }),
) )
} }
@ -209,14 +187,12 @@ impl<'a> visit::IntoEdgeReferences for &'a Mesh {
impl<'a> visit::IntoNeighbors for &'a Mesh { impl<'a> visit::IntoNeighbors for &'a Mesh {
type Neighbors = Box<dyn Iterator<Item = VertexIndex> + 'a>; type Neighbors = Box<dyn Iterator<Item = VertexIndex> + 'a>;
fn neighbors(self, a: Self::NodeId) -> Self::Neighbors { fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
Box::new( Box::new(
self.triangulation self.triangulation
.vertex(a.handle) .vertex(self.handle(vertex))
.out_edges() .out_edges()
.map(|handle| VertexIndex { .map(|handle| self.vertex(handle.to().fix())),
handle: handle.to().fix(),
}),
) )
} }
} }
@ -227,15 +203,11 @@ impl<'a> visit::IntoEdges for &'a Mesh {
fn edges(self, a: Self::NodeId) -> Self::Edges { fn edges(self, a: Self::NodeId) -> Self::Edges {
Box::new( Box::new(
self.triangulation self.triangulation
.vertex(a.handle) .vertex(self.handle(a))
.out_edges() .out_edges()
.map(|edge| MeshEdgeReference { .map(|edge| MeshEdgeReference {
from: VertexIndex { from: self.vertex(edge.from().fix()),
handle: edge.from().fix(), to: self.vertex(edge.to().fix()),
},
to: VertexIndex {
handle: edge.to().fix(),
},
}), }),
) )
} }

View File

@ -53,7 +53,7 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<u64> { fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<u64> {
self.observer.before_probe(&self.tracer, &self.trace, edge); self.observer.before_probe(&self.tracer, &self.trace, edge);
if edge.target() != self.tracer.mesh.vertex(self.to.into()) if edge.target() != self.to.into()
&& self && self
.tracer .tracer
.step(&mut self.trace, edge.target(), 5.0) .step(&mut self.trace, edge.target(), 5.0)
@ -98,7 +98,7 @@ impl Router {
let (_cost, _path) = astar( let (_cost, _path) = astar(
&mesh, &mesh,
mesh.vertex(from.into()), from.into(),
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer), &mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
) )
.unwrap(); // TODO. .unwrap(); // TODO.

View File

@ -4,7 +4,7 @@ use crate::{
draw::{BareHead, Draw, Head, SegbendHead}, draw::{BareHead, Draw, Head, SegbendHead},
graph::FixedDotIndex, graph::FixedDotIndex,
layout::Layout, layout::Layout,
mesh::{Mesh, VertexGraphIndex, VertexIndex}, mesh::{Mesh, VertexIndex},
rules::Rules, rules::Rules,
}; };
@ -31,7 +31,7 @@ impl<'a> Tracer<'a> {
pub fn start(&mut self, from: FixedDotIndex) -> Trace { pub fn start(&mut self, from: FixedDotIndex) -> Trace {
Trace { Trace {
path: vec![self.mesh.vertex(from.into())], path: vec![from.into()],
head: BareHead { dot: from }.into(), head: BareHead { dot: from }.into(),
} }
} }
@ -113,10 +113,10 @@ impl<'a> Tracer<'a> {
} }
}*/ }*/
match self.mesh.graph_index(around) { match around {
VertexGraphIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width), VertexIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width),
VertexGraphIndex::FixedBend(_fixed_bend) => todo!(), VertexIndex::FixedBend(_fixed_bend) => todo!(),
VertexGraphIndex::LooseBend(_loose_bend) => todo!(), VertexIndex::LooseBend(_loose_bend) => todo!(),
} }
} }