Compare commits

..

No commits in common. "d77be1b0b36cab0fae0c965b9fc0c5bba97975c8" and "e36b63102914e61d6ff2f2a9f200140d92d8d0fe" have entirely different histories.

4 changed files with 43 additions and 214 deletions

View File

@ -7,19 +7,21 @@ use derive_getters::{Dissolve, Getters};
use undoredo::{ApplyDelta, Delta, FlushDelta};
use crate::layout::{
Joint, JointId, Layout, LayoutHalfDelta, NetId, PinId, Polygon, PolygonId, Segment, SegmentId,
Via, ViaId,
Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId, Via, ViaId,
};
struct Layer {
name: String,
index: usize,
}
#[derive(Clone, Debug, Getters)]
pub struct Board {
layout: Layout,
#[getter(skip)]
layer_names: BiBTreeMap<usize, String>,
#[getter(skip)]
net_names: BiBTreeMap<NetId, String>,
#[getter(skip)]
pin_names: BiBTreeMap<PinId, String>,
net_names: BiBTreeMap<usize, String>,
}
impl Board {
@ -28,7 +30,6 @@ impl Board {
layout: Layout::new(boundary, layer_count),
layer_names: BiBTreeMap::new(),
net_names: BiBTreeMap::new(),
pin_names: BiBTreeMap::new(),
}
}
@ -36,27 +37,15 @@ impl Board {
boundary: Vec<[i64; 2]>,
layer_count: usize,
layer_names: BiBTreeMap<usize, String>,
net_names: BiBTreeMap<NetId, String>,
net_names: BiBTreeMap<usize, String>,
) -> Self {
Self {
layout: Layout::new(boundary, layer_count),
layer_names,
net_names,
pin_names: BiBTreeMap::new(),
}
}
pub fn ensure_pin(&mut self, pin_name: String) -> PinId {
if let Some(pin) = self.pin_names.get_by_right(&pin_name) {
return *pin;
};
let pin_id = self.layout.add_pin();
self.pin_names.insert(pin_id, pin_name);
pin_id
}
pub fn add_joint(&mut self, joint: Joint) -> JointId {
self.layout.add_joint(joint)
}
@ -81,11 +70,11 @@ impl Board {
self.layer_names.get_by_right(name).copied()
}
pub fn net_name(&self, net: NetId) -> Option<&str> {
pub fn net_name(&self, net: usize) -> Option<&str> {
self.net_names.get_by_left(&net).map(String::as_str)
}
pub fn net_id(&self, name: &str) -> Option<NetId> {
pub fn net_id(&self, name: &str) -> Option<usize> {
self.net_names.get_by_right(name).copied()
}
}

View File

@ -8,59 +8,6 @@ use derive_getters::{Dissolve, Getters};
use stable_vec::StableVec;
use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct PinId(usize);
impl PinId {
/// Wrap a pin 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, Debug)]
pub struct Pin {
joints: Vec<JointId>,
segments: Vec<SegmentId>,
vias: Vec<ViaId>,
polygons: Vec<PolygonId>,
}
impl Pin {
pub fn new() -> Self {
Self {
joints: Vec::new(),
segments: Vec::new(),
vias: Vec::new(),
polygons: Vec::new(),
}
}
}
#[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)]
pub struct JointId(usize);
@ -83,8 +30,6 @@ pub struct Joint {
pub position: [i64; 2],
pub layer: usize,
pub radius: u64,
pub net: NetId,
pub pin: Option<PinId>,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -109,8 +54,6 @@ pub struct Segment {
pub endjoints: [JointId; 2],
pub layer: usize,
pub half_width: u64,
pub net: NetId,
pub pin: Option<PinId>,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -135,8 +78,6 @@ pub struct Via {
pub endpoints: [JointId; 2],
pub layer: usize,
pub radius: u64,
pub net: NetId,
pub pin: Option<PinId>,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -160,8 +101,6 @@ impl PolygonId {
pub struct Polygon {
pub vertices: Vec<[i64; 2]>,
pub layer: usize,
pub net: NetId,
pub pin: Option<PinId>,
}
#[derive(Clone, Debug, Getters)]
@ -170,7 +109,6 @@ pub struct Layout {
place_boundary: Vec<[i64; 2]>,
layer_count: usize,
pins: StableVec<Pin>,
joints: Recorder<StableVec<Joint>>,
segments: Recorder<StableVec<Segment>>,
vias: Recorder<StableVec<Via>>,
@ -184,7 +122,6 @@ impl Layout {
place_boundary: boundary,
layer_count,
pins: StableVec::new(),
joints: Recorder::new(StableVec::new()),
segments: Recorder::new(StableVec::new()),
vias: Recorder::new(StableVec::new()),
@ -192,52 +129,20 @@ impl Layout {
}
}
pub fn add_pin(&mut self) -> PinId {
PinId::new(self.pins.push(Pin::new()))
}
pub fn add_joint(&mut self, joint: Joint) -> JointId {
let pin_id = joint.pin;
let joint_id = JointId::new(self.joints.push(joint));
if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].joints.push(joint_id);
}
joint_id
JointId::new(self.joints.push(joint))
}
pub fn add_segment(&mut self, segment: Segment) -> SegmentId {
let pin_id = segment.pin;
let segment_id = SegmentId::new(self.segments.push(segment));
if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].segments.push(segment_id);
}
segment_id
SegmentId::new(self.segments.push(segment))
}
pub fn add_via(&mut self, via: Via) -> ViaId {
let pin_id = via.pin;
let via_id = ViaId::new(self.vias.push(via));
if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].vias.push(via_id);
}
via_id
ViaId::new(self.vias.push(via))
}
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
let pin_id = polygon.pin;
let polygon_id = PolygonId::new(self.polygons.push(polygon));
if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].polygons.push(polygon_id);
}
polygon_id
PolygonId::new(self.polygons.push(polygon))
}
pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] {
@ -247,10 +152,6 @@ impl Layout {
self.joints.get(&endjoints[1].id()).unwrap().position,
]
}
pub fn pin(&self, pin: PinId) -> &Pin {
&self.pins[pin.id()]
}
}
#[derive(Clone, Debug, Dissolve)]

View File

@ -12,15 +12,13 @@ use crate::{
#[derive(Clone, Debug, Getters)]
pub struct LayerNavmesher {
boundary: Vec<[i64; 2]>,
navmeshes: Vec<RecordingTriangulator<i64>>,
inflation_factors: Vec<f64>,
}
impl LayerNavmesher {
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>) -> Self {
pub fn new() -> Self {
Self {
boundary: boundary.into_iter().collect(),
navmeshes: vec![RecordingTriangulator::new()],
inflation_factors: vec![0.0],
}
@ -30,10 +28,10 @@ impl LayerNavmesher {
let polygon: Vec<[i64; 2]> = polygon.into_iter().collect();
for i in 0..self.navmeshes.len() {
self.navmeshes[i].insert_polygon_and_rebuild(
Self::inflate_polygon(polygon.clone(), self.inflation_factors[i]),
self.boundary.clone(),
);
self.navmeshes[i].insert_polygon_and_rebuild(Self::inflate_polygon(
polygon.clone(),
self.inflation_factors[i],
));
}
}
@ -76,11 +74,9 @@ pub struct Navmesher {
}
impl Navmesher {
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>, layer_count: usize) -> Self {
let boundary: Vec<[i64; 2]> = boundary.into_iter().collect();
pub fn new(layer_count: usize) -> Self {
Self {
layers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone()))
layers: std::iter::repeat_with(LayerNavmesher::new)
.take(layer_count)
.collect(),
}
@ -99,10 +95,7 @@ pub struct NavmesherBoard {
impl NavmesherBoard {
pub fn with_board(board: Board) -> Self {
let mut navmesher = Navmesher::new(
board.layout().boundary().clone(),
*board.layout().layer_count(),
);
let mut navmesher = Navmesher::new(*board.layout().layer_count());
for (_, joint) in board.layout().joints().collection() {
Self::insert_joint_in_navmesher(&mut navmesher, *joint);

View File

@ -2,8 +2,6 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use std::collections::BTreeMap;
use bimap::BiBTreeMap;
use specctra::{
math::PointWithRotation,
@ -13,7 +11,7 @@ use specctra::{
use crate::{
Segment,
board::Board,
layout::{Joint, NetId, PinId, Polygon},
layout::{Joint, Polygon},
math::Vector2,
};
@ -42,12 +40,7 @@ impl Board {
tmp.sort_unstable();
tmp.dedup();
BiBTreeMap::from_iter(
tmp.into_iter()
.cloned()
.enumerate()
.map(|(i, v)| (NetId::new(i), v)),
)
BiBTreeMap::from_iter(tmp.into_iter().cloned().enumerate())
};
let mut board = Board::with_names(
@ -57,8 +50,6 @@ impl Board {
.coords()
.into_owned()
.into_iter()
.skip(1)
.rev()
.map(|p| [p.x as i64, p.y as i64])
.collect(),
dsn.pcb.structure.layers.len(),
@ -67,14 +58,14 @@ impl Board {
);
// Mapping of pin -> net prepared for adding pins.
let pin_nets: BTreeMap<String, NetId> = dsn
let pin_nets = dsn
.pcb
.network
.nets
.iter()
.filter_map(|net_pin_assignments| {
// Resolve the id so we don't work with strings.
let net = board.net_id(&net_pin_assignments.name).unwrap();
let net = board.net_id(&net_pin_assignments.name);
net_pin_assignments.pins.as_ref().map(|pins| {
// Take the list of pins
@ -83,8 +74,7 @@ impl Board {
})
})
// Flatten the nested iters into a single stream of tuples.
.flatten()
.collect();
.flatten();
// Add pins from components.
for component in &dsn.pcb.placement.components {
@ -103,9 +93,6 @@ impl Board {
};
for pin in &image.pins {
let pin_name = format!("{}-{}", place.name, pin.id);
let pin_id = board.ensure_pin(pin_name.clone());
let net = pin_nets.get(&pin_name).copied().unwrap();
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
for shape in padstack.shapes.iter() {
@ -118,8 +105,6 @@ impl Board {
pin.point_with_rotation(),
(circle.diameter / 2.0) as u64,
layer,
net,
Some(pin_id),
!place_side_is_front,
)
}
@ -134,8 +119,6 @@ impl Board {
rect.x2,
rect.y2,
layer,
net,
Some(pin_id),
!place_side_is_front,
)
}
@ -148,8 +131,6 @@ impl Board {
&path.coords,
path.width,
layer,
net,
Some(pin_id),
!place_side_is_front,
)
}
@ -162,8 +143,6 @@ impl Board {
&polygon.coords,
polygon.width,
layer,
net,
Some(pin_id),
!place_side_is_front,
)
}
@ -174,7 +153,7 @@ impl Board {
}
for via in &dsn.pcb.wiring.vias {
let net = board.net_id(&via.net).unwrap();
let net = board.net_id(&via.net);
let padstack = dsn.pcb.library.find_padstack_by_name(&via.name).unwrap();
let get_layer = |board: &Board, name: &str| {
@ -191,8 +170,6 @@ impl Board {
PointWithRotation::default(),
(circle.diameter / 2.0) as u64,
layer,
net,
None,
false,
)
}
@ -207,8 +184,6 @@ impl Board {
rect.x2,
rect.y2,
layer,
net,
None,
false,
)
}
@ -221,8 +196,6 @@ impl Board {
&path.coords,
path.width,
layer,
net,
None,
false,
)
}
@ -235,8 +208,6 @@ impl Board {
&polygon.coords,
polygon.width,
layer,
net,
None,
false,
)
}
@ -246,7 +217,7 @@ impl Board {
for wire in dsn.pcb.wiring.wires.iter() {
let layer = board.layer_id(&wire.path.layer).unwrap();
let net = board.net_id(&wire.net).unwrap();
let net = board.net_id(&wire.net);
Self::place_path(
&mut board,
@ -255,8 +226,6 @@ impl Board {
&wire.path.coords,
wire.path.width,
layer,
net,
None,
false,
);
}
@ -267,18 +236,14 @@ impl Board {
fn place_circle(
board: &mut Board,
place: PointWithRotation,
pin_pos: PointWithRotation,
pin: PointWithRotation,
radius: u64,
layer: usize,
net: NetId,
pin: Option<PinId>,
flip: bool,
) {
board.add_joint(Joint {
position: Self::pos(place, pin_pos, 0.0, 0.0, flip),
position: Self::pos(place, pin, 0.0, 0.0, flip),
layer,
net,
pin,
radius,
});
}
@ -286,53 +251,45 @@ impl Board {
fn place_rect(
board: &mut Board,
place: PointWithRotation,
pin_pos: PointWithRotation,
pin: PointWithRotation,
x1: f64,
y1: f64,
x2: f64,
y2: f64,
layer: usize,
net: NetId,
pin: Option<PinId>,
flip: bool,
) {
board.add_polygon(Polygon {
vertices: vec![
Self::pos(place, pin_pos, x1, y1, flip),
Self::pos(place, pin_pos, x2, y1, flip),
Self::pos(place, pin_pos, x2, y2, flip),
Self::pos(place, pin_pos, x1, y2, flip),
Self::pos(place, pin, x1, y1, flip),
Self::pos(place, pin, x2, y1, flip),
Self::pos(place, pin, x2, y2, flip),
Self::pos(place, pin, x1, y2, flip),
],
layer,
net,
pin,
});
}
fn place_path(
board: &mut Board,
place: PointWithRotation,
pin_pos: PointWithRotation,
pin: PointWithRotation,
coords: &[Point],
width: f64,
layer: usize,
net: NetId,
pin: Option<PinId>,
flip: bool,
) {
// Add the first coordinate in the wire path as a dot and save its index.
let mut prev_pos = Self::pos(place, pin_pos, coords[0].x, coords[0].y, flip);
let mut prev_pos = Self::pos(place, pin, coords[0].x, coords[0].y, flip);
let mut prev_joint = board.add_joint(Joint {
position: prev_pos,
layer,
radius: (width / 2.0) as u64,
net,
pin,
});
// Iterate through path coords starting from the second.
for coord in coords.iter().skip(1) {
let pos = Self::pos(place, pin_pos, coord.x, coord.y, flip);
let pos = Self::pos(place, pin, coord.x, coord.y, flip);
if pos == prev_pos {
continue;
@ -340,10 +297,8 @@ impl Board {
let joint = board.add_joint(Joint {
position: pos,
layer,
radius: (width / 2.0) as u64,
net,
pin,
layer,
});
// Add a seg between the current and previous coords.
@ -351,8 +306,6 @@ impl Board {
endjoints: [prev_joint, joint],
layer,
half_width: (width / 2.0) as u64,
net,
pin,
});
prev_pos = pos;
@ -363,24 +316,17 @@ impl Board {
fn place_polygon(
board: &mut Board,
place: PointWithRotation,
pin_pos: PointWithRotation,
pin: PointWithRotation,
coords: &[Point],
width: f64,
layer: usize,
net: NetId,
pin: Option<PinId>,
flip: bool,
) {
let vertices: Vec<[i64; 2]> = coords
.iter()
.map(|coord| Self::pos(place, pin_pos, coord.x, coord.y, flip))
.map(|coord| Self::pos(place, pin, coord.x, coord.y, flip))
.collect();
board.add_polygon(Polygon {
vertices,
layer,
net,
pin,
});
board.add_polygon(Polygon { vertices, layer });
}
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize {