From 7d75f918e7b283dbe61b2eec972395ccd8096a93 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 21 Oct 2024 23:20:00 +0200 Subject: [PATCH] feat(autorouter): add pointroute execution, which routes to a point Not available as a command (for now?). Hasn't been tested yet. --- src/autorouter/autoroute.rs | 14 ++++---- src/autorouter/autorouter.rs | 54 ++++++++++++++++++++++++++--- src/autorouter/mod.rs | 1 + src/autorouter/pointroute.rs | 67 ++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 11 deletions(-) create mode 100644 src/autorouter/pointroute.rs diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index 44873e9..a85443b 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -55,17 +55,19 @@ impl AutorouteExecutionStepper { return Err(AutorouterError::NothingToRoute); }; - let (source, target) = autorouter.ratline_endpoints(curr_ratline); + let (origin, destination) = autorouter.ratline_endpoints(curr_ratline); let mut router = Router::new(autorouter.board.layout_mut(), options.router_options); - let this = Self { + Ok(Self { ratlines_iter, options, - route: Some(router.route(source, target, options.router_options.routed_band_width)?), + route: Some(router.route( + origin, + destination, + options.router_options.routed_band_width, + )?), curr_ratline: Some(curr_ratline), - }; - - Ok(this) + }) } } diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index b011faa..77f8951 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -1,5 +1,6 @@ use derive_getters::Getters; -use petgraph::graph::EdgeIndex; +use geo::Point; +use petgraph::graph::{EdgeIndex, NodeIndex}; use serde::{Deserialize, Serialize}; use spade::InsertionError; use thiserror::Error; @@ -17,6 +18,7 @@ use super::{ compare_detours::CompareDetoursExecutionStepper, measure_length::MeasureLengthExecutionStepper, place_via::PlaceViaExecutionStepper, + pointroute::PointrouteExecutionStepper, ratsnest::{Ratsnest, RatvertexIndex}, remove_bands::RemoveBandsExecutionStepper, selection::{BandSelection, PinSelection}, @@ -56,6 +58,34 @@ impl Autorouter { Ok(Self { board, ratsnest }) } + pub fn pointroute( + &mut self, + selection: &PinSelection, + point: Point, + options: AutorouterOptions, + ) -> Result { + let ratvertex = self.find_selected_ratvertex(selection).unwrap(); + let origin_dot = match self + .ratsnest + .graph() + .node_weight(ratvertex) + .unwrap() + .node_index() + { + RatvertexIndex::FixedDot(dot) => dot, + RatvertexIndex::Poly(poly) => self.board.poly_apex(poly), + }; + + PointrouteExecutionStepper::new(self, origin_dot, point, options) + } + + pub fn undo_pointroute(&mut self, band: BandTermsegIndex) -> Result<(), AutorouterError> { + self.board + .layout_mut() + .remove_band(band) + .map_err(|_| AutorouterError::CouldNotRemoveBand(band)) + } + pub fn autoroute( &mut self, selection: &PinSelection, @@ -185,22 +215,36 @@ impl Autorouter { .filter(|ratline| { let (source, target) = self.ratsnest.graph().edge_endpoints(*ratline).unwrap(); - let source_navvertex = self + let source_ratvertex = self .ratsnest .graph() .node_weight(source) .unwrap() .node_index(); - let to_navvertex = self + let to_ratvertex = self .ratsnest .graph() .node_weight(target) .unwrap() .node_index(); - selection.contains_node(&self.board, source_navvertex.into()) - && selection.contains_node(&self.board, to_navvertex.into()) + selection.contains_node(&self.board, source_ratvertex.into()) + && selection.contains_node(&self.board, to_ratvertex.into()) }) .collect() } + + fn find_selected_ratvertex(&self, selection: &PinSelection) -> Option> { + self.ratsnest.graph().node_indices().find(|ratvertex| { + selection.contains_node( + &self.board, + self.ratsnest + .graph() + .node_weight(*ratvertex) + .unwrap() + .node_index() + .into(), + ) + }) + } } diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index 93093de..d2d4171 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -8,6 +8,7 @@ pub mod history; pub mod invoker; pub mod measure_length; pub mod place_via; +pub mod pointroute; pub mod ratsnest; pub mod remove_bands; pub mod selection; diff --git a/src/autorouter/pointroute.rs b/src/autorouter/pointroute.rs new file mode 100644 index 0000000..74217e8 --- /dev/null +++ b/src/autorouter/pointroute.rs @@ -0,0 +1,67 @@ +use std::ops::ControlFlow; + +use geo::Point; + +use crate::{ + board::mesadata::AccessMesadata, + drawing::{ + band::BandTermsegIndex, + dot::{FixedDotIndex, FixedDotWeight}, + }, + math::Circle, + router::{route::RouteStepper, Router}, + stepper::Step, +}; + +use super::{Autorouter, AutorouterError, AutorouterOptions}; + +pub struct PointrouteExecutionStepper { + point: Point, + route: RouteStepper, + options: AutorouterOptions, +} + +impl PointrouteExecutionStepper { + pub fn new( + autorouter: &mut Autorouter, + origin: FixedDotIndex, + point: Point, + options: AutorouterOptions, + ) -> Result { + let destination = autorouter.board.add_fixed_dot_infringably( + FixedDotWeight { + circle: Circle { + pos: point, + r: options.router_options.routed_band_width / 2.0, + }, + layer: 0, + maybe_net: None, + }, + None, + ); + + let mut router = Router::new(autorouter.board.layout_mut(), options.router_options); + + Ok(Self { + point, + route: router.route( + origin, + destination, + options.router_options.routed_band_width, + )?, + options, + }) + } +} + +impl Step, BandTermsegIndex> for PointrouteExecutionStepper { + type Error = AutorouterError; + + fn step( + &mut self, + autorouter: &mut Autorouter, + ) -> Result, AutorouterError> { + let mut router = Router::new(autorouter.board.layout_mut(), self.options.router_options); + Ok(self.route.step(&mut router)?) + } +}