mirror of https://codeberg.org/topola/topola.git
Load layers to primitives
This commit is contained in:
parent
5e6ddac19f
commit
8a50e70a6a
|
|
@ -9,6 +9,7 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
bimap = "0.6"
|
||||
dearcut = { version = "0.1", features = ["undoredo"] }
|
||||
derive-getters.workspace = true
|
||||
derive_more.workspace = true
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use bimap::BiBTreeMap;
|
||||
use derive_getters::{Dissolve, Getters};
|
||||
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||
|
||||
|
|
@ -18,12 +19,30 @@ struct Layer {
|
|||
#[derive(Clone, Debug, Getters)]
|
||||
pub struct Board {
|
||||
layout: Layout,
|
||||
#[getter(skip)]
|
||||
layer_names: BiBTreeMap<usize, String>,
|
||||
#[getter(skip)]
|
||||
net_names: BiBTreeMap<usize, String>,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
pub fn new(boundary: Vec<[i64; 2]>) -> Self {
|
||||
Self {
|
||||
layout: Layout::new(boundary),
|
||||
layer_names: BiBTreeMap::new(),
|
||||
net_names: BiBTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_names(
|
||||
boundary: Vec<[i64; 2]>,
|
||||
layer_names: BiBTreeMap<usize, String>,
|
||||
net_names: BiBTreeMap<usize, String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
layout: Layout::new(boundary),
|
||||
layer_names,
|
||||
net_names,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +65,22 @@ impl Board {
|
|||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
self.layout.add_polygon(polygon)
|
||||
}
|
||||
|
||||
pub fn layer_name(&self, layer: usize) -> &str {
|
||||
&self.layer_names.get_by_left(&layer).unwrap()
|
||||
}
|
||||
|
||||
pub fn layer_id(&self, name: &str) -> usize {
|
||||
*self.layer_names.get_by_right(name).unwrap()
|
||||
}
|
||||
|
||||
pub fn net_name(&self, net: usize) -> &str {
|
||||
&self.net_names.get_by_left(&net).unwrap()
|
||||
}
|
||||
|
||||
pub fn net_id(&self, name: &str) -> usize {
|
||||
*self.net_names.get_by_right(name).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Dissolve)]
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use bimap::BiBTreeMap;
|
||||
use specctra::{
|
||||
math::PointWithRotation,
|
||||
structure::{DsnFile, Point, Shape},
|
||||
structure::{DsnFile, Layer, Point, Shape},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -16,7 +17,33 @@ use crate::{
|
|||
|
||||
impl Board {
|
||||
pub fn from_specctra(dsn: DsnFile) -> Self {
|
||||
let mut board = Board::new(
|
||||
let layer_names = BiBTreeMap::from_iter(
|
||||
dsn.pcb
|
||||
.structure
|
||||
.layers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, layer)| (index, layer.name.clone())),
|
||||
);
|
||||
|
||||
// assign IDs to all nets named in pcb.network
|
||||
let net_names = {
|
||||
let mut tmp: Vec<_> = dsn
|
||||
.pcb
|
||||
.network
|
||||
.classes
|
||||
.iter()
|
||||
.flat_map(|class| &class.nets)
|
||||
.chain(dsn.pcb.network.nets.iter().map(|net| &net.name))
|
||||
.collect();
|
||||
// deduplicate net names
|
||||
tmp.sort_unstable();
|
||||
tmp.dedup();
|
||||
|
||||
BiBTreeMap::from_iter(tmp.into_iter().cloned().enumerate())
|
||||
};
|
||||
|
||||
let mut board = Board::with_names(
|
||||
dsn.pcb
|
||||
.structure
|
||||
.boundary
|
||||
|
|
@ -25,8 +52,29 @@ impl Board {
|
|||
.into_iter()
|
||||
.map(|p| [p.x as i64, p.y as i64])
|
||||
.collect(),
|
||||
layer_names,
|
||||
net_names,
|
||||
);
|
||||
|
||||
// Mapping of pin -> net prepared for adding pins.
|
||||
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);
|
||||
|
||||
net_pin_assignments.pins.as_ref().map(|pins| {
|
||||
// Take the list of pins
|
||||
// and for each pin output (pin name, net id).
|
||||
pins.names.iter().map(move |pinname| (pinname.clone(), net))
|
||||
})
|
||||
})
|
||||
// Flatten the nested iters into a single stream of tuples.
|
||||
.flatten();
|
||||
|
||||
// Add pins from components.
|
||||
for component in &dsn.pcb.placement.components {
|
||||
let image = dsn
|
||||
|
|
@ -38,54 +86,65 @@ impl Board {
|
|||
.unwrap();
|
||||
|
||||
for place in &component.places {
|
||||
/*let place_side_is_front = place.side == "front";
|
||||
let place_side_is_front = place.side == "front";
|
||||
let get_layer = |board: &Board, name: &str| {
|
||||
Self::layer(board, &dsn.pcb.structure.layers, name, place_side_is_front)
|
||||
};*/
|
||||
};
|
||||
|
||||
for pin in &image.pins {
|
||||
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
|
||||
|
||||
for shape in padstack.shapes.iter() {
|
||||
match shape {
|
||||
Shape::Circle(circle) => Self::place_circle(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
0,
|
||||
(circle.diameter / 2.0) as u64,
|
||||
false,
|
||||
),
|
||||
Shape::Rect(rect) => Self::place_rect(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
rect.x1,
|
||||
rect.y1,
|
||||
rect.x2,
|
||||
rect.y2,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
Shape::Path(path) => Self::place_path(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
&path.coords,
|
||||
path.width,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
Shape::Polygon(polygon) => Self::place_polygon(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
&polygon.coords,
|
||||
polygon.width,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
_ => (),
|
||||
Shape::Circle(circle) => {
|
||||
let layer = get_layer(&board, &circle.layer);
|
||||
Self::place_circle(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
layer,
|
||||
(circle.diameter / 2.0) as u64,
|
||||
false,
|
||||
)
|
||||
}
|
||||
Shape::Rect(rect) => {
|
||||
let layer = get_layer(&board, &rect.layer);
|
||||
Self::place_rect(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
rect.x1,
|
||||
rect.y1,
|
||||
rect.x2,
|
||||
rect.y2,
|
||||
layer,
|
||||
false,
|
||||
)
|
||||
}
|
||||
Shape::Path(path) => {
|
||||
let layer = get_layer(&board, &path.layer);
|
||||
Self::place_path(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
&path.coords,
|
||||
path.width,
|
||||
layer,
|
||||
false,
|
||||
)
|
||||
}
|
||||
Shape::Polygon(polygon) => {
|
||||
let layer = get_layer(&board, &polygon.layer);
|
||||
Self::place_polygon(
|
||||
&mut board,
|
||||
place.point_with_rotation(),
|
||||
pin.point_with_rotation(),
|
||||
&polygon.coords,
|
||||
polygon.width,
|
||||
layer,
|
||||
false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +154,7 @@ impl Board {
|
|||
board
|
||||
}
|
||||
|
||||
pub fn place_circle(
|
||||
fn place_circle(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
|
|
@ -110,7 +169,7 @@ impl Board {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn place_rect(
|
||||
fn place_rect(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
|
|
@ -132,7 +191,7 @@ impl Board {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn place_path(
|
||||
fn place_path(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
|
|
@ -175,7 +234,7 @@ impl Board {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn place_polygon(
|
||||
fn place_polygon(
|
||||
board: &mut Board,
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
|
|
@ -191,6 +250,16 @@ impl Board {
|
|||
board.add_polygon(Polygon { vertices, layer });
|
||||
}
|
||||
|
||||
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize {
|
||||
let image_layer = board.layer_id(name);
|
||||
|
||||
if front {
|
||||
image_layer
|
||||
} else {
|
||||
layers.len() - image_layer - 1
|
||||
}
|
||||
}
|
||||
|
||||
fn pos(
|
||||
place: PointWithRotation,
|
||||
pin: PointWithRotation,
|
||||
|
|
|
|||
Loading…
Reference in New Issue