mirror of https://codeberg.org/topola/topola.git
Compare commits
3 Commits
e36b631029
...
d77be1b0b3
| Author | SHA1 | Date |
|---|---|---|
|
|
d77be1b0b3 | |
|
|
3f362d62c3 | |
|
|
3f6073af03 |
|
|
@ -7,21 +7,19 @@ use derive_getters::{Dissolve, Getters};
|
|||
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||
|
||||
use crate::layout::{
|
||||
Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId, Via, ViaId,
|
||||
Joint, JointId, Layout, LayoutHalfDelta, NetId, PinId, 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<usize, String>,
|
||||
net_names: BiBTreeMap<NetId, String>,
|
||||
#[getter(skip)]
|
||||
pin_names: BiBTreeMap<PinId, String>,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
|
|
@ -30,6 +28,7 @@ impl Board {
|
|||
layout: Layout::new(boundary, layer_count),
|
||||
layer_names: BiBTreeMap::new(),
|
||||
net_names: BiBTreeMap::new(),
|
||||
pin_names: BiBTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,15 +36,27 @@ impl Board {
|
|||
boundary: Vec<[i64; 2]>,
|
||||
layer_count: usize,
|
||||
layer_names: BiBTreeMap<usize, String>,
|
||||
net_names: BiBTreeMap<usize, String>,
|
||||
net_names: BiBTreeMap<NetId, 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)
|
||||
}
|
||||
|
|
@ -70,11 +81,11 @@ impl Board {
|
|||
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)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,59 @@ 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);
|
||||
|
||||
|
|
@ -30,6 +83,8 @@ 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)]
|
||||
|
|
@ -54,6 +109,8 @@ 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)]
|
||||
|
|
@ -78,6 +135,8 @@ 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)]
|
||||
|
|
@ -101,6 +160,8 @@ impl PolygonId {
|
|||
pub struct Polygon {
|
||||
pub vertices: Vec<[i64; 2]>,
|
||||
pub layer: usize,
|
||||
pub net: NetId,
|
||||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
|
|
@ -109,6 +170,7 @@ 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>>,
|
||||
|
|
@ -122,6 +184,7 @@ 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()),
|
||||
|
|
@ -129,20 +192,52 @@ 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 {
|
||||
JointId::new(self.joints.push(joint))
|
||||
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
|
||||
}
|
||||
|
||||
pub fn add_segment(&mut self, segment: Segment) -> SegmentId {
|
||||
SegmentId::new(self.segments.push(segment))
|
||||
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
|
||||
}
|
||||
|
||||
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||
ViaId::new(self.vias.push(via))
|
||||
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
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
PolygonId::new(self.polygons.push(polygon))
|
||||
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
|
||||
}
|
||||
|
||||
pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] {
|
||||
|
|
@ -152,6 +247,10 @@ 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)]
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ 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() -> Self {
|
||||
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>) -> Self {
|
||||
Self {
|
||||
boundary: boundary.into_iter().collect(),
|
||||
navmeshes: vec![RecordingTriangulator::new()],
|
||||
inflation_factors: vec![0.0],
|
||||
}
|
||||
|
|
@ -28,10 +30,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.navmeshes[i].insert_polygon_and_rebuild(
|
||||
Self::inflate_polygon(polygon.clone(), self.inflation_factors[i]),
|
||||
self.boundary.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,9 +76,11 @@ pub struct Navmesher {
|
|||
}
|
||||
|
||||
impl Navmesher {
|
||||
pub fn new(layer_count: usize) -> Self {
|
||||
pub fn new(boundary: impl IntoIterator<Item = [i64; 2]>, layer_count: usize) -> Self {
|
||||
let boundary: Vec<[i64; 2]> = boundary.into_iter().collect();
|
||||
|
||||
Self {
|
||||
layers: std::iter::repeat_with(LayerNavmesher::new)
|
||||
layers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone()))
|
||||
.take(layer_count)
|
||||
.collect(),
|
||||
}
|
||||
|
|
@ -95,7 +99,10 @@ pub struct NavmesherBoard {
|
|||
|
||||
impl NavmesherBoard {
|
||||
pub fn with_board(board: Board) -> Self {
|
||||
let mut navmesher = Navmesher::new(*board.layout().layer_count());
|
||||
let mut navmesher = Navmesher::new(
|
||||
board.layout().boundary().clone(),
|
||||
*board.layout().layer_count(),
|
||||
);
|
||||
|
||||
for (_, joint) in board.layout().joints().collection() {
|
||||
Self::insert_joint_in_navmesher(&mut navmesher, *joint);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use bimap::BiBTreeMap;
|
||||
use specctra::{
|
||||
math::PointWithRotation,
|
||||
|
|
@ -11,7 +13,7 @@ use specctra::{
|
|||
use crate::{
|
||||
Segment,
|
||||
board::Board,
|
||||
layout::{Joint, Polygon},
|
||||
layout::{Joint, NetId, PinId, Polygon},
|
||||
math::Vector2,
|
||||
};
|
||||
|
||||
|
|
@ -40,7 +42,12 @@ impl Board {
|
|||
tmp.sort_unstable();
|
||||
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(
|
||||
|
|
@ -50,6 +57,8 @@ 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(),
|
||||
|
|
@ -58,14 +67,14 @@ impl Board {
|
|||
);
|
||||
|
||||
// Mapping of pin -> net prepared for adding pins.
|
||||
let pin_nets = dsn
|
||||
let pin_nets: BTreeMap<String, NetId> = 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);
|
||||
let net = board.net_id(&net_pin_assignments.name).unwrap();
|
||||
|
||||
net_pin_assignments.pins.as_ref().map(|pins| {
|
||||
// Take the list of pins
|
||||
|
|
@ -74,7 +83,8 @@ impl Board {
|
|||
})
|
||||
})
|
||||
// Flatten the nested iters into a single stream of tuples.
|
||||
.flatten();
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
// Add pins from components.
|
||||
for component in &dsn.pcb.placement.components {
|
||||
|
|
@ -93,6 +103,9 @@ 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() {
|
||||
|
|
@ -105,6 +118,8 @@ impl Board {
|
|||
pin.point_with_rotation(),
|
||||
(circle.diameter / 2.0) as u64,
|
||||
layer,
|
||||
net,
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
}
|
||||
|
|
@ -119,6 +134,8 @@ impl Board {
|
|||
rect.x2,
|
||||
rect.y2,
|
||||
layer,
|
||||
net,
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
}
|
||||
|
|
@ -131,6 +148,8 @@ impl Board {
|
|||
&path.coords,
|
||||
path.width,
|
||||
layer,
|
||||
net,
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
}
|
||||
|
|
@ -143,6 +162,8 @@ impl Board {
|
|||
&polygon.coords,
|
||||
polygon.width,
|
||||
layer,
|
||||
net,
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
}
|
||||
|
|
@ -153,7 +174,7 @@ impl Board {
|
|||
}
|
||||
|
||||
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 get_layer = |board: &Board, name: &str| {
|
||||
|
|
@ -170,6 +191,8 @@ impl Board {
|
|||
PointWithRotation::default(),
|
||||
(circle.diameter / 2.0) as u64,
|
||||
layer,
|
||||
net,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -184,6 +207,8 @@ impl Board {
|
|||
rect.x2,
|
||||
rect.y2,
|
||||
layer,
|
||||
net,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -196,6 +221,8 @@ impl Board {
|
|||
&path.coords,
|
||||
path.width,
|
||||
layer,
|
||||
net,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -208,6 +235,8 @@ impl Board {
|
|||
&polygon.coords,
|
||||
polygon.width,
|
||||
layer,
|
||||
net,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -217,7 +246,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);
|
||||
let net = board.net_id(&wire.net).unwrap();
|
||||
|
||||
Self::place_path(
|
||||
&mut board,
|
||||
|
|
@ -226,6 +255,8 @@ impl Board {
|
|||
&wire.path.coords,
|
||||
wire.path.width,
|
||||
layer,
|
||||
net,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
|
@ -236,14 +267,18 @@ impl Board {
|
|||
fn place_circle(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
pin_pos: PointWithRotation,
|
||||
radius: u64,
|
||||
layer: usize,
|
||||
net: NetId,
|
||||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
board.add_joint(Joint {
|
||||
position: Self::pos(place, pin, 0.0, 0.0, flip),
|
||||
position: Self::pos(place, pin_pos, 0.0, 0.0, flip),
|
||||
layer,
|
||||
net,
|
||||
pin,
|
||||
radius,
|
||||
});
|
||||
}
|
||||
|
|
@ -251,45 +286,53 @@ impl Board {
|
|||
fn place_rect(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
pin_pos: 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, x1, y1, flip),
|
||||
Self::pos(place, pin, x2, y1, flip),
|
||||
Self::pos(place, pin, x2, y2, flip),
|
||||
Self::pos(place, pin, x1, y2, flip),
|
||||
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),
|
||||
],
|
||||
layer,
|
||||
net,
|
||||
pin,
|
||||
});
|
||||
}
|
||||
|
||||
fn place_path(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
pin_pos: 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, coords[0].x, coords[0].y, flip);
|
||||
let mut prev_pos = Self::pos(place, pin_pos, 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, coord.x, coord.y, flip);
|
||||
let pos = Self::pos(place, pin_pos, coord.x, coord.y, flip);
|
||||
|
||||
if pos == prev_pos {
|
||||
continue;
|
||||
|
|
@ -297,8 +340,10 @@ impl Board {
|
|||
|
||||
let joint = board.add_joint(Joint {
|
||||
position: pos,
|
||||
radius: (width / 2.0) as u64,
|
||||
layer,
|
||||
radius: (width / 2.0) as u64,
|
||||
net,
|
||||
pin,
|
||||
});
|
||||
|
||||
// Add a seg between the current and previous coords.
|
||||
|
|
@ -306,6 +351,8 @@ impl Board {
|
|||
endjoints: [prev_joint, joint],
|
||||
layer,
|
||||
half_width: (width / 2.0) as u64,
|
||||
net,
|
||||
pin,
|
||||
});
|
||||
|
||||
prev_pos = pos;
|
||||
|
|
@ -316,17 +363,24 @@ impl Board {
|
|||
fn place_polygon(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
pin_pos: 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, coord.x, coord.y, flip))
|
||||
.map(|coord| Self::pos(place, pin_pos, coord.x, coord.y, flip))
|
||||
.collect();
|
||||
board.add_polygon(Polygon { vertices, layer });
|
||||
board.add_polygon(Polygon {
|
||||
vertices,
|
||||
layer,
|
||||
net,
|
||||
pin,
|
||||
});
|
||||
}
|
||||
|
||||
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize {
|
||||
|
|
|
|||
Loading…
Reference in New Issue