From f9ea3940d2ef223faa1c8dc4f133968e86883f3d Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 24 May 2026 00:27:11 +0200 Subject: [PATCH] Load outlines to its own separate layer and group --- topola/src/board/mod.rs | 7 +++-- topola/src/navmesher.rs | 4 +-- topola/src/specctra.rs | 65 +++++++++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/topola/src/board/mod.rs b/topola/src/board/mod.rs index 25e6489..e3d3243 100644 --- a/topola/src/board/mod.rs +++ b/topola/src/board/mod.rs @@ -76,11 +76,10 @@ impl Board { pub fn with_names( boundary: Vec>, - layer_groups: impl Into>, + layer_groups: Vec, layer_names: BiBTreeMap, net_names: BiBTreeMap, ) -> Self { - let layer_groups = layer_groups.into(); Self { layout: Layout::new( boundary.into_iter().map(Into::into).collect(), @@ -171,6 +170,10 @@ impl Board { self.layer_names.as_ref().get_by_right(layer_name).copied() } + pub fn layer_group(&self, layer: LayerId) -> LayerGroupId { + self.layer_groups[layer.index()] + } + pub fn net_name(&self, id: NetId) -> Option<&str> { self.net_names.get_by_left(&id).map(String::as_str) } diff --git a/topola/src/navmesher.rs b/topola/src/navmesher.rs index 21266a4..f6f1f6c 100644 --- a/topola/src/navmesher.rs +++ b/topola/src/navmesher.rs @@ -218,7 +218,7 @@ impl NavmesherBoard { polygon_multiobstacles: Recorder::new(StableVec::new()), }; - for (i, joint) in this.board.layout().joints().container().iter() { + /*for (i, joint) in this.board.layout().joints().container().iter() { this.joint_multiobstacles.insert( i, this.navmesher @@ -240,7 +240,7 @@ impl NavmesherBoard { this.navmesher .insert_multiobstacle(polygon.layer, polygon.vertices.clone()), ); - } + }*/ this } diff --git a/topola/src/specctra.rs b/topola/src/specctra.rs index 24791d2..aeac185 100644 --- a/topola/src/specctra.rs +++ b/topola/src/specctra.rs @@ -11,7 +11,7 @@ use specctra::{ }; use crate::{ - board::Board, + board::{Board, LayerGroupId}, layout::LayerId, layout::compounds::{ComponentId, NetId, PinId}, math::Vector2, @@ -20,37 +20,43 @@ use crate::{ impl Board { pub fn from_specctra(dsn: DsnFile) -> Self { - let layer_names = BiBTreeMap::from_iter( - dsn.pcb - .structure - .layers - .iter() - .enumerate() - .map(|(index, layer)| (LayerId::new(index), layer.name.clone())), - ); + let top_outline_layer_id = LayerId::new(0); + let pcb_layer_offset = 1; + let bottom_outline_layer_id = + LayerId::new(dsn.pcb.structure.layers.len() + pcb_layer_offset); + let mut layer_names = + BiBTreeMap::from_iter(dsn.pcb.structure.layers.iter().enumerate().map( + |(index, layer)| (LayerId::new(index + pcb_layer_offset), layer.name.clone()), + )); + layer_names.insert(top_outline_layer_id, "outlines.top".to_string()); + layer_names.insert(bottom_outline_layer_id, "outlines.bottom".to_string()); // assign IDs to all nets named in pcb.network let net_names = { - let mut tmp: Vec<_> = dsn + let mut tmp: Vec = dsn .pcb .network .classes .iter() .flat_map(|class| &class.nets) .chain(dsn.pcb.network.nets.iter().map(|net| &net.name)) + .cloned() .collect(); // deduplicate net names + tmp.push("outlines".to_string()); 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().enumerate().map(|(i, v)| (NetId::new(i), v))) }; + let mut layer_groups = vec![LayerGroupId::new(1)]; + layer_groups.extend(std::iter::repeat_n( + LayerGroupId::new(0), + dsn.pcb.structure.layers.len(), + )); + layer_groups.push(LayerGroupId::new(1)); + let mut board = Board::with_names( dsn.pcb .structure @@ -62,10 +68,11 @@ impl Board { .rev() .map(|p| Vector2::new(p.x as i64, p.y as i64)) .collect(), - vec![crate::board::LayerGroupId::new(0); dsn.pcb.structure.layers.len()], + layer_groups, layer_names, net_names, ); + let outline_net = board.net_id("outlines").unwrap(); // Mapping of pin -> net prepared for adding pins. let pin_nets: BTreeMap = dsn @@ -105,6 +112,26 @@ impl Board { Self::layer(board, &dsn.pcb.structure.layers, name, place_side_is_front) }; + for outline in &image.outlines { + let outline_layer_id = if place_side_is_front { + top_outline_layer_id + } else { + bottom_outline_layer_id + }; + Self::place_path( + &mut board, + place.point_with_rotation(), + PointWithRotation::default(), + &outline.path.coords, + outline.path.width, + outline_layer_id, + outline_net, + Some(component_id), + None, + !place_side_is_front, + ); + } + for pin in &image.pins { let pin_name = format!("{}-{}", place.name, pin.id); @@ -413,12 +440,14 @@ impl Board { } fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> LayerId { + let pcb_layer_offset = 1; let image_layer = board.layer_id(name).unwrap(); + let image_layer_index = image_layer.index() - pcb_layer_offset; if front { image_layer } else { - LayerId::new(layers.len() - image_layer.index() - 1) + LayerId::new(layers.len() - image_layer_index) } }