mirror of https://codeberg.org/topola/topola.git
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:
parent
0760fb2da3
commit
fe8fd3909f
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ impl PointrouteExecutionStepper {
|
|||
Ok(Self {
|
||||
point,
|
||||
route: router.route(
|
||||
LayoutEdit::new(),
|
||||
origin,
|
||||
destination,
|
||||
options.router_options.routed_band_width,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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])]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue