Split `Via` into input `ViaSpec` and actually stored `Via`

This commit is contained in:
Mikolaj Wielgus 2026-05-17 03:01:59 +02:00
parent 258b43267d
commit 272bdb326d
6 changed files with 70 additions and 27 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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(),

View File

@ -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 {

View File

@ -54,7 +54,9 @@ impl Segment {
point.inside_polygon(&vertices)
}
pub fn bbox(&self) -> [Vector2<i64>; 4] {
/// NOTE: This is not the bounding box. The output rectangle is in general
/// not axis-aligned.
pub fn bounding_rectangle(&self) -> [Vector2<i64>; 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;

View File

@ -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<PinId>,
}
impl Via {
/*pub fn bbox(&self) -> Rectangle<[i64; 3]> {
//
}*/
#[derive(Clone, Copy, Debug)]
pub struct Via {
pub spec: ViaSpec,
pub position: Vector2<i64>,
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,
],
))
}
}