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.
This commit is contained in:
Mikolaj Wielgus 2024-12-02 05:56:37 +01:00
parent 0760fb2da3
commit fe8fd3909f
8 changed files with 84 additions and 39 deletions

View File

@ -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

View File

@ -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<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, 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(

View File

@ -47,6 +47,7 @@ impl PointrouteExecutionStepper {
Ok(Self {
point,
route: router.route(
LayoutEdit::new(),
origin,
destination,
options.router_options.routed_band_width,

View File

@ -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<R>,
}
@ -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::<DrawException>::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<CaneHead, DrawingException> {
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<Head, Infringement> {
fn extend_head(
&mut self,
recorder: &mut LayoutEdit,
head: Head,
to: Point,
) -> Result<Head, Infringement> {
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 {

View File

@ -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<NavvertexIndex>,
/// 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<CaneHead, NavcorderException> {
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<CaneHead, NavcorderException> {
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 {

View File

@ -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<BandTermsegIndex, NavcorderException> {
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])]

View File

@ -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<Navmesh, f64>,
navcord: NavcordStepper,
ghosts: Vec<PrimitiveShape>,
@ -25,16 +30,18 @@ pub struct RouteStepper {
impl RouteStepper {
pub fn new(
router: &mut Router<impl AccessRules>,
recorder: LayoutEdit,
from: FixedDotIndex,
to: FixedDotIndex,
width: f64,
) -> Result<Self, NavmeshError> {
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<impl AccessRules>,
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<Router<'a, R>, BandTermsegIndex> for RouteStepper {

View File

@ -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, NavmeshError> {
RouteStepper::new(self, from, to, width)
RouteStepper::new(self, recorder, from, to, width)
}
pub fn layout_mut(&mut self) -> &mut Layout<R> {