mirror of https://codeberg.org/topola/topola.git
Add location methods for inside rect and intersecting rect
I did some renames while at it.
This commit is contained in:
parent
d9a4c7a11f
commit
1b4bb49a89
|
|
@ -54,7 +54,7 @@ impl Display {
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
board.layer_desc(joint.spec.layer),
|
board.layer_desc(joint.spec.layer),
|
||||||
board.pin_selection_contains_joint(&workspace.selection.pins, joint_id),
|
board.pins_contain_joint(&workspace.selection.pins, joint_id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +69,7 @@ impl Display {
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
board.layer_desc(segment.layer),
|
board.layer_desc(segment.layer),
|
||||||
board.pin_selection_contains_segment(&workspace.selection.pins, segment_id),
|
board.pins_contain_segment(&workspace.selection.pins, segment_id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +84,7 @@ impl Display {
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
board.layer_desc(layer),
|
board.layer_desc(layer),
|
||||||
board.pin_selection_contains_via(&workspace.selection.pins, via_id),
|
board.pins_contain_via(&workspace.selection.pins, via_id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +99,7 @@ impl Display {
|
||||||
workspace.appearance_panel.layer_color(
|
workspace.appearance_panel.layer_color(
|
||||||
ctx,
|
ctx,
|
||||||
board.layer_desc(polygon.layer),
|
board.layer_desc(polygon.layer),
|
||||||
board.pin_selection_contains_polygon(&workspace.selection.pins, polygon_id),
|
board.pins_contain_polygon(&workspace.selection.pins, polygon_id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use egui::{Context, Grid, ScrollArea, SidePanel, widget_text::WidgetText};
|
use egui::{Context, Grid, ScrollArea, SidePanel, widget_text::WidgetText};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use topola::{Board, LayerDesc, LayerId, LayerTier, LayerType};
|
use topola::{Board, LayerDesc, LayerId, LayerSide, LayerType};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
|
|
@ -59,8 +59,8 @@ impl LayersPanel {
|
||||||
};
|
};
|
||||||
|
|
||||||
let color = match layer_desc.typ {
|
let color = match layer_desc.typ {
|
||||||
LayerType::Copper => match layer_desc.tier {
|
LayerType::Copper => match layer_desc.side {
|
||||||
LayerTier::Top => Some((
|
LayerSide::Top => Some((
|
||||||
LayerColors {
|
LayerColors {
|
||||||
normal: egui::Color32::from_rgb(255, 52, 52),
|
normal: egui::Color32::from_rgb(255, 52, 52),
|
||||||
highlighted: egui::Color32::from_rgb(255, 100, 100),
|
highlighted: egui::Color32::from_rgb(255, 100, 100),
|
||||||
|
|
@ -70,7 +70,7 @@ impl LayersPanel {
|
||||||
highlighted: egui::Color32::from_rgb(255, 52, 52),
|
highlighted: egui::Color32::from_rgb(255, 52, 52),
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
LayerTier::Bottom => Some((
|
LayerSide::Bottom => Some((
|
||||||
LayerColors {
|
LayerColors {
|
||||||
normal: egui::Color32::from_rgb(52, 52, 255),
|
normal: egui::Color32::from_rgb(52, 52, 255),
|
||||||
highlighted: egui::Color32::from_rgb(100, 100, 255),
|
highlighted: egui::Color32::from_rgb(100, 100, 255),
|
||||||
|
|
@ -80,7 +80,7 @@ impl LayersPanel {
|
||||||
highlighted: egui::Color32::from_rgb(52, 52, 255),
|
highlighted: egui::Color32::from_rgb(52, 52, 255),
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
LayerTier::Inner => (layer_desc.index % 2 == 0)
|
LayerSide::Inner => (layer_desc.index % 2 == 0)
|
||||||
.then_some((
|
.then_some((
|
||||||
LayerColors {
|
LayerColors {
|
||||||
normal: egui::Color32::from_rgb(127, 200, 127),
|
normal: egui::Color32::from_rgb(127, 200, 127),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub enum LayerType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub enum LayerTier {
|
pub enum LayerSide {
|
||||||
Top,
|
Top,
|
||||||
Inner,
|
Inner,
|
||||||
Bottom,
|
Bottom,
|
||||||
|
|
@ -23,22 +23,22 @@ pub enum LayerTier {
|
||||||
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub struct LayerDesc {
|
pub struct LayerDesc {
|
||||||
pub typ: LayerType,
|
pub typ: LayerType,
|
||||||
pub tier: LayerTier,
|
pub side: LayerSide,
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for LayerDesc {
|
impl Display for LayerDesc {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self.typ {
|
match self.typ {
|
||||||
LayerType::Copper => match self.tier {
|
LayerType::Copper => match self.side {
|
||||||
LayerTier::Top => write!(f, "F.Cu"),
|
LayerSide::Top => write!(f, "F.Cu"),
|
||||||
LayerTier::Bottom => write!(f, "B.Cu"),
|
LayerSide::Bottom => write!(f, "B.Cu"),
|
||||||
LayerTier::Inner => write!(f, "In{}.Cu", self.index.saturating_sub(1)),
|
LayerSide::Inner => write!(f, "In{}.Cu", self.index.saturating_sub(1)),
|
||||||
},
|
},
|
||||||
LayerType::Outline => match self.tier {
|
LayerType::Outline => match self.side {
|
||||||
LayerTier::Top => write!(f, "outlines.top"),
|
LayerSide::Top => write!(f, "F.Outl"),
|
||||||
LayerTier::Bottom => write!(f, "outlines.bottom"),
|
LayerSide::Bottom => write!(f, "B.Outl"),
|
||||||
LayerTier::Inner => write!(f, "outlines.{}", self.index),
|
LayerSide::Inner => write!(f, "In{}.Outl", self.index),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Vector2,
|
Rect2, Vector2,
|
||||||
board::Board,
|
board::Board,
|
||||||
layout::LayerId,
|
layout::LayerId,
|
||||||
selections::{ComponentSelector, PinSelector},
|
selections::{ComponentSelector, PinSelector},
|
||||||
|
|
@ -34,6 +34,56 @@ impl Board {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_component_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = ComponentSelector> + '_ {
|
||||||
|
self.layout
|
||||||
|
.locate_joints_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|joint_id| self.joint_component_selector(joint_id))
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_segments_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|segment_id| self.segment_component_selector(segment_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_vias_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|via_id| self.via_component_selector(via_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_polygons_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|polygon_id| self.polygon_component_selector(polygon_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_component_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = ComponentSelector> + '_ {
|
||||||
|
self.layout
|
||||||
|
.locate_joints_inside_rect(layer, rect)
|
||||||
|
.filter_map(|joint_id| self.joint_component_selector(joint_id))
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_segments_inside_rect(layer, rect)
|
||||||
|
.filter_map(|segment_id| self.segment_component_selector(segment_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_vias_inside_rect(layer, rect)
|
||||||
|
.filter_map(|via_id| self.via_component_selector(via_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_polygons_inside_rect(layer, rect)
|
||||||
|
.filter_map(|polygon_id| self.polygon_component_selector(polygon_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn locate_pin_at_point(&self, layer: LayerId, point: Vector2<i64>) -> Option<PinSelector> {
|
pub fn locate_pin_at_point(&self, layer: LayerId, point: Vector2<i64>) -> Option<PinSelector> {
|
||||||
if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() {
|
if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() {
|
||||||
return self.joint_pin_selector(joint_id);
|
return self.joint_pin_selector(joint_id);
|
||||||
|
|
@ -53,4 +103,54 @@ impl Board {
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_pin_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = PinSelector> + '_ {
|
||||||
|
self.layout
|
||||||
|
.locate_joints_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|joint_id| self.joint_pin_selector(joint_id))
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_segments_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|segment_id| self.segment_pin_selector(segment_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_vias_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|via_id| self.via_pin_selector(via_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_polygons_intersecting_rect(layer, rect)
|
||||||
|
.filter_map(|polygon_id| self.polygon_pin_selector(polygon_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_pin_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = PinSelector> + '_ {
|
||||||
|
self.layout
|
||||||
|
.locate_joints_inside_rect(layer, rect)
|
||||||
|
.filter_map(|joint_id| self.joint_pin_selector(joint_id))
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_segments_inside_rect(layer, rect)
|
||||||
|
.filter_map(|segment_id| self.segment_pin_selector(segment_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_vias_inside_rect(layer, rect)
|
||||||
|
.filter_map(|via_id| self.via_pin_selector(via_id)),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.layout
|
||||||
|
.locate_polygons_inside_rect(layer, rect)
|
||||||
|
.filter_map(|polygon_id| self.polygon_pin_selector(polygon_id)),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ mod select;
|
||||||
pub mod selections;
|
pub mod selections;
|
||||||
mod transforms;
|
mod transforms;
|
||||||
|
|
||||||
pub use crate::board::layer::{LayerDesc, LayerTier, LayerType};
|
pub use crate::board::layer::{LayerDesc, LayerSide, LayerType};
|
||||||
|
|
||||||
use bidimap::BiBTreeMap;
|
use bidimap::BiBTreeMap;
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,11 @@ use crate::{
|
||||||
Board,
|
Board,
|
||||||
selections::{ComponentSelection, ComponentSelector, PinSelection, PinSelector},
|
selections::{ComponentSelection, ComponentSelector, PinSelection, PinSelector},
|
||||||
},
|
},
|
||||||
layout::LayerId,
|
|
||||||
math::Vector2,
|
|
||||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Board {
|
impl Board {
|
||||||
pub fn pin_selection_to_component_selection(
|
pub fn pins_to_components(&mut self, pin_selection: PinSelection) -> ComponentSelection {
|
||||||
&mut self,
|
|
||||||
pin_selection: PinSelection,
|
|
||||||
) -> ComponentSelection {
|
|
||||||
let mut component_selection = ComponentSelection::new();
|
let mut component_selection = ComponentSelection::new();
|
||||||
|
|
||||||
for selector in pin_selection.0 {
|
for selector in pin_selection.0 {
|
||||||
|
|
@ -80,11 +75,7 @@ impl Board {
|
||||||
component_selection
|
component_selection
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn component_selection_contains_joint(
|
pub fn components_contain_joint(&self, selection: &ComponentSelection, id: JointId) -> bool {
|
||||||
&self,
|
|
||||||
selection: &ComponentSelection,
|
|
||||||
id: JointId,
|
|
||||||
) -> bool {
|
|
||||||
let Some(selector) = self.joint_component_selector(id) else {
|
let Some(selector) = self.joint_component_selector(id) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -92,7 +83,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn component_selection_contains_segment(
|
pub fn components_contain_segment(
|
||||||
&self,
|
&self,
|
||||||
selection: &ComponentSelection,
|
selection: &ComponentSelection,
|
||||||
id: SegmentId,
|
id: SegmentId,
|
||||||
|
|
@ -104,11 +95,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn component_selection_contains_via(
|
pub fn components_contain_via(&self, selection: &ComponentSelection, id: ViaId) -> bool {
|
||||||
&self,
|
|
||||||
selection: &ComponentSelection,
|
|
||||||
id: ViaId,
|
|
||||||
) -> bool {
|
|
||||||
let Some(selector) = self.via_component_selector(id) else {
|
let Some(selector) = self.via_component_selector(id) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -116,7 +103,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn component_selection_contains_polygon(
|
pub fn components_contain_polygon(
|
||||||
&self,
|
&self,
|
||||||
selection: &ComponentSelection,
|
selection: &ComponentSelection,
|
||||||
id: PolygonId,
|
id: PolygonId,
|
||||||
|
|
@ -160,7 +147,7 @@ impl Board {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pin_selection_contains_joint(&self, selection: &PinSelection, id: JointId) -> bool {
|
pub fn pins_contain_joint(&self, selection: &PinSelection, id: JointId) -> bool {
|
||||||
let Some(selector) = self.joint_pin_selector(id) else {
|
let Some(selector) = self.joint_pin_selector(id) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -168,7 +155,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pin_selection_contains_segment(&self, selection: &PinSelection, id: SegmentId) -> bool {
|
pub fn pins_contain_segment(&self, selection: &PinSelection, id: SegmentId) -> bool {
|
||||||
let Some(selector) = self.segment_pin_selector(id) else {
|
let Some(selector) = self.segment_pin_selector(id) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -176,7 +163,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pin_selection_contains_via(&self, selection: &PinSelection, id: ViaId) -> bool {
|
pub fn pins_contain_via(&self, selection: &PinSelection, id: ViaId) -> bool {
|
||||||
let Some(selector) = self.via_pin_selector(id) else {
|
let Some(selector) = self.via_pin_selector(id) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -184,7 +171,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pin_selection_contains_polygon(&self, selection: &PinSelection, id: PolygonId) -> bool {
|
pub fn pins_contain_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 {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -192,26 +179,6 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn point_pin_selector(&self, layer: LayerId, point: Vector2<i64>) -> Option<PinSelector> {
|
|
||||||
if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() {
|
|
||||||
return self.joint_pin_selector(joint_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() {
|
|
||||||
return self.segment_pin_selector(segment_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn joint_pin_selector(&self, id: JointId) -> Option<PinSelector> {
|
pub fn joint_pin_selector(&self, id: JointId) -> Option<PinSelector> {
|
||||||
let joint = self.layout.joint(id);
|
let joint = self.layout.joint(id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Vector2,
|
Rect2, Vector2,
|
||||||
layout::{LayerId, Layout},
|
layout::{LayerId, Layout},
|
||||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||||
};
|
};
|
||||||
|
|
@ -21,6 +21,31 @@ impl Layout {
|
||||||
.filter(move |&joint_id| self.joints[joint_id.index()].contains_point(point))
|
.filter(move |&joint_id| self.joints[joint_id.index()].contains_point(point))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_joints_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = JointId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.joints_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope_intersecting(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
.filter(move |&joint_id| self.joint(joint_id).spec.layer == layer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_joints_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = JointId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.joints_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn locate_segments_at_point(
|
pub fn locate_segments_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: LayerId,
|
layer: LayerId,
|
||||||
|
|
@ -33,6 +58,31 @@ impl Layout {
|
||||||
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
|
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_segments_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = SegmentId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.segments_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope_intersecting(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
.filter(move |&segment_id| self.segment(segment_id).layer == layer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_segments_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = SegmentId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.segments_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn locate_vias_at_point(
|
pub fn locate_vias_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: LayerId,
|
layer: LayerId,
|
||||||
|
|
@ -45,6 +95,34 @@ impl Layout {
|
||||||
.filter(move |&via_id| self.vias[via_id.index()].contains_point(layer, point))
|
.filter(move |&via_id| self.vias[via_id.index()].contains_point(layer, point))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_vias_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = ViaId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.vias_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope_intersecting(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
.filter(move |&via_id| {
|
||||||
|
let via = self.via(via_id);
|
||||||
|
via.min_layer <= layer && layer <= via.max_layer
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_vias_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = ViaId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.vias_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn locate_polygons_at_point(
|
pub fn locate_polygons_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: LayerId,
|
layer: LayerId,
|
||||||
|
|
@ -56,4 +134,29 @@ impl Layout {
|
||||||
.map(|geom_with_data| geom_with_data.data)
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
.filter(move |&polygon_id| self.polygons[polygon_id.index()].contains_point(point))
|
.filter(move |&polygon_id| self.polygons[polygon_id.index()].contains_point(point))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_polygons_intersecting_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = PolygonId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.polygons_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope_intersecting(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
.filter(move |&polygon_id| self.polygon(polygon_id).layer == layer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn locate_polygons_inside_rect(
|
||||||
|
&self,
|
||||||
|
layer: LayerId,
|
||||||
|
rect: Rect2<i64>,
|
||||||
|
) -> impl Iterator<Item = PolygonId> {
|
||||||
|
let rect_aabb = rect.aabb3(layer.index() as i64);
|
||||||
|
self.polygons_rtree
|
||||||
|
.as_ref()
|
||||||
|
.locate_in_envelope(&rect_aabb)
|
||||||
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@ mod specctra;
|
||||||
pub use crate::autorouter::Autorouter;
|
pub use crate::autorouter::Autorouter;
|
||||||
pub use crate::board::Board;
|
pub use crate::board::Board;
|
||||||
pub use crate::board::LayerDesc;
|
pub use crate::board::LayerDesc;
|
||||||
pub use crate::board::LayerTier;
|
pub use crate::board::LayerSide;
|
||||||
pub use crate::board::LayerType;
|
pub use crate::board::LayerType;
|
||||||
pub use crate::board::selections;
|
pub use crate::board::selections;
|
||||||
pub use crate::layout::LayerId;
|
pub use crate::layout::LayerId;
|
||||||
pub use crate::layout::Layout;
|
pub use crate::layout::Layout;
|
||||||
pub use crate::layout::compounds::{Pin, PinId};
|
pub use crate::layout::compounds::{Pin, PinId};
|
||||||
pub use crate::layout::primitives;
|
pub use crate::layout::primitives;
|
||||||
pub use crate::math::Vector2;
|
pub use crate::math::{Rect2, Vector2};
|
||||||
pub use crate::ratsnest::{Ratline, Ratsnest};
|
pub use crate::ratsnest::{Ratline, Ratsnest};
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,35 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
use derive_getters::Getters;
|
||||||
use derive_more::{
|
use derive_more::{
|
||||||
Add, AddAssign, Constructor, Div, DivAssign, From, Into, Mul, MulAssign, Sub, SubAssign,
|
Add, AddAssign, Constructor, Div, DivAssign, From, Into, Mul, MulAssign, Sub, SubAssign,
|
||||||
};
|
};
|
||||||
use polygon_unionfind::UnionFind;
|
use polygon_unionfind::UnionFind;
|
||||||
|
use rstar::AABB;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Getters, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub struct Rect2<T> {
|
||||||
|
min: Vector2<T>,
|
||||||
|
max: Vector2<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Ord + Copy> Rect2<T> {
|
||||||
|
pub fn new(from: Vector2<T>, to: Vector2<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
min: Vector2::new(std::cmp::min(from.x, to.x), std::cmp::min(from.y, to.y)),
|
||||||
|
max: Vector2::new(std::cmp::max(from.x, to.x), std::cmp::max(from.y, to.y)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rect2<i64> {
|
||||||
|
pub fn aabb3(self, z: i64) -> AABB<[i64; 3]> {
|
||||||
|
AABB::from_corners([self.min.x, self.min.y, z], [self.max.x, self.max.y, z])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Add,
|
Add,
|
||||||
AddAssign,
|
AddAssign,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use specctra::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
board::{Board, LayerDesc, LayerTier, LayerType},
|
board::{Board, LayerDesc, LayerSide, LayerType},
|
||||||
layout::LayerId,
|
layout::LayerId,
|
||||||
layout::compounds::{ComponentId, NetId, PinId},
|
layout::compounds::{ComponentId, NetId, PinId},
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
|
|
@ -31,11 +31,11 @@ impl Board {
|
||||||
BiBTreeMap::from_iter(dsn.pcb.structure.layers.iter().enumerate().map(
|
BiBTreeMap::from_iter(dsn.pcb.structure.layers.iter().enumerate().map(
|
||||||
|(index, _layer)| {
|
|(index, _layer)| {
|
||||||
let tier = if index == 0 {
|
let tier = if index == 0 {
|
||||||
LayerTier::Top
|
LayerSide::Top
|
||||||
} else if index + 1 == dsn.pcb.structure.layers.len() {
|
} else if index + 1 == dsn.pcb.structure.layers.len() {
|
||||||
LayerTier::Bottom
|
LayerSide::Bottom
|
||||||
} else {
|
} else {
|
||||||
LayerTier::Inner
|
LayerSide::Inner
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
LayerId::new(index + pcb_layer_offset),
|
LayerId::new(index + pcb_layer_offset),
|
||||||
|
|
@ -48,7 +48,7 @@ impl Board {
|
||||||
top_outline_layer_id,
|
top_outline_layer_id,
|
||||||
LayerDesc::new(
|
LayerDesc::new(
|
||||||
LayerType::Outline,
|
LayerType::Outline,
|
||||||
LayerTier::Top,
|
LayerSide::Top,
|
||||||
top_outline_layer_id.index(),
|
top_outline_layer_id.index(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -56,7 +56,7 @@ impl Board {
|
||||||
bottom_outline_layer_id,
|
bottom_outline_layer_id,
|
||||||
LayerDesc::new(
|
LayerDesc::new(
|
||||||
LayerType::Outline,
|
LayerType::Outline,
|
||||||
LayerTier::Bottom,
|
LayerSide::Bottom,
|
||||||
bottom_outline_layer_id.index(),
|
bottom_outline_layer_id.index(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue