From 272bdb326dc66edd31076a1fea35fbba6b0682b1 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 17 May 2026 03:01:59 +0200 Subject: [PATCH] Split `Via` into input `ViaSpec` and actually stored `Via` --- topola/src/board.rs | 12 ++++++++--- topola/src/layout.rs | 37 +++++++++++++++++++++----------- topola/src/navmesher.rs | 4 ++-- topola/src/primitives/mod.rs | 2 +- topola/src/primitives/segment.rs | 6 ++++-- topola/src/primitives/via.rs | 36 +++++++++++++++++++++++++------ 6 files changed, 70 insertions(+), 27 deletions(-) diff --git a/topola/src/board.rs b/topola/src/board.rs index 0c5a92b..2c571b2 100644 --- a/topola/src/board.rs +++ b/topola/src/board.rs @@ -9,7 +9,9 @@ use undoredo::{ApplyDelta, Delta, FlushDelta}; use crate::{ layout::{Layout, LayoutHalfDelta, NetId, PinId}, math::Vector2, - primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId}, + primitives::{ + Joint, JointId, Polygon, PolygonId, Segment, SegmentId, SegmentSpec, Via, ViaId, ViaSpec, + }, selection::{PinSelection, PinSelector}, }; @@ -71,8 +73,12 @@ impl Board { self.layout.add_segment_raw(segment) } - pub fn add_via(&mut self, via: Via) -> ViaId { - self.layout.add_via(via) + 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 { diff --git a/topola/src/layout.rs b/topola/src/layout.rs index 6a0d7ce..3f2876e 100644 --- a/topola/src/layout.rs +++ b/topola/src/layout.rs @@ -16,7 +16,7 @@ use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder}; use crate::{ Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2, Via, ViaId, - primitives::SegmentSpec, + primitives::{SegmentSpec, ViaSpec}, }; #[derive( @@ -123,21 +123,21 @@ impl Layout { joint_id } - pub fn add_segment(&mut self, segment: SegmentSpec) -> SegmentId { + pub fn add_segment(&mut self, spec: SegmentSpec) -> SegmentId { self.add_segment_raw(Segment { - spec: segment, + spec, endpoints: [ - self.joint(segment.endjoints[0]).position, - self.joint(segment.endjoints[1]).position, + self.joint(spec.endjoints[0]).position, + self.joint(spec.endjoints[1]).position, ], - layer: self.joint(segment.endjoints[0]).layer, - net: self.joint(segment.endjoints[0]).net, + layer: self.joint(spec.endjoints[0]).layer, + net: self.joint(spec.endjoints[0]).net, }) } pub fn add_segment_raw(&mut self, segment: Segment) -> SegmentId { let pin_id = segment.spec.pin; - let bbox = segment.rtree_bbox(); + let bbox = segment.bbox(); let segment_id = SegmentId::new(self.segments.push(segment)); self.segments_rtree @@ -150,12 +150,25 @@ impl Layout { segment_id } - pub fn add_via(&mut self, via: Via) -> ViaId { - //let bbox = via.bbox(); - let pin_id = via.pin; + pub fn add_via(&mut self, spec: ViaSpec) -> ViaId { + let joint0 = self.joint(spec.endjoints[0]); + let joint1 = self.joint(spec.endjoints[1]); + + self.add_via_raw(Via { + spec, + min_layer: std::cmp::min(joint0.layer, joint1.layer), + max_layer: std::cmp::max(joint0.layer, joint1.layer), + net: joint0.net, + position: (joint0.position + joint1.position) / 2, + }) + } + + pub fn add_via_raw(&mut self, via: Via) -> ViaId { + let bbox = via.bbox(); + let pin_id = via.spec.pin; let via_id = ViaId::new(self.vias.push(via)); - //self.vias_rtree.insert(GeomWithData::new(bbox, via_id), ()); + self.vias_rtree.insert(GeomWithData::new(bbox, via_id), ()); if let Some(pin_id) = pin_id { self.pins[pin_id.index()].vias.push(via_id); diff --git a/topola/src/navmesher.rs b/topola/src/navmesher.rs index 3400769..cceb41a 100644 --- a/topola/src/navmesher.rs +++ b/topola/src/navmesher.rs @@ -211,7 +211,7 @@ impl NavmesherBoard { this.segment_multiobstacles.insert( i, this.navmesher - .insert_multiobstacle(segment.layer, segment.bbox()), + .insert_multiobstacle(segment.layer, segment.bounding_rectangle()), ); } @@ -256,7 +256,7 @@ impl NavmesherBoard { pub fn insert_segment_with_cache(&mut self, segment: Segment) -> SegmentId { let layer = segment.layer; - let obstacle = segment.bbox(); + let obstacle = segment.bounding_rectangle(); let segment_id = self.board.add_segment_raw(segment); self.segment_multiobstacles.insert( segment_id.index(), diff --git a/topola/src/primitives/mod.rs b/topola/src/primitives/mod.rs index 6eef915..5d56de0 100644 --- a/topola/src/primitives/mod.rs +++ b/topola/src/primitives/mod.rs @@ -12,7 +12,7 @@ mod via; pub use joint::{Joint, JointId}; pub use polygon::{Polygon, PolygonId}; pub use segment::{Segment, SegmentId, SegmentSpec}; -pub use via::{Via, ViaId}; +pub use via::{Via, ViaId, ViaSpec}; #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub enum PrimitiveId { diff --git a/topola/src/primitives/segment.rs b/topola/src/primitives/segment.rs index 4b1c711..64e80b1 100644 --- a/topola/src/primitives/segment.rs +++ b/topola/src/primitives/segment.rs @@ -54,7 +54,9 @@ impl Segment { point.inside_polygon(&vertices) } - pub fn bbox(&self) -> [Vector2; 4] { + /// NOTE: This is not the bounding box. The output rectangle is in general + /// not axis-aligned. + pub fn bounding_rectangle(&self) -> [Vector2; 4] { crate::math::inflated_segment( self.endpoints[0].x, self.endpoints[0].y, @@ -64,7 +66,7 @@ impl Segment { ) } - pub fn rtree_bbox(&self) -> Rectangle<[i64; 3]> { + pub fn bbox(&self) -> Rectangle<[i64; 3]> { let endpoints = self.endpoints; let layer = self.layer as i64; let half_width = self.spec.half_width as i64; diff --git a/topola/src/primitives/via.rs b/topola/src/primitives/via.rs index 3c4387c..70236ec 100644 --- a/topola/src/primitives/via.rs +++ b/topola/src/primitives/via.rs @@ -3,9 +3,11 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use derive_more::Constructor; +use rstar::{AABB, primitives::Rectangle}; use serde::{Deserialize, Serialize}; use crate::layout::{NetId, PinId}; +use crate::math::Vector2; use super::joint::JointId; @@ -23,16 +25,36 @@ impl ViaId { } #[derive(Clone, Copy, Debug)] -pub struct Via { +pub struct ViaSpec { pub endjoints: [JointId; 2], - pub layer: usize, // ??? This should be a range. pub radius: u64, - pub net: NetId, pub pin: Option, } -impl Via { - /*pub fn bbox(&self) -> Rectangle<[i64; 3]> { - // - }*/ +#[derive(Clone, Copy, Debug)] +pub struct Via { + pub spec: ViaSpec, + pub position: Vector2, + pub min_layer: usize, + pub max_layer: usize, + pub net: NetId, +} + +impl Via { + pub fn bbox(&self) -> Rectangle<[i64; 3]> { + let radius = self.spec.radius as i64; + + Rectangle::from_aabb(AABB::from_corners( + [ + self.position.x - radius, + self.position.y - radius, + self.min_layer as i64, + ], + [ + self.position.x + radius, + self.position.y + radius, + self.max_layer as i64, + ], + )) + } }