Place joints, segments, polygons in R-trees

This commit is contained in:
Mikolaj Wielgus 2026-03-14 00:12:43 +01:00
parent ce5634ee6a
commit 7b5bffada8
3 changed files with 78 additions and 12 deletions

View File

@ -13,6 +13,7 @@ bimap = "0.6"
dearcut = { version = "0.1", features = ["undoredo"] } dearcut = { version = "0.1", features = ["undoredo"] }
derive-getters.workspace = true derive-getters.workspace = true
derive_more.workspace = true derive_more.workspace = true
rstar = "0.12"
serde.workspace = true serde.workspace = true
specctra = { path = "../specctra" } specctra = { path = "../specctra" }
stable-vec = "0.4" stable-vec = "0.4"

View File

@ -6,6 +6,10 @@ use std::collections::BTreeMap;
use derive_getters::{Dissolve, Getters}; use derive_getters::{Dissolve, Getters};
use derive_more::Constructor; use derive_more::Constructor;
use rstar::{
RTree,
primitives::{GeomWithData, Rectangle},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use stable_vec::StableVec; use stable_vec::StableVec;
use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder}; use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
@ -64,10 +68,16 @@ pub struct Layout {
layer_count: usize, layer_count: usize,
pins: StableVec<Pin>, pins: StableVec<Pin>,
joints: Recorder<StableVec<Joint>>, joints: Recorder<StableVec<Joint>>,
segments: Recorder<StableVec<Segment>>, segments: Recorder<StableVec<Segment>>,
vias: Recorder<StableVec<Via>>, vias: Recorder<StableVec<Via>>,
polygons: Recorder<StableVec<Polygon>>, polygons: Recorder<StableVec<Polygon>>,
joints_rtree: Recorder<RTree<GeomWithData<Rectangle<[i64; 3]>, JointId>>>,
segments_rtree: Recorder<RTree<GeomWithData<Rectangle<[i64; 3]>, SegmentId>>>,
vias_rtree: Recorder<RTree<GeomWithData<Rectangle<[i64; 3]>, ViaId>>>,
polygons_rtree: Recorder<RTree<GeomWithData<Rectangle<[i64; 3]>, PolygonId>>>,
} }
impl Layout { impl Layout {
@ -78,10 +88,16 @@ impl Layout {
layer_count, layer_count,
pins: StableVec::new(), pins: StableVec::new(),
joints: Recorder::new(StableVec::new()), joints: Recorder::new(StableVec::new()),
segments: Recorder::new(StableVec::new()), segments: Recorder::new(StableVec::new()),
vias: Recorder::new(StableVec::new()), vias: Recorder::new(StableVec::new()),
polygons: Recorder::new(StableVec::new()), polygons: Recorder::new(StableVec::new()),
joints_rtree: Recorder::new(RTree::new()),
segments_rtree: Recorder::new(RTree::new()),
vias_rtree: Recorder::new(RTree::new()),
polygons_rtree: Recorder::new(RTree::new()),
} }
} }
@ -90,9 +106,13 @@ impl Layout {
} }
pub fn add_joint(&mut self, joint: Joint) -> JointId { pub fn add_joint(&mut self, joint: Joint) -> JointId {
let bbox = joint.bbox();
let pin_id = joint.pin; let pin_id = joint.pin;
let joint_id = JointId::new(self.joints.push(joint)); let joint_id = JointId::new(self.joints.push(joint));
self.joints_rtree
.insert(GeomWithData::new(bbox, joint_id), ());
if let Some(pin_id) = pin_id { if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].joints.push(joint_id); self.pins[pin_id.id()].joints.push(joint_id);
} }
@ -103,6 +123,10 @@ impl Layout {
pub fn add_segment(&mut self, segment: Segment) -> SegmentId { pub fn add_segment(&mut self, segment: Segment) -> SegmentId {
let pin_id = segment.pin; let pin_id = segment.pin;
let segment_id = SegmentId::new(self.segments.push(segment)); let segment_id = SegmentId::new(self.segments.push(segment));
let bbox = self.segment_bbox(segment_id);
self.segments_rtree
.insert(GeomWithData::new(bbox, segment_id), ());
if let Some(pin_id) = pin_id { if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].segments.push(segment_id); self.pins[pin_id.id()].segments.push(segment_id);
@ -112,9 +136,12 @@ impl Layout {
} }
pub fn add_via(&mut self, via: Via) -> ViaId { pub fn add_via(&mut self, via: Via) -> ViaId {
//let bbox = via.bbox();
let pin_id = via.pin; let pin_id = via.pin;
let via_id = ViaId::new(self.vias.push(via)); let via_id = ViaId::new(self.vias.push(via));
//self.vias_rtree.insert(GeomWithData::new(bbox, via_id), ());
if let Some(pin_id) = pin_id { if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].vias.push(via_id); self.pins[pin_id.id()].vias.push(via_id);
} }
@ -123,9 +150,13 @@ impl Layout {
} }
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId { pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
let bbox = polygon.bbox();
let pin_id = polygon.pin; let pin_id = polygon.pin;
let polygon_id = PolygonId::new(self.polygons.push(polygon)); let polygon_id = PolygonId::new(self.polygons.push(polygon));
self.polygons_rtree
.insert(GeomWithData::new(bbox, polygon_id), ());
if let Some(pin_id) = pin_id { if let Some(pin_id) = pin_id {
self.pins[pin_id.id()].polygons.push(polygon_id); self.pins[pin_id.id()].polygons.push(polygon_id);
} }
@ -133,14 +164,27 @@ impl Layout {
polygon_id polygon_id
} }
pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] { pub fn segment_endpoints(&self, segment_id: SegmentId) -> [[i64; 2]; 2] {
let endjoints = self.segments.get(&segment.id()).unwrap().endjoints; let endjoints = self.segments.get(&segment_id.id()).unwrap().endjoints;
[ [
self.joints.get(&endjoints[0].id()).unwrap().position, self.joints.get(&endjoints[0].id()).unwrap().position,
self.joints.get(&endjoints[1].id()).unwrap().position, self.joints.get(&endjoints[1].id()).unwrap().position,
] ]
} }
pub fn segment_bbox(&self, segment_id: SegmentId) -> Rectangle<[i64; 3]> {
let endpoints = self.segment_endpoints(segment_id);
let layer = self.segments.get(&segment_id.id()).unwrap().layer as i64;
let half_width = self.segments.get(&segment_id.id()).unwrap().half_width as i64;
let min_x = std::cmp::min(endpoints[0][0], endpoints[1][0]) - half_width;
let min_y = std::cmp::min(endpoints[0][1], endpoints[1][1]) - half_width;
let max_x = std::cmp::max(endpoints[0][0], endpoints[1][0]) + half_width;
let max_y = std::cmp::max(endpoints[0][1], endpoints[1][1]) + half_width;
Rectangle::from_corners([min_x, min_y, layer], [max_x, max_y, layer])
}
pub fn pin(&self, pin: PinId) -> &Pin { pub fn pin(&self, pin: PinId) -> &Pin {
&self.pins[pin.id()] &self.pins[pin.id()]
} }

View File

@ -2,7 +2,8 @@
// //
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use derive_more::{Constructor, From}; use derive_more::Constructor;
use rstar::{AABB, Envelope, primitives::Rectangle};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -10,14 +11,6 @@ use crate::{
selection::PinSelector, selection::PinSelector,
}; };
#[derive(Clone, Copy, Debug, Deserialize, Eq, From, Ord, PartialEq, PartialOrd, Serialize)]
pub enum PrimitiveId {
Joint(JointId),
Segment(SegmentId),
Via(ViaId),
Polygon(PolygonId),
}
#[derive( #[derive(
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize, Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
)] )]
@ -41,6 +34,21 @@ pub struct Joint {
} }
impl Joint { impl Joint {
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
Rectangle::from_aabb(AABB::from_corners(
[
self.position[0] - self.radius as i64,
self.position[1] - self.radius as i64,
self.layer as i64,
],
[
self.position[0] + self.radius as i64,
self.position[1] + self.radius as i64,
self.layer as i64,
],
))
}
pub fn pin_selector(&self) -> Option<PinSelector> { pub fn pin_selector(&self) -> Option<PinSelector> {
Some(PinSelector { Some(PinSelector {
pin: self.pin?, pin: self.pin?,
@ -95,7 +103,7 @@ impl ViaId {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Via { pub struct Via {
pub endpoints: [JointId; 2], pub endjoints: [JointId; 2],
pub layer: usize, // ??? This should be a range. pub layer: usize, // ??? This should be a range.
pub radius: u64, pub radius: u64,
pub net: NetId, pub net: NetId,
@ -103,6 +111,10 @@ pub struct Via {
} }
impl Via { impl Via {
/*pub fn bbox(&self) -> Rectangle<[i64; 3]> {
//
}*/
pub fn pin_selector(&self) -> Option<PinSelector> { pub fn pin_selector(&self) -> Option<PinSelector> {
Some(PinSelector { Some(PinSelector {
pin: self.pin?, pin: self.pin?,
@ -133,6 +145,15 @@ pub struct Polygon {
} }
impl Polygon { impl Polygon {
pub fn bbox(&self) -> Rectangle<[i64; 3]> {
Rectangle::from_aabb(self.vertices.clone().into_iter().fold(
AABB::new_empty(),
|aabb, vertex| {
aabb.merged(&AABB::from_point([vertex[0], vertex[1], self.layer as i64]))
},
))
}
pub fn pin_selector(&self) -> Option<PinSelector> { pub fn pin_selector(&self) -> Option<PinSelector> {
Some(PinSelector { Some(PinSelector {
pin: self.pin?, pin: self.pin?,