Wrap net ids in `NetId` type

This commit is contained in:
Mikolaj Wielgus 2026-03-13 11:22:40 +01:00
parent 3f6073af03
commit 3f362d62c3
3 changed files with 68 additions and 14 deletions

View File

@ -7,7 +7,8 @@ use derive_getters::{Dissolve, Getters};
use undoredo::{ApplyDelta, Delta, FlushDelta}; use undoredo::{ApplyDelta, Delta, FlushDelta};
use crate::layout::{ use crate::layout::{
Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId, Via, ViaId, Joint, JointId, Layout, LayoutHalfDelta, NetId, Polygon, PolygonId, Segment, SegmentId, Via,
ViaId,
}; };
struct Layer { struct Layer {
@ -21,7 +22,7 @@ pub struct Board {
#[getter(skip)] #[getter(skip)]
layer_names: BiBTreeMap<usize, String>, layer_names: BiBTreeMap<usize, String>,
#[getter(skip)] #[getter(skip)]
net_names: BiBTreeMap<usize, String>, net_names: BiBTreeMap<NetId, String>,
} }
impl Board { impl Board {
@ -37,7 +38,7 @@ impl Board {
boundary: Vec<[i64; 2]>, boundary: Vec<[i64; 2]>,
layer_count: usize, layer_count: usize,
layer_names: BiBTreeMap<usize, String>, layer_names: BiBTreeMap<usize, String>,
net_names: BiBTreeMap<usize, String>, net_names: BiBTreeMap<NetId, String>,
) -> Self { ) -> Self {
Self { Self {
layout: Layout::new(boundary, layer_count), layout: Layout::new(boundary, layer_count),
@ -70,11 +71,11 @@ impl Board {
self.layer_names.get_by_right(name).copied() self.layer_names.get_by_right(name).copied()
} }
pub fn net_name(&self, net: usize) -> Option<&str> { pub fn net_name(&self, net: NetId) -> Option<&str> {
self.net_names.get_by_left(&net).map(String::as_str) self.net_names.get_by_left(&net).map(String::as_str)
} }
pub fn net_id(&self, name: &str) -> Option<usize> { pub fn net_id(&self, name: &str) -> Option<NetId> {
self.net_names.get_by_right(name).copied() self.net_names.get_by_right(name).copied()
} }
} }

View File

@ -8,6 +8,23 @@ use derive_getters::{Dissolve, Getters};
use stable_vec::StableVec; use stable_vec::StableVec;
use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder}; use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct NetId(usize);
impl NetId {
/// Wrap a joint index in a newtype struct.
#[inline]
pub fn new(id: usize) -> Self {
Self(id)
}
/// Returns the underlying index.
#[inline]
pub fn id(self) -> usize {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct JointId(usize); pub struct JointId(usize);
@ -30,6 +47,7 @@ pub struct Joint {
pub position: [i64; 2], pub position: [i64; 2],
pub layer: usize, pub layer: usize,
pub radius: u64, pub radius: u64,
pub net: NetId,
} }
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -54,6 +72,7 @@ pub struct Segment {
pub endjoints: [JointId; 2], pub endjoints: [JointId; 2],
pub layer: usize, pub layer: usize,
pub half_width: u64, pub half_width: u64,
pub net: NetId,
} }
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -78,6 +97,7 @@ pub struct Via {
pub endpoints: [JointId; 2], pub endpoints: [JointId; 2],
pub layer: usize, pub layer: usize,
pub radius: u64, pub radius: u64,
pub net: NetId,
} }
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -101,6 +121,7 @@ impl PolygonId {
pub struct Polygon { pub struct Polygon {
pub vertices: Vec<[i64; 2]>, pub vertices: Vec<[i64; 2]>,
pub layer: usize, pub layer: usize,
pub net: NetId,
} }
#[derive(Clone, Debug, Getters)] #[derive(Clone, Debug, Getters)]

View File

@ -2,6 +2,8 @@
// //
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use std::collections::BTreeMap;
use bimap::BiBTreeMap; use bimap::BiBTreeMap;
use specctra::{ use specctra::{
math::PointWithRotation, math::PointWithRotation,
@ -11,7 +13,7 @@ use specctra::{
use crate::{ use crate::{
Segment, Segment,
board::Board, board::Board,
layout::{Joint, Polygon}, layout::{Joint, NetId, Polygon},
math::Vector2, math::Vector2,
}; };
@ -40,7 +42,12 @@ impl Board {
tmp.sort_unstable(); tmp.sort_unstable();
tmp.dedup(); tmp.dedup();
BiBTreeMap::from_iter(tmp.into_iter().cloned().enumerate()) BiBTreeMap::from_iter(
tmp.into_iter()
.cloned()
.enumerate()
.map(|(i, v)| (NetId::new(i), v)),
)
}; };
let mut board = Board::with_names( let mut board = Board::with_names(
@ -60,14 +67,14 @@ impl Board {
); );
// Mapping of pin -> net prepared for adding pins. // Mapping of pin -> net prepared for adding pins.
let pin_nets = dsn let pin_nets: BTreeMap<String, NetId> = dsn
.pcb .pcb
.network .network
.nets .nets
.iter() .iter()
.filter_map(|net_pin_assignments| { .filter_map(|net_pin_assignments| {
// Resolve the id so we don't work with strings. // Resolve the id so we don't work with strings.
let net = board.net_id(&net_pin_assignments.name); let net = board.net_id(&net_pin_assignments.name).unwrap();
net_pin_assignments.pins.as_ref().map(|pins| { net_pin_assignments.pins.as_ref().map(|pins| {
// Take the list of pins // Take the list of pins
@ -76,7 +83,8 @@ impl Board {
}) })
}) })
// Flatten the nested iters into a single stream of tuples. // Flatten the nested iters into a single stream of tuples.
.flatten(); .flatten()
.collect();
// Add pins from components. // Add pins from components.
for component in &dsn.pcb.placement.components { for component in &dsn.pcb.placement.components {
@ -95,6 +103,8 @@ impl Board {
}; };
for pin in &image.pins { for pin in &image.pins {
let pin_name = format!("{}-{}", place.name, pin.id);
let net = pin_nets.get(&pin_name).copied().unwrap();
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap(); let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
for shape in padstack.shapes.iter() { for shape in padstack.shapes.iter() {
@ -107,6 +117,7 @@ impl Board {
pin.point_with_rotation(), pin.point_with_rotation(),
(circle.diameter / 2.0) as u64, (circle.diameter / 2.0) as u64,
layer, layer,
net,
!place_side_is_front, !place_side_is_front,
) )
} }
@ -121,6 +132,7 @@ impl Board {
rect.x2, rect.x2,
rect.y2, rect.y2,
layer, layer,
net,
!place_side_is_front, !place_side_is_front,
) )
} }
@ -133,6 +145,7 @@ impl Board {
&path.coords, &path.coords,
path.width, path.width,
layer, layer,
net,
!place_side_is_front, !place_side_is_front,
) )
} }
@ -145,6 +158,7 @@ impl Board {
&polygon.coords, &polygon.coords,
polygon.width, polygon.width,
layer, layer,
net,
!place_side_is_front, !place_side_is_front,
) )
} }
@ -155,7 +169,7 @@ impl Board {
} }
for via in &dsn.pcb.wiring.vias { for via in &dsn.pcb.wiring.vias {
let net = board.net_id(&via.net); let net = board.net_id(&via.net).unwrap();
let padstack = dsn.pcb.library.find_padstack_by_name(&via.name).unwrap(); let padstack = dsn.pcb.library.find_padstack_by_name(&via.name).unwrap();
let get_layer = |board: &Board, name: &str| { let get_layer = |board: &Board, name: &str| {
@ -172,6 +186,7 @@ impl Board {
PointWithRotation::default(), PointWithRotation::default(),
(circle.diameter / 2.0) as u64, (circle.diameter / 2.0) as u64,
layer, layer,
net,
false, false,
) )
} }
@ -186,6 +201,7 @@ impl Board {
rect.x2, rect.x2,
rect.y2, rect.y2,
layer, layer,
net,
false, false,
) )
} }
@ -198,6 +214,7 @@ impl Board {
&path.coords, &path.coords,
path.width, path.width,
layer, layer,
net,
false, false,
) )
} }
@ -210,6 +227,7 @@ impl Board {
&polygon.coords, &polygon.coords,
polygon.width, polygon.width,
layer, layer,
net,
false, false,
) )
} }
@ -219,7 +237,7 @@ impl Board {
for wire in dsn.pcb.wiring.wires.iter() { for wire in dsn.pcb.wiring.wires.iter() {
let layer = board.layer_id(&wire.path.layer).unwrap(); let layer = board.layer_id(&wire.path.layer).unwrap();
let net = board.net_id(&wire.net); let net = board.net_id(&wire.net).unwrap();
Self::place_path( Self::place_path(
&mut board, &mut board,
@ -228,6 +246,7 @@ impl Board {
&wire.path.coords, &wire.path.coords,
wire.path.width, wire.path.width,
layer, layer,
net,
false, false,
); );
} }
@ -241,11 +260,13 @@ impl Board {
pin: PointWithRotation, pin: PointWithRotation,
radius: u64, radius: u64,
layer: usize, layer: usize,
net: NetId,
flip: bool, flip: bool,
) { ) {
board.add_joint(Joint { board.add_joint(Joint {
position: Self::pos(place, pin, 0.0, 0.0, flip), position: Self::pos(place, pin, 0.0, 0.0, flip),
layer, layer,
net,
radius, radius,
}); });
} }
@ -259,6 +280,7 @@ impl Board {
x2: f64, x2: f64,
y2: f64, y2: f64,
layer: usize, layer: usize,
net: NetId,
flip: bool, flip: bool,
) { ) {
board.add_polygon(Polygon { board.add_polygon(Polygon {
@ -269,6 +291,7 @@ impl Board {
Self::pos(place, pin, x1, y2, flip), Self::pos(place, pin, x1, y2, flip),
], ],
layer, layer,
net,
}); });
} }
@ -279,6 +302,7 @@ impl Board {
coords: &[Point], coords: &[Point],
width: f64, width: f64,
layer: usize, layer: usize,
net: NetId,
flip: bool, flip: bool,
) { ) {
// Add the first coordinate in the wire path as a dot and save its index. // Add the first coordinate in the wire path as a dot and save its index.
@ -287,6 +311,7 @@ impl Board {
position: prev_pos, position: prev_pos,
layer, layer,
radius: (width / 2.0) as u64, radius: (width / 2.0) as u64,
net,
}); });
// Iterate through path coords starting from the second. // Iterate through path coords starting from the second.
@ -299,8 +324,9 @@ impl Board {
let joint = board.add_joint(Joint { let joint = board.add_joint(Joint {
position: pos, position: pos,
radius: (width / 2.0) as u64,
layer, layer,
radius: (width / 2.0) as u64,
net,
}); });
// Add a seg between the current and previous coords. // Add a seg between the current and previous coords.
@ -308,6 +334,7 @@ impl Board {
endjoints: [prev_joint, joint], endjoints: [prev_joint, joint],
layer, layer,
half_width: (width / 2.0) as u64, half_width: (width / 2.0) as u64,
net,
}); });
prev_pos = pos; prev_pos = pos;
@ -322,13 +349,18 @@ impl Board {
coords: &[Point], coords: &[Point],
width: f64, width: f64,
layer: usize, layer: usize,
net: NetId,
flip: bool, flip: bool,
) { ) {
let vertices: Vec<[i64; 2]> = coords let vertices: Vec<[i64; 2]> = coords
.iter() .iter()
.map(|coord| Self::pos(place, pin, coord.x, coord.y, flip)) .map(|coord| Self::pos(place, pin, coord.x, coord.y, flip))
.collect(); .collect();
board.add_polygon(Polygon { vertices, layer }); board.add_polygon(Polygon {
vertices,
layer,
net,
});
} }
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize { fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize {