From 07528175385ee7c953fdbe6792213e43a96a12f0 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 12 Jul 2025 02:28:13 +0200 Subject: [PATCH] refactor(autorouter/ratsnest): Split out ratline code to new file, ratline.rs --- src/autorouter/autoroute.rs | 20 +++--- src/autorouter/autorouter.rs | 45 +++---------- src/autorouter/compare_detours.rs | 11 ++-- src/autorouter/mod.rs | 1 + src/autorouter/ratline.rs | 103 ++++++++++++++++++++++++++++++ src/autorouter/ratsnest.rs | 11 ++-- src/router/navmesh.rs | 9 +-- tests/common/mod.rs | 7 +- 8 files changed, 141 insertions(+), 66 deletions(-) create mode 100644 src/autorouter/ratline.rs diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index 46e8820..90a906a 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -7,12 +7,11 @@ use std::ops::ControlFlow; -use petgraph::graph::EdgeIndex; - use crate::{ board::AccessMesadata, drawing::{band::BandTermsegIndex, graph::PrimitiveIndex, Collect}, geometry::primitive::PrimitiveShape, + graph::MakeRef, layout::LayoutEdit, router::{ navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper, RouteStepper, Router, @@ -20,7 +19,10 @@ use crate::{ stepper::{EstimateProgress, Step}, }; -use super::{invoker::GetDebugOverlayData, Autorouter, AutorouterError, AutorouterOptions}; +use super::{ + invoker::GetDebugOverlayData, ratline::RatlineIndex, Autorouter, AutorouterError, + AutorouterOptions, +}; /// Represents the current status of the autoroute operation. pub enum AutorouteContinueStatus { @@ -35,7 +37,7 @@ pub enum AutorouteContinueStatus { /// Manages the autorouting process across multiple ratlines. pub struct AutorouteExecutionStepper { /// The ratlines which we are routing. - ratlines: Vec>, + ratlines: Vec, /// Keeps track of the current ratline being routed, if one is active. curr_ratline_index: usize, /// Stores the current route being processed, if any. @@ -52,14 +54,14 @@ impl AutorouteExecutionStepper { /// and stores the associated data for future routing steps. pub fn new( autorouter: &mut Autorouter, - ratlines: Vec>, + ratlines: Vec, options: AutorouterOptions, ) -> Result { if ratlines.is_empty() { return Err(AutorouterError::NothingToRoute); }; - let (origin, destination) = autorouter.ratline_endpoints(ratlines[0]); + let (origin, destination) = ratlines[0].ref_(autorouter).endpoint_dots(); let mut router = Router::new(autorouter.board.layout_mut(), options.router_options); Ok(Self { @@ -101,7 +103,9 @@ impl Step, Option, AutorouteContinu return Ok(ControlFlow::Break(None)); }; - let (source, target) = autorouter.ratline_endpoints(self.ratlines[self.curr_ratline_index]); + let (source, target) = self.ratlines[self.curr_ratline_index] + .ref_(autorouter) + .endpoint_dots(); let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(source, target) { AutorouteContinueStatus::Skipped(band_termseg[false]) @@ -138,7 +142,7 @@ impl Step, Option, AutorouteContinu self.curr_ratline_index += 1; if let Some(new_ratline) = self.ratlines.get(self.curr_ratline_index) { - let (source, target) = autorouter.ratline_endpoints(*new_ratline); + let (source, target) = new_ratline.ref_(autorouter).endpoint_dots(); let mut router = Router::new(autorouter.board.layout_mut(), self.options.router_options); diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 7d2e02b..6e07ef2 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -4,7 +4,7 @@ use derive_getters::Getters; use geo::Point; -use petgraph::graph::{EdgeIndex, NodeIndex}; +use petgraph::graph::NodeIndex; use serde::{Deserialize, Serialize}; use spade::InsertionError; use std::collections::BTreeSet; @@ -25,6 +25,7 @@ use super::{ measure_length::MeasureLengthExecutionStepper, place_via::PlaceViaExecutionStepper, pointroute::PointrouteExecutionStepper, + ratline::RatlineIndex, ratsnest::{Ratsnest, RatvertexIndex}, remove_bands::RemoveBandsExecutionStepper, selection::{BandSelection, PinSelection}, @@ -104,7 +105,7 @@ impl Autorouter { pub(super) fn autoroute_ratlines( &mut self, - ratlines: Vec>, + ratlines: Vec, options: AutorouterOptions, ) -> Result { AutorouteExecutionStepper::new(self, ratlines, options) @@ -116,7 +117,7 @@ impl Autorouter { pub(super) fn undo_autoroute_ratlines( &mut self, - ratlines: Vec>, + ratlines: Vec, ) -> Result<(), AutorouterError> { for ratline in ratlines.iter() { let band = self @@ -157,7 +158,7 @@ impl Autorouter { pub(super) fn topo_autoroute_ratlines( &mut self, - ratlines: Vec>, + ratlines: Vec, allowed_edges: BTreeSet, active_layer: usize, width: f64, @@ -187,7 +188,7 @@ impl Autorouter { active_layer, allowed_edges, ratlines.into_iter().filter_map(|ratline| { - let (source, target) = self.ratline_endpoints(ratline); + let (source, target) = ratline.ref_(self).endpoint_dots(); if navmesh .as_ref() @@ -260,8 +261,8 @@ impl Autorouter { pub(super) fn compare_detours_ratlines( &mut self, - ratline1: EdgeIndex, - ratline2: EdgeIndex, + ratline1: RatlineIndex, + ratline2: RatlineIndex, options: AutorouterOptions, ) -> Result { CompareDetoursExecutionStepper::new(self, ratline1, ratline2, options) @@ -274,35 +275,7 @@ impl Autorouter { MeasureLengthExecutionStepper::new(selection) } - pub fn ratline_endpoints(&self, ratline: EdgeIndex) -> (FixedDotIndex, FixedDotIndex) { - let (source, target) = self.ratsnest.graph().edge_endpoints(ratline).unwrap(); - - let source_dot = match self - .ratsnest - .graph() - .node_weight(source) - .unwrap() - .node_index() - { - RatvertexIndex::FixedDot(dot) => dot, - RatvertexIndex::Poly(poly) => poly.ref_(self.board.layout()).apex(), - }; - - let target_dot = match self - .ratsnest - .graph() - .node_weight(target) - .unwrap() - .node_index() - { - RatvertexIndex::FixedDot(dot) => dot, - RatvertexIndex::Poly(poly) => poly.ref_(self.board.layout()).apex(), - }; - - (source_dot, target_dot) - } - - pub(super) fn selected_ratlines(&self, selection: &PinSelection) -> Vec> { + pub(super) fn selected_ratlines(&self, selection: &PinSelection) -> Vec { self.ratsnest .graph() .edge_indices() diff --git a/src/autorouter/compare_detours.rs b/src/autorouter/compare_detours.rs index 6bcd76a..3b8b704 100644 --- a/src/autorouter/compare_detours.rs +++ b/src/autorouter/compare_detours.rs @@ -7,8 +7,6 @@ use std::ops::ControlFlow; -use petgraph::graph::EdgeIndex; - use crate::{ board::AccessMesadata, drawing::graph::PrimitiveIndex, @@ -21,14 +19,15 @@ use crate::{ use super::{ autoroute::{AutorouteContinueStatus, AutorouteExecutionStepper}, invoker::GetDebugOverlayData, + ratline::RatlineIndex, Autorouter, AutorouterError, AutorouterOptions, }; pub struct CompareDetoursExecutionStepper { autoroute: AutorouteExecutionStepper, next_autoroute: Option, - ratline1: EdgeIndex, - ratline2: EdgeIndex, + ratline1: RatlineIndex, + ratline2: RatlineIndex, total_length1: f64, total_length2: f64, done: bool, @@ -37,8 +36,8 @@ pub struct CompareDetoursExecutionStepper { impl CompareDetoursExecutionStepper { pub fn new( autorouter: &mut Autorouter, - ratline1: EdgeIndex, - ratline2: EdgeIndex, + ratline1: RatlineIndex, + ratline2: RatlineIndex, options: AutorouterOptions, ) -> Result { Ok(Self { diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index 10ddb44..67bcbbf 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -13,6 +13,7 @@ pub mod invoker; pub mod measure_length; pub mod place_via; pub mod pointroute; +pub mod ratline; pub mod ratsnest; pub mod remove_bands; pub mod selection; diff --git a/src/autorouter/ratline.rs b/src/autorouter/ratline.rs new file mode 100644 index 0000000..4d80d66 --- /dev/null +++ b/src/autorouter/ratline.rs @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2025 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use geo::{Distance, Euclidean}; +use petgraph::graph::EdgeIndex; +use specctra_core::mesadata::AccessMesadata; + +use crate::{ + drawing::{band::BandTermsegIndex, dot::FixedDotIndex}, + geometry::shape::MeasureLength, + graph::MakeRef, + triangulation::GetTrianvertexNodeIndex, +}; + +use super::{ratsnest::RatvertexIndex, Autorouter}; + +pub type RatlineIndex = EdgeIndex; + +#[derive(Debug, Default, Clone, Copy)] +pub struct RatlineWeight { + pub band_termseg: Option, +} + +impl<'a, M: AccessMesadata + 'a> MakeRef<'a, Autorouter> for RatlineIndex { + type Output = RatlineRef<'a, M>; + fn ref_(&self, autorouter: &'a Autorouter) -> RatlineRef<'a, M> { + RatlineRef::new(*self, autorouter) + } +} + +pub struct RatlineRef<'a, M: AccessMesadata> { + index: RatlineIndex, + autorouter: &'a Autorouter, +} + +impl<'a, M: AccessMesadata> RatlineRef<'a, M> { + pub fn new(index: RatlineIndex, autorouter: &'a Autorouter) -> Self { + Self { index, autorouter } + } + + pub fn endpoint_dots(&self) -> (FixedDotIndex, FixedDotIndex) { + let (source, target) = self + .autorouter + .ratsnest + .graph() + .edge_endpoints(self.index) + .unwrap(); + + let source_dot = match self + .autorouter + .ratsnest + .graph() + .node_weight(source) + .unwrap() + .node_index() + { + RatvertexIndex::FixedDot(dot) => dot, + RatvertexIndex::Poly(poly) => poly.ref_(self.autorouter.board.layout()).apex(), + }; + + let target_dot = match self + .autorouter + .ratsnest + .graph() + .node_weight(target) + .unwrap() + .node_index() + { + RatvertexIndex::FixedDot(dot) => dot, + RatvertexIndex::Poly(poly) => poly.ref_(self.autorouter.board.layout()).apex(), + }; + + (source_dot, target_dot) + } +} + +impl<'a, M: AccessMesadata> MeasureLength for RatlineRef<'a, M> { + fn length(&self) -> f64 { + let (ratvertex0, ratvertex1) = self + .autorouter + .ratsnest + .graph() + .edge_endpoints(self.index) + .unwrap(); + let ratvertex0_pos = self + .autorouter + .ratsnest + .graph() + .node_weight(ratvertex0) + .unwrap() + .pos; + let ratvertex1_pos = self + .autorouter + .ratsnest + .graph() + .node_weight(ratvertex1) + .unwrap() + .pos; + + Euclidean::distance(&ratvertex0_pos, &ratvertex1_pos) + } +} diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index f33c69d..51412e8 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -13,7 +13,7 @@ use enum_dispatch::enum_dispatch; use geo::Point; use petgraph::{ data::Element, - graph::{EdgeIndex, NodeIndex, UnGraph}, + graph::{NodeIndex, UnGraph}, unionfind::UnionFind, visit::{EdgeRef, IntoEdgeReferences, NodeIndexable}, }; @@ -36,6 +36,8 @@ use crate::{ triangulation::{GetTrianvertexNodeIndex, Triangulation}, }; +use super::ratline::{RatlineIndex, RatlineWeight}; + #[enum_dispatch(GetPetgraphIndex)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum RatvertexIndex { @@ -71,11 +73,6 @@ impl HasPosition for RatvertexWeight { } } -#[derive(Debug, Default, Clone, Copy)] -pub struct RatlineWeight { - pub band_termseg: Option, -} - pub struct Ratsnest { graph: UnGraph, } @@ -161,7 +158,7 @@ impl Ratsnest { pub fn assign_band_termseg_to_ratline( &mut self, - ratline: EdgeIndex, + ratline: RatlineIndex, termseg: BandTermsegIndex, ) { self.graph.edge_weight_mut(ratline).unwrap().band_termseg = Some(termseg); diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index 9101002..f559183 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -11,8 +11,7 @@ use petgraph::{ graph::UnGraph, stable_graph::NodeIndex, visit::{ - Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors, - IntoNodeIdentifiers, NodeIndexable, + Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNodeIdentifiers, }, }; use spade::InsertionError; @@ -23,21 +22,19 @@ use crate::{ bend::{FixedBendIndex, LooseBendIndex}, dot::FixedDotIndex, gear::{GearIndex, GetNextGear}, - graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex}, + graph::{MakePrimitive, PrimitiveIndex}, primitive::Primitive, rules::AccessRules, Drawing, }, - geometry::GetLayer, graph::{GetPetgraphIndex, MakeRef}, layout::Layout, math::RotationSense, router::thetastar::MakeEdgeRef, - triangulation::Triangulation, }; use super::{ - prenavmesh::{Prenavmesh, PrenavmeshConstraint, PrenavmeshNodeIndex, PrenavmeshWeight}, + prenavmesh::{Prenavmesh, PrenavmeshNodeIndex}, RouterOptions, }; diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 8e21180..7dd9106 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -83,7 +83,8 @@ pub fn assert_navnode_count( .collect::>() .iter() .find_map(|ratline| { - let (candidate_origin, candidate_destination) = autorouter.ratline_endpoints(*ratline); + let (candidate_origin, candidate_destination) = + autorouter.ratline_endpoint_dots(*ratline); let candidate_origin_pin = autorouter .board() .node_pinname(&GenericNode::Primitive(candidate_origin.into())) @@ -121,7 +122,7 @@ pub fn assert_single_layer_groundless_autoroute( let unionfind = unionfind(autorouter); for ratline in autorouter.ratsnest().graph().edge_indices() { - let (origin_dot, destination_dot) = autorouter.ratline_endpoints(ratline); + let (origin_dot, destination_dot) = autorouter.ratline_endpoint_dots(ratline); let origin_layer = autorouter .board() @@ -219,7 +220,7 @@ fn unionfind(autorouter: &mut Autorouter) -> UnionFind