mirror of https://codeberg.org/topola/topola.git
Encapsulate layer indices in new `LayerId` type
This commit is contained in:
parent
1b9673e3e7
commit
a947a72a02
|
|
@ -3,6 +3,7 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use crate::{viewport::Viewport, workspace::Workspace};
|
use crate::{viewport::Viewport, workspace::Workspace};
|
||||||
|
use topola::LayerId;
|
||||||
use topola::primitives::{Joint, Polygon, Segment};
|
use topola::primitives::{Joint, Polygon, Segment};
|
||||||
|
|
||||||
pub struct Display {}
|
pub struct Display {}
|
||||||
|
|
@ -38,8 +39,8 @@ impl Display {
|
||||||
let layout = board.layout();
|
let layout = board.layout();
|
||||||
|
|
||||||
// Start from the bottom layer so that top layers are drawn on top.
|
// Start from the bottom layer so that top layers are drawn on top.
|
||||||
for layer in (0..*layout.layer_count()).rev() {
|
for layer in (0..*layout.layer_count()).rev().map(LayerId::new) {
|
||||||
if !workspace.appearance_panel.visible[layer] {
|
if !workspace.appearance_panel.visible[layer.index()] {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,8 +168,8 @@ impl Display {
|
||||||
let board = workspace.autorouter.router().navmesher_board().board();
|
let board = workspace.autorouter.router().navmesher_board().board();
|
||||||
let layout = board.layout();
|
let layout = board.layout();
|
||||||
|
|
||||||
for layer in (0..*layout.layer_count()).rev() {
|
for layer in (0..*layout.layer_count()).rev().map(LayerId::new) {
|
||||||
if !workspace.appearance_panel.visible[layer] {
|
if !workspace.appearance_panel.visible[layer.index()] {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,22 +232,23 @@ impl Display {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
) {
|
) {
|
||||||
for layer in 0..*workspace
|
for layer in (0..*workspace
|
||||||
.autorouter
|
.autorouter
|
||||||
.router()
|
.router()
|
||||||
.navmesher_board()
|
.navmesher_board()
|
||||||
.board()
|
.board()
|
||||||
.layout()
|
.layout()
|
||||||
.layer_count()
|
.layer_count())
|
||||||
|
.map(LayerId::new)
|
||||||
{
|
{
|
||||||
if workspace.appearance_panel.visible[layer] {
|
if workspace.appearance_panel.visible[layer.index()] {
|
||||||
for navmesh in workspace
|
for navmesh in workspace
|
||||||
.autorouter
|
.autorouter
|
||||||
.router()
|
.router()
|
||||||
.navmesher_board()
|
.navmesher_board()
|
||||||
.navmesher()
|
.navmesher()
|
||||||
.layer_navmeshers()[layer]
|
.layer_navmeshers()[layer.index()]
|
||||||
.navmeshes()
|
.navmeshes()
|
||||||
{
|
{
|
||||||
for edge_geom in navmesh
|
for edge_geom in navmesh
|
||||||
.triangulation()
|
.triangulation()
|
||||||
|
|
@ -305,8 +307,8 @@ impl Display {
|
||||||
let layers = *ratline.endpoint_layers();
|
let layers = *ratline.endpoint_layers();
|
||||||
let endpoints = *ratline.endpoints();
|
let endpoints = *ratline.endpoints();
|
||||||
|
|
||||||
if !workspace.appearance_panel.visible[layers[0]]
|
if !workspace.appearance_panel.visible[layers[0].index()]
|
||||||
|| !workspace.appearance_panel.visible[layers[1]]
|
|| !workspace.appearance_panel.visible[layers[1].index()]
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
use topola::{Board, LayerId};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
|
|
@ -42,7 +42,7 @@ pub struct LayersPanel {
|
||||||
light_colors: Colors,
|
light_colors: Colors,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub active: usize,
|
pub active: LayerId,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub visible: Box<[bool]>,
|
pub visible: Box<[bool]>,
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +161,7 @@ impl LayersPanel {
|
||||||
Self {
|
Self {
|
||||||
dark_colors,
|
dark_colors,
|
||||||
light_colors,
|
light_colors,
|
||||||
active: 0,
|
active: LayerId::new(0),
|
||||||
visible,
|
visible,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,17 +181,16 @@ impl LayersPanel {
|
||||||
.num_columns(3)
|
.num_columns(3)
|
||||||
.start_row(start_row)
|
.start_row(start_row)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
for layer in row_range {
|
for layer_index in row_range {
|
||||||
let visible = &mut self.visible[layer];
|
let layer = LayerId::new(layer_index);
|
||||||
|
let visible = &mut self.visible[layer.index()];
|
||||||
let layer_name = board.layer_name(layer);
|
let layer_name = board.layer_name(layer);
|
||||||
|
|
||||||
ui.radio_value(&mut self.active, layer, WidgetText::default());
|
ui.radio_value(&mut self.active, layer, WidgetText::default());
|
||||||
ui.checkbox(visible, WidgetText::default());
|
ui.checkbox(visible, WidgetText::default());
|
||||||
ui.label(
|
ui.label(layer_name.map(|i| i.to_string()).unwrap_or_else(|| {
|
||||||
layer_name
|
format!("{} - Unnamed layer", layer.index())
|
||||||
.map(|i| i.to_string())
|
}));
|
||||||
.unwrap_or_else(|| format!("{} - Unnamed layer", layer)),
|
|
||||||
);
|
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use undoredo::{Delta, Recorder};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
compounds::{ComponentId, NetId, PinId},
|
compounds::{ComponentId, NetId, PinId},
|
||||||
|
layout::LayerId,
|
||||||
layout::{
|
layout::{
|
||||||
Layout, LayoutHalfDelta,
|
Layout, LayoutHalfDelta,
|
||||||
primitives::{
|
primitives::{
|
||||||
|
|
@ -31,7 +32,7 @@ pub struct Board {
|
||||||
#[getter(skip)]
|
#[getter(skip)]
|
||||||
pin_names: Recorder<BiBTreeMap<PinId, String>>,
|
pin_names: Recorder<BiBTreeMap<PinId, String>>,
|
||||||
#[getter(skip)]
|
#[getter(skip)]
|
||||||
layer_names: Recorder<BiBTreeMap<usize, String>>,
|
layer_names: Recorder<BiBTreeMap<LayerId, String>>,
|
||||||
#[getter(skip)]
|
#[getter(skip)]
|
||||||
net_names: Recorder<BiBTreeMap<NetId, String>>,
|
net_names: Recorder<BiBTreeMap<NetId, String>>,
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +51,7 @@ impl Board {
|
||||||
pub fn with_names(
|
pub fn with_names(
|
||||||
boundary: Vec<Vector2<i64>>,
|
boundary: Vec<Vector2<i64>>,
|
||||||
layer_count: usize,
|
layer_count: usize,
|
||||||
layer_names: BiBTreeMap<usize, String>,
|
layer_names: BiBTreeMap<LayerId, String>,
|
||||||
net_names: BiBTreeMap<NetId, String>,
|
net_names: BiBTreeMap<NetId, String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -131,11 +132,11 @@ impl Board {
|
||||||
self.pin_names.as_ref().get_by_right(pin_name).copied()
|
self.pin_names.as_ref().get_by_right(pin_name).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_name(&self, layer: usize) -> Option<&str> {
|
pub fn layer_name(&self, layer: LayerId) -> Option<&str> {
|
||||||
self.layer_names.get_by_left(&layer).map(String::as_str)
|
self.layer_names.get_by_left(&layer).map(String::as_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_id(&self, layer_name: &str) -> Option<usize> {
|
pub fn layer_id(&self, layer_name: &str) -> Option<LayerId> {
|
||||||
self.layer_names.as_ref().get_by_right(layer_name).copied()
|
self.layer_names.as_ref().get_by_right(layer_name).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
Board,
|
Board,
|
||||||
selections::{ComponentSelection, ComponentSelector, PinSelection, PinSelector},
|
selections::{ComponentSelection, ComponentSelector, PinSelection, PinSelector},
|
||||||
},
|
},
|
||||||
|
layout::LayerId,
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
primitives::{JointId, PolygonId, SegmentId},
|
primitives::{JointId, PolygonId, SegmentId},
|
||||||
};
|
};
|
||||||
|
|
@ -109,7 +110,7 @@ impl Board {
|
||||||
|
|
||||||
pub fn point_component_selector(
|
pub fn point_component_selector(
|
||||||
&self,
|
&self,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
point: Vector2<i64>,
|
point: Vector2<i64>,
|
||||||
) -> Option<ComponentSelector> {
|
) -> Option<ComponentSelector> {
|
||||||
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() {
|
||||||
|
|
@ -181,7 +182,7 @@ impl Board {
|
||||||
selection.0.contains(&selector)
|
selection.0.contains(&selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn point_pin_selector(&self, layer: usize, point: Vector2<i64>) -> Option<PinSelector> {
|
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() {
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,18 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct ComponentId(usize);
|
pub struct ComponentId(usize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,18 @@ use derive_more::{Constructor, From};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct NetId(usize);
|
pub struct NetId(usize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,18 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct PinId(usize);
|
pub struct PinId(usize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ pub mod primitives;
|
||||||
mod transforms;
|
mod transforms;
|
||||||
|
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
|
use derive_more::{Constructor, From};
|
||||||
use rstar::{
|
use rstar::{
|
||||||
AABB, RTree,
|
AABB, RTree,
|
||||||
primitives::{GeomWithData, Rectangle},
|
primitives::{GeomWithData, Rectangle},
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use stable_vec::StableVec;
|
use stable_vec::StableVec;
|
||||||
use undoredo::aliases::RTreeHalfDelta;
|
use undoredo::aliases::RTreeHalfDelta;
|
||||||
use undoredo::{Delta, Recorder};
|
use undoredo::{Delta, Recorder};
|
||||||
|
|
@ -23,6 +25,29 @@ use crate::{
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
|
)]
|
||||||
|
pub struct LayerId(usize);
|
||||||
|
|
||||||
|
impl LayerId {
|
||||||
|
#[inline]
|
||||||
|
pub fn index(self) -> usize {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Delta, Getters)]
|
#[derive(Clone, Debug, Delta, Getters)]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
#[undoredo(skip)]
|
#[undoredo(skip)]
|
||||||
|
|
@ -346,24 +371,24 @@ impl Layout {
|
||||||
|
|
||||||
pub fn locate_joints_at_point(
|
pub fn locate_joints_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
point: Vector2<i64>,
|
point: Vector2<i64>,
|
||||||
) -> impl Iterator<Item = JointId> {
|
) -> impl Iterator<Item = JointId> {
|
||||||
self.joints_rtree
|
self.joints_rtree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.locate_all_at_point(&[point.x, point.y, layer as i64])
|
.locate_all_at_point(&[point.x, point.y, layer.index() as i64])
|
||||||
.map(|geom_with_data| geom_with_data.data)
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
.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_segments_at_point(
|
pub fn locate_segments_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
point: Vector2<i64>,
|
point: Vector2<i64>,
|
||||||
) -> impl Iterator<Item = SegmentId> {
|
) -> impl Iterator<Item = SegmentId> {
|
||||||
self.segments_rtree
|
self.segments_rtree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.locate_all_at_point(&[point.x, point.y, layer as i64])
|
.locate_all_at_point(&[point.x, point.y, layer.index() as i64])
|
||||||
.map(|geom_with_data| geom_with_data.data)
|
.map(|geom_with_data| geom_with_data.data)
|
||||||
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
|
.filter(move |&segment_id| self.segment(segment_id).contains_point(point))
|
||||||
}
|
}
|
||||||
|
|
@ -372,17 +397,17 @@ impl Layout {
|
||||||
|
|
||||||
pub fn locate_polygons_at_point(
|
pub fn locate_polygons_at_point(
|
||||||
&self,
|
&self,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
point: Vector2<i64>,
|
point: Vector2<i64>,
|
||||||
) -> impl Iterator<Item = PolygonId> {
|
) -> impl Iterator<Item = PolygonId> {
|
||||||
self.polygons_rtree
|
self.polygons_rtree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.locate_all_at_point(&[point.x, point.y, layer as i64])
|
.locate_all_at_point(&[point.x, point.y, layer.index() as i64])
|
||||||
.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 layer_joints(&self, layer: usize) -> impl Iterator<Item = JointId> + '_ {
|
pub fn layer_joints(&self, layer: LayerId) -> impl Iterator<Item = JointId> + '_ {
|
||||||
let envelope = Self::whole_layer_aabb(layer);
|
let envelope = Self::whole_layer_aabb(layer);
|
||||||
self.joints_rtree
|
self.joints_rtree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -391,7 +416,7 @@ impl Layout {
|
||||||
.filter(move |&id| self.joint(id).spec.layer == layer)
|
.filter(move |&id| self.joint(id).spec.layer == layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_segments(&self, layer: usize) -> impl Iterator<Item = SegmentId> + '_ {
|
pub fn layer_segments(&self, layer: LayerId) -> impl Iterator<Item = SegmentId> + '_ {
|
||||||
let envelope = Self::whole_layer_aabb(layer);
|
let envelope = Self::whole_layer_aabb(layer);
|
||||||
self.segments_rtree
|
self.segments_rtree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -400,7 +425,7 @@ impl Layout {
|
||||||
.filter(move |&id| self.segment(id).layer == layer)
|
.filter(move |&id| self.segment(id).layer == layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_polygons(&self, layer: usize) -> 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
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -409,10 +434,10 @@ impl Layout {
|
||||||
.filter(move |&id| self.polygon(id).layer == layer)
|
.filter(move |&id| self.polygon(id).layer == layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn whole_layer_aabb(layer: usize) -> AABB<[i64; 3]> {
|
fn whole_layer_aabb(layer: LayerId) -> AABB<[i64; 3]> {
|
||||||
AABB::from_corners(
|
AABB::from_corners(
|
||||||
[i64::MIN, i64::MIN, layer as i64],
|
[i64::MIN, i64::MIN, layer.index() as i64],
|
||||||
[i64::MAX, i64::MAX, layer as i64],
|
[i64::MAX, i64::MAX, layer.index() as i64],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,24 @@ use rstar::{AABB, primitives::Rectangle};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::compounds::{ComponentId, NetId, PinId};
|
use crate::compounds::{ComponentId, NetId, PinId};
|
||||||
|
use crate::layout::LayerId;
|
||||||
use crate::math::Vector2;
|
use crate::math::Vector2;
|
||||||
|
|
||||||
use super::{SegmentId, ViaId};
|
use super::{SegmentId, ViaId};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct JointId(usize);
|
pub struct JointId(usize);
|
||||||
|
|
||||||
|
|
@ -27,7 +39,7 @@ impl JointId {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct JointSpec {
|
pub struct JointSpec {
|
||||||
pub position: Vector2<i64>,
|
pub position: Vector2<i64>,
|
||||||
pub layer: usize,
|
pub layer: LayerId,
|
||||||
pub radius: u64,
|
pub radius: u64,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
pub component: Option<ComponentId>,
|
pub component: Option<ComponentId>,
|
||||||
|
|
@ -51,12 +63,12 @@ impl Joint {
|
||||||
[
|
[
|
||||||
self.spec.position.x - self.spec.radius as i64,
|
self.spec.position.x - self.spec.radius as i64,
|
||||||
self.spec.position.y - self.spec.radius as i64,
|
self.spec.position.y - self.spec.radius as i64,
|
||||||
self.spec.layer as i64,
|
self.spec.layer.index() as i64,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
self.spec.position.x + self.spec.radius as i64,
|
self.spec.position.x + self.spec.radius as i64,
|
||||||
self.spec.position.y + self.spec.radius as i64,
|
self.spec.position.y + self.spec.radius as i64,
|
||||||
self.spec.layer as i64,
|
self.spec.layer.index() as i64,
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,22 @@ use rstar::{AABB, Envelope, primitives::Rectangle};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::compounds::{ComponentId, NetId, PinId};
|
use crate::compounds::{ComponentId, NetId, PinId};
|
||||||
|
use crate::layout::LayerId;
|
||||||
use crate::math::Vector2;
|
use crate::math::Vector2;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct PolygonId(usize);
|
pub struct PolygonId(usize);
|
||||||
|
|
||||||
|
|
@ -25,7 +37,7 @@ impl PolygonId {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Polygon {
|
pub struct Polygon {
|
||||||
pub vertices: Vec<Vector2<i64>>,
|
pub vertices: Vec<Vector2<i64>>,
|
||||||
pub layer: usize,
|
pub layer: LayerId,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
pub component: Option<ComponentId>,
|
pub component: Option<ComponentId>,
|
||||||
pub pin: Option<PinId>,
|
pub pin: Option<PinId>,
|
||||||
|
|
@ -33,14 +45,16 @@ pub struct Polygon {
|
||||||
|
|
||||||
impl Polygon {
|
impl Polygon {
|
||||||
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
||||||
Rectangle::from_aabb(
|
Rectangle::from_aabb(self.vertices.clone().into_iter().fold(
|
||||||
self.vertices
|
AABB::new_empty(),
|
||||||
.clone()
|
|aabb, vertex| {
|
||||||
.into_iter()
|
aabb.merged(&AABB::from_point([
|
||||||
.fold(AABB::new_empty(), |aabb, vertex| {
|
vertex.x,
|
||||||
aabb.merged(&AABB::from_point([vertex.x, vertex.y, self.layer as i64]))
|
vertex.y,
|
||||||
}),
|
self.layer.index() as i64,
|
||||||
)
|
]))
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn center(&self) -> Vector2<i64> {
|
pub fn center(&self) -> Vector2<i64> {
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,24 @@ use rstar::primitives::Rectangle;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::compounds::{ComponentId, NetId, PinId};
|
use crate::compounds::{ComponentId, NetId, PinId};
|
||||||
|
use crate::layout::LayerId;
|
||||||
use crate::math::Vector2;
|
use crate::math::Vector2;
|
||||||
|
|
||||||
use super::JointId;
|
use super::JointId;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct SegmentId(usize);
|
pub struct SegmentId(usize);
|
||||||
|
|
||||||
|
|
@ -36,7 +48,7 @@ pub struct SegmentSpec {
|
||||||
pub struct Segment {
|
pub struct Segment {
|
||||||
pub spec: SegmentSpec,
|
pub spec: SegmentSpec,
|
||||||
pub endpoints: [Vector2<i64>; 2],
|
pub endpoints: [Vector2<i64>; 2],
|
||||||
pub layer: usize,
|
pub layer: LayerId,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +82,7 @@ impl Segment {
|
||||||
|
|
||||||
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
|
||||||
let endpoints = self.endpoints;
|
let endpoints = self.endpoints;
|
||||||
let layer = self.layer as i64;
|
let layer = self.layer.index() as i64;
|
||||||
let half_width = self.spec.half_width as i64;
|
let half_width = self.spec.half_width as i64;
|
||||||
|
|
||||||
let min_x = std::cmp::min(endpoints[0].x, endpoints[1].x) - half_width;
|
let min_x = std::cmp::min(endpoints[0].x, endpoints[1].x) - half_width;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,24 @@ use rstar::{AABB, primitives::Rectangle};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::compounds::{ComponentId, NetId, PinId};
|
use crate::compounds::{ComponentId, NetId, PinId};
|
||||||
|
use crate::layout::LayerId;
|
||||||
use crate::math::Vector2;
|
use crate::math::Vector2;
|
||||||
|
|
||||||
use super::JointId;
|
use super::JointId;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct ViaId(usize);
|
pub struct ViaId(usize);
|
||||||
|
|
||||||
|
|
@ -36,8 +48,8 @@ pub struct ViaSpec {
|
||||||
pub struct Via {
|
pub struct Via {
|
||||||
pub spec: ViaSpec,
|
pub spec: ViaSpec,
|
||||||
pub position: Vector2<i64>,
|
pub position: Vector2<i64>,
|
||||||
pub min_layer: usize,
|
pub min_layer: LayerId,
|
||||||
pub max_layer: usize,
|
pub max_layer: LayerId,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,12 +61,12 @@ impl Via {
|
||||||
[
|
[
|
||||||
self.position.x - radius,
|
self.position.x - radius,
|
||||||
self.position.y - radius,
|
self.position.y - radius,
|
||||||
self.min_layer as i64,
|
self.min_layer.index() as i64,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
self.position.x + radius,
|
self.position.x + radius,
|
||||||
self.position.y + radius,
|
self.position.y + radius,
|
||||||
self.max_layer as i64,
|
self.max_layer.index() as i64,
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ pub use crate::autorouter::Autorouter;
|
||||||
pub use crate::board::Board;
|
pub use crate::board::Board;
|
||||||
pub use crate::board::selections;
|
pub use crate::board::selections;
|
||||||
pub use crate::compounds::{Pin, PinId};
|
pub use crate::compounds::{Pin, PinId};
|
||||||
|
pub use crate::layout::LayerId;
|
||||||
pub use crate::layout::Layout;
|
pub use crate::layout::Layout;
|
||||||
pub use crate::layout::primitives;
|
pub use crate::layout::primitives;
|
||||||
pub use crate::math::Vector2;
|
pub use crate::math::Vector2;
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,34 @@ use undoredo::Recorder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Board,
|
Board,
|
||||||
|
layout::LayerId,
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
primitives::{Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId},
|
primitives::{Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone,
|
||||||
|
Constructor,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
From,
|
||||||
|
Ord,
|
||||||
|
PartialEq,
|
||||||
|
PartialOrd,
|
||||||
|
Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct MultiObstacleId {
|
pub struct MultiObstacleId {
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiObstacleId {
|
impl MultiObstacleId {
|
||||||
/// Layer of the obstacle.
|
/// Layer of the obstacle.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn layer(self) -> usize {
|
pub fn layer(self) -> LayerId {
|
||||||
self.layer
|
self.layer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,17 +50,17 @@ impl MultiObstacleId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
Clone, Constructor, Debug, Default, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct MultiVertexId {
|
pub struct MultiVertexId {
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
indices: Vec<VertexId>,
|
indices: Vec<VertexId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiVertexId {
|
impl MultiVertexId {
|
||||||
/// Layer of the obstacle.
|
/// Layer of the obstacle.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn layer(self) -> usize {
|
pub fn layer(self) -> LayerId {
|
||||||
self.layer
|
self.layer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,12 +168,12 @@ impl Navmesher {
|
||||||
|
|
||||||
pub fn insert_multiobstacle(
|
pub fn insert_multiobstacle(
|
||||||
&mut self,
|
&mut self,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
multiobstacle: impl IntoIterator<Item = Vector2<i64>>,
|
multiobstacle: impl IntoIterator<Item = Vector2<i64>>,
|
||||||
) -> MultiObstacleId {
|
) -> MultiObstacleId {
|
||||||
MultiObstacleId::new(
|
MultiObstacleId::new(
|
||||||
layer,
|
layer,
|
||||||
self.layer_navmeshers[layer].insert_multiobstacle(multiobstacle),
|
self.layer_navmeshers[layer.index()].insert_multiobstacle(multiobstacle),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +184,7 @@ impl Navmesher {
|
||||||
) -> MultiVertexId {
|
) -> MultiVertexId {
|
||||||
MultiVertexId {
|
MultiVertexId {
|
||||||
layer: multiobstacle_id.layer,
|
layer: multiobstacle_id.layer,
|
||||||
indices: self.layer_navmeshers[multiobstacle_id.layer]
|
indices: self.layer_navmeshers[multiobstacle_id.layer.index()]
|
||||||
.insert_free_multivertex_in_multiobstacle(multiobstacle_id.index, position),
|
.insert_free_multivertex_in_multiobstacle(multiobstacle_id.index, position),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use spade::{DelaunayTriangulation, HasPosition, Triangulation, handles::FixedVer
|
||||||
use crate::{
|
use crate::{
|
||||||
Board,
|
Board,
|
||||||
compounds::NetId,
|
compounds::NetId,
|
||||||
|
layout::LayerId,
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
primitives::{JointId, PolygonId, PrimitiveId, SegmentId},
|
primitives::{JointId, PolygonId, PrimitiveId, SegmentId},
|
||||||
};
|
};
|
||||||
|
|
@ -18,12 +19,12 @@ use crate::{
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Getters, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Getters, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub struct Ratline {
|
pub struct Ratline {
|
||||||
endpoint_primitive_ids: [PrimitiveId; 2],
|
endpoint_primitive_ids: [PrimitiveId; 2],
|
||||||
endpoint_layers: [usize; 2],
|
endpoint_layers: [LayerId; 2],
|
||||||
endpoints: [Vector2<i64>; 2],
|
endpoints: [Vector2<i64>; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DelaunayVertex {
|
struct DelaunayVertex {
|
||||||
pub layer: usize,
|
pub layer: LayerId,
|
||||||
pub center: Vector2<i64>,
|
pub center: Vector2<i64>,
|
||||||
pub position: spade::Point2<f64>,
|
pub position: spade::Point2<f64>,
|
||||||
pub primitive_id: PrimitiveId,
|
pub primitive_id: PrimitiveId,
|
||||||
|
|
@ -46,7 +47,7 @@ impl Ratsnest {
|
||||||
pub fn new(board: &Board) -> Self {
|
pub fn new(board: &Board) -> Self {
|
||||||
let mut ratlines = Vec::new();
|
let mut ratlines = Vec::new();
|
||||||
|
|
||||||
let mut triangulations: BTreeMap<(NetId, usize), DelaunayTriangulation<DelaunayVertex>> =
|
let mut triangulations: BTreeMap<(NetId, LayerId), DelaunayTriangulation<DelaunayVertex>> =
|
||||||
BTreeMap::new();
|
BTreeMap::new();
|
||||||
|
|
||||||
for (i, joint) in board.layout().joints().container().iter() {
|
for (i, joint) in board.layout().joints().container().iter() {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use specctra::{
|
||||||
use crate::{
|
use crate::{
|
||||||
board::Board,
|
board::Board,
|
||||||
compounds::{ComponentId, NetId, PinId},
|
compounds::{ComponentId, NetId, PinId},
|
||||||
|
layout::LayerId,
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
primitives::{JointSpec, Polygon, Segment, SegmentSpec},
|
primitives::{JointSpec, Polygon, Segment, SegmentSpec},
|
||||||
};
|
};
|
||||||
|
|
@ -25,7 +26,7 @@ impl Board {
|
||||||
.layers
|
.layers
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, layer)| (index, layer.name.clone())),
|
.map(|(index, layer)| (LayerId::new(index), layer.name.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
// assign IDs to all nets named in pcb.network
|
// assign IDs to all nets named in pcb.network
|
||||||
|
|
@ -284,7 +285,7 @@ impl Board {
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin_pos: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
radius: u64,
|
radius: u64,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
component: Option<ComponentId>,
|
component: Option<ComponentId>,
|
||||||
pin: Option<PinId>,
|
pin: Option<PinId>,
|
||||||
|
|
@ -308,7 +309,7 @@ impl Board {
|
||||||
y1: f64,
|
y1: f64,
|
||||||
x2: f64,
|
x2: f64,
|
||||||
y2: f64,
|
y2: f64,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
component: Option<ComponentId>,
|
component: Option<ComponentId>,
|
||||||
pin: Option<PinId>,
|
pin: Option<PinId>,
|
||||||
|
|
@ -334,7 +335,7 @@ impl Board {
|
||||||
pin_pos: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
coords: &[Point],
|
coords: &[Point],
|
||||||
width: f64,
|
width: f64,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
component: Option<ComponentId>,
|
component: Option<ComponentId>,
|
||||||
pin: Option<PinId>,
|
pin: Option<PinId>,
|
||||||
|
|
@ -392,7 +393,7 @@ impl Board {
|
||||||
pin_pos: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
coords: &[Point],
|
coords: &[Point],
|
||||||
_width: f64,
|
_width: f64,
|
||||||
layer: usize,
|
layer: LayerId,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
component: Option<ComponentId>,
|
component: Option<ComponentId>,
|
||||||
pin: Option<PinId>,
|
pin: Option<PinId>,
|
||||||
|
|
@ -411,13 +412,13 @@ impl Board {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> usize {
|
fn layer(board: &Board, layers: &[Layer], name: &str, front: bool) -> LayerId {
|
||||||
let image_layer = board.layer_id(name).unwrap();
|
let image_layer = board.layer_id(name).unwrap();
|
||||||
|
|
||||||
if front {
|
if front {
|
||||||
image_layer
|
image_layer
|
||||||
} else {
|
} else {
|
||||||
layers.len() - image_layer - 1
|
LayerId::new(layers.len() - image_layer.index() - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue