From dd8a4c5808f5166b940ae903d1024547243bd7d8 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 19 Oct 2025 22:31:16 +0200 Subject: [PATCH] fix(autorouter/conncomps): Take into account vias when computing connected components --- src/autorouter/conncomps.rs | 38 +++++++++++++++++++++++-------------- src/layout/via.rs | 13 ++++++++++++- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/autorouter/conncomps.rs b/src/autorouter/conncomps.rs index f9b475c..e672597 100644 --- a/src/autorouter/conncomps.rs +++ b/src/autorouter/conncomps.rs @@ -37,20 +37,9 @@ impl ConncompsWithPrincipalLayer { } } - /*for layer in 0..board.layout().drawing().layer_count() { - if layer != principal_layer { - for primitive in board.layout().drawing().layer_primitive_nodes(layer) { - if let Some(pinname) = board.node_pinname(&GenericNode::Primitive(primitive)) { - if !principally_visited_pins.contains(pinname) { - Self::unionize_by_primitive(board, &mut unionfind, primitive); - } - } - } - } - }*/ - - //TODO for pinname in board.pins() if !principally_visited_pins.contains(pinname) for node in board.pinname_nodes() unionize to first found element - + // Pins can have padstacks that span multiple layers. To account for + // that, we have another loop to go over all the pins and connect all + // their primitives. for pinname in board.pinnames() { if principally_visited_pins.contains(pinname) { let mut iter = board.pinname_nodes(pinname); @@ -85,6 +74,8 @@ impl ConncompsWithPrincipalLayer { PrimitiveIndex::FixedSeg(seg) => { let joints = board.layout().drawing().primitive(seg).joints(); unionfind.union(joints.0.index(), joints.1.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.0); + Self::unionize_fixed_dot_via(board, unionfind, joints.1); } PrimitiveIndex::LoneLooseSeg(seg) => { let joints = board.layout().drawing().primitive(seg).joints(); @@ -97,6 +88,8 @@ impl ConncompsWithPrincipalLayer { PrimitiveIndex::FixedBend(bend) => { let joints = board.layout().drawing().primitive(bend).joints(); unionfind.union(joints.0.index(), joints.1.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.0); + Self::unionize_fixed_dot_via(board, unionfind, joints.1); } PrimitiveIndex::LooseBend(bend) => { let joints = board.layout().drawing().primitive(bend).joints(); @@ -115,6 +108,7 @@ impl ConncompsWithPrincipalLayer { match primitive { PrimitiveIndex::FixedDot(dot) => { unionfind.union(common.index(), dot.index()); + Self::unionize_fixed_dot_via(board, unionfind, dot); } PrimitiveIndex::LooseDot(dot) => { unionfind.union(common.index(), dot.index()); @@ -122,7 +116,9 @@ impl ConncompsWithPrincipalLayer { PrimitiveIndex::FixedSeg(seg) => { let joints = board.layout().drawing().primitive(seg).joints(); unionfind.union(common.index(), joints.0.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.0); unionfind.union(common.index(), joints.1.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.1); } PrimitiveIndex::LoneLooseSeg(seg) => { let joints = board.layout().drawing().primitive(seg).joints(); @@ -137,7 +133,9 @@ impl ConncompsWithPrincipalLayer { PrimitiveIndex::FixedBend(bend) => { let joints = board.layout().drawing().primitive(bend).joints(); unionfind.union(common.index(), joints.0.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.0); unionfind.union(common.index(), joints.1.index()); + Self::unionize_fixed_dot_via(board, unionfind, joints.1); } PrimitiveIndex::LooseBend(bend) => { let joints = board.layout().drawing().primitive(bend).joints(); @@ -147,4 +145,16 @@ impl ConncompsWithPrincipalLayer { _ => (), } } + + fn unionize_fixed_dot_via( + board: &Board, + unionfind: &mut UnionFind, + dot: FixedDotIndex, + ) { + if let Some(via) = board.layout().fixed_dot_via(dot) { + for via_dot in board.layout().via(via).dots() { + unionfind.union(dot.index(), via_dot.index()); + } + } + } } diff --git a/src/layout/via.rs b/src/layout/via.rs index c4d7c00..d36976f 100644 --- a/src/layout/via.rs +++ b/src/layout/via.rs @@ -8,12 +8,16 @@ use serde::{Deserialize, Serialize}; use crate::{ drawing::{ + dot::FixedDotIndex, graph::{GetMaybeNet, IsInLayer}, primitive::MakePrimitiveShape, rules::AccessRules, Drawing, }, - geometry::primitive::{DotShape, PrimitiveShape}, + geometry::{ + compound::ManageCompounds, + primitive::{DotShape, PrimitiveShape}, + }, graph::{GenericIndex, GetIndex}, layout::{CompoundEntryLabel, CompoundWeight}, math::Circle, @@ -32,6 +36,13 @@ impl<'a, R> Via<'a, R> { ) -> Self { Self { index, drawing } } + + pub fn dots(&self) -> impl Iterator + '_ { + self.drawing + .geometry() + .compound_members(self.index.into()) + .map(|(_, index)| FixedDotIndex::new(index.index())) + } } impl GetMaybeNet for Via<'_, R> {