From a3cedff5771d5d117fff9d66ccd84de9940fe0b4 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 30 Oct 2023 18:22:14 +0000 Subject: [PATCH] mesh: Make it possible for fixed and loose bends to be vertices But not adding tem to the mesh yet, as it's going to take some effort. --- src/draw.rs | 5 ++--- src/layout.rs | 6 +++--- src/main.rs | 32 ++++++++++++++++---------------- src/mesh.rs | 38 ++++++++++++++++++++++++++------------ src/router.rs | 16 +++++++--------- src/tracer.rs | 24 ++++++++++++++++++------ 6 files changed, 72 insertions(+), 49 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index 1262fff..80bb5bd 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -5,13 +5,12 @@ use geo::{EuclideanLength, Point}; use crate::{ graph::{ BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex, - LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight, - MakePrimitive, + LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive, }, guide::Guide, layout::Layout, math::Circle, - primitive::{GetOtherEnd, GetWeight}, + primitive::GetOtherEnd, rules::{Conditions, Rules}, segbend::Segbend, }; diff --git a/src/layout.rs b/src/layout.rs index 4d6b031..e60c2e3 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -357,7 +357,7 @@ impl Layout { } pub fn nodes(&self) -> impl Iterator + '_ { - self.node_indexes().map(|ni| { + self.node_indices().map(|ni| { self.graph .node_weight(ni.node_index()) .unwrap() @@ -366,7 +366,7 @@ impl Layout { } pub fn shapes(&self) -> impl Iterator + '_ { - self.node_indexes() + self.node_indices() .map(|ni| ni.primitive(&self.graph).shape()) } @@ -374,7 +374,7 @@ impl Layout { self.graph.node_count() } - fn node_indexes(&self) -> impl Iterator + '_ { + fn node_indices(&self) -> impl Iterator + '_ { self.rtree.iter().map(|wrapper| wrapper.data) } } diff --git a/src/main.rs b/src/main.rs index 87ed6e1..9710677 100644 --- a/src/main.rs +++ b/src/main.rs @@ -454,27 +454,27 @@ fn render_times( //let result = panic::catch_unwind(|| { for shape in layout.shapes() { match shape { - Shape::Dot(FixedDot) => { + Shape::Dot(dot) => { let _ = canvas.filled_circle( - FixedDot.c.pos.x() as i16, - FixedDot.c.pos.y() as i16, - FixedDot.c.r as i16, + dot.c.pos.x() as i16, + dot.c.pos.y() as i16, + dot.c.r as i16, Color::RGB(200, 52, 52), ); } - Shape::Seg(FixedSeg) => { + Shape::Seg(seg) => { let _ = canvas.thick_line( - FixedSeg.from.x() as i16, - FixedSeg.from.y() as i16, - FixedSeg.to.x() as i16, - FixedSeg.to.y() as i16, - FixedSeg.width as u8, + seg.from.x() as i16, + seg.from.y() as i16, + seg.to.x() as i16, + seg.to.y() as i16, + seg.width as u8, Color::RGB(200, 52, 52), ); } - Shape::Bend(FixedBend) => { - let delta1 = FixedBend.from - FixedBend.c.pos; - let delta2 = FixedBend.to - FixedBend.c.pos; + Shape::Bend(bend) => { + let delta1 = bend.from - bend.c.pos; + let delta2 = bend.to - bend.c.pos; let angle1 = delta1.y().atan2(delta1.x()); let angle2 = delta2.y().atan2(delta2.x()); @@ -483,10 +483,10 @@ fn render_times( let _ = canvas.arc( //around_circle.pos.x() as i16, //around_circle.pos.y() as i16, - FixedBend.c.pos.x() as i16, - FixedBend.c.pos.y() as i16, + bend.c.pos.x() as i16, + bend.c.pos.y() as i16, //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, - (FixedBend.circle().r + (d as f64)) as i16, + (bend.circle().r + (d as f64)) as i16, angle1.to_degrees() as i16, angle2.to_degrees() as i16, Color::RGB(200, 52, 52), diff --git a/src/mesh.rs b/src/mesh.rs index 36fe65e..3c083d0 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -1,5 +1,7 @@ +use enum_dispatch::enum_dispatch; use fixedbitset::FixedBitSet; use geo::{point, Point}; +use petgraph::stable_graph::NodeIndex; use petgraph::visit::{self, NodeIndexable}; use spade::{ handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle}, @@ -8,18 +10,26 @@ use spade::{ }; use crate::{ - graph::{DotIndex, FixedDotIndex, GetNodeIndex, Index}, + graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex}, layout::Layout, }; use crate::{primitive::MakeShape, shape::ShapeTrait}; #[derive(Debug, Clone)] struct Vertex { - dot: FixedDotIndex, + graph_index: VertexGraphIndex, x: f64, y: f64, } +#[enum_dispatch(GetNodeIndex)] +#[derive(Debug, Clone, Copy)] +pub enum VertexGraphIndex { + FixedDot(FixedDotIndex), + FixedBend(FixedBendIndex), + LooseBend(LooseBendIndex), +} + #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] pub struct VertexIndex { handle: FixedVertexHandle, @@ -35,29 +45,30 @@ impl HasPosition for Vertex { #[derive(Debug, Clone)] pub struct Mesh { triangulation: DelaunayTriangulation, - dot_to_vertex: Vec>, + graph_index_to_vertex: Vec>, } impl Mesh { pub fn new() -> Self { Self { triangulation: DelaunayTriangulation::new(), - dot_to_vertex: Vec::new(), + graph_index_to_vertex: Vec::new(), } } pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> { self.triangulation.clear(); - self.dot_to_vertex = Vec::new(); - self.dot_to_vertex.resize(layout.graph.node_bound(), None); + self.graph_index_to_vertex = Vec::new(); + self.graph_index_to_vertex + .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.dot_to_vertex[dot.node_index().index()] = Some(VertexIndex { + self.graph_index_to_vertex[dot.node_index().index()] = Some(VertexIndex { handle: self.triangulation.insert(Vertex { - dot, + graph_index: dot.into(), x: center.x(), y: center.y(), })?, @@ -68,12 +79,15 @@ impl Mesh { Ok(()) } - pub fn dot(&self, vertex: VertexIndex) -> FixedDotIndex { - self.triangulation.vertex(vertex.handle).as_ref().dot + pub fn graph_index(&self, vertex: VertexIndex) -> VertexGraphIndex { + self.triangulation + .vertex(vertex.handle) + .as_ref() + .graph_index } - pub fn vertex(&self, dot: FixedDotIndex) -> VertexIndex { - self.dot_to_vertex[dot.node_index().index()].unwrap() + pub fn vertex(&self, graph_index: VertexGraphIndex) -> VertexIndex { + self.graph_index_to_vertex[graph_index.node_index().index()].unwrap() } pub fn position(&self, vertex: VertexIndex) -> Point { diff --git a/src/router.rs b/src/router.rs index 1c22ec7..0f882a4 100644 --- a/src/router.rs +++ b/src/router.rs @@ -3,7 +3,7 @@ use petgraph::visit::EdgeRef; use spade::InsertionError; use crate::astar::{astar, AstarStrategy, PathTracker}; -use crate::graph::{DotIndex, FixedDotIndex}; +use crate::graph::FixedDotIndex; use crate::layout::Layout; use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex}; @@ -26,12 +26,12 @@ pub struct Router { struct RouterAstarStrategy<'a, RO: RouterObserver> { tracer: Tracer<'a>, trace: Trace, - to: VertexIndex, + to: FixedDotIndex, observer: &'a mut RO, } impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> { - pub fn new(tracer: Tracer<'a>, trace: Trace, to: VertexIndex, observer: &'a mut RO) -> Self { + pub fn new(tracer: Tracer<'a>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self { Self { tracer, trace, @@ -48,14 +48,12 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<' self.tracer.rework_path(&mut self.trace, &new_path, 5.0); self.observer.on_rework(&self.tracer, &self.trace); - self.tracer - .finish(&mut self.trace, self.tracer.mesh.dot(self.to), 5.0) - .is_ok() + self.tracer.finish(&mut self.trace, self.to, 5.0).is_ok() } fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option { self.observer.before_probe(&self.tracer, &self.trace, edge); - if edge.target() != self.to + if edge.target() != self.tracer.mesh.vertex(self.to.into()) && self .tracer .step(&mut self.trace, edge.target(), 5.0) @@ -100,8 +98,8 @@ impl Router { let (_cost, _path) = astar( &mesh, - mesh.vertex(from), - &mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer), + mesh.vertex(from.into()), + &mut RouterAstarStrategy::new(tracer, trace, to.into(), observer), ) .unwrap(); // TODO. diff --git a/src/tracer.rs b/src/tracer.rs index e721717..50194d9 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -1,10 +1,10 @@ use contracts::debug_ensures; use crate::{ - draw::{BareHead, Draw, Head, HeadTrait, SegbendHead}, + draw::{BareHead, Draw, Head, SegbendHead}, graph::FixedDotIndex, layout::Layout, - mesh::{Mesh, VertexIndex}, + mesh::{Mesh, VertexGraphIndex, 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)], + path: vec![self.mesh.vertex(from.into())], head: BareHead { dot: from }.into(), } } @@ -81,14 +81,13 @@ impl<'a> Tracer<'a> { #[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + 1))] #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))] pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> { - let to_dot = self.mesh.dot(to); - trace.head = self.wrap(trace.head, to_dot, width)?.into(); + trace.head = self.wrap(trace.head, to, width)?.into(); trace.path.push(to); Ok(()) } - fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result { + fn wrap(&mut self, head: Head, around: VertexIndex, width: f64) -> Result { /*let _around_pos = self.layout.primitive(around).weight().circle.pos; let _around_primitive = self.layout.primitive(around); @@ -114,6 +113,19 @@ 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!(), + } + } + + fn wrap_around_fixed_dot( + &mut self, + head: Head, + around: FixedDotIndex, + width: f64, + ) -> Result { self.draw().segbend_around_dot(head, around.into(), width) }