mirror of https://codeberg.org/topola/topola.git
refactor(autorouter/ratsnest): Move unionfind to new file, don't use `.graph()` there
This commit is contained in:
parent
e0cfc521ef
commit
71fdec2f06
|
|
@ -21,6 +21,7 @@ allowed_scopes = [
|
|||
"autorouter/autoroute",
|
||||
"autorouter/autorouter",
|
||||
"autorouter/compare_detours",
|
||||
"autorouter/conncomps",
|
||||
"autorouter/execution",
|
||||
"autorouter/history",
|
||||
"autorouter/invoker",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
// SPDX-FileCopyrightText: 2025 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use derive_getters::Getters;
|
||||
use petgraph::unionfind::UnionFind;
|
||||
use specctra_core::rules::AccessRules;
|
||||
|
||||
use crate::{
|
||||
drawing::{graph::PrimitiveIndex, primitive::GetJoints},
|
||||
graph::GetIndex,
|
||||
layout::Layout,
|
||||
};
|
||||
|
||||
#[derive(Clone, Getters)]
|
||||
pub struct Conncomps {
|
||||
unionfind: UnionFind<usize>,
|
||||
}
|
||||
|
||||
impl Conncomps {
|
||||
pub fn new(layout: &Layout<impl AccessRules>) -> Self {
|
||||
let mut unionfind = UnionFind::new(layout.drawing().geometry().dot_index_bound());
|
||||
|
||||
for primitive in layout.drawing().primitive_nodes() {
|
||||
match primitive {
|
||||
PrimitiveIndex::FixedSeg(seg) => {
|
||||
let joints = layout.drawing().primitive(seg).joints();
|
||||
unionfind.union(joints.0.index(), joints.1.index());
|
||||
}
|
||||
PrimitiveIndex::LoneLooseSeg(seg) => {
|
||||
let joints = layout.drawing().primitive(seg).joints();
|
||||
unionfind.union(joints.0.index(), joints.1.index());
|
||||
}
|
||||
PrimitiveIndex::SeqLooseSeg(seg) => {
|
||||
let joints = layout.drawing().primitive(seg).joints();
|
||||
unionfind.union(joints.0.index(), joints.1.index());
|
||||
}
|
||||
PrimitiveIndex::FixedBend(bend) => {
|
||||
let joints = layout.drawing().primitive(bend).joints();
|
||||
unionfind.union(joints.0.index(), joints.1.index());
|
||||
}
|
||||
PrimitiveIndex::LooseBend(bend) => {
|
||||
let joints = layout.drawing().primitive(bend).joints();
|
||||
unionfind.union(joints.0.index(), joints.1.index());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
Self { unionfind }
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
pub mod autoroute;
|
||||
mod autorouter;
|
||||
pub mod compare_detours;
|
||||
pub mod conncomps;
|
||||
pub mod execution;
|
||||
pub mod history;
|
||||
pub mod invoker;
|
||||
|
|
|
|||
|
|
@ -6,15 +6,11 @@ use std::collections::BTreeMap;
|
|||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use geo::Point;
|
||||
use petgraph::{
|
||||
data::Element,
|
||||
prelude::StableUnGraph,
|
||||
unionfind::UnionFind,
|
||||
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
|
||||
};
|
||||
use petgraph::{data::Element, prelude::StableUnGraph, visit::NodeIndexable};
|
||||
use spade::{HasPosition, InsertionError, Point2};
|
||||
|
||||
use crate::{
|
||||
autorouter::conncomps::Conncomps,
|
||||
drawing::{
|
||||
band::BandTermsegIndex,
|
||||
dot::FixedDotIndex,
|
||||
|
|
@ -74,11 +70,7 @@ pub struct Ratsnest {
|
|||
|
||||
impl Ratsnest {
|
||||
pub fn new(layout: &Layout<impl AccessRules>) -> Result<Self, InsertionError> {
|
||||
let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound());
|
||||
|
||||
for edge in layout.drawing().geometry().graph().edge_references() {
|
||||
unionfind.union(edge.source().index(), edge.target().index());
|
||||
}
|
||||
let conncomps = Conncomps::new(layout);
|
||||
|
||||
let mut this = Self {
|
||||
graph: StableUnGraph::default(),
|
||||
|
|
@ -145,7 +137,7 @@ impl Ratsnest {
|
|||
if let Some((source, target)) = g.edge_endpoints(i) {
|
||||
let source_index = g.node_weight(source).unwrap().node_index().index();
|
||||
let target_index = g.node_weight(target).unwrap().node_index().index();
|
||||
!unionfind.equiv(source_index, target_index)
|
||||
!conncomps.unionfind().equiv(source_index, target_index)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use enum_dispatch::enum_dispatch;
|
|||
use geo::Point;
|
||||
use petgraph::{
|
||||
stable_graph::StableDiGraph,
|
||||
visit::{EdgeRef, Walker},
|
||||
visit::{EdgeRef, NodeIndexable, Walker},
|
||||
Direction::{Incoming, Outgoing},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -518,6 +518,18 @@ impl<
|
|||
pub fn bend_joints(&self, bend: BI) -> (DI, DI) {
|
||||
self.joints(bend.into())
|
||||
}
|
||||
|
||||
pub fn dot_index_bound(&self) -> usize {
|
||||
self.graph.node_bound()
|
||||
}
|
||||
|
||||
pub fn seg_index_bound(&self) -> usize {
|
||||
self.graph.node_bound()
|
||||
}
|
||||
|
||||
pub fn bend_index_bound(&self) -> usize {
|
||||
self.graph.node_bound()
|
||||
}
|
||||
}
|
||||
|
||||
impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
use std::{fs::File, io::BufReader};
|
||||
|
||||
use petgraph::{unionfind::UnionFind, visit::NodeIndexable};
|
||||
use topola::{
|
||||
autorouter::{
|
||||
conncomps::Conncomps,
|
||||
history::{History, HistoryError},
|
||||
invoker::{Invoker, InvokerError},
|
||||
Autorouter,
|
||||
|
|
@ -160,7 +160,7 @@ pub fn assert_single_layer_groundless_autoroute(
|
|||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
layername: &str,
|
||||
) {
|
||||
let unionfind = unionfind(autorouter);
|
||||
let conncomps = Conncomps::new(autorouter.board().layout());
|
||||
|
||||
for ratline in autorouter.ratsnest().graph().edge_indices() {
|
||||
let (origin_dot, destination_dot) = ratline.ref_(autorouter).endpoint_dots();
|
||||
|
|
@ -217,8 +217,8 @@ pub fn assert_single_layer_groundless_autoroute(
|
|||
|
||||
if let Some(netname) = autorouter.board().layout().rules().net_netname(net) {
|
||||
// We don't route ground.
|
||||
let org = unionfind.find(origin_dot.index());
|
||||
let desc = unionfind.find(destination_dot.index());
|
||||
let org = conncomps.unionfind().find(origin_dot.index());
|
||||
let desc = conncomps.unionfind().find(destination_dot.index());
|
||||
|
||||
if netname != "GND" {
|
||||
assert_eq!(org, desc);
|
||||
|
|
@ -256,35 +256,3 @@ pub fn assert_band_length(
|
|||
rel_err
|
||||
);
|
||||
}
|
||||
|
||||
fn unionfind(autorouter: &mut Autorouter<impl AccessMesadata>) -> UnionFind<usize> {
|
||||
for ratline in autorouter.ratsnest().graph().edge_indices() {
|
||||
// Accessing endpoints may create new dots because apex construction is lazy, so we access
|
||||
// tem all before starting unionfind, as it requires a constant index bound.
|
||||
let _ = ratline.ref_(autorouter).endpoint_dots();
|
||||
}
|
||||
|
||||
let mut unionfind = UnionFind::new(
|
||||
autorouter
|
||||
.board()
|
||||
.layout()
|
||||
.drawing()
|
||||
.geometry()
|
||||
.graph()
|
||||
.node_bound(),
|
||||
);
|
||||
|
||||
for primitive in autorouter.board().layout().drawing().primitive_nodes() {
|
||||
for joined in autorouter
|
||||
.board()
|
||||
.layout()
|
||||
.drawing()
|
||||
.geometry()
|
||||
.joineds(primitive)
|
||||
{
|
||||
unionfind.union(primitive.index(), joined.index());
|
||||
}
|
||||
}
|
||||
|
||||
unionfind
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue