mirror of https://codeberg.org/topola/topola.git
Add methods to delete primitives and distribute some methods across new files
This commit is contained in:
parent
5a3a870a13
commit
623dc967ca
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use crate::{
|
||||
board::Board,
|
||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||
};
|
||||
|
||||
impl Board {
|
||||
pub fn delete_joint(&mut self, joint_id: JointId) {
|
||||
self.layout.delete_joint(joint_id);
|
||||
}
|
||||
|
||||
pub fn delete_segment(&mut self, segment_id: SegmentId) {
|
||||
self.layout.delete_segment(segment_id);
|
||||
}
|
||||
|
||||
pub fn delete_via(&mut self, via_id: ViaId) {
|
||||
self.layout.delete_via(via_id);
|
||||
}
|
||||
|
||||
pub fn delete_polygon(&mut self, polygon_id: PolygonId) {
|
||||
self.layout.delete_polygon(polygon_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use crate::{
|
||||
board::Board,
|
||||
layout::compounds::ComponentId,
|
||||
primitives::{
|
||||
JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
};
|
||||
|
||||
impl Board {
|
||||
pub fn insert_component(&mut self) -> ComponentId {
|
||||
self.layout.insert_component()
|
||||
}
|
||||
|
||||
pub fn insert_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
self.layout.insert_joint(spec)
|
||||
}
|
||||
|
||||
pub fn insert_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
self.layout.insert_segment(spec)
|
||||
}
|
||||
|
||||
pub fn insert_segment_raw(&mut self, segment: Segment) -> SegmentId {
|
||||
self.layout.insert_segment_raw(segment)
|
||||
}
|
||||
|
||||
pub fn insert_via(&mut self, spec: ViaSpec) -> ViaId {
|
||||
self.layout.insert_via(spec)
|
||||
}
|
||||
|
||||
pub fn insert_via_raw(&mut self, via: Via) -> ViaId {
|
||||
self.layout.insert_via_raw(via)
|
||||
}
|
||||
|
||||
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
self.layout.insert_polygon(polygon)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
mod delete;
|
||||
mod insert;
|
||||
pub mod interactors;
|
||||
mod layer;
|
||||
mod locate;
|
||||
|
|
@ -20,10 +22,6 @@ use crate::{
|
|||
layout::{
|
||||
LayerId, Layout, LayoutHalfDelta,
|
||||
compounds::{ComponentId, NetId, PinId},
|
||||
primitives::{
|
||||
JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
},
|
||||
math::Vector2,
|
||||
};
|
||||
|
|
@ -74,7 +72,7 @@ impl Board {
|
|||
return *component;
|
||||
};
|
||||
|
||||
let component_id = self.layout.add_component();
|
||||
let component_id = self.layout.insert_component();
|
||||
self.component_names.insert(component_id, component_name);
|
||||
|
||||
component_id
|
||||
|
|
@ -85,40 +83,12 @@ impl Board {
|
|||
return *pin;
|
||||
};
|
||||
|
||||
let pin_id = self.layout.add_pin();
|
||||
let pin_id = self.layout.insert_pin();
|
||||
self.pin_names.insert(pin_id, pin_name);
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
self.layout.add_segment(spec)
|
||||
}
|
||||
|
||||
pub fn add_segment_raw(&mut self, segment: Segment) -> SegmentId {
|
||||
self.layout.add_segment_raw(segment)
|
||||
}
|
||||
|
||||
pub fn add_via(&mut self, spec: ViaSpec) -> ViaId {
|
||||
self.layout.add_via(spec)
|
||||
}
|
||||
|
||||
pub fn add_via_raw(&mut self, via: Via) -> ViaId {
|
||||
self.layout.add_via_raw(via)
|
||||
}
|
||||
|
||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
self.layout.add_polygon(polygon)
|
||||
}
|
||||
|
||||
pub fn component_name(&self, id: ComponentId) -> Option<&str> {
|
||||
self.component_names.get_by_left(&id).map(String::as_str)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use rstar::primitives::GeomWithData;
|
||||
|
||||
use crate::{
|
||||
layout::Layout,
|
||||
primitives::{JointId, PolygonId, SegmentId, ViaId},
|
||||
};
|
||||
|
||||
impl Layout {
|
||||
pub fn delete_joint(&mut self, joint_id: JointId) {
|
||||
let joint = self.joint(joint_id);
|
||||
let bbox = joint.bbox();
|
||||
let component = joint.spec.component;
|
||||
let pin = joint.spec.pin;
|
||||
|
||||
if let Some(component_id) = component {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
if let Some(index) = component.joints.iter().position(|&curr| curr == joint_id) {
|
||||
component.joints.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin {
|
||||
self.pins.modify(pin_id.index(), |pin| {
|
||||
if let Some(index) = pin.joints.iter().position(|&curr| curr == joint_id) {
|
||||
pin.joints.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.joints_rtree.remove(&GeomWithData::new(bbox, joint_id));
|
||||
self.joints.remove(&joint_id.index());
|
||||
}
|
||||
|
||||
pub fn delete_segment(&mut self, segment_id: SegmentId) {
|
||||
let segment = self.segment(segment_id);
|
||||
let bbox = segment.bbox();
|
||||
let component = segment.spec.component;
|
||||
let pin = segment.spec.pin;
|
||||
|
||||
if let Some(component_id) = component {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
if let Some(index) = component
|
||||
.segments
|
||||
.iter()
|
||||
.position(|&curr| curr == segment_id)
|
||||
{
|
||||
component.segments.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin {
|
||||
self.pins.modify(pin_id.index(), |pin| {
|
||||
if let Some(index) = pin.segments.iter().position(|&curr| curr == segment_id) {
|
||||
pin.segments.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.segments_rtree
|
||||
.remove(&GeomWithData::new(bbox, segment_id));
|
||||
self.segments.remove(&segment_id.index());
|
||||
}
|
||||
|
||||
pub fn delete_via(&mut self, via_id: ViaId) {
|
||||
let via = self.via(via_id);
|
||||
let bbox = via.bbox();
|
||||
let component = via.spec.component;
|
||||
let pin = via.spec.pin;
|
||||
|
||||
if let Some(component_id) = component {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
if let Some(index) = component.vias.iter().position(|&curr| curr == via_id) {
|
||||
component.vias.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin {
|
||||
self.pins.modify(pin_id.index(), |pin| {
|
||||
if let Some(index) = pin.vias.iter().position(|&curr| curr == via_id) {
|
||||
pin.vias.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.vias_rtree.remove(&GeomWithData::new(bbox, via_id));
|
||||
self.vias.remove(&via_id.index());
|
||||
}
|
||||
|
||||
pub fn delete_polygon(&mut self, polygon_id: PolygonId) {
|
||||
let polygon = self.polygon(polygon_id);
|
||||
let bbox = polygon.bbox();
|
||||
let component = polygon.component;
|
||||
let pin = polygon.pin;
|
||||
|
||||
if let Some(component_id) = component {
|
||||
self.components.modify(component_id.index(), |component| {
|
||||
if let Some(index) = component
|
||||
.polygons
|
||||
.iter()
|
||||
.position(|&curr| curr == polygon_id)
|
||||
{
|
||||
component.polygons.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(pin_id) = pin {
|
||||
self.pins.modify(pin_id.index(), |pin| {
|
||||
if let Some(index) = pin.polygons.iter().position(|&curr| curr == polygon_id) {
|
||||
pin.polygons.remove(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.polygons_rtree
|
||||
.remove(&GeomWithData::new(bbox, polygon_id));
|
||||
self.polygons.remove(&polygon_id.index());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use rstar::primitives::GeomWithData;
|
||||
|
||||
use crate::{
|
||||
Pin, PinId,
|
||||
layout::{
|
||||
Layout,
|
||||
compounds::{Component, ComponentId},
|
||||
},
|
||||
primitives::{
|
||||
Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
};
|
||||
|
||||
impl Layout {
|
||||
pub fn insert_component(&mut self) -> ComponentId {
|
||||
ComponentId::new(self.components.push(Component::new()))
|
||||
}
|
||||
|
||||
pub fn insert_pin(&mut self) -> PinId {
|
||||
PinId::new(self.pins.push(Pin::new()))
|
||||
}
|
||||
|
||||
pub fn insert_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
let joint = Joint {
|
||||
spec,
|
||||
segments: Vec::new(),
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.joints.push(joint_id));
|
||||
}
|
||||
|
||||
joint_id
|
||||
}
|
||||
|
||||
pub fn insert_segment(&mut self, spec: SegmentSpec) -> SegmentId {
|
||||
self.insert_segment_raw(Segment {
|
||||
spec,
|
||||
endpoints: [
|
||||
self.joint(spec.endjoints[0]).spec.position,
|
||||
self.joint(spec.endjoints[1]).spec.position,
|
||||
],
|
||||
layer: self.joint(spec.endjoints[0]).spec.layer,
|
||||
net: self.joint(spec.endjoints[0]).spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert_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));
|
||||
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[0].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[1].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.segments.push(segment_id));
|
||||
}
|
||||
|
||||
segment_id
|
||||
}
|
||||
|
||||
pub fn insert_via(&mut self, spec: ViaSpec) -> ViaId {
|
||||
let joints = [self.joint(spec.endjoints[0]), self.joint(spec.endjoints[1])];
|
||||
|
||||
self.insert_via_raw(Via {
|
||||
spec,
|
||||
position: joints[0].spec.position,
|
||||
min_layer: std::cmp::min(joints[0].spec.layer, joints[1].spec.layer),
|
||||
max_layer: std::cmp::max(joints[0].spec.layer, joints[1].spec.layer),
|
||||
net: joints[0].spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert_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));
|
||||
|
||||
self.joints.modify(via.spec.endjoints[0].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
self.joints.modify(via.spec.endjoints[1].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.vias.push(via_id));
|
||||
}
|
||||
|
||||
via_id
|
||||
}
|
||||
|
||||
pub fn insert_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
|
||||
.modify(pin_id.index(), |pin| pin.polygons.push(polygon_id));
|
||||
}
|
||||
|
||||
polygon_id
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,10 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
pub mod compounds;
|
||||
mod delete;
|
||||
mod insert;
|
||||
mod locate;
|
||||
mod modify;
|
||||
pub mod primitives;
|
||||
mod transforms;
|
||||
|
||||
|
|
@ -19,11 +22,8 @@ use undoredo::aliases::RTreeHalfDelta;
|
|||
use undoredo::{Delta, Recorder};
|
||||
|
||||
use crate::{
|
||||
layout::compounds::{Component, ComponentId, Pin, PinId},
|
||||
layout::primitives::{
|
||||
Joint, JointId, JointSpec, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId,
|
||||
ViaSpec,
|
||||
},
|
||||
layout::compounds::{Component, Pin, PinId},
|
||||
layout::primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
|
|
@ -106,270 +106,6 @@ 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()))
|
||||
}
|
||||
|
||||
pub fn add_joint(&mut self, spec: JointSpec) -> JointId {
|
||||
let joint = Joint {
|
||||
spec,
|
||||
segments: Vec::new(),
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.joints.push(joint_id));
|
||||
}
|
||||
|
||||
joint_id
|
||||
}
|
||||
|
||||
pub fn modify_joint<F>(&mut self, id: JointId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut JointSpec),
|
||||
{
|
||||
self.modify_joint_raw(id, |joint| f(&mut joint.spec));
|
||||
let new_joint = self.joints[id.index()].clone();
|
||||
|
||||
for &segment_id in &new_joint.segments {
|
||||
self.update_segment(segment_id);
|
||||
}
|
||||
|
||||
for &via_id in &new_joint.vias {
|
||||
self.update_via(via_id);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
endpoints: [
|
||||
self.joint(spec.endjoints[0]).spec.position,
|
||||
self.joint(spec.endjoints[1]).spec.position,
|
||||
],
|
||||
layer: self.joint(spec.endjoints[0]).spec.layer,
|
||||
net: self.joint(spec.endjoints[0]).spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[0].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
self.joints
|
||||
.modify(segment.spec.endjoints[1].index(), |joint| {
|
||||
joint.segments.push(segment_id)
|
||||
});
|
||||
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.segments.push(segment_id));
|
||||
}
|
||||
|
||||
segment_id
|
||||
}
|
||||
|
||||
pub fn modify_segment<F>(&mut self, id: SegmentId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut SegmentSpec),
|
||||
{
|
||||
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[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_segment(&mut self, id: SegmentId) {
|
||||
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[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];
|
||||
segment.layer = endjoint_specs[0].layer;
|
||||
segment.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn add_via(&mut self, spec: ViaSpec) -> ViaId {
|
||||
let joints = [self.joint(spec.endjoints[0]), self.joint(spec.endjoints[1])];
|
||||
|
||||
self.add_via_raw(Via {
|
||||
spec,
|
||||
position: joints[0].spec.position,
|
||||
min_layer: std::cmp::min(joints[0].spec.layer, joints[1].spec.layer),
|
||||
max_layer: std::cmp::max(joints[0].spec.layer, joints[1].spec.layer),
|
||||
net: joints[0].spec.net,
|
||||
})
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
self.joints.modify(via.spec.endjoints[0].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
self.joints.modify(via.spec.endjoints[1].index(), |joint| {
|
||||
joint.vias.push(via_id)
|
||||
});
|
||||
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.vias.push(via_id));
|
||||
}
|
||||
|
||||
via_id
|
||||
}
|
||||
|
||||
pub fn modify_via<F>(&mut self, id: ViaId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut ViaSpec),
|
||||
{
|
||||
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[id.index()];
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
fn update_via(&mut self, id: ViaId) {
|
||||
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[endjoint_ids[0].index()].spec,
|
||||
self.joints[endjoint_ids[1].index()].spec,
|
||||
];
|
||||
self.vias.modify(id.index(), |via| {
|
||||
via.position = endjoint_specs[0].position;
|
||||
via.min_layer = std::cmp::min(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.max_layer = std::cmp::max(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
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
|
||||
.modify(pin_id.index(), |pin| pin.polygons.push(polygon_id));
|
||||
}
|
||||
|
||||
polygon_id
|
||||
}
|
||||
|
||||
pub fn modify_polygon<F>(&mut self, id: PolygonId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Polygon),
|
||||
{
|
||||
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[id.index()];
|
||||
self.polygons_rtree
|
||||
.insert(GeomWithData::new(new_polygon.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn layer_joints(&self, layer: LayerId) -> impl Iterator<Item = JointId> + '_ {
|
||||
let envelope = Self::whole_layer_aabb(layer);
|
||||
self.joints_rtree
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
// SPDX-FileCopyrightText: 2026 Topola contributors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use rstar::primitives::GeomWithData;
|
||||
|
||||
use crate::{
|
||||
layout::Layout,
|
||||
primitives::{
|
||||
Joint, JointId, JointSpec, Polygon, PolygonId, SegmentId, SegmentSpec, ViaId, ViaSpec,
|
||||
},
|
||||
};
|
||||
|
||||
impl Layout {
|
||||
pub fn modify_joint<F>(&mut self, id: JointId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut JointSpec),
|
||||
{
|
||||
self.modify_joint_raw(id, |joint| f(&mut joint.spec));
|
||||
let new_joint = self.joints[id.index()].clone();
|
||||
|
||||
for &segment_id in &new_joint.segments {
|
||||
self.update_segment(segment_id);
|
||||
}
|
||||
|
||||
for &via_id in &new_joint.vias {
|
||||
self.update_via(via_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) 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 modify_segment<F>(&mut self, id: SegmentId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut SegmentSpec),
|
||||
{
|
||||
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[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub(super) fn update_segment(&mut self, id: SegmentId) {
|
||||
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[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];
|
||||
segment.layer = endjoint_specs[0].layer;
|
||||
segment.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_segment = &self.segments[id.index()];
|
||||
self.segments_rtree
|
||||
.insert(GeomWithData::new(new_segment.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn modify_via<F>(&mut self, id: ViaId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut ViaSpec),
|
||||
{
|
||||
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[id.index()];
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub(super) fn update_via(&mut self, id: ViaId) {
|
||||
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[endjoint_ids[0].index()].spec,
|
||||
self.joints[endjoint_ids[1].index()].spec,
|
||||
];
|
||||
self.vias.modify(id.index(), |via| {
|
||||
via.position = endjoint_specs[0].position;
|
||||
via.min_layer = std::cmp::min(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.max_layer = std::cmp::max(endjoint_specs[0].layer, endjoint_specs[1].layer);
|
||||
via.net = endjoint_specs[0].net;
|
||||
});
|
||||
|
||||
let new_via = &self.vias[id.index()];
|
||||
self.vias_rtree
|
||||
.insert(GeomWithData::new(new_via.bbox(), id), ());
|
||||
}
|
||||
|
||||
pub fn modify_polygon<F>(&mut self, id: PolygonId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Polygon),
|
||||
{
|
||||
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[id.index()];
|
||||
self.polygons_rtree
|
||||
.insert(GeomWithData::new(new_polygon.bbox(), id), ());
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ impl NavmesherBoard {
|
|||
segments: Vec::new(),
|
||||
vias: Vec::new(),
|
||||
});
|
||||
let joint_id = self.board.add_joint(spec);
|
||||
let joint_id = self.board.insert_joint(spec);
|
||||
self.joint_multiobstacles.insert(
|
||||
joint_id.index(),
|
||||
self.navmesher.insert_multiobstacle(layer, obstacle),
|
||||
|
|
@ -281,7 +281,7 @@ impl NavmesherBoard {
|
|||
pub fn insert_segment_with_cache(&mut self, segment: Segment) -> SegmentId {
|
||||
let layer = segment.layer;
|
||||
let obstacle = segment.bounding_rectangle();
|
||||
let segment_id = self.board.add_segment_raw(segment);
|
||||
let segment_id = self.board.insert_segment_raw(segment);
|
||||
self.segment_multiobstacles.insert(
|
||||
segment_id.index(),
|
||||
self.navmesher.insert_multiobstacle(layer, obstacle),
|
||||
|
|
@ -291,7 +291,7 @@ impl NavmesherBoard {
|
|||
}
|
||||
|
||||
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||
let polygon_id = self.board.add_polygon(polygon.clone());
|
||||
let polygon_id = self.board.insert_polygon(polygon.clone());
|
||||
self.polygon_multiobstacles.insert(
|
||||
polygon_id.index(),
|
||||
self.navmesher
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ impl Board {
|
|||
flip: bool,
|
||||
coordinate_scale: f64,
|
||||
) {
|
||||
board.add_joint(JointSpec {
|
||||
board.insert_joint(JointSpec {
|
||||
position: Self::pos(place, pin_pos, 0.0, 0.0, flip, coordinate_scale),
|
||||
layer,
|
||||
net,
|
||||
|
|
@ -381,7 +381,7 @@ impl Board {
|
|||
flip: bool,
|
||||
coordinate_scale: f64,
|
||||
) {
|
||||
board.add_polygon(Polygon {
|
||||
board.insert_polygon(Polygon {
|
||||
vertices: vec![
|
||||
Self::pos(place, pin_pos, x1, y1, flip, coordinate_scale),
|
||||
Self::pos(place, pin_pos, x2, y1, flip, coordinate_scale),
|
||||
|
|
@ -416,7 +416,7 @@ impl Board {
|
|||
flip,
|
||||
coordinate_scale,
|
||||
);
|
||||
let mut prev_joint = board.add_joint(JointSpec {
|
||||
let mut prev_joint = board.insert_joint(JointSpec {
|
||||
position: prev_pos,
|
||||
layer,
|
||||
radius: Self::scale_size(width / 2.0, coordinate_scale),
|
||||
|
|
@ -432,7 +432,7 @@ impl Board {
|
|||
continue;
|
||||
}
|
||||
|
||||
let joint = board.add_joint(JointSpec {
|
||||
let joint = board.insert_joint(JointSpec {
|
||||
position: pos,
|
||||
layer,
|
||||
radius: Self::scale_size(width / 2.0, coordinate_scale),
|
||||
|
|
@ -441,7 +441,7 @@ impl Board {
|
|||
pin,
|
||||
});
|
||||
|
||||
let _ = board.add_segment_raw(Segment {
|
||||
let _ = board.insert_segment_raw(Segment {
|
||||
spec: SegmentSpec {
|
||||
endjoints: [prev_joint, joint],
|
||||
half_width: Self::scale_size(width / 2.0, coordinate_scale),
|
||||
|
|
@ -475,7 +475,7 @@ impl Board {
|
|||
.iter()
|
||||
.map(|coord| Self::pos(place, pin_pos, coord.x, coord.y, flip, coordinate_scale))
|
||||
.collect();
|
||||
board.add_polygon(Polygon {
|
||||
board.insert_polygon(Polygon {
|
||||
vertices,
|
||||
layer,
|
||||
net,
|
||||
|
|
|
|||
Loading…
Reference in New Issue