From ea22ba705c91f17b69a1c1e28a95605f933698c1 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 1 May 2024 20:57:49 +0200 Subject: [PATCH] layout: create `Zone` struct for accessing zone properties --- src/autorouter/ratsnest.rs | 7 +- src/bin/topola-egui/app.rs | 18 ++--- src/bin/topola-egui/overlay.rs | 5 +- src/layout/layout.rs | 14 +++- src/layout/zone.rs | 116 ++++++++++++++++----------------- 5 files changed, 73 insertions(+), 87 deletions(-) diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index bc596b3..b626a7a 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -98,7 +98,7 @@ impl Ratsnest { } } - for zone in layout.zones() { + for zone in layout.zone_nodes() { if let Some(net) = layout.drawing().compound_weight(zone).maybe_net() { if !triangulations.contains_key(&net) { triangulations.insert( @@ -112,10 +112,7 @@ impl Ratsnest { .unwrap() .add_vertex(VertexWeight { vertex: RatsnestVertexIndex::Zone(zone), - pos: layout - .compound_weight(zone) - .shape(&layout.drawing(), zone) - .center(), + pos: layout.zone(zone).shape().center(), })? } } diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 3076f83..128b544 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -178,19 +178,14 @@ impl eframe::App for App { painter.paint_shape(&shape, color); } - for zone in autorouter.router().layout().layer_zones(1) { + for zone in autorouter.router().layout().layer_zone_nodes(1) { let color = if overlay.selection().contains(&GenericNode::Compound(zone)) { egui::Color32::from_rgb(100, 100, 255) } else { egui::Color32::from_rgb(52, 52, 200) }; painter.paint_polygon( - &autorouter - .router() - .layout() - .compound_weight(zone) - .shape(&autorouter.router().layout().drawing(), zone) - .polygon, + &autorouter.router().layout().zone(zone).shape().polygon, color, ) } @@ -216,19 +211,14 @@ impl eframe::App for App { painter.paint_shape(&shape, color); } - for zone in autorouter.router().layout().layer_zones(0) { + for zone in autorouter.router().layout().layer_zone_nodes(0) { let color = if overlay.selection().contains(&GenericNode::Compound(zone)) { egui::Color32::from_rgb(255, 100, 100) } else { egui::Color32::from_rgb(200, 52, 52) }; painter.paint_polygon( - &autorouter - .router() - .layout() - .compound_weight(zone) - .shape(&autorouter.router().layout().drawing(), zone) - .polygon, + &autorouter.router().layout().zone(zone).shape().polygon, color, ) } diff --git a/src/bin/topola-egui/overlay.rs b/src/bin/topola-egui/overlay.rs index e1f406c..c0c2ce4 100644 --- a/src/bin/topola-egui/overlay.rs +++ b/src/bin/topola-egui/overlay.rs @@ -69,10 +69,7 @@ impl Overlay { ) -> bool { let shape: Shape = match node { NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(), - NodeIndex::Compound(compound) => layout - .compound_weight(compound) - .shape(layout.drawing(), compound) - .into(), + NodeIndex::Compound(compound) => layout.zone(compound).shape().into(), }; if shape.contains_point(p) { diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 63076da..290a93f 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -25,12 +25,13 @@ use crate::{ connectivity::{ BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex, }, - zone::{PourZoneIndex, SolidZoneIndex, ZoneWeight}, + zone::{PourZoneIndex, SolidZoneIndex, Zone, ZoneWeight}, }, }; pub type NodeIndex = GenericNode>; +#[derive(Debug)] pub struct Layout { drawing: Drawing, connectivity: StableDiGraph, @@ -168,7 +169,7 @@ impl Layout { ContinentIndex::new(0.into()) } - pub fn zones(&self) -> impl Iterator> + '_ { + pub fn zone_nodes(&self) -> impl Iterator> + '_ { self.drawing.rtree().iter().filter_map(|wrapper| { if let NodeIndex::Compound(zone) = wrapper.data { Some(zone) @@ -178,7 +179,10 @@ impl Layout { }) } - pub fn layer_zones(&self, layer: u64) -> impl Iterator> + '_ { + pub fn layer_zone_nodes( + &self, + layer: u64, + ) -> impl Iterator> + '_ { self.drawing .rtree() .locate_in_envelope_intersecting(&AABB::from_corners( @@ -206,6 +210,10 @@ impl Layout { pub fn drawing(&self) -> &Drawing { &self.drawing } + + pub fn zone(&self, index: GenericIndex) -> Zone { + Zone::new(index, self) + } } impl CompoundManagerTrait> for Layout { diff --git a/src/layout/zone.rs b/src/layout/zone.rs index 8a2aad2..0921f94 100644 --- a/src/layout/zone.rs +++ b/src/layout/zone.rs @@ -11,20 +11,68 @@ use crate::{ rules::RulesTrait, Drawing, }, - geometry::{poly::PolyShape, GetPos}, + geometry::{compound::CompoundManagerTrait, poly::PolyShape, GetPos}, graph::{GenericIndex, GetNodeIndex}, + layout::Layout, }; #[enum_dispatch] pub trait MakePolyShape { - fn shape( - &self, - drawing: &Drawing, - index: GenericIndex, - ) -> PolyShape; + fn shape(&self) -> PolyShape; } -#[enum_dispatch(GetLayer, GetMaybeNet, MakePolyShape)] +#[derive(Debug)] +pub struct Zone<'a, R: RulesTrait> { + pub index: GenericIndex, + layout: &'a Layout, +} + +impl<'a, R: RulesTrait> Zone<'a, R> { + pub fn new(index: GenericIndex, layout: &'a Layout) -> Self { + Self { index, layout } + } +} + +impl<'a, R: RulesTrait> GetLayer for Zone<'a, R> { + fn layer(&self) -> u64 { + self.layout.drawing().compound_weight(self.index).layer() + } +} + +impl<'a, R: RulesTrait> GetMaybeNet for Zone<'a, R> { + fn maybe_net(&self) -> Option { + self.layout + .drawing() + .compound_weight(self.index) + .maybe_net() + } +} + +impl<'a, R: RulesTrait> MakePolyShape for Zone<'a, R> { + fn shape(&self) -> PolyShape { + PolyShape { + polygon: Polygon::new( + LineString::from( + self.layout + .drawing() + .geometry() + .compound_members(self.index) + .filter_map(|primitive_node| { + if let Ok(dot) = DotIndex::try_from(primitive_node) { + Some(self.layout.drawing().geometry().dot_weight(dot).pos()) + } else { + None + } + }) + .collect::>(), + ), + vec![], + ), + } + } +} + +#[enum_dispatch(GetLayer, GetMaybeNet)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum ZoneWeight { Solid(SolidZoneWeight), @@ -49,33 +97,6 @@ impl<'a> GetMaybeNet for SolidZoneWeight { } } -impl MakePolyShape for SolidZoneWeight { - fn shape( - &self, - drawing: &Drawing, - index: GenericIndex, - ) -> PolyShape { - PolyShape { - polygon: Polygon::new( - LineString::from( - drawing - .geometry() - .compound_members(index) - .filter_map(|primitive_node| { - if let Ok(dot) = DotIndex::try_from(primitive_node) { - Some(drawing.geometry().dot_weight(dot).pos()) - } else { - None - } - }) - .collect::>(), - ), - vec![], - ), - } - } -} - pub type SolidZoneIndex = GenericIndex; #[derive(Debug, Clone, Copy, PartialEq)] @@ -96,31 +117,4 @@ impl<'a> GetMaybeNet for PourZoneWeight { } } -impl MakePolyShape for PourZoneWeight { - fn shape( - &self, - drawing: &Drawing, - index: GenericIndex, - ) -> PolyShape { - PolyShape { - polygon: Polygon::new( - LineString::from( - drawing - .geometry() - .compound_members(index) - .filter_map(|primitive_node| { - if let Ok(dot) = DotIndex::try_from(primitive_node) { - Some(drawing.geometry().dot_weight(dot).pos()) - } else { - None - } - }) - .collect::>(), - ), - vec![], - ), - } - } -} - pub type PourZoneIndex = GenericIndex;