From dc4ce2fbc7a22adaaadf7887d010bd393e5ebc92 Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 27 Sep 2024 16:09:39 +0200 Subject: [PATCH 1/5] math, spectra: factor out PointWithRotation --- src/math.rs | 19 +++++- src/specctra/design.rs | 123 +++++++++++++------------------------- src/specctra/structure.rs | 19 ++++++ 3 files changed, 76 insertions(+), 85 deletions(-) diff --git a/src/math.rs b/src/math.rs index cd25e16..1aea605 100644 --- a/src/math.rs +++ b/src/math.rs @@ -20,14 +20,29 @@ pub struct Circle { pub r: f64, } +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct PointWithRotation { + pub pos: Point, + pub rot: f64, +} + impl Sub for Circle { type Output = Self; fn sub(self, other: Self) -> Self { - return Self { + Self { pos: self.pos - other.pos, r: self.r, - }; + } + } +} + +impl Default for PointWithRotation { + fn default() -> Self { + Self { + pos: (0.0, 0.0).into(), + rot: 0.0, + } } } diff --git a/src/specctra/design.rs b/src/specctra/design.rs index e7fbec8..63ee2a8 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -14,7 +14,7 @@ use crate::{ }, geometry::{primitive::PrimitiveShape, GetWidth}, layout::{poly::SolidPolyWeight, Layout}, - math::Circle, + math::{Circle, PointWithRotation}, specctra::{ mesadata::SpecctraMesadata, read::{self, ListTokenizer}, @@ -253,10 +253,8 @@ impl SpecctraDesign { ); Self::add_circle( &mut board, - (place.x, place.y).into(), - place.rotation, - (pin.x, pin.y).into(), - pin.rotate.unwrap_or(0.0), + place.point_with_rotation(), + pin.point_with_rotation(), circle.diameter / 2.0, layer, *net, @@ -272,10 +270,8 @@ impl SpecctraDesign { ); Self::add_rect( &mut board, - (place.x, place.y).into(), - place.rotation, - (pin.x, pin.y).into(), - pin.rotate.unwrap_or(0.0), + place.point_with_rotation(), + pin.point_with_rotation(), rect.x1, rect.y1, rect.x2, @@ -294,10 +290,8 @@ impl SpecctraDesign { ); Self::add_path( &mut board, - (place.x, place.y).into(), - place.rotation, - (pin.x, pin.y).into(), - pin.rotate.unwrap_or(0.0), + place.point_with_rotation(), + pin.point_with_rotation(), &path.coords, path.width, layer, @@ -314,10 +308,8 @@ impl SpecctraDesign { ); Self::add_polygon( &mut board, - (place.x, place.y).into(), - place.rotation, - (pin.x, pin.y).into(), - pin.rotate.unwrap_or(0.0), + place.point_with_rotation(), + pin.point_with_rotation(), &polygon.coords, polygon.width, layer, @@ -359,10 +351,8 @@ impl SpecctraDesign { ); Self::add_circle( &mut board, - (0.0, 0.0).into(), - 0.0, - (0.0, 0.0).into(), - 0.0, + PointWithRotation::default(), + PointWithRotation::default(), circle.diameter / 2.0, layer, net, @@ -374,10 +364,8 @@ impl SpecctraDesign { Self::layer(&mut board, &self.pcb.structure.layers, &rect.layer, true); Self::add_rect( &mut board, - (0.0, 0.0).into(), - 0.0, - (0.0, 0.0).into(), - 0.0, + PointWithRotation::default(), + PointWithRotation::default(), rect.x1, rect.y1, rect.x2, @@ -392,10 +380,8 @@ impl SpecctraDesign { Self::layer(&mut board, &self.pcb.structure.layers, &path.layer, true); Self::add_path( &mut board, - (0.0, 0.0).into(), - 0.0, - (0.0, 0.0).into(), - 0.0, + PointWithRotation::default(), + PointWithRotation::default(), &path.coords, path.width, layer, @@ -412,10 +398,8 @@ impl SpecctraDesign { ); Self::add_polygon( &mut board, - (0.0, 0.0).into(), - 0.0, - (0.0, 0.0).into(), - 0.0, + PointWithRotation::default(), + PointWithRotation::default(), &polygon.coords, polygon.width, layer, @@ -443,10 +427,8 @@ impl SpecctraDesign { Self::add_path( &mut board, - (0.0, 0.0).into(), - 0.0, - (0.0, 0.0).into(), - 0.0, + PointWithRotation::default(), + PointWithRotation::default(), &wire.path.coords, wire.path.width, layer, @@ -500,17 +482,15 @@ impl SpecctraDesign { fn add_circle( board: &mut Board, - place_pos: Point, - place_rot: f64, - pin_pos: Point, - pin_rot: f64, + place: PointWithRotation, + pin: PointWithRotation, r: f64, layer: usize, net: usize, maybe_pin: Option, ) { let circle = Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, 0.0, 0.0), + pos: Self::pos(place, pin, 0.0, 0.0), r, }; @@ -526,10 +506,8 @@ impl SpecctraDesign { fn add_rect( board: &mut Board, - place_pos: Point, - place_rot: f64, - pin_pos: Point, - pin_rot: f64, + place: PointWithRotation, + pin: PointWithRotation, x1: f64, y1: f64, x2: f64, @@ -551,7 +529,7 @@ impl SpecctraDesign { let dot_1_1 = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, x1, y1), + pos: Self::pos(place, pin, x1, y1), r: 0.5, }, layer, @@ -562,7 +540,7 @@ impl SpecctraDesign { let dot_2_1 = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, x2, y1), + pos: Self::pos(place, pin, x2, y1), r: 0.5, }, layer, @@ -573,7 +551,7 @@ impl SpecctraDesign { let dot_2_2 = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, x2, y2), + pos: Self::pos(place, pin, x2, y2), r: 0.5, }, layer, @@ -584,7 +562,7 @@ impl SpecctraDesign { let dot_1_2 = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, x1, y2), + pos: Self::pos(place, pin, x1, y2), r: 0.5, }, layer, @@ -637,10 +615,8 @@ impl SpecctraDesign { fn add_path( board: &mut Board, - place_pos: Point, - place_rot: f64, - pin_pos: Point, - pin_rot: f64, + place: PointWithRotation, + pin: PointWithRotation, coords: &Vec, width: f64, layer: usize, @@ -648,14 +624,7 @@ impl SpecctraDesign { maybe_pin: Option, ) { // add the first coordinate in the wire path as a dot and save its index - let mut prev_pos = Self::pos( - place_pos, - place_rot, - pin_pos, - pin_rot, - coords[0].x, - coords[0].y, - ); + let mut prev_pos = Self::pos(place, pin, coords[0].x, coords[0].y); let mut prev_index = board.add_fixed_dot_infringably( FixedDotWeight { circle: Circle { @@ -670,7 +639,7 @@ impl SpecctraDesign { // iterate through path coords starting from the second for coord in coords.iter().skip(1) { - let pos = Self::pos(place_pos, place_rot, pin_pos, pin_rot, coord.x, coord.y); + let pos = Self::pos(place, pin, coord.x, coord.y); if pos == prev_pos { continue; @@ -707,10 +676,8 @@ impl SpecctraDesign { fn add_polygon( board: &mut Board, - place_pos: Point, - place_rot: f64, - pin_pos: Point, - pin_rot: f64, + place: PointWithRotation, + pin: PointWithRotation, coords: &Vec, width: f64, layer: usize, @@ -730,14 +697,7 @@ impl SpecctraDesign { let mut prev_index = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos( - place_pos, - place_rot, - pin_pos, - pin_rot, - coords[0].x, - coords[0].y, - ), + pos: Self::pos(place, pin, coords[0].x, coords[0].y), r: width / 2.0, }, layer, @@ -753,8 +713,7 @@ impl SpecctraDesign { let index = board.add_poly_fixed_dot_infringably( FixedDotWeight { circle: Circle { - pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, coord.x, coord.y) - .into(), + pos: Self::pos(place, pin, coord.x, coord.y).into(), r: width / 2.0, }, layer, @@ -782,14 +741,12 @@ impl SpecctraDesign { } fn pos( - place_pos: Point, - place_rot: f64, - pin_pos: Point, - pin_rot: f64, + place: PointWithRotation, + pin: PointWithRotation, x: f64, y: f64, ) -> Point { - let pos = (point! {x: x, y: y} + pin_pos).rotate_around_point(pin_rot, pin_pos); - (pos + place_pos).rotate_around_point(place_rot, place_pos) + let pos = (point! {x: x, y: y} + pin.pos).rotate_around_point(pin.rot, pin.pos); + (pos + place.pos).rotate_around_point(place.rot, place.pos) } } diff --git a/src/specctra/structure.rs b/src/specctra/structure.rs index d0a6c36..897ab2b 100644 --- a/src/specctra/structure.rs +++ b/src/specctra/structure.rs @@ -3,6 +3,7 @@ use super::read::ReadDsn; use super::read::{ListTokenizer, ParseError}; use super::write::ListWriter; use super::write::WriteSes; +use crate::math::PointWithRotation; use specctra_derive::ReadDsn; use specctra_derive::WriteSes; @@ -151,6 +152,15 @@ pub struct Place { pub PN: Option, } +impl Place { + pub fn point_with_rotation(&self) -> PointWithRotation { + PointWithRotation { + pos: (self.x, self.y).into(), + rot: self.rotation, + } + } +} + #[derive(ReadDsn, WriteSes, Debug)] pub struct Library { #[vec("image")] @@ -189,6 +199,15 @@ pub struct Pin { pub y: f64, } +impl Pin { + pub fn point_with_rotation(&self) -> PointWithRotation { + PointWithRotation { + pos: (self.x, self.y).into(), + rot: self.rotate.unwrap_or(0.0), + } + } +} + #[derive(ReadDsn, WriteSes, Debug)] pub struct Keepout { #[anon] From cd12775f461babf07b02cc01c47c0ef0ddc30105 Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 27 Sep 2024 16:26:18 +0200 Subject: [PATCH 2/5] specctra/design: refactor Self::layer calls to avoid repetition --- src/specctra/design.rs | 59 ++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/src/specctra/design.rs b/src/specctra/design.rs index 63ee2a8..d703e23 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -230,6 +230,14 @@ impl SpecctraDesign { .find(|image| image.name == component.name) .unwrap(); + let place_side_is_front = place.side == "front"; + let get_layer = |board: &Board, name: &str| Self::layer( + board, + &self.pcb.structure.layers, + name, + place_side_is_front, + ); + for pin in &image.pins { let pinname = format!("{}-{}", place.name, pin.id); let net = pin_nets.get(&pinname).unwrap(); @@ -245,12 +253,7 @@ impl SpecctraDesign { for shape in padstack.shapes.iter() { match shape { Shape::Circle(circle) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &circle.layer, - place.side == "front", - ); + let layer = get_layer(&board, &circle.layer); Self::add_circle( &mut board, place.point_with_rotation(), @@ -262,12 +265,7 @@ impl SpecctraDesign { ) } Shape::Rect(rect) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &rect.layer, - place.side == "front", - ); + let layer = get_layer(&board, &rect.layer); Self::add_rect( &mut board, place.point_with_rotation(), @@ -282,12 +280,7 @@ impl SpecctraDesign { ) } Shape::Path(path) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &path.layer, - place.side == "front", - ); + let layer = get_layer(&board, &path.layer); Self::add_path( &mut board, place.point_with_rotation(), @@ -300,12 +293,7 @@ impl SpecctraDesign { ) } Shape::Polygon(polygon) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &polygon.layer, - place.side == "front", - ); + let layer = get_layer(&board, &polygon.layer); Self::add_polygon( &mut board, place.point_with_rotation(), @@ -340,15 +328,13 @@ impl SpecctraDesign { .find(|padstack| padstack.name == via.name) .unwrap(); + let get_layer = |board: &Board, name: &str| + Self::layer(board, &self.pcb.structure.layers, name, true); + for shape in &padstack.shapes { match shape { Shape::Circle(circle) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &circle.layer, - true, - ); + let layer = get_layer(&board, &circle.layer); Self::add_circle( &mut board, PointWithRotation::default(), @@ -360,8 +346,7 @@ impl SpecctraDesign { ) } Shape::Rect(rect) => { - let layer = - Self::layer(&mut board, &self.pcb.structure.layers, &rect.layer, true); + let layer = get_layer(&board, &rect.layer); Self::add_rect( &mut board, PointWithRotation::default(), @@ -376,8 +361,7 @@ impl SpecctraDesign { ) } Shape::Path(path) => { - let layer = - Self::layer(&mut board, &self.pcb.structure.layers, &path.layer, true); + let layer = get_layer(&board, &path.layer); Self::add_path( &mut board, PointWithRotation::default(), @@ -390,12 +374,7 @@ impl SpecctraDesign { ) } Shape::Polygon(polygon) => { - let layer = Self::layer( - &mut board, - &self.pcb.structure.layers, - &polygon.layer, - true, - ); + let layer = get_layer(&board, &polygon.layer); Self::add_polygon( &mut board, PointWithRotation::default(), From 60d9880ab297f1362723a58856736ac5e795d462 Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 27 Sep 2024 16:29:52 +0200 Subject: [PATCH 3/5] specctra/design: remove code duplication at padstack lookup --- src/specctra/design.rs | 13 ++++--------- src/specctra/structure.rs | 6 ++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/specctra/design.rs b/src/specctra/design.rs index d703e23..fe67692 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -242,12 +242,10 @@ impl SpecctraDesign { let pinname = format!("{}-{}", place.name, pin.id); let net = pin_nets.get(&pinname).unwrap(); - let padstack = &self + let padstack = self .pcb .library - .padstacks - .iter() - .find(|padstack| padstack.name == pin.name) + .find_padstack_by_name(&pin.name) .unwrap(); for shape in padstack.shapes.iter() { @@ -319,13 +317,10 @@ impl SpecctraDesign { .netname_net(&via.net) .unwrap(); - // find the padstack referenced by this via placement - let padstack = &self + let padstack = self .pcb .library - .padstacks - .iter() - .find(|padstack| padstack.name == via.name) + .find_padstack_by_name(&via.name) .unwrap(); let get_layer = |board: &Board, name: &str| diff --git a/src/specctra/structure.rs b/src/specctra/structure.rs index 897ab2b..5e932f0 100644 --- a/src/specctra/structure.rs +++ b/src/specctra/structure.rs @@ -169,6 +169,12 @@ pub struct Library { pub padstacks: Vec, } +impl Library { + pub fn find_padstack_by_name(&self, name: &str) -> Option<&Padstack> { + self.padstacks.iter().find(|padstack| &padstack.name == name) + } +} + #[derive(ReadDsn, WriteSes, Debug)] pub struct Image { #[anon] From 12f43a112ecea4605e96eef0dbec5ceea95479e6 Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 27 Sep 2024 17:23:25 +0200 Subject: [PATCH 4/5] specctra/design: get rid of unnecessary re-inserts of bimap entries This code should've been redundant since introduction of bimap usage for layer<->layername and net<->netname lookup. --- src/specctra/design.rs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/specctra/design.rs b/src/specctra/design.rs index fe67692..21ee076 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -411,26 +411,6 @@ impl SpecctraDesign { ); } - // The clones here are bad, we'll have something better later on. - - let layername_to_layer = &board.layout().drawing().rules().layer_layername.clone(); - - for (layer, layername) in layername_to_layer.iter() { - board - .layout_mut() - .rules_mut() - .bename_layer(*layer, layername.to_string()); - } - - let netname_to_net = &board.layout().drawing().rules().net_netname.clone(); - - for (net, netname) in netname_to_net.iter() { - board - .layout_mut() - .rules_mut() - .bename_net(*net, netname.to_string()); - } - board } From 55be63b942d5b778de45fda45ac1b6afde9a016e Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 28 Sep 2024 21:37:54 +0200 Subject: [PATCH 5/5] egui: remove long-superseded `channel_text()` routine --- src/bin/topola-egui/app.rs | 12 ------------ src/bin/topola-egui/top.rs | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index ea89b97..b6f1095 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -220,15 +220,3 @@ pub fn execute + Send + 'static>(f: F) { pub fn execute + 'static>(f: F) { wasm_bindgen_futures::spawn_local(f); } - -#[cfg(not(target_arch = "wasm32"))] -pub async fn channel_text(file_handle: rfd::FileHandle) -> String { - file_handle.path().to_str().unwrap().to_string() -} - -#[cfg(target_arch = "wasm32")] -pub async fn channel_text(file_handle: rfd::FileHandle) -> String { - std::str::from_utf8(&file_handle.read().await) - .unwrap() - .to_string() -} diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index ee2151f..634f501 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -15,7 +15,7 @@ use topola::{ use crate::{ action::{Action, Switch, Trigger}, - app::{channel_text, execute}, + app::execute, file_sender::FileSender, overlay::Overlay, translator::Translator,