layout: keep track of node pins

For the time being we're storing pin names in a hashmap with nodes as
keys. We need to know which node belongs to which pin because pins
provide stable identifiers for continents (connected components) that
we need for replayable command files.
This commit is contained in:
Mikolaj Wielgus 2024-05-17 02:22:48 +02:00
parent 84a1842f3d
commit 530f81557a
3 changed files with 103 additions and 29 deletions

View File

@ -89,7 +89,7 @@ impl Ratsnest {
for node in layout.drawing().layer_primitive_nodes(layer) { for node in layout.drawing().layer_primitive_nodes(layer) {
match node { match node {
PrimitiveIndex::FixedDot(dot) => { PrimitiveIndex::FixedDot(dot) => {
if layout.compounds(dot).next().is_none() { if layout.zones(dot).next().is_none() {
if let Some(net) = layout.drawing().primitive(dot).maybe_net() { if let Some(net) = layout.drawing().primitive(dot).maybe_net() {
if !triangulations.contains_key(&(layer, net)) { if !triangulations.contains_key(&(layer, net)) {
triangulations.insert( triangulations.insert(

View File

@ -106,6 +106,7 @@ impl DsnDesign {
circle.diameter as f64 / 2.0, circle.diameter as f64 / 2.0,
layer as u64, layer as u64,
*net_id, *net_id,
Some(pin_name.clone()),
) )
} }
Shape::Rect(rect) => { Shape::Rect(rect) => {
@ -127,6 +128,7 @@ impl DsnDesign {
rect.y2 as f64, rect.y2 as f64,
layer as u64, layer as u64,
*net_id, *net_id,
Some(pin_name.clone()),
) )
} }
Shape::Path(path) => { Shape::Path(path) => {
@ -146,6 +148,7 @@ impl DsnDesign {
path.width as f64, path.width as f64,
layer as u64, layer as u64,
*net_id, *net_id,
Some(pin_name.clone()),
) )
} }
Shape::Polygon(polygon) => { Shape::Polygon(polygon) => {
@ -165,6 +168,7 @@ impl DsnDesign {
polygon.width as f64, polygon.width as f64,
layer as u64, layer as u64,
*net_id, *net_id,
Some(pin_name.clone()),
) )
} }
}; };
@ -203,6 +207,7 @@ impl DsnDesign {
circle.diameter as f64 / 2.0, circle.diameter as f64 / 2.0,
layer as u64, layer as u64,
net_id, net_id,
None,
) )
} }
Shape::Rect(rect) => { Shape::Rect(rect) => {
@ -224,6 +229,7 @@ impl DsnDesign {
rect.y2 as f64, rect.y2 as f64,
layer as u64, layer as u64,
net_id, net_id,
None,
) )
} }
Shape::Path(path) => { Shape::Path(path) => {
@ -243,6 +249,7 @@ impl DsnDesign {
path.width as f64, path.width as f64,
layer as u64, layer as u64,
net_id, net_id,
None,
) )
} }
Shape::Polygon(polygon) => { Shape::Polygon(polygon) => {
@ -262,6 +269,7 @@ impl DsnDesign {
polygon.width as f64, polygon.width as f64,
layer as u64, layer as u64,
net_id, net_id,
None,
) )
} }
}; };
@ -287,6 +295,7 @@ impl DsnDesign {
wire.path.width as f64, wire.path.width as f64,
layer_id as u64, layer_id as u64,
net_id, net_id,
None,
); );
} }
@ -317,6 +326,7 @@ impl DsnDesign {
r: f64, r: f64,
layer: u64, layer: u64,
net: usize, net: usize,
maybe_pin: Option<String>,
) { ) {
let circle = Circle { let circle = Circle {
pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, 0.0, 0.0), pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, 0.0, 0.0),
@ -324,11 +334,14 @@ impl DsnDesign {
}; };
layout layout
.add_fixed_dot(FixedDotWeight { .add_fixed_dot(
FixedDotWeight {
circle, circle,
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}) },
maybe_pin.clone(),
)
.unwrap(); .unwrap();
} }
@ -344,13 +357,15 @@ impl DsnDesign {
y2: f64, y2: f64,
layer: u64, layer: u64,
net: usize, net: usize,
maybe_pin: Option<String>,
) { ) {
let zone = layout.add_compound( let zone = layout.add_zone(
SolidZoneWeight { SolidZoneWeight {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
} }
.into(), .into(),
maybe_pin.clone(),
); );
// Corners. // Corners.
@ -467,6 +482,7 @@ impl DsnDesign {
width: f64, width: f64,
layer: u64, layer: u64,
net: usize, net: usize,
maybe_pin: Option<String>,
) { ) {
// add the first coordinate in the wire path as a dot and save its index // add the first coordinate in the wire path as a dot and save its index
let mut prev_pos = Self::pos( let mut prev_pos = Self::pos(
@ -478,14 +494,17 @@ impl DsnDesign {
coords[0].y as f64, coords[0].y as f64,
); );
let mut prev_index = layout let mut prev_index = layout
.add_fixed_dot(FixedDotWeight { .add_fixed_dot(
FixedDotWeight {
circle: Circle { circle: Circle {
pos: prev_pos, pos: prev_pos,
r: width / 2.0, r: width / 2.0,
}, },
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}) },
maybe_pin.clone(),
)
.unwrap(); .unwrap();
// iterate through path coords starting from the second // iterate through path coords starting from the second
@ -504,14 +523,17 @@ impl DsnDesign {
} }
let index = layout let index = layout
.add_fixed_dot(FixedDotWeight { .add_fixed_dot(
FixedDotWeight {
circle: Circle { circle: Circle {
pos, pos,
r: width / 2.0, r: width / 2.0,
}, },
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}) },
maybe_pin.clone(),
)
.unwrap(); .unwrap();
// add a seg between the current and previous coords // add a seg between the current and previous coords
@ -524,6 +546,7 @@ impl DsnDesign {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
}, },
maybe_pin.clone(),
) )
.unwrap(); .unwrap();
@ -542,13 +565,15 @@ impl DsnDesign {
width: f64, width: f64,
layer: u64, layer: u64,
net: usize, net: usize,
maybe_pin: Option<String>,
) { ) {
let zone = layout.add_compound( let zone = layout.add_zone(
SolidZoneWeight { SolidZoneWeight {
layer, layer,
maybe_net: Some(net), maybe_net: Some(net),
} }
.into(), .into(),
maybe_pin.clone(),
); );
// add the first coordinate in the wire path as a dot and save its index // add the first coordinate in the wire path as a dot and save its index

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use geo::Point; use geo::Point;
use petgraph::stable_graph::StableDiGraph; use petgraph::stable_graph::StableDiGraph;
use rstar::AABB; use rstar::AABB;
@ -31,11 +33,15 @@ pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)] #[derive(Debug)]
pub struct Layout<R: RulesTrait> { pub struct Layout<R: RulesTrait> {
drawing: Drawing<ZoneWeight, R>, drawing: Drawing<ZoneWeight, R>,
node_to_pin: HashMap<NodeIndex, String>,
} }
impl<R: RulesTrait> Layout<R> { impl<R: RulesTrait> Layout<R> {
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self { pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
Self { drawing } Self {
drawing,
node_to_pin: HashMap::new(),
}
} }
pub fn remove_band(&mut self, band: BandIndex) { pub fn remove_band(&mut self, band: BandIndex) {
@ -59,8 +65,19 @@ impl<R: RulesTrait> Layout<R> {
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw) .insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
} }
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> { pub fn add_fixed_dot(
self.drawing.add_fixed_dot(weight) &mut self,
weight: FixedDotWeight,
maybe_pin: Option<String>,
) -> Result<FixedDotIndex, Infringement> {
let dot = self.drawing.add_fixed_dot(weight)?;
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(dot.into()), pin);
}
Ok(dot)
} }
pub fn add_zone_fixed_dot( pub fn add_zone_fixed_dot(
@ -68,6 +85,7 @@ impl<R: RulesTrait> Layout<R> {
weight: FixedDotWeight, weight: FixedDotWeight,
zone: GenericIndex<ZoneWeight>, zone: GenericIndex<ZoneWeight>,
) -> Result<FixedDotIndex, Infringement> { ) -> Result<FixedDotIndex, Infringement> {
let pin = self.node_to_pin.get(&GenericNode::Compound(zone));
let maybe_dot = self.drawing.add_fixed_dot(weight); let maybe_dot = self.drawing.add_fixed_dot(weight);
if let Ok(dot) = maybe_dot { if let Ok(dot) = maybe_dot {
@ -82,8 +100,16 @@ impl<R: RulesTrait> Layout<R> {
from: FixedDotIndex, from: FixedDotIndex,
to: FixedDotIndex, to: FixedDotIndex,
weight: FixedSegWeight, weight: FixedSegWeight,
maybe_pin: Option<String>,
) -> Result<FixedSegIndex, Infringement> { ) -> Result<FixedSegIndex, Infringement> {
self.drawing.add_fixed_seg(from, to, weight) let seg = self.drawing.add_fixed_seg(from, to, weight)?;
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(seg.into()), pin);
}
Ok(seg)
} }
pub fn add_zone_fixed_seg( pub fn add_zone_fixed_seg(
@ -93,7 +119,8 @@ impl<R: RulesTrait> Layout<R> {
weight: FixedSegWeight, weight: FixedSegWeight,
zone: GenericIndex<ZoneWeight>, zone: GenericIndex<ZoneWeight>,
) -> Result<FixedSegIndex, Infringement> { ) -> Result<FixedSegIndex, Infringement> {
let maybe_seg = self.add_fixed_seg(from, to, weight); let pin = self.node_to_pin.get(&GenericNode::Compound(zone));
let maybe_seg = self.add_fixed_seg(from, to, weight, pin.cloned());
if let Ok(seg) = maybe_seg { if let Ok(seg) = maybe_seg {
self.drawing.add_to_compound(seg, zone); self.drawing.add_to_compound(seg, zone);
@ -124,6 +151,28 @@ impl<R: RulesTrait> Layout<R> {
self.drawing.move_dot(dot, to) self.drawing.move_dot(dot, to)
} }
pub fn add_zone(
&mut self,
weight: ZoneWeight,
maybe_pin: Option<String>,
) -> GenericIndex<ZoneWeight> {
let zone = self.drawing.add_compound(weight);
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Compound(zone.into()), pin);
}
zone
}
pub fn zones<W: 'static>(
&self,
node: GenericIndex<W>,
) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
self.drawing.compounds(node)
}
pub fn band_length(&self, face: DotIndex) -> f64 { pub fn band_length(&self, face: DotIndex) -> f64 {
// TODO. // TODO.
0.0 0.0
@ -195,7 +244,7 @@ impl<R: RulesTrait> Layout<R> {
} }
} }
impl<R: RulesTrait> CompoundManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> for Layout<R> { /*impl<R: RulesTrait> CompoundManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> for Layout<R> {
fn add_compound(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> { fn add_compound(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> {
self.drawing.add_compound(weight) self.drawing.add_compound(weight)
} }
@ -222,4 +271,4 @@ impl<R: RulesTrait> CompoundManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> f
) -> impl Iterator<Item = GenericIndex<ZoneWeight>> { ) -> impl Iterator<Item = GenericIndex<ZoneWeight>> {
self.drawing.compounds(node) self.drawing.compounds(node)
} }
} }*/