From 5e6ddac19f8d2922593941a42326993f5d2acbe4 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 10 Mar 2026 18:08:56 +0100 Subject: [PATCH] Import and display segments in pads --- topola-egui/src/displayer.rs | 34 ++++++++++++++++++++-- topola/src/layout.rs | 10 ++++++- topola/src/specctra.rs | 56 ++++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/topola-egui/src/displayer.rs b/topola-egui/src/displayer.rs index 5ac4979..146991f 100644 --- a/topola-egui/src/displayer.rs +++ b/topola-egui/src/displayer.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use crate::{viewport::Viewport, workspace::Workspace}; -use topola::{Joint, Polygon}; +use topola::{Joint, Polygon, Segment, SegmentId}; pub struct Displayer {} @@ -49,7 +49,18 @@ impl Displayer { self.paint_joint(ctx, ui, viewport, joint); } - // TODO. + for (i, segment) in workspace.board.layout().segments().collection() { + self.paint_segment( + ctx, + ui, + viewport, + segment, + workspace + .board + .layout() + .segment_endpoints(SegmentId::new(i)), + ); + } for (_, polygon) in workspace.board.layout().polygons().collection() { self.paint_polygon(ctx, ui, viewport, polygon); @@ -64,12 +75,29 @@ impl Displayer { joint: &Joint, ) { ui.painter().circle_filled( - egui::Pos2::new(joint.position[0] as f32, joint.position[1] as f32), + egui::pos2(joint.position[0] as f32, joint.position[1] as f32), joint.radius as f32, egui::Color32::RED, ); } + fn paint_segment( + &mut self, + ctx: &egui::Context, + ui: &egui::Ui, + viewport: &Viewport, + segment: &Segment, + endpoints: [[i64; 2]; 2], + ) { + ui.painter().line_segment( + [ + egui::pos2(endpoints[0][0] as f32, endpoints[0][1] as f32), + egui::pos2(endpoints[1][0] as f32, endpoints[1][1] as f32), + ], + egui::Stroke::new(segment.half_width as f32 * 2.0, egui::Color32::RED), + ); + } + fn paint_polygon( &mut self, ctx: &egui::Context, diff --git a/topola/src/layout.rs b/topola/src/layout.rs index 39639e9..81717b4 100644 --- a/topola/src/layout.rs +++ b/topola/src/layout.rs @@ -51,7 +51,7 @@ impl SegmentId { #[derive(Clone, Copy, Debug)] pub struct Segment { - pub endpoints: [JointId; 2], + pub endjoints: [JointId; 2], pub layer: usize, pub half_width: u64, } @@ -171,6 +171,14 @@ impl Layout { pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId { PolygonId::new(self.polygons.push(polygon)) } + + pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] { + let endjoints = self.segments.get(&segment.id()).unwrap().endjoints; + [ + self.joints.get(&endjoints[0].id()).unwrap().position, + self.joints.get(&endjoints[1].id()).unwrap().position, + ] + } } #[derive(Clone, Debug, Dissolve)] diff --git a/topola/src/specctra.rs b/topola/src/specctra.rs index 7ce39e8..0cbce85 100644 --- a/topola/src/specctra.rs +++ b/topola/src/specctra.rs @@ -8,6 +8,7 @@ use specctra::{ }; use crate::{ + Segment, board::Board, layout::{Joint, Polygon}, math::Vector2, @@ -26,7 +27,7 @@ impl Board { .collect(), ); - // add pins from components + // Add pins from components. for component in &dsn.pcb.placement.components { let image = dsn .pcb @@ -66,7 +67,15 @@ impl Board { 0, false, ), - // ... TODO. + 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(), @@ -123,6 +132,49 @@ impl Board { }); } + pub fn place_path( + board: &mut Board, + place: PointWithRotation, + pin: PointWithRotation, + coords: &[Point], + width: f64, + layer: usize, + 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_joint = board.add_joint(Joint { + position: prev_pos, + layer, + radius: (width / 2.0) as u64, + }); + + // 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); + + if pos == prev_pos { + continue; + } + + let joint = board.add_joint(Joint { + position: pos, + radius: (width / 2.0) as u64, + layer, + }); + + // Add a seg between the current and previous coords. + let _ = board.add_segment(Segment { + endjoints: [prev_joint, joint], + layer, + half_width: (width / 2.0) as u64, + }); + + prev_pos = pos; + prev_joint = joint; + } + } + pub fn place_polygon( board: &mut Board, place: PointWithRotation,