mirror of https://codeberg.org/topola/topola.git
Add missing code for vias
This commit is contained in:
parent
eef69694fd
commit
d9a4c7a11f
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use crate::{viewport::Viewport, workspace::Workspace};
|
use crate::{viewport::Viewport, workspace::Workspace};
|
||||||
use topola::LayerId;
|
use topola::LayerId;
|
||||||
use topola::primitives::{Joint, Polygon, Segment};
|
use topola::primitives::{Joint, Polygon, Segment, Via};
|
||||||
|
|
||||||
pub struct Display {}
|
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) {
|
for polygon_id in layout.layer_polygons(layer) {
|
||||||
let polygon = layout.polygon(polygon_id);
|
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(
|
fn paint_polygon(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &egui::Context,
|
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) {
|
for polygon_id in layout.layer_polygons(layer) {
|
||||||
let polygon = layout.polygon(polygon_id);
|
let polygon = layout.polygon(polygon_id);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ impl Board {
|
||||||
return self.segment_component_selector(segment_id);
|
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() {
|
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
|
||||||
return self.polygon_component_selector(polygon_id);
|
return self.polygon_component_selector(polygon_id);
|
||||||
|
|
@ -41,7 +43,9 @@ impl Board {
|
||||||
return self.segment_pin_selector(segment_id);
|
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() {
|
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
|
||||||
return self.polygon_pin_selector(polygon_id);
|
return self.polygon_pin_selector(polygon_id);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
layout::LayerId,
|
layout::LayerId,
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
primitives::{JointId, PolygonId, SegmentId},
|
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Board {
|
impl Board {
|
||||||
|
|
@ -40,7 +40,17 @@ impl Board {
|
||||||
component_selection.0.insert(component_selector);
|
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) {
|
for segment_id in self.layout.layer_segments(layer_id) {
|
||||||
if self.layout.segment(segment_id).spec.pin != Some(pin_id) {
|
if self.layout.segment(segment_id).spec.pin != Some(pin_id) {
|
||||||
|
|
@ -94,7 +104,17 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
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(
|
pub fn component_selection_contains_polygon(
|
||||||
&self,
|
&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> {
|
pub fn polygon_component_selector(&self, id: PolygonId) -> Option<ComponentSelector> {
|
||||||
let polygon = self.layout.polygon(id);
|
let polygon = self.layout.polygon(id);
|
||||||
|
|
@ -150,7 +176,13 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
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 {
|
pub fn pin_selection_contains_polygon(&self, selection: &PinSelection, id: PolygonId) -> bool {
|
||||||
let Some(selector) = self.polygon_pin_selector(id) else {
|
let Some(selector) = self.polygon_pin_selector(id) else {
|
||||||
|
|
@ -169,7 +201,9 @@ impl Board {
|
||||||
return self.segment_pin_selector(segment_id);
|
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() {
|
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
|
||||||
return self.polygon_pin_selector(polygon_id);
|
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> {
|
pub fn polygon_pin_selector(&self, id: PolygonId) -> Option<PinSelector> {
|
||||||
let polygon = self.layout.polygon(id);
|
let polygon = self.layout.polygon(id);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Vector2,
|
Vector2,
|
||||||
layout::{LayerId, Layout},
|
layout::{LayerId, Layout},
|
||||||
primitives::{JointId, PolygonId, SegmentId},
|
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
|
|
@ -33,7 +33,17 @@ impl Layout {
|
||||||
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
|
.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(
|
pub fn locate_polygons_at_point(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,18 @@ impl Layout {
|
||||||
.filter(move |&id| self.segment(id).layer == layer)
|
.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> + '_ {
|
pub fn layer_polygons(&self, layer: LayerId) -> impl Iterator<Item = PolygonId> + '_ {
|
||||||
let envelope = Self::whole_layer_aabb(layer);
|
let envelope = Self::whole_layer_aabb(layer);
|
||||||
self.polygons_rtree
|
self.polygons_rtree
|
||||||
|
|
@ -412,6 +424,10 @@ impl Layout {
|
||||||
&self.segments[segment_id.index()]
|
&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 {
|
pub fn polygon(&self, polygon_id: PolygonId) -> &Polygon {
|
||||||
&self.polygons[polygon_id.index()]
|
&self.polygons[polygon_id.index()]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,15 @@ pub struct Via {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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]> {
|
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
||||||
let radius = self.spec.radius as i64;
|
let radius = self.spec.radius as i64;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue