From fe8fd3909fed81c6b39626b7e3d9b2b6c08bd9f0 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 2 Dec 2024 05:56:37 +0100 Subject: [PATCH] fix(autorouter,router): actually propagate the edit out of route steppers I forgot to do this earlier, and didn't notice because I didn't test it. There are still a few changes to be done before recording and edit applying is functional. --- Cargo.toml | 1 + src/autorouter/autoroute.rs | 11 ++++++++++- src/autorouter/pointroute.rs | 1 + src/router/draw.rs | 32 +++++++++++++++++++++--------- src/router/navcord.rs | 38 ++++++++++++++++++++++++++---------- src/router/navcorder.rs | 12 +++++++++--- src/router/route.rs | 23 +++++++++------------- src/router/router.rs | 5 +++-- 8 files changed, 84 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 87fd074..fac58d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ derive-getters.workspace = true enum_dispatch = "0.3.13" geo.workspace = true petgraph.workspace = true +replace_with = "0.1.7" rstar.workspace = true serde.workspace = true spade.workspace = true diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index 90facc5..af72e85 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -63,6 +63,7 @@ impl AutorouteExecutionStepper { ratlines_iter, options, route: Some(router.route( + LayoutEdit::new(), origin, destination, options.router_options.routed_band_width, @@ -123,14 +124,22 @@ impl Step, Option, AutorouteContinu Router::new(autorouter.board.layout_mut(), self.options.router_options); self.curr_ratline = Some(new_ratline); + + let recorder = if let Some(taken_route) = self.route.take() { + let (_astar, navcord, ..) = taken_route.dissolve(); + navcord.recorder + } else { + LayoutEdit::new() + }; + self.route = Some(router.route( + recorder, source, target, self.options.router_options.routed_band_width, )?); } else { self.curr_ratline = None; - //return Ok(AutorouteStatus::Finished); } Ok(ControlFlow::Continue(AutorouteContinueStatus::Routed( diff --git a/src/autorouter/pointroute.rs b/src/autorouter/pointroute.rs index 42b3f86..9da6c5f 100644 --- a/src/autorouter/pointroute.rs +++ b/src/autorouter/pointroute.rs @@ -47,6 +47,7 @@ impl PointrouteExecutionStepper { Ok(Self { point, route: router.route( + LayoutEdit::new(), origin, destination, options.router_options.routed_band_width, diff --git a/src/router/draw.rs b/src/router/draw.rs index d3f785a..b1a24c5 100644 --- a/src/router/draw.rs +++ b/src/router/draw.rs @@ -31,6 +31,9 @@ pub enum DrawException { CannotWrapAround(GearIndex, #[source] DrawingException), } +/// This struct is a simple wrapper whose sole purpose is to have a separate +/// file for the router module's routines for drawing and erasing the primitives +/// to pull out or contract the currently routed band. pub struct Draw<'a, R: AccessRules> { layout: &'a mut Layout, } @@ -48,6 +51,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { #[debug_ensures(ret.is_err() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] pub fn finish_in_dot( &mut self, + recorder: &mut LayoutEdit, head: Head, into: FixedDotIndex, width: f64, @@ -57,7 +61,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { .head_into_dot_segment(&head, into, width) .map_err(Into::::into)?; let head = self - .extend_head(head, tangent.start_point()) + .extend_head(recorder, head, tangent.start_point()) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; let layer = head.face().primitive(self.layout.drawing()).layer(); let maybe_net = head.face().primitive(self.layout.drawing()).maybe_net(); @@ -66,7 +70,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { DotIndex::Fixed(dot) => BandTermsegIndex::Straight( self.layout .add_lone_loose_seg( - &mut LayoutEdit::new(), + recorder, dot, into, LoneLooseSegWeight { @@ -80,7 +84,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { DotIndex::Loose(dot) => BandTermsegIndex::Bended( self.layout .add_seq_loose_seg( - &mut LayoutEdit::new(), + recorder, into.into(), dot, SeqLooseSegWeight { @@ -98,6 +102,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { #[debug_ensures(ret.is_err() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] pub fn cane_around_dot( &mut self, + recorder: &mut LayoutEdit, head: Head, around: FixedDotIndex, cw: bool, @@ -110,6 +115,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { .guide() .head_around_dot_offset(&head, around.into(), width); self.cane_around( + recorder, head, around.into(), tangent.start_point(), @@ -125,6 +131,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { #[debug_ensures(ret.is_err() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] pub fn cane_around_bend( &mut self, + recorder: &mut LayoutEdit, head: Head, around: BendIndex, cw: bool, @@ -136,6 +143,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { let offset = self.guide().head_around_bend_offset(&head, around, width); self.cane_around( + recorder, head, around.into(), tangent.start_point(), @@ -151,6 +159,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { #[debug_ensures(ret.is_err() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] fn cane_around( &mut self, + recorder: &mut LayoutEdit, head: Head, around: GearIndex, from: Point, @@ -159,15 +168,19 @@ impl<'a, R: AccessRules> Draw<'a, R> { width: f64, offset: f64, ) -> Result { - let head = self.extend_head(head, from)?; - self.cane(head, around, to, cw, width, offset) + let head = self.extend_head(recorder, head, from)?; + self.cane(recorder, head, around, to, cw, width, offset) } #[debug_ensures(self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] - fn extend_head(&mut self, head: Head, to: Point) -> Result { + fn extend_head( + &mut self, + recorder: &mut LayoutEdit, + head: Head, + to: Point, + ) -> Result { if let Head::Cane(head) = head { - self.layout - .move_dot(&mut LayoutEdit::new(), head.face.into(), to)?; + self.layout.move_dot(recorder, head.face.into(), to)?; Ok(Head::Cane(head)) } else { Ok(head) @@ -178,6 +191,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { #[debug_ensures(ret.is_err() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count()))] fn cane( &mut self, + recorder: &mut LayoutEdit, head: Head, around: GearIndex, to: Point, @@ -188,7 +202,7 @@ impl<'a, R: AccessRules> Draw<'a, R> { let layer = head.face().primitive(self.layout.drawing()).layer(); let maybe_net = head.face().primitive(self.layout.drawing()).maybe_net(); let cane = self.layout.insert_cane( - &mut LayoutEdit::new(), + recorder, head.face(), around, LooseDotWeight { diff --git a/src/router/navcord.rs b/src/router/navcord.rs index 1ff95e0..620fc43 100644 --- a/src/router/navcord.rs +++ b/src/router/navcord.rs @@ -1,12 +1,15 @@ use contracts_try::debug_ensures; use petgraph::data::DataMap; -use crate::drawing::{ - bend::LooseBendIndex, - dot::FixedDotIndex, - graph::PrimitiveIndex, - head::{BareHead, CaneHead, Head}, - rules::AccessRules, +use crate::{ + drawing::{ + bend::LooseBendIndex, + dot::FixedDotIndex, + graph::PrimitiveIndex, + head::{BareHead, CaneHead, Head}, + rules::AccessRules, + }, + layout::LayoutEdit, }; use super::{ @@ -15,13 +18,14 @@ use super::{ navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex}, }; -/// The navcord is a structure that holds the movable non-borrowing data of the -/// currently running routing process. +/// The navcord (stepper) is a structure that holds the movable non-borrowing +/// data of the currently running routing process. /// /// The name "navcord" is a shortening of "navigation cord", by analogy to /// "navmesh" being a shortening of "navigation mesh". #[derive(Debug)] pub struct NavcordStepper { + pub recorder: LayoutEdit, /// The currently attempted path. pub path: Vec, /// Head of the routed band. @@ -33,11 +37,13 @@ pub struct NavcordStepper { impl NavcordStepper { /// Creates a new navcord. pub fn new( + recorder: LayoutEdit, source: FixedDotIndex, source_navvertex: NavvertexIndex, width: f64, ) -> NavcordStepper { Self { + recorder, path: vec![source_navvertex], head: BareHead { face: source }.into(), width, @@ -75,7 +81,13 @@ impl NavcordStepper { cw: bool, width: f64, ) -> Result { - Ok(Draw::new(navcorder.layout).cane_around_dot(head, around, cw, width)?) + Ok(Draw::new(navcorder.layout).cane_around_dot( + &mut self.recorder, + head, + around, + cw, + width, + )?) } fn wrap_around_loose_bend( @@ -86,7 +98,13 @@ impl NavcordStepper { cw: bool, width: f64, ) -> Result { - Ok(Draw::new(navcorder.layout).cane_around_bend(head, around.into(), cw, width)?) + Ok(Draw::new(navcorder.layout).cane_around_bend( + &mut self.recorder, + head, + around.into(), + cw, + width, + )?) } fn binavvertex(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> BinavvertexNodeIndex { diff --git a/src/router/navcorder.rs b/src/router/navcorder.rs index 1080a5d..ba6f529 100644 --- a/src/router/navcorder.rs +++ b/src/router/navcorder.rs @@ -3,7 +3,7 @@ use thiserror::Error; use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, - layout::Layout, + layout::{Layout, LayoutEdit}, }; use super::{ @@ -32,11 +32,12 @@ impl<'a, R: AccessRules> Navcorder<'a, R> { pub fn start( &mut self, + recorder: LayoutEdit, source: FixedDotIndex, source_navvertex: NavvertexIndex, width: f64, ) -> NavcordStepper { - NavcordStepper::new(source, source_navvertex, width) + NavcordStepper::new(recorder, source, source_navvertex, width) } pub fn finish( @@ -46,7 +47,12 @@ impl<'a, R: AccessRules> Navcorder<'a, R> { target: FixedDotIndex, width: f64, ) -> Result { - Ok(Draw::new(self.layout).finish_in_dot(navcord.head, target, width)?) + Ok(Draw::new(self.layout).finish_in_dot( + &mut navcord.recorder, + navcord.head, + target, + width, + )?) } #[debug_requires(path[0] == navcord.path[0])] diff --git a/src/router/route.rs b/src/router/route.rs index 24eef0c..b51114e 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -1,10 +1,13 @@ use std::ops::ControlFlow; +use derive_getters::{Dissolve, Getters}; + use crate::{ drawing::{ band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules, }, geometry::primitive::PrimitiveShape, + layout::LayoutEdit, router::{ astar::{Astar, AstarError}, navcord::NavcordStepper, @@ -15,7 +18,9 @@ use crate::{ stepper::Step, }; +#[derive(Getters, Dissolve)] pub struct RouteStepper { + #[getter(skip)] astar: Astar, navcord: NavcordStepper, ghosts: Vec, @@ -25,16 +30,18 @@ pub struct RouteStepper { impl RouteStepper { pub fn new( router: &mut Router, + recorder: LayoutEdit, from: FixedDotIndex, to: FixedDotIndex, width: f64, ) -> Result { let navmesh = Navmesh::new(router.layout(), from, to, router.options().clone())?; - Ok(Self::new_from_navmesh(router, navmesh, width)) + Ok(Self::new_from_navmesh(router, recorder, navmesh, width)) } pub fn new_from_navmesh( router: &mut Router, + recorder: LayoutEdit, navmesh: Navmesh, width: f64, ) -> Self { @@ -43,7 +50,7 @@ impl RouteStepper { let target = navmesh.destination(); let mut navcorder = Navcorder::new(router.layout_mut()); - let mut navcord = navcorder.start(source, source_navvertex, width); + let mut navcord = navcorder.start(recorder, source, source_navvertex, width); let mut strategy = RouterAstarStrategy::new(navcorder, &mut navcord, target); let astar = Astar::new(navmesh, source_navvertex, &mut strategy); @@ -61,18 +68,6 @@ impl RouteStepper { pub fn navmesh(&self) -> &Navmesh { &self.astar.graph } - - pub fn navcord(&self) -> &NavcordStepper { - &self.navcord - } - - pub fn ghosts(&self) -> &[PrimitiveShape] { - &self.ghosts - } - - pub fn obstacles(&self) -> &[PrimitiveIndex] { - &self.obstacles - } } impl<'a, R: AccessRules> Step, BandTermsegIndex> for RouteStepper { diff --git a/src/router/router.rs b/src/router/router.rs index c7457df..4972047 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -18,7 +18,7 @@ use crate::{ shape::{AccessShape, MeasureLength}, }, graph::{GetPetgraphIndex, MakeRef}, - layout::Layout, + layout::{Layout, LayoutEdit}, }; use super::{ @@ -182,11 +182,12 @@ impl<'a, R: AccessRules> Router<'a, R> { pub fn route( &mut self, + recorder: LayoutEdit, from: FixedDotIndex, to: FixedDotIndex, width: f64, ) -> Result { - RouteStepper::new(self, from, to, width) + RouteStepper::new(self, recorder, from, to, width) } pub fn layout_mut(&mut self) -> &mut Layout {