From 623dc967cacb8e05dad295a73201a551dbd49dec Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 27 May 2026 03:28:48 +0200 Subject: [PATCH] Add methods to delete primitives and distribute some methods across new files --- topola/src/board/delete.rs | 26 ++++ topola/src/board/insert.rs | 42 ++++++ topola/src/board/mod.rs | 38 +---- topola/src/layout/delete.rs | 126 +++++++++++++++++ topola/src/layout/insert.rs | 163 +++++++++++++++++++++ topola/src/layout/mod.rs | 274 +----------------------------------- topola/src/layout/modify.rs | 134 ++++++++++++++++++ topola/src/navmesher.rs | 6 +- topola/src/specctra.rs | 12 +- 9 files changed, 509 insertions(+), 312 deletions(-) create mode 100644 topola/src/board/delete.rs create mode 100644 topola/src/board/insert.rs create mode 100644 topola/src/layout/delete.rs create mode 100644 topola/src/layout/insert.rs create mode 100644 topola/src/layout/modify.rs diff --git a/topola/src/board/delete.rs b/topola/src/board/delete.rs new file mode 100644 index 0000000..e6ac40c --- /dev/null +++ b/topola/src/board/delete.rs @@ -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); + } +} diff --git a/topola/src/board/insert.rs b/topola/src/board/insert.rs new file mode 100644 index 0000000..245ecd3 --- /dev/null +++ b/topola/src/board/insert.rs @@ -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) + } +} diff --git a/topola/src/board/mod.rs b/topola/src/board/mod.rs index 9f4e2ce..acdb928 100644 --- a/topola/src/board/mod.rs +++ b/topola/src/board/mod.rs @@ -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) } diff --git a/topola/src/layout/delete.rs b/topola/src/layout/delete.rs new file mode 100644 index 0000000..3f369ff --- /dev/null +++ b/topola/src/layout/delete.rs @@ -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()); + } +} diff --git a/topola/src/layout/insert.rs b/topola/src/layout/insert.rs new file mode 100644 index 0000000..cf0da53 --- /dev/null +++ b/topola/src/layout/insert.rs @@ -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 + } +} diff --git a/topola/src/layout/mod.rs b/topola/src/layout/mod.rs index 753f1e4..a5e2ed3 100644 --- a/topola/src/layout/mod.rs +++ b/topola/src/layout/mod.rs @@ -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(&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(&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(&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(&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(&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 + '_ { let envelope = Self::whole_layer_aabb(layer); self.joints_rtree diff --git a/topola/src/layout/modify.rs b/topola/src/layout/modify.rs new file mode 100644 index 0000000..5132319 --- /dev/null +++ b/topola/src/layout/modify.rs @@ -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(&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(&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(&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(&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(&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), ()); + } +} diff --git a/topola/src/navmesher.rs b/topola/src/navmesher.rs index f6f1f6c..727b900 100644 --- a/topola/src/navmesher.rs +++ b/topola/src/navmesher.rs @@ -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 diff --git a/topola/src/specctra.rs b/topola/src/specctra.rs index 193dbd5..ab1309d 100644 --- a/topola/src/specctra.rs +++ b/topola/src/specctra.rs @@ -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,