From 13e38c68899024066b4250e719929e6c9c9081cd Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 3 Nov 2023 00:31:01 +0000 Subject: [PATCH] mesh: Use a tagged graph index as vertex index instead of a Spade handle --- src/graph.rs | 21 +++++++++++-- src/mesh.rs | 82 +++++++++++++++++---------------------------------- src/router.rs | 4 +-- src/tracer.rs | 12 ++++---- 4 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index a61853e..20cc674 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,7 +1,10 @@ use enum_as_inner::EnumAsInner; use enum_dispatch::enum_dispatch; use petgraph::stable_graph::{NodeIndex, StableDiGraph}; -use std::marker::PhantomData; +use std::{ + hash::{Hash, Hasher}, + marker::PhantomData, +}; use crate::{ math::Circle, @@ -243,7 +246,7 @@ pub trait MakePrimitive { fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a>; } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy)] pub struct GenericIndex { node_index: NodeIndex, marker: PhantomData, @@ -258,6 +261,20 @@ impl GenericIndex { } } +impl Hash for GenericIndex { + fn hash(&self, state: &mut H) { + self.node_index.hash(state) + } +} + +impl PartialEq for GenericIndex { + fn eq(&self, other: &Self) -> bool { + self.node_index == other.node_index + } +} + +impl Eq for GenericIndex {} + impl GetNodeIndex for GenericIndex { fn node_index(&self) -> NodeIndex { self.node_index diff --git a/src/mesh.rs b/src/mesh.rs index 4102270..e1c0586 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -16,24 +16,19 @@ use crate::{primitive::MakeShape, shape::ShapeTrait}; #[derive(Debug, Clone)] struct Vertex { - graph_index: VertexGraphIndex, + graph_index: VertexIndex, x: f64, y: f64, } #[enum_dispatch(GetNodeIndex)] -#[derive(Debug, Clone, Copy)] -pub enum VertexGraphIndex { +#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] +pub enum VertexIndex { FixedDot(FixedDotIndex), FixedBend(FixedBendIndex), LooseBend(LooseBendIndex), } -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] -pub struct VertexIndex { - handle: FixedVertexHandle, -} - impl HasPosition for Vertex { type Scalar = f64; fn position(&self) -> Point2 { @@ -44,53 +39,49 @@ impl HasPosition for Vertex { #[derive(Debug, Clone)] pub struct Mesh { triangulation: DelaunayTriangulation, - graph_index_to_vertex: Vec>, + vertex_to_handle: Vec>, } impl Mesh { pub fn new() -> Self { Self { triangulation: DelaunayTriangulation::new(), - graph_index_to_vertex: Vec::new(), + vertex_to_handle: Vec::new(), } } pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> { self.triangulation.clear(); - self.graph_index_to_vertex = Vec::new(); - self.graph_index_to_vertex + self.vertex_to_handle = Vec::new(); + self.vertex_to_handle .resize(layout.graph.node_bound(), None); for node in layout.nodes() { if let Index::FixedDot(dot) = node { let center = layout.primitive(dot).shape().center(); - self.graph_index_to_vertex[dot.node_index().index()] = Some(VertexIndex { - handle: self.triangulation.insert(Vertex { + self.vertex_to_handle[dot.node_index().index()] = + Some(self.triangulation.insert(Vertex { graph_index: dot.into(), x: center.x(), y: center.y(), - })?, - }); + })?); } } Ok(()) } - pub fn graph_index(&self, vertex: VertexIndex) -> VertexGraphIndex { - self.triangulation - .vertex(vertex.handle) - .as_ref() - .graph_index + pub fn vertex(&self, handle: FixedVertexHandle) -> VertexIndex { + self.triangulation.vertex(handle).as_ref().graph_index } - pub fn vertex(&self, graph_index: VertexGraphIndex) -> VertexIndex { - self.graph_index_to_vertex[graph_index.node_index().index()].unwrap() + pub fn handle(&self, graph_index: VertexIndex) -> FixedVertexHandle { + self.vertex_to_handle[graph_index.node_index().index()].unwrap() } 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} } } @@ -120,23 +111,13 @@ impl MeshVisitMap { } } -pub trait IndexHolder { - fn index(&self) -> usize; -} - -impl IndexHolder for VertexIndex { - fn index(&self) -> usize { - self.handle.index() - } -} - -impl visit::VisitMap for MeshVisitMap { +impl visit::VisitMap for MeshVisitMap { 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 { - self.fixedbitset.contains(a.index()) + self.fixedbitset.contains(a.node_index().index()) } } @@ -144,6 +125,7 @@ impl visit::Visitable for Mesh { type Map = MeshVisitMap; fn visit_map(&self) -> Self::Map { + // FIXME: This seems wrong, but pathfinding works for some reason. Investigate. MeshVisitMap::with_capacity(self.triangulation.num_vertices()) } @@ -195,12 +177,8 @@ impl<'a> visit::IntoEdgeReferences for &'a Mesh { self.triangulation .directed_edges() .map(|edge| MeshEdgeReference { - from: VertexIndex { - handle: edge.from().fix(), - }, - to: VertexIndex { - handle: edge.to().fix(), - }, + from: self.vertex(edge.from().fix()), + to: self.vertex(edge.to().fix()), }), ) } @@ -209,14 +187,12 @@ impl<'a> visit::IntoEdgeReferences for &'a Mesh { impl<'a> visit::IntoNeighbors for &'a Mesh { type Neighbors = Box + 'a>; - fn neighbors(self, a: Self::NodeId) -> Self::Neighbors { + fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors { Box::new( self.triangulation - .vertex(a.handle) + .vertex(self.handle(vertex)) .out_edges() - .map(|handle| VertexIndex { - handle: handle.to().fix(), - }), + .map(|handle| self.vertex(handle.to().fix())), ) } } @@ -227,15 +203,11 @@ impl<'a> visit::IntoEdges for &'a Mesh { fn edges(self, a: Self::NodeId) -> Self::Edges { Box::new( self.triangulation - .vertex(a.handle) + .vertex(self.handle(a)) .out_edges() .map(|edge| MeshEdgeReference { - from: VertexIndex { - handle: edge.from().fix(), - }, - to: VertexIndex { - handle: edge.to().fix(), - }, + from: self.vertex(edge.from().fix()), + to: self.vertex(edge.to().fix()), }), ) } diff --git a/src/router.rs b/src/router.rs index 0f882a4..93e9aa8 100644 --- a/src/router.rs +++ b/src/router.rs @@ -53,7 +53,7 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<' fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option { 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 .tracer .step(&mut self.trace, edge.target(), 5.0) @@ -98,7 +98,7 @@ impl Router { let (_cost, _path) = astar( &mesh, - mesh.vertex(from.into()), + from.into(), &mut RouterAstarStrategy::new(tracer, trace, to.into(), observer), ) .unwrap(); // TODO. diff --git a/src/tracer.rs b/src/tracer.rs index 50194d9..a94d7a0 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -4,7 +4,7 @@ use crate::{ draw::{BareHead, Draw, Head, SegbendHead}, graph::FixedDotIndex, layout::Layout, - mesh::{Mesh, VertexGraphIndex, VertexIndex}, + mesh::{Mesh, VertexIndex}, rules::Rules, }; @@ -31,7 +31,7 @@ impl<'a> Tracer<'a> { pub fn start(&mut self, from: FixedDotIndex) -> Trace { Trace { - path: vec![self.mesh.vertex(from.into())], + path: vec![from.into()], head: BareHead { dot: from }.into(), } } @@ -113,10 +113,10 @@ impl<'a> Tracer<'a> { } }*/ - match self.mesh.graph_index(around) { - VertexGraphIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width), - VertexGraphIndex::FixedBend(_fixed_bend) => todo!(), - VertexGraphIndex::LooseBend(_loose_bend) => todo!(), + match around { + VertexIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width), + VertexIndex::FixedBend(_fixed_bend) => todo!(), + VertexIndex::LooseBend(_loose_bend) => todo!(), } }