mirror of https://codeberg.org/topola/topola.git
Compare commits
6 Commits
618905f56d
...
76bad7a2a0
| Author | SHA1 | Date |
|---|---|---|
|
|
76bad7a2a0 | |
|
|
25efbd1627 | |
|
|
e536e94039 | |
|
|
bc5e205b90 | |
|
|
b05c31f767 | |
|
|
79f859f8cb |
|
|
@ -3,7 +3,7 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use crate::{viewport::Viewport, workspace::Workspace};
|
||||
use topola::{Joint, Polygon, Segment};
|
||||
use topola::primitives::{Joint, Polygon, Segment};
|
||||
|
||||
pub struct Display {}
|
||||
|
||||
|
|
@ -53,7 +53,10 @@ impl Display {
|
|||
workspace.appearance_panel.layer_color(
|
||||
ctx,
|
||||
board.layer_name(joint.spec.layer),
|
||||
board.pin_selection_contains_joint(&workspace.pin_selection, joint_id),
|
||||
board.pin_with_layer_selection_contains_joint(
|
||||
&workspace.selection.pins,
|
||||
joint_id,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -68,7 +71,10 @@ impl Display {
|
|||
workspace.appearance_panel.layer_color(
|
||||
ctx,
|
||||
board.layer_name(segment.layer),
|
||||
board.pin_selection_contains_segment(&workspace.pin_selection, segment_id),
|
||||
board.pin_with_layer_selection_contains_segment(
|
||||
&workspace.selection.pins,
|
||||
segment_id,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -85,7 +91,10 @@ impl Display {
|
|||
workspace.appearance_panel.layer_color(
|
||||
ctx,
|
||||
board.layer_name(polygon.layer),
|
||||
board.pin_selection_contains_polygon(&workspace.pin_selection, polygon_id),
|
||||
board.pin_with_layer_selection_contains_polygon(
|
||||
&workspace.selection.pins,
|
||||
polygon_id,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl Viewport {
|
|||
.router()
|
||||
.navmesher_board()
|
||||
.board()
|
||||
.point_pin_selector(
|
||||
.point_pin_with_layer_selector(
|
||||
0,
|
||||
Vector2::new(
|
||||
pointer_scene_pos.x as i64,
|
||||
|
|
@ -66,7 +66,7 @@ impl Viewport {
|
|||
),
|
||||
)
|
||||
{
|
||||
workspace.pin_selection.toggle(pin_selector);
|
||||
workspace.selection.pins.toggle(pin_selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use topola::{Autorouter, Board, PinSelection};
|
||||
use topola::{Autorouter, Board, selections::PersistableSelection};
|
||||
|
||||
use crate::{appearance_panel::AppearancePanel, translator::Translator};
|
||||
|
||||
pub struct Workspace {
|
||||
pub autorouter: Autorouter,
|
||||
pub appearance_panel: AppearancePanel,
|
||||
pub pin_selection: PinSelection,
|
||||
pub selection: PersistableSelection,
|
||||
}
|
||||
|
||||
impl Workspace {
|
||||
|
|
@ -19,7 +19,7 @@ impl Workspace {
|
|||
Self {
|
||||
autorouter: Autorouter::new(board),
|
||||
appearance_panel,
|
||||
pin_selection: PinSelection::new(),
|
||||
selection: PersistableSelection::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,24 @@ use derive_getters::{Dissolve, Getters};
|
|||
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||
|
||||
use crate::{
|
||||
layout::{Layout, LayoutHalfDelta, NetId, PinId},
|
||||
compounds::{ComponentId, NetId, PinId},
|
||||
layout::{Layout, LayoutHalfDelta},
|
||||
math::Vector2,
|
||||
primitives::{
|
||||
JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
selection::{PinSelection, PinSelector},
|
||||
selections::{
|
||||
ComponentSelection, ComponentSelector, PinWithLayerSelection, PinWithLayerSelector,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
pub struct Board {
|
||||
layout: Layout,
|
||||
#[getter(skip)]
|
||||
component_names: BiBTreeMap<ComponentId, String>,
|
||||
#[getter(skip)]
|
||||
pin_names: BiBTreeMap<PinId, String>,
|
||||
#[getter(skip)]
|
||||
layer_names: BiBTreeMap<usize, String>,
|
||||
|
|
@ -31,6 +36,7 @@ impl Board {
|
|||
pub fn new(boundary: Vec<Vector2<i64>>, layer_count: usize) -> Self {
|
||||
Self {
|
||||
layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count),
|
||||
component_names: BiBTreeMap::new(),
|
||||
pin_names: BiBTreeMap::new(),
|
||||
layer_names: BiBTreeMap::new(),
|
||||
net_names: BiBTreeMap::new(),
|
||||
|
|
@ -45,13 +51,25 @@ impl Board {
|
|||
) -> Self {
|
||||
Self {
|
||||
layout: Layout::new(boundary.into_iter().map(Into::into).collect(), layer_count),
|
||||
component_names: BiBTreeMap::new(),
|
||||
pin_names: BiBTreeMap::new(),
|
||||
layer_names,
|
||||
net_names,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_pin(&mut self, pin_name: String) -> PinId {
|
||||
pub fn ensure_named_component(&mut self, component_name: String) -> ComponentId {
|
||||
if let Some(component) = self.component_names.get_by_right(&component_name) {
|
||||
return *component;
|
||||
};
|
||||
|
||||
let component_id = self.layout.add_component();
|
||||
self.component_names.insert(component_id, component_name);
|
||||
|
||||
component_id
|
||||
}
|
||||
|
||||
pub fn ensure_named_pin(&mut self, pin_name: String) -> PinId {
|
||||
if let Some(pin) = self.pin_names.get_by_right(&pin_name) {
|
||||
return *pin;
|
||||
};
|
||||
|
|
@ -62,6 +80,10 @@ impl Board {
|
|||
pin_id
|
||||
}
|
||||
|
||||
pub fn add_component(&mut self) -> ComponentId {
|
||||
self.layout.add_component()
|
||||
}
|
||||
|
||||
pub fn add_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
self.layout.add_joint(spec)
|
||||
}
|
||||
|
|
@ -86,19 +108,105 @@ impl Board {
|
|||
self.layout.add_polygon(polygon)
|
||||
}
|
||||
|
||||
pub fn joint_pin_selector(&self, joint_id: JointId) -> Option<PinSelector> {
|
||||
let joint = self.layout.joint(joint_id);
|
||||
pub fn joint_component_selector(&self, id: JointId) -> Option<ComponentSelector> {
|
||||
let joint = self.layout.joint(id);
|
||||
|
||||
Some(PinSelector {
|
||||
Some(ComponentSelector {
|
||||
component: self.component_name(joint.spec.component?)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn segment_component_selector(&self, id: SegmentId) -> Option<ComponentSelector> {
|
||||
let segment = self.layout.segment(id);
|
||||
|
||||
Some(ComponentSelector {
|
||||
component: self.component_name(segment.spec.component?)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: Vias.
|
||||
|
||||
pub fn polygon_component_selector(&self, id: PolygonId) -> Option<ComponentSelector> {
|
||||
let polygon = self.layout.polygon(id);
|
||||
|
||||
Some(ComponentSelector {
|
||||
component: self.component_name(polygon.component?)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn point_component_selector(
|
||||
&self,
|
||||
layer: usize,
|
||||
point: Vector2<i64>,
|
||||
) -> Option<ComponentSelector> {
|
||||
if let Some(joint_id) = self.layout.locate_joints_at_point(layer, point).next() {
|
||||
return self.joint_component_selector(joint_id);
|
||||
}
|
||||
|
||||
if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() {
|
||||
return self.segment_component_selector(segment_id);
|
||||
}
|
||||
|
||||
// TODO: Vias.
|
||||
|
||||
if let Some(polygon_id) = self.layout.locate_polygons_at_point(layer, point).next() {
|
||||
return self.polygon_component_selector(polygon_id);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn component_selection_contains_joint(
|
||||
&self,
|
||||
selection: &ComponentSelection,
|
||||
id: JointId,
|
||||
) -> bool {
|
||||
let Some(selector) = self.joint_component_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
pub fn component_selection_contains_segment(
|
||||
&self,
|
||||
selection: &ComponentSelection,
|
||||
id: SegmentId,
|
||||
) -> bool {
|
||||
let Some(selector) = self.segment_component_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
// TODO: Vias.
|
||||
|
||||
pub fn component_selection_contains_polygon(
|
||||
&self,
|
||||
selection: &ComponentSelection,
|
||||
id: PolygonId,
|
||||
) -> bool {
|
||||
let Some(selector) = self.polygon_component_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
pub fn joint_pin_with_layer_selector(&self, id: JointId) -> Option<PinWithLayerSelector> {
|
||||
let joint = self.layout.joint(id);
|
||||
|
||||
Some(PinWithLayerSelector {
|
||||
pin: self.pin_name(joint.spec.pin?)?.to_string(),
|
||||
layer: self.layer_name(joint.spec.layer)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn segment_pin_selector(&self, segment_id: SegmentId) -> Option<PinSelector> {
|
||||
let segment = self.layout.segment(segment_id);
|
||||
pub fn segment_pin_with_layer_selector(&self, id: SegmentId) -> Option<PinWithLayerSelector> {
|
||||
let segment = self.layout.segment(id);
|
||||
|
||||
Some(PinSelector {
|
||||
Some(PinWithLayerSelector {
|
||||
pin: self.pin_name(segment.spec.pin?)?.to_string(),
|
||||
layer: self.layer_name(segment.layer)?.to_string(),
|
||||
})
|
||||
|
|
@ -106,73 +214,85 @@ impl Board {
|
|||
|
||||
// TODO: Vias.
|
||||
|
||||
pub fn polygon_pin_selector(&self, polygon_id: PolygonId) -> Option<PinSelector> {
|
||||
let polygon = self.layout.polygon(polygon_id);
|
||||
pub fn polygon_pin_with_layer_selector(&self, id: PolygonId) -> Option<PinWithLayerSelector> {
|
||||
let polygon = self.layout.polygon(id);
|
||||
|
||||
Some(PinSelector {
|
||||
Some(PinWithLayerSelector {
|
||||
pin: self.pin_name(polygon.pin?)?.to_string(),
|
||||
layer: self.layer_name(polygon.layer)?.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn point_pin_selector(&self, layer: usize, point: Vector2<i64>) -> Option<PinSelector> {
|
||||
pub fn point_pin_with_layer_selector(
|
||||
&self,
|
||||
layer: usize,
|
||||
point: Vector2<i64>,
|
||||
) -> Option<PinWithLayerSelector> {
|
||||
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_with_layer_selector(joint_id);
|
||||
}
|
||||
|
||||
if let Some(segment_id) = self.layout.locate_segments_at_point(layer, point).next() {
|
||||
return self.segment_pin_selector(segment_id);
|
||||
return self.segment_pin_with_layer_selector(segment_id);
|
||||
}
|
||||
|
||||
// TODO: Vias.
|
||||
|
||||
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_with_layer_selector(polygon_id);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn pin_selection_contains_joint(
|
||||
pub fn pin_with_layer_selection_contains_joint(
|
||||
&self,
|
||||
pin_selection: &PinSelection,
|
||||
joint_id: JointId,
|
||||
selection: &PinWithLayerSelection,
|
||||
id: JointId,
|
||||
) -> bool {
|
||||
let Some(pin_selector) = self.joint_pin_selector(joint_id) else {
|
||||
let Some(selector) = self.joint_pin_with_layer_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
pin_selection.0.contains(&pin_selector)
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
pub fn pin_selection_contains_segment(
|
||||
pub fn pin_with_layer_selection_contains_segment(
|
||||
&self,
|
||||
pin_selection: &PinSelection,
|
||||
segment_id: SegmentId,
|
||||
selection: &PinWithLayerSelection,
|
||||
id: SegmentId,
|
||||
) -> bool {
|
||||
let Some(pin_selector) = self.segment_pin_selector(segment_id) else {
|
||||
let Some(selector) = self.segment_pin_with_layer_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
pin_selection.0.contains(&pin_selector)
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
// TODO: Vias.
|
||||
|
||||
pub fn pin_selection_contains_polygon(
|
||||
pub fn pin_with_layer_selection_contains_polygon(
|
||||
&self,
|
||||
pin_selection: &PinSelection,
|
||||
polygon_id: PolygonId,
|
||||
selection: &PinWithLayerSelection,
|
||||
id: PolygonId,
|
||||
) -> bool {
|
||||
let Some(pin_selector) = self.polygon_pin_selector(polygon_id) else {
|
||||
let Some(selector) = self.polygon_pin_with_layer_selector(id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
pin_selection.0.contains(&pin_selector)
|
||||
selection.0.contains(&selector)
|
||||
}
|
||||
|
||||
pub fn pin_name(&self, pin: PinId) -> Option<&str> {
|
||||
self.pin_names.get_by_left(&pin).map(String::as_str)
|
||||
pub fn component_name(&self, id: ComponentId) -> Option<&str> {
|
||||
self.component_names.get_by_left(&id).map(String::as_str)
|
||||
}
|
||||
|
||||
pub fn component_id(&self, component_name: &str) -> Option<ComponentId> {
|
||||
self.component_names.get_by_right(component_name).copied()
|
||||
}
|
||||
|
||||
pub fn pin_name(&self, id: PinId) -> Option<&str> {
|
||||
self.pin_names.get_by_left(&id).map(String::as_str)
|
||||
}
|
||||
|
||||
pub fn pin_id(&self, pin_name: &str) -> Option<PinId> {
|
||||
|
|
@ -187,8 +307,8 @@ impl Board {
|
|||
self.layer_names.get_by_right(layer_name).copied()
|
||||
}
|
||||
|
||||
pub fn net_name(&self, net: NetId) -> Option<&str> {
|
||||
self.net_names.get_by_left(&net).map(String::as_str)
|
||||
pub fn net_name(&self, id: NetId) -> Option<&str> {
|
||||
self.net_names.get_by_left(&id).map(String::as_str)
|
||||
}
|
||||
|
||||
pub fn net_id(&self, net_name: &str) -> Option<NetId> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_more::Constructor;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct ComponentId(usize);
|
||||
|
||||
impl ComponentId {
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Component {
|
||||
pub joints: Vec<JointId>,
|
||||
pub segments: Vec<SegmentId>,
|
||||
pub vias: Vec<ViaId>,
|
||||
pub polygons: Vec<PolygonId>,
|
||||
}
|
||||
|
||||
impl Component {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
joints: Vec::new(),
|
||||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
polygons: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod component;
|
||||
mod net;
|
||||
mod pin;
|
||||
|
||||
pub use component::*;
|
||||
pub use net::*;
|
||||
pub use pin::*;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_more::Constructor;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct NetId(usize);
|
||||
|
||||
impl NetId {
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_more::Constructor;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::primitives::{JointId, PolygonId, SegmentId, ViaId};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct PinId(usize);
|
||||
|
||||
impl PinId {
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Pin {
|
||||
pub joints: Vec<JointId>,
|
||||
pub segments: Vec<SegmentId>,
|
||||
pub vias: Vec<ViaId>,
|
||||
pub polygons: Vec<PolygonId>,
|
||||
}
|
||||
|
||||
impl Pin {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
joints: Vec::new(),
|
||||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
polygons: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,66 +3,23 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use derive_getters::Getters;
|
||||
use derive_more::Constructor;
|
||||
use rstar::{
|
||||
AABB, RTree,
|
||||
primitives::{GeomWithData, Rectangle},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use stable_vec::StableVec;
|
||||
use undoredo::aliases::RTreeHalfDelta;
|
||||
use undoredo::{Delta, Recorder};
|
||||
|
||||
use crate::{
|
||||
Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, Via, ViaId,
|
||||
primitives::{JointSpec, SegmentSpec, ViaSpec},
|
||||
compounds::{Component, ComponentId, Pin, PinId},
|
||||
math::Vector2,
|
||||
primitives::{
|
||||
Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct PinId(usize);
|
||||
|
||||
impl PinId {
|
||||
/// Returns the underlying index.
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Pin {
|
||||
joints: Vec<JointId>,
|
||||
segments: Vec<SegmentId>,
|
||||
vias: Vec<ViaId>,
|
||||
polygons: Vec<PolygonId>,
|
||||
}
|
||||
|
||||
impl Pin {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
joints: Vec::new(),
|
||||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
polygons: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
)]
|
||||
pub struct NetId(usize);
|
||||
|
||||
impl NetId {
|
||||
/// Returns the underlying index.
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Delta, Clone, Debug, Getters)]
|
||||
pub struct Layout {
|
||||
#[undoredo(skip)]
|
||||
|
|
@ -72,8 +29,8 @@ pub struct Layout {
|
|||
#[undoredo(skip)]
|
||||
layer_count: usize,
|
||||
|
||||
#[undoredo(skip)]
|
||||
pins: StableVec<Pin>,
|
||||
components: Recorder<StableVec<Component>>,
|
||||
pins: Recorder<StableVec<Pin>>,
|
||||
|
||||
joints: Recorder<StableVec<Joint>>,
|
||||
segments: Recorder<StableVec<Segment>>,
|
||||
|
|
@ -105,7 +62,8 @@ impl Layout {
|
|||
place_boundary: boundary,
|
||||
layer_count,
|
||||
|
||||
pins: StableVec::new(),
|
||||
components: Recorder::new(StableVec::new()),
|
||||
pins: Recorder::new(StableVec::new()),
|
||||
|
||||
joints: Recorder::new(StableVec::new()),
|
||||
segments: Recorder::new(StableVec::new()),
|
||||
|
|
@ -119,6 +77,10 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_component(&mut self) -> ComponentId {
|
||||
ComponentId::new(self.components.push(Component::new()))
|
||||
}
|
||||
|
||||
pub fn add_pin(&mut self) -> PinId {
|
||||
PinId::new(self.pins.push(Pin::new()))
|
||||
}
|
||||
|
|
@ -130,14 +92,22 @@ impl Layout {
|
|||
vias: Vec::new(),
|
||||
};
|
||||
let bbox = joint.bbox();
|
||||
let component_id = joint.spec.component;
|
||||
let pin_id = joint.spec.pin;
|
||||
let joint_id = JointId::new(self.joints.push(joint));
|
||||
|
||||
self.joints_rtree
|
||||
.insert(GeomWithData::new(bbox, joint_id), ());
|
||||
|
||||
if let Some(component_id) = component_id {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
component.joints.push(joint_id)
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin_id {
|
||||
self.pins[pin_id.index()].joints.push(joint_id);
|
||||
self.pins
|
||||
.modify(pin_id.index(), |pin| pin.joints.push(joint_id));
|
||||
}
|
||||
|
||||
joint_id
|
||||
|
|
@ -147,15 +117,8 @@ impl Layout {
|
|||
where
|
||||
F: FnOnce(&mut JointSpec),
|
||||
{
|
||||
let old_joint = self.joints.get(&id.index()).unwrap();
|
||||
self.joints_rtree
|
||||
.remove(&GeomWithData::new(old_joint.bbox(), id));
|
||||
|
||||
self.joints.modify(id.index(), |joint| f(&mut joint.spec));
|
||||
|
||||
let new_joint = self.joints.get(&id.index()).unwrap().clone();
|
||||
self.joints_rtree
|
||||
.insert(GeomWithData::new(new_joint.bbox(), id), ());
|
||||
self.modify_joint_raw(id, |joint| f(&mut joint.spec));
|
||||
let new_joint = self.joints[id.index()].clone();
|
||||
|
||||
for &segment in &new_joint.segments {
|
||||
self.update_segment(segment);
|
||||
|
|
@ -166,6 +129,21 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
fn modify_joint_raw<F>(&mut self, id: JointId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Joint),
|
||||
{
|
||||
let old_joint = &self.joints[id.index()];
|
||||
self.joints_rtree
|
||||
.remove(&GeomWithData::new(old_joint.bbox(), id));
|
||||
|
||||
self.joints.modify(id.index(), |joint| f(joint));
|
||||
|
||||
let new_joint = self.joints[id.index()].clone();
|
||||
self.joints_rtree
|
||||
.insert(GeomWithData::new(new_joint.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
self.add_segment_raw(Segment {
|
||||
spec,
|
||||
|
|
@ -179,6 +157,7 @@ impl Layout {
|
|||
}
|
||||
|
||||
pub fn add_segment_raw(&mut self, segment: Segment) -> SegmentId {
|
||||
let component_id = segment.spec.component;
|
||||
let pin_id = segment.spec.pin;
|
||||
let bbox = segment.bbox();
|
||||
let segment_id = SegmentId::new(self.segments.push(segment));
|
||||
|
|
@ -195,8 +174,15 @@ impl Layout {
|
|||
self.segments_rtree
|
||||
.insert(GeomWithData::new(bbox, segment_id), ());
|
||||
|
||||
if let Some(component_id) = component_id {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
component.segments.push(segment_id)
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin_id {
|
||||
self.pins[pin_id.index()].segments.push(segment_id);
|
||||
self.pins
|
||||
.modify(pin_id.index(), |pin| pin.segments.push(segment_id));
|
||||
}
|
||||
|
||||
segment_id
|
||||
|
|
@ -206,27 +192,27 @@ impl Layout {
|
|||
where
|
||||
F: FnOnce(&mut SegmentSpec),
|
||||
{
|
||||
let old_segment = self.segments.get(&id.index()).unwrap();
|
||||
let old_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.remove(&GeomWithData::new(old_segment.bbox(), id));
|
||||
|
||||
self.segments
|
||||
.modify(id.index(), |segment| f(&mut segment.spec));
|
||||
|
||||
let new_segment = self.segments.get(&id.index()).unwrap();
|
||||
let new_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_segment(&mut self, id: SegmentId) {
|
||||
let old_segment = self.segments.get(&id.index()).unwrap();
|
||||
let old_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.remove(&GeomWithData::new(old_segment.bbox(), id));
|
||||
|
||||
let endjoint_ids = old_segment.spec.endjoints;
|
||||
let endjoint_specs = [
|
||||
self.joints.get(&endjoint_ids[0].index()).unwrap().spec,
|
||||
self.joints.get(&endjoint_ids[1].index()).unwrap().spec,
|
||||
self.joints[endjoint_ids[0].index()].spec,
|
||||
self.joints[endjoint_ids[1].index()].spec,
|
||||
];
|
||||
self.segments.modify(id.index(), |segment| {
|
||||
segment.endpoints = [endjoint_specs[0].position, endjoint_specs[1].position];
|
||||
|
|
@ -234,7 +220,7 @@ impl Layout {
|
|||
segment.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_segment = self.segments.get(&id.index()).unwrap();
|
||||
let new_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
|
@ -253,6 +239,7 @@ impl Layout {
|
|||
|
||||
pub fn add_via_raw(&mut self, via: Via) -> ViaId {
|
||||
let bbox = via.bbox();
|
||||
let component_id = via.spec.component;
|
||||
let pin_id = via.spec.pin;
|
||||
let via_id = ViaId::new(self.vias.push(via));
|
||||
|
||||
|
|
@ -265,8 +252,15 @@ impl Layout {
|
|||
|
||||
self.vias_rtree.insert(GeomWithData::new(bbox, via_id), ());
|
||||
|
||||
if let Some(component_id) = component_id {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
component.vias.push(via_id)
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin_id {
|
||||
self.pins[pin_id.index()].vias.push(via_id);
|
||||
self.pins
|
||||
.modify(pin_id.index(), |pin| pin.vias.push(via_id));
|
||||
}
|
||||
|
||||
via_id
|
||||
|
|
@ -276,26 +270,26 @@ impl Layout {
|
|||
where
|
||||
F: FnOnce(&mut ViaSpec),
|
||||
{
|
||||
let old_via = self.vias.get(&id.index()).unwrap();
|
||||
let old_via = &self.vias[id.index()];
|
||||
self.vias_rtree
|
||||
.remove(&GeomWithData::new(old_via.bbox(), id));
|
||||
|
||||
self.vias.modify(id.index(), |via| f(&mut via.spec));
|
||||
|
||||
let new_via = self.vias.get(&id.index()).unwrap();
|
||||
let new_via = &self.vias[id.index()];
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_via(&mut self, id: ViaId) {
|
||||
let old_via = self.vias.get(&id.index()).unwrap();
|
||||
let old_via = &self.vias[id.index()];
|
||||
self.vias_rtree
|
||||
.remove(&GeomWithData::new(old_via.bbox(), id));
|
||||
|
||||
let endjoint_ids = old_via.spec.endjoints;
|
||||
let endjoint_specs = [
|
||||
self.joints.get(&endjoint_ids[0].index()).unwrap().spec,
|
||||
self.joints.get(&endjoint_ids[1].index()).unwrap().spec,
|
||||
self.joints[endjoint_ids[0].index()].spec,
|
||||
self.joints[endjoint_ids[1].index()].spec,
|
||||
];
|
||||
self.vias.modify(id.index(), |via| {
|
||||
via.position = endjoint_specs[0].position;
|
||||
|
|
@ -304,21 +298,29 @@ impl Layout {
|
|||
via.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_via = self.vias.get(&id.index()).unwrap();
|
||||
let new_via = &self.vias[id.index()];
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
let bbox = polygon.bbox();
|
||||
let component_id = polygon.component;
|
||||
let pin_id = polygon.pin;
|
||||
let polygon_id = PolygonId::new(self.polygons.push(polygon));
|
||||
|
||||
self.polygons_rtree
|
||||
.insert(GeomWithData::new(bbox, polygon_id), ());
|
||||
|
||||
if let Some(component_id) = component_id {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
component.polygons.push(polygon_id)
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin_id {
|
||||
self.pins[pin_id.index()].polygons.push(polygon_id);
|
||||
self.pins
|
||||
.modify(pin_id.index(), |pin| pin.polygons.push(polygon_id));
|
||||
}
|
||||
|
||||
polygon_id
|
||||
|
|
@ -328,13 +330,13 @@ impl Layout {
|
|||
where
|
||||
F: FnOnce(&mut Polygon),
|
||||
{
|
||||
let old_polygon = self.polygons.get(&id.index()).unwrap();
|
||||
let old_polygon = &self.polygons[id.index()];
|
||||
self.polygons_rtree
|
||||
.remove(&GeomWithData::new(old_polygon.bbox(), id));
|
||||
|
||||
self.polygons.modify(id.index(), |polygon| f(polygon));
|
||||
|
||||
let new_polygon = self.polygons.get(&id.index()).unwrap();
|
||||
let new_polygon = &self.polygons[id.index()];
|
||||
self.polygons_rtree
|
||||
.insert(GeomWithData::new(new_polygon.bbox(), id), ());
|
||||
}
|
||||
|
|
@ -348,12 +350,7 @@ impl Layout {
|
|||
.as_ref()
|
||||
.locate_all_at_point(&[point.x, point.y, layer as i64])
|
||||
.map(|geom_with_data| geom_with_data.data)
|
||||
.filter(move |&joint_id| {
|
||||
self.joints
|
||||
.get(&joint_id.index())
|
||||
.unwrap()
|
||||
.contains_point(point)
|
||||
})
|
||||
.filter(move |&joint_id| self.joints[joint_id.index()].contains_point(point))
|
||||
}
|
||||
|
||||
pub fn locate_segments_at_point(
|
||||
|
|
@ -379,12 +376,7 @@ impl Layout {
|
|||
.as_ref()
|
||||
.locate_all_at_point(&[point.x, point.y, layer as i64])
|
||||
.map(|geom_with_data| geom_with_data.data)
|
||||
.filter(move |&polygon_id| {
|
||||
self.polygons
|
||||
.get(&polygon_id.index())
|
||||
.unwrap()
|
||||
.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> + '_ {
|
||||
|
|
@ -422,15 +414,15 @@ impl Layout {
|
|||
}
|
||||
|
||||
pub fn joint(&self, joint_id: JointId) -> &Joint {
|
||||
self.joints.get(&joint_id.index()).unwrap()
|
||||
&self.joints[joint_id.index()]
|
||||
}
|
||||
|
||||
pub fn segment(&self, segment_id: SegmentId) -> &Segment {
|
||||
self.segments.get(&segment_id.index()).unwrap()
|
||||
&self.segments[segment_id.index()]
|
||||
}
|
||||
|
||||
pub fn polygon(&self, polygon_id: PolygonId) -> &Polygon {
|
||||
self.polygons.get(&polygon_id.index()).unwrap()
|
||||
&self.polygons[polygon_id.index()]
|
||||
}
|
||||
|
||||
pub fn pin(&self, pin_id: PinId) -> &Pin {
|
||||
|
|
|
|||
|
|
@ -4,23 +4,21 @@
|
|||
|
||||
mod autorouter;
|
||||
mod board;
|
||||
mod compounds;
|
||||
mod drawer;
|
||||
mod layout;
|
||||
mod math;
|
||||
mod navmesher;
|
||||
mod pathfinder;
|
||||
mod primitives;
|
||||
pub mod primitives;
|
||||
mod ratsnest;
|
||||
mod router;
|
||||
mod selection;
|
||||
pub mod selections;
|
||||
mod specctra;
|
||||
|
||||
pub use crate::autorouter::Autorouter;
|
||||
pub use crate::board::Board;
|
||||
pub use crate::compounds::{Pin, PinId};
|
||||
pub use crate::layout::Layout;
|
||||
pub use crate::math::Vector2;
|
||||
pub use crate::primitives::{
|
||||
Joint, JointId, Polygon, PolygonId, PrimitiveId, Segment, SegmentId, Via, ViaId,
|
||||
};
|
||||
pub use crate::ratsnest::{Ratline, Ratsnest};
|
||||
pub use crate::selection::{PinSelection, PinSelector};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ use stable_vec::StableVec;
|
|||
use undoredo::Recorder;
|
||||
|
||||
use crate::{
|
||||
Board, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, primitives::JointSpec,
|
||||
Board,
|
||||
math::Vector2,
|
||||
primitives::{Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use derive_more::Constructor;
|
|||
use rstar::{AABB, primitives::Rectangle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::layout::{NetId, PinId};
|
||||
use crate::compounds::{ComponentId, NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
use crate::primitives::{SegmentId, ViaId};
|
||||
|
||||
|
|
@ -29,6 +29,7 @@ pub struct JointSpec {
|
|||
pub layer: usize,
|
||||
pub radius: u64,
|
||||
pub net: NetId,
|
||||
pub component: Option<ComponentId>,
|
||||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ mod polygon;
|
|||
mod segment;
|
||||
mod via;
|
||||
|
||||
pub use joint::{Joint, JointId, JointSpec};
|
||||
pub use polygon::{Polygon, PolygonId};
|
||||
pub use segment::{Segment, SegmentId, SegmentSpec};
|
||||
pub use via::{Via, ViaId, ViaSpec};
|
||||
pub use joint::*;
|
||||
pub use polygon::*;
|
||||
pub use segment::*;
|
||||
pub use via::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub enum PrimitiveId {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use derive_more::Constructor;
|
|||
use rstar::{AABB, Envelope, primitives::Rectangle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::layout::{NetId, PinId};
|
||||
use crate::compounds::{ComponentId, NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
|
||||
#[derive(
|
||||
|
|
@ -27,6 +27,7 @@ pub struct Polygon {
|
|||
pub vertices: Vec<Vector2<i64>>,
|
||||
pub layer: usize,
|
||||
pub net: NetId,
|
||||
pub component: Option<ComponentId>,
|
||||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use derive_more::Constructor;
|
|||
use rstar::primitives::Rectangle;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::layout::{NetId, PinId};
|
||||
use crate::compounds::{ComponentId, NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
use crate::primitives::JointId;
|
||||
|
||||
|
|
@ -27,6 +27,7 @@ impl SegmentId {
|
|||
pub struct SegmentSpec {
|
||||
pub endjoints: [JointId; 2],
|
||||
pub half_width: u64,
|
||||
pub component: Option<ComponentId>,
|
||||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ use derive_more::Constructor;
|
|||
use rstar::{AABB, primitives::Rectangle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::layout::{NetId, PinId};
|
||||
use crate::compounds::{ComponentId, NetId, PinId};
|
||||
use crate::math::Vector2;
|
||||
|
||||
use super::joint::JointId;
|
||||
use crate::primitives::JointId;
|
||||
|
||||
#[derive(
|
||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||
|
|
@ -28,6 +27,7 @@ impl ViaId {
|
|||
pub struct ViaSpec {
|
||||
pub endjoints: [JointId; 2],
|
||||
pub radius: u64,
|
||||
pub component: Option<ComponentId>,
|
||||
pub pin: Option<PinId>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ use serde::{Deserialize, Serialize};
|
|||
use spade::{DelaunayTriangulation, HasPosition, Triangulation, handles::FixedVertexHandle};
|
||||
|
||||
use crate::{
|
||||
Board, JointId, PolygonId, SegmentId, Vector2, layout::NetId, primitives::PrimitiveId,
|
||||
Board,
|
||||
compounds::NetId,
|
||||
math::Vector2,
|
||||
primitives::{JointId, PolygonId, PrimitiveId, SegmentId},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Getters, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct ComponentSelector {
|
||||
pub component: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct ComponentSelection(pub BTreeSet<ComponentSelector>);
|
||||
|
||||
impl ComponentSelection {
|
||||
pub fn new() -> Self {
|
||||
Self(BTreeSet::new())
|
||||
}
|
||||
|
||||
pub fn toggle(&mut self, selector: ComponentSelector) {
|
||||
if self.0.contains(&selector) {
|
||||
self.0.remove(&selector);
|
||||
} else {
|
||||
self.0.insert(selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod component;
|
||||
mod persistable;
|
||||
mod pin_with_layer;
|
||||
|
||||
pub use component::*;
|
||||
pub use persistable::*;
|
||||
pub use pin_with_layer::*;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::selections::{ComponentSelection, PinWithLayerSelection};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct PersistableSelection {
|
||||
pub components: ComponentSelection,
|
||||
pub pins: PinWithLayerSelection,
|
||||
}
|
||||
|
||||
impl PersistableSelection {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
components: ComponentSelection::new(),
|
||||
pins: PinWithLayerSelection::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,24 +7,24 @@ use std::collections::BTreeSet;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct PinSelector {
|
||||
pub struct PinWithLayerSelector {
|
||||
pub pin: String,
|
||||
pub layer: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct PinSelection(pub BTreeSet<PinSelector>);
|
||||
pub struct PinWithLayerSelection(pub BTreeSet<PinWithLayerSelector>);
|
||||
|
||||
impl PinSelection {
|
||||
impl PinWithLayerSelection {
|
||||
pub fn new() -> Self {
|
||||
Self(BTreeSet::new())
|
||||
}
|
||||
|
||||
pub fn toggle(&mut self, pin_selector: PinSelector) {
|
||||
if self.0.contains(&pin_selector) {
|
||||
self.0.remove(&pin_selector);
|
||||
pub fn toggle(&mut self, selector: PinWithLayerSelector) {
|
||||
if self.0.contains(&selector) {
|
||||
self.0.remove(&selector);
|
||||
} else {
|
||||
self.0.insert(pin_selector);
|
||||
self.0.insert(selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,10 +11,10 @@ use specctra::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
Segment, Vector2,
|
||||
board::Board,
|
||||
layout::{NetId, PinId},
|
||||
primitives::{JointSpec, Polygon, SegmentSpec},
|
||||
compounds::{ComponentId, NetId, PinId},
|
||||
math::Vector2,
|
||||
primitives::{JointSpec, Polygon, Segment, SegmentSpec},
|
||||
};
|
||||
|
||||
impl Board {
|
||||
|
|
@ -97,6 +97,8 @@ impl Board {
|
|||
.unwrap();
|
||||
|
||||
for place in &component.places {
|
||||
let component_id = board.ensure_named_component(place.name.clone());
|
||||
|
||||
let place_side_is_front = place.side == "front";
|
||||
let get_layer = |board: &Board, name: &str| {
|
||||
Self::layer(board, &dsn.pcb.structure.layers, name, place_side_is_front)
|
||||
|
|
@ -109,7 +111,7 @@ impl Board {
|
|||
continue;
|
||||
};
|
||||
|
||||
let pin_id = board.ensure_pin(pin_name.clone());
|
||||
let pin_id = board.ensure_named_pin(pin_name.clone());
|
||||
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
|
||||
|
||||
for shape in padstack.shapes.iter() {
|
||||
|
|
@ -123,6 +125,7 @@ impl Board {
|
|||
(circle.diameter / 2.0) as u64,
|
||||
layer,
|
||||
net,
|
||||
Some(component_id),
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
|
|
@ -139,6 +142,7 @@ impl Board {
|
|||
rect.y2,
|
||||
layer,
|
||||
net,
|
||||
Some(component_id),
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
|
|
@ -153,6 +157,7 @@ impl Board {
|
|||
path.width,
|
||||
layer,
|
||||
net,
|
||||
Some(component_id),
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
|
|
@ -167,6 +172,7 @@ impl Board {
|
|||
polygon.width,
|
||||
layer,
|
||||
net,
|
||||
Some(component_id),
|
||||
Some(pin_id),
|
||||
!place_side_is_front,
|
||||
)
|
||||
|
|
@ -197,6 +203,7 @@ impl Board {
|
|||
layer,
|
||||
net,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -213,6 +220,7 @@ impl Board {
|
|||
layer,
|
||||
net,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -227,6 +235,7 @@ impl Board {
|
|||
layer,
|
||||
net,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -241,6 +250,7 @@ impl Board {
|
|||
layer,
|
||||
net,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
@ -261,6 +271,7 @@ impl Board {
|
|||
layer,
|
||||
net,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
|
@ -275,6 +286,7 @@ impl Board {
|
|||
radius: u64,
|
||||
layer: usize,
|
||||
net: NetId,
|
||||
component: Option<ComponentId>,
|
||||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
|
|
@ -282,6 +294,7 @@ impl Board {
|
|||
position: Self::pos(place, pin_pos, 0.0, 0.0, flip),
|
||||
layer,
|
||||
net,
|
||||
component,
|
||||
pin,
|
||||
radius,
|
||||
});
|
||||
|
|
@ -297,6 +310,7 @@ impl Board {
|
|||
y2: f64,
|
||||
layer: usize,
|
||||
net: NetId,
|
||||
component: Option<ComponentId>,
|
||||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
|
|
@ -309,6 +323,7 @@ impl Board {
|
|||
],
|
||||
layer,
|
||||
net,
|
||||
component,
|
||||
pin,
|
||||
});
|
||||
}
|
||||
|
|
@ -321,6 +336,7 @@ impl Board {
|
|||
width: f64,
|
||||
layer: usize,
|
||||
net: NetId,
|
||||
component: Option<ComponentId>,
|
||||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
|
|
@ -331,6 +347,7 @@ impl Board {
|
|||
layer,
|
||||
radius: (width / 2.0) as u64,
|
||||
net,
|
||||
component,
|
||||
pin,
|
||||
});
|
||||
|
||||
|
|
@ -347,6 +364,7 @@ impl Board {
|
|||
layer,
|
||||
radius: (width / 2.0) as u64,
|
||||
net,
|
||||
component,
|
||||
pin,
|
||||
});
|
||||
|
||||
|
|
@ -355,6 +373,7 @@ impl Board {
|
|||
spec: SegmentSpec {
|
||||
endjoints: [prev_joint, joint],
|
||||
half_width: (width / 2.0) as u64,
|
||||
component,
|
||||
pin,
|
||||
},
|
||||
endpoints: [prev_pos, pos],
|
||||
|
|
@ -375,6 +394,7 @@ impl Board {
|
|||
_width: f64,
|
||||
layer: usize,
|
||||
net: NetId,
|
||||
component: Option<ComponentId>,
|
||||
pin: Option<PinId>,
|
||||
flip: bool,
|
||||
) {
|
||||
|
|
@ -386,6 +406,7 @@ impl Board {
|
|||
vertices,
|
||||
layer,
|
||||
net,
|
||||
component,
|
||||
pin,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue