From e5ba7401c1db7078171e9c700f20567796e4d681 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 31 Aug 2023 20:33:34 +0200 Subject: [PATCH] Move routing methods to the `Route` struct Commented out shove/squeeze features for now. --- src/draw.rs | 7 ++- src/guide.rs | 2 +- src/main.rs | 7 +-- src/mesh.rs | 4 +- src/route.rs | 92 +++++++++++++++++++++++++++++++++++++++ src/router.rs | 118 ++++++++++++-------------------------------------- 6 files changed, 131 insertions(+), 99 deletions(-) create mode 100644 src/route.rs diff --git a/src/draw.rs b/src/draw.rs index 4d4f321..e7a22f7 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -5,11 +5,16 @@ use crate::{ guide::Guide, layout::Layout, math::Circle, - router::Head, rules::{Conditions, Rules}, segbend::Segbend, }; +#[derive(Debug, Clone, Copy)] +pub struct Head { + pub dot: DotIndex, + pub segbend: Option, +} + pub struct Draw<'a> { layout: &'a mut Layout, rules: &'a Rules, diff --git a/src/guide.rs b/src/guide.rs index 8a52395..b1f2f7e 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -1,10 +1,10 @@ use geo::Line; use crate::{ + draw::Head, graph::{BendIndex, DotIndex}, layout::Layout, math::{self, Circle}, - router::Head, rules::{Conditions, Rules}, }; diff --git a/src/main.rs b/src/main.rs index 6074a3f..bed772b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod layout; mod math; mod mesh; mod primitive; +mod route; mod router; mod rules; mod segbend; @@ -217,7 +218,7 @@ fn main() { let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap(); let _ = router.draw_finish(head, dot7, 5.0);*/ - router.route(dot1_1, dot1_2); + router.enroute(dot1_1, dot1_2); render_times(&mut event_pump, &mut canvas, &mut router, None, -1); render_times( @@ -257,10 +258,10 @@ fn render_times( if let Some(follower) = follower { let state = event_pump.mouse_state(); - let _ = router.move_dot( + /*let _ = router.move_dot( *follower.as_dot().unwrap(), (state.x() as f64, state.y() as f64).into(), - ); + );*/ } let result = panic::catch_unwind(|| { diff --git a/src/mesh.rs b/src/mesh.rs index 9f47b9b..5c1b175 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -1,8 +1,6 @@ use fixedbitset::FixedBitSet; use geo::{point, Point}; -use petgraph::{ - visit::{self, NodeIndexable}, -}; +use petgraph::visit::{self, NodeIndexable}; use spade::{ handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle}, iterators::DirectedEdgeIterator, diff --git a/src/route.rs b/src/route.rs new file mode 100644 index 0000000..0ae0adc --- /dev/null +++ b/src/route.rs @@ -0,0 +1,92 @@ +use crate::{ + draw::{Draw, Head}, + layout::Layout, + mesh::{Mesh, VertexIndex}, + rules::Rules, +}; + +#[derive(Debug)] +pub struct Trace { + path: Vec, + head: Head, +} + +pub struct Route<'a> { + layout: &'a mut Layout, + rules: &'a Rules, + mesh: &'a Mesh, + width: f64, +} + +impl<'a> Route<'a> { + pub fn new(layout: &'a mut Layout, rules: &'a Rules, mesh: &'a Mesh, width: f64) -> Self { + Route { + layout, + rules, + mesh, + width, + } + } + + pub fn start(&mut self, from: VertexIndex) -> Trace { + Trace { + path: vec![from], + head: Head { + dot: self.mesh.dot(from), + segbend: None, + }, + } + } + + pub fn finish(&mut self, trace: Trace, into: VertexIndex) { + let into_dot = self.mesh.dot(into); + let width = self.width; + self.draw().finish(trace.head, into_dot, width); + } + + pub fn rework_path(&mut self, mut trace: Trace, path: &[VertexIndex]) -> Result { + let prefix_length = trace + .path + .iter() + .zip(path) + .take_while(|(v1, v2)| v1 == v2) + .count(); + + let length = trace.path.len(); + trace = self.undo_path(trace, length - prefix_length)?; + self.path(trace, &path[prefix_length..]) + } + + pub fn path(&mut self, mut trace: Trace, path: &[VertexIndex]) -> Result { + for vertex in path { + trace = self.step(trace, *vertex)?; + } + Ok(trace) + } + + pub fn undo_path(&mut self, mut trace: Trace, step_count: usize) -> Result { + for _ in 0..step_count { + trace = self.undo_step(trace)?; + } + Ok(trace) + } + + pub fn step(&mut self, mut trace: Trace, to: VertexIndex) -> Result { + let to_dot = self.mesh.dot(to); + let width = self.width; + trace.head = self + .draw() + .segbend_around_dot(trace.head, to_dot, true, width)?; + Ok(trace) + } + + pub fn undo_step(&mut self, mut trace: Trace) -> Result { + trace.head = self.draw().undo_segbend(trace.head).unwrap(); + trace.path.pop(); + Ok(trace) + } + + fn draw(&mut self) -> Draw { + Draw::new(&mut self.layout, &self.rules) + } +} diff --git a/src/router.rs b/src/router.rs index f07e09c..d6c663c 100644 --- a/src/router.rs +++ b/src/router.rs @@ -4,7 +4,7 @@ use spade::InsertionError; use crate::astar::astar; use crate::bow::Bow; -use crate::draw::Draw; +use crate::draw::{Draw, Head}; use crate::graph::{BendIndex, DotIndex, Ends, SegIndex, TaggedIndex}; use crate::graph::{BendWeight, DotWeight, SegWeight}; use crate::guide::Guide; @@ -12,123 +12,59 @@ use crate::layout::Layout; use crate::math::Circle; use crate::mesh::{Mesh, VertexIndex}; +use crate::route::Route; use crate::rules::{Conditions, Rules}; use crate::segbend::Segbend; pub struct Router { pub layout: Layout, - mesh: Mesh, rules: Rules, } -struct Route { - path: Vec, - head: Head, - width: f64, -} - -#[derive(Debug, Clone, Copy)] -pub struct Head { - pub dot: DotIndex, - pub segbend: Option, -} - impl Router { pub fn new() -> Self { Router { layout: Layout::new(), - mesh: Mesh::new(), rules: Rules::new(), } } - pub fn route(&mut self, from: DotIndex, to: DotIndex) -> Result<(), InsertionError> { + pub fn enroute(&mut self, from: DotIndex, to: DotIndex) -> Result<(), InsertionError> { // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // right. - self.mesh.triangulate(&self.layout)?; + //self.mesh.triangulate(&self.layout)?; + let mut mesh = Mesh::new(); + mesh.triangulate(&self.layout)?; - let (_cost, mesh_path) = astar( - &self.mesh, - self.mesh.vertex(from), + let (_cost, path) = astar( + &mesh, + mesh.vertex(from), |node, tracker| { let new_path = tracker.reconstruct_path_to(node); - (node != self.mesh.vertex(to)).then_some(0) + (node != mesh.vertex(to)).then_some(0) }, |_edge| 1, |_| 0, ) .unwrap(); // TODO. - let path: Vec = mesh_path - .iter() - .map(|vertex| self.mesh.dot(*vertex)) - .collect(); + /*let path: Vec = mesh_path + .iter() + .map(|vertex| self.mesh.dot(*vertex)) + .collect();*/ - let mut route = self.route_start(path[0], 5.0); - route = self.route_path(route, &path[1..(path.len() - 1)]).unwrap(); // TODO. - let _ = self.route_finish(route, path[path.len() - 1]); + let mut trace = self.route(&mesh, 5.0).start(path[0]); + trace = self + .route(&mesh, 5.0) + .path(trace, &path[1..(path.len() - 1)]) + .unwrap(); // TODO. + let _ = self.route(&mesh, 5.0).finish(trace, path[path.len() - 1]); Ok(()) } - fn route_start(&mut self, from: DotIndex, width: f64) -> Route { - Route { - path: vec![], - head: self.draw().start(from), - width, - } - } - - fn route_finish(&mut self, route: Route, into: DotIndex) -> Result<(), ()> { - self.draw().finish(route.head, into, route.width)?; - Ok(()) - } - - fn route_path(&mut self, mut route: Route, path: &[DotIndex]) -> Result { - for dot in path { - route = self.route_step(route, *dot)?; - } - - Ok(route) - } - - fn reroute_path(&mut self, mut route: Route, path: &[DotIndex]) -> Result { - let prefix_length = route - .path - .iter() - .zip(path) - .take_while(|(vertex, dot)| **vertex == self.mesh.vertex(**dot)) - .count(); - - let length = route.path.len(); - route = self.unroute_steps(route, length - prefix_length)?; - route = self.route_path(route, &path[prefix_length..])?; - Ok(route) - } - - fn unroute_step(&mut self, mut route: Route) -> Result { - route.head = self.draw().undo_segbend(route.head).unwrap(); - route.path.pop(); - Ok(route) - } - - fn unroute_steps(&mut self, mut route: Route, step_count: usize) -> Result { - for _ in 0..step_count { - route = self.unroute_step(route)?; - } - Ok(route) - } - - fn route_step(&mut self, mut route: Route, to: DotIndex) -> Result { - route.head = self - .draw() - .segbend_around_dot(route.head, to, true, route.width)?; - route.path.push(self.mesh.vertex(to)); - Ok(route) - } - - pub fn squeeze_around_dot( + /*pub fn squeeze_around_dot( &mut self, head: Head, around: DotIndex, @@ -238,18 +174,18 @@ impl Router { } Ok(()) + }*/ + + pub fn route<'a>(&'a mut self, mesh: &'a Mesh, width: f64) -> Route { + Route::new(&mut self.layout, &self.rules, mesh, width) } - pub fn draw(&mut self) -> Draw { - Draw::new(&mut self.layout, &self.rules) - } - - pub fn routeedges(&self) -> impl Iterator + '_ { + /*pub fn routeedges(&self) -> impl Iterator + '_ { self.mesh.edge_references().map(|edge| { ( self.mesh.position(edge.source()), self.mesh.position(edge.target()), ) }) - } + }*/ }