Add missing code for vias

This commit is contained in:
Mikolaj Wielgus 2026-05-25 23:32:39 +02:00
parent eef69694fd
commit d9a4c7a11f
6 changed files with 135 additions and 14 deletions

View File

@ -4,7 +4,7 @@
use crate::{viewport::Viewport, workspace::Workspace};
use topola::LayerId;
use topola::primitives::{Joint, Polygon, Segment};
use topola::primitives::{Joint, Polygon, Segment, Via};
pub struct Display {}
@ -74,7 +74,20 @@ impl Display {
);
}
// TODO: Vias.
for via_id in layout.layer_vias(layer) {
let via = layout.via(via_id);
self.paint_via(
ctx,
ui,
viewport,
via,
workspace.appearance_panel.layer_color(
ctx,
board.layer_desc(layer),
board.pin_selection_contains_via(&workspace.selection.pins, via_id),
),
);
}
for polygon_id in layout.layer_polygons(layer) {
let polygon = layout.polygon(polygon_id);
@ -137,6 +150,21 @@ impl Display {
);
}
fn paint_via(
&mut self,
ctx: &egui::Context,
ui: &egui::Ui,
viewport: &Viewport,
via: &Via,
color: egui::Color32,
) {
ui.painter().circle_filled(
egui::pos2(via.position.x as f32, via.position.y as f32),
via.spec.radius as f32,
color,
);
}
fn paint_polygon(
&mut self,
ctx: &egui::Context,
@ -206,7 +234,20 @@ impl Display {
);
}
// TODO: vias.
for via_id in layout.layer_vias(layer) {
let via = layout.via(via_id);
let bbox = via.bbox();
ui.painter().rect_stroke(
egui::Rect {
min: egui::pos2(bbox.lower()[0] as f32, bbox.lower()[1] as f32),
max: egui::pos2(bbox.upper()[0] as f32, bbox.upper()[1] as f32),
},
egui::CornerRadius::ZERO,
egui::Stroke::new(5.0, egui::Color32::GRAY),
egui::StrokeKind::Middle,
);
}
for polygon_id in layout.layer_polygons(layer) {
let polygon = layout.polygon(polygon_id);

View File

@ -23,7 +23,9 @@ impl Board {
return self.segment_component_selector(segment_id);
}
// TODO: Vias.
if let Some(via_id) = self.layout.locate_vias_at_point(layer, point).next() {
return self.via_component_selector(via_id);
}
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
return self.polygon_component_selector(polygon_id);
@ -41,7 +43,9 @@ impl Board {
return self.segment_pin_selector(segment_id);
}
// TODO: Vias.
if let Some(via_id) = self.layout.locate_vias_at_point(layer, point).next() {
return self.via_pin_selector(via_id);
}
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
return self.polygon_pin_selector(polygon_id);

View File

@ -9,7 +9,7 @@ use crate::{
},
layout::LayerId,
math::Vector2,
primitives::{JointId, PolygonId, SegmentId},
primitives::{JointId, PolygonId, SegmentId, ViaId},
};
impl Board {
@ -40,7 +40,17 @@ impl Board {
component_selection.0.insert(component_selector);
}
// TODO: Vias.
for via_id in self.layout.layer_vias(layer_id) {
if self.layout.via(via_id).spec.pin != Some(pin_id) {
continue;
}
let Some(component_selector) = self.via_component_selector(via_id) else {
continue;
};
component_selection.0.insert(component_selector);
}
for segment_id in self.layout.layer_segments(layer_id) {
if self.layout.segment(segment_id).spec.pin != Some(pin_id) {
@ -94,7 +104,17 @@ impl Board {
selection.0.contains(&selector)
}
// TODO: Vias.
pub fn component_selection_contains_via(
&self,
selection: &ComponentSelection,
id: ViaId,
) -> bool {
let Some(selector) = self.via_component_selector(id) else {
return false;
};
selection.0.contains(&selector)
}
pub fn component_selection_contains_polygon(
&self,
@ -124,7 +144,13 @@ impl Board {
})
}
// TODO: Vias.
pub fn via_component_selector(&self, id: ViaId) -> Option<ComponentSelector> {
let via = self.layout.via(id);
Some(ComponentSelector {
component: self.component_name(via.spec.component?)?.to_string(),
})
}
pub fn polygon_component_selector(&self, id: PolygonId) -> Option<ComponentSelector> {
let polygon = self.layout.polygon(id);
@ -150,7 +176,13 @@ impl Board {
selection.0.contains(&selector)
}
// TODO: Vias.
pub fn pin_selection_contains_via(&self, selection: &PinSelection, id: ViaId) -> bool {
let Some(selector) = self.via_pin_selector(id) else {
return false;
};
selection.0.contains(&selector)
}
pub fn pin_selection_contains_polygon(&self, selection: &PinSelection, id: PolygonId) -> bool {
let Some(selector) = self.polygon_pin_selector(id) else {
@ -169,7 +201,9 @@ impl Board {
return self.segment_pin_selector(segment_id);
}
// TODO: Vias.
if let Some(via_id) = self.layout.locate_vias_at_point(layer, point).next() {
return self.via_pin_selector(via_id);
}
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
return self.polygon_pin_selector(polygon_id);
@ -196,7 +230,14 @@ impl Board {
})
}
// TODO: Vias.
pub fn via_pin_selector(&self, id: ViaId) -> Option<PinSelector> {
let via = self.layout.via(id);
Some(PinSelector {
pin: self.pin_name(via.spec.pin?)?.to_string(),
layer: self.layer_name(via.min_layer)?,
})
}
pub fn polygon_pin_selector(&self, id: PolygonId) -> Option<PinSelector> {
let polygon = self.layout.polygon(id);

View File

@ -5,7 +5,7 @@
use crate::{
Vector2,
layout::{LayerId, Layout},
primitives::{JointId, PolygonId, SegmentId},
primitives::{JointId, PolygonId, SegmentId, ViaId},
};
impl Layout {
@ -33,7 +33,17 @@ impl Layout {
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
}
// TODO: vias.
pub fn locate_vias_at_point(
&self,
layer: LayerId,
point: Vector2<i64>,
) -> impl Iterator<Item = ViaId> {
self.vias_rtree
.as_ref()
.locate_all_at_point(&[point.x, point.y, layer.index() as i64])
.map(|geom_with_data| geom_with_data.data)
.filter(move |&via_id| self.vias[via_id.index()].contains_point(layer, point))
}
pub fn locate_polygons_at_point(
&self,

View File

@ -388,6 +388,18 @@ impl Layout {
.filter(move |&id| self.segment(id).layer == layer)
}
pub fn layer_vias(&self, layer: LayerId) -> impl Iterator<Item = ViaId> + '_ {
let envelope = Self::whole_layer_aabb(layer);
self.vias_rtree
.as_ref()
.locate_in_envelope_intersecting(&envelope)
.map(|geom_with_data| geom_with_data.data)
.filter(move |&id| {
let via = self.via(id);
via.min_layer <= layer && layer <= via.max_layer
})
}
pub fn layer_polygons(&self, layer: LayerId) -> impl Iterator<Item = PolygonId> + '_ {
let envelope = Self::whole_layer_aabb(layer);
self.polygons_rtree
@ -412,6 +424,10 @@ impl Layout {
&self.segments[segment_id.index()]
}
pub fn via(&self, via_id: ViaId) -> &Via {
&self.vias[via_id.index()]
}
pub fn polygon(&self, polygon_id: PolygonId) -> &Polygon {
&self.polygons[polygon_id.index()]
}

View File

@ -54,6 +54,15 @@ pub struct Via {
}
impl Via {
pub fn contains_point(&self, layer: LayerId, point: Vector2<i64>) -> bool {
if layer < self.min_layer || layer > self.max_layer {
return false;
}
(point.x - self.position.x).pow(2) as u64 + (point.y - self.position.y).pow(2) as u64
<= self.spec.radius.pow(2)
}
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
let radius = self.spec.radius as i64;