use derive_more::{Constructor, From};
use serde::{Deserialize, Serialize};
use crate::{
layout::{
Layout,
compounds::{ComponentId, NetId},
primitives::{JointId, PolyId, PrimitiveId, SegId, ViaId},
},
vector::Vector2,
};
#[derive(
Clone,
Constructor,
Copy,
Debug,
Default,
Deserialize,
Eq,
From,
Ord,
PartialEq,
PartialOrd,
Serialize,
)]
pub struct PinId(usize);
impl PinId {
#[inline]
pub fn index(self) -> usize {
self.0
}
}
#[derive(Clone, Copy, Debug)]
pub struct PinSpec {
pub component: Option<ComponentId>,
pub net: Option<NetId>,
}
#[derive(Clone, Debug)]
pub struct Pin {
pub spec: PinSpec,
pub joints: Vec<JointId>,
pub segs: Vec<SegId>,
pub vias: Vec<ViaId>,
pub polys: Vec<PolyId>,
}
impl Pin {
pub fn new(spec: PinSpec) -> Self {
Pin {
spec,
joints: Vec::new(),
segs: Vec::new(),
vias: Vec::new(),
polys: Vec::new(),
}
}
pub fn primitives(&self) -> impl Iterator<Item = PrimitiveId> + '_ {
self.joints
.iter()
.map(|&joint_id| PrimitiveId::Joint(joint_id))
.chain(self.segs.iter().map(|&seg_id| PrimitiveId::Seg(seg_id)))
.chain(self.vias.iter().map(|&via_id| PrimitiveId::Via(via_id)))
.chain(self.polys.iter().map(|&poly_id| PrimitiveId::Poly(poly_id)))
}
}
impl Layout {
pub fn pin_centroid(&self, pin_id: PinId) -> Vector2<i64> {
crate::profile_function!();
let pin = self.pin(pin_id);
let mut sum = Vector2::new(0, 0);
let mut count = 0;
for &joint_id in &pin.joints {
sum = sum + self.joint(joint_id).center();
count += 1;
}
for &seg_id in &pin.segs {
sum = sum + self.seg(seg_id).center();
count += 1;
}
for &via_id in &pin.vias {
sum = sum + self.via(via_id).position;
count += 1;
}
for &poly_id in &pin.polys {
sum = sum + self.poly(poly_id).centroid;
count += 1;
}
if count == 0 {
return Vector2::new(0, 0);
}
let count = count as i64;
Vector2::new(sum.x / count, sum.y / count)
}
}