layout: create `Zone` struct for accessing zone properties

This commit is contained in:
Mikolaj Wielgus 2024-05-01 20:57:49 +02:00
parent c74e69a5e9
commit ea22ba705c
5 changed files with 73 additions and 87 deletions

View File

@ -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 let Some(net) = layout.drawing().compound_weight(zone).maybe_net() {
if !triangulations.contains_key(&net) { if !triangulations.contains_key(&net) {
triangulations.insert( triangulations.insert(
@ -112,10 +112,7 @@ impl Ratsnest {
.unwrap() .unwrap()
.add_vertex(VertexWeight { .add_vertex(VertexWeight {
vertex: RatsnestVertexIndex::Zone(zone), vertex: RatsnestVertexIndex::Zone(zone),
pos: layout pos: layout.zone(zone).shape().center(),
.compound_weight(zone)
.shape(&layout.drawing(), zone)
.center(),
})? })?
} }
} }

View File

@ -178,19 +178,14 @@ impl eframe::App for App {
painter.paint_shape(&shape, color); 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)) { let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
egui::Color32::from_rgb(100, 100, 255) egui::Color32::from_rgb(100, 100, 255)
} else { } else {
egui::Color32::from_rgb(52, 52, 200) egui::Color32::from_rgb(52, 52, 200)
}; };
painter.paint_polygon( painter.paint_polygon(
&autorouter &autorouter.router().layout().zone(zone).shape().polygon,
.router()
.layout()
.compound_weight(zone)
.shape(&autorouter.router().layout().drawing(), zone)
.polygon,
color, color,
) )
} }
@ -216,19 +211,14 @@ impl eframe::App for App {
painter.paint_shape(&shape, color); 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)) { let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
egui::Color32::from_rgb(255, 100, 100) egui::Color32::from_rgb(255, 100, 100)
} else { } else {
egui::Color32::from_rgb(200, 52, 52) egui::Color32::from_rgb(200, 52, 52)
}; };
painter.paint_polygon( painter.paint_polygon(
&autorouter &autorouter.router().layout().zone(zone).shape().polygon,
.router()
.layout()
.compound_weight(zone)
.shape(&autorouter.router().layout().drawing(), zone)
.polygon,
color, color,
) )
} }

View File

@ -69,10 +69,7 @@ impl Overlay {
) -> bool { ) -> bool {
let shape: Shape = match node { let shape: Shape = match node {
NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(), NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(),
NodeIndex::Compound(compound) => layout NodeIndex::Compound(compound) => layout.zone(compound).shape().into(),
.compound_weight(compound)
.shape(layout.drawing(), compound)
.into(),
}; };
if shape.contains_point(p) { if shape.contains_point(p) {

View File

@ -25,12 +25,13 @@ use crate::{
connectivity::{ connectivity::{
BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex, BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex,
}, },
zone::{PourZoneIndex, SolidZoneIndex, ZoneWeight}, zone::{PourZoneIndex, SolidZoneIndex, Zone, ZoneWeight},
}, },
}; };
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>; pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)]
pub struct Layout<R: RulesTrait> { pub struct Layout<R: RulesTrait> {
drawing: Drawing<ZoneWeight, R>, drawing: Drawing<ZoneWeight, R>,
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>, connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
@ -168,7 +169,7 @@ impl<R: RulesTrait> Layout<R> {
ContinentIndex::new(0.into()) ContinentIndex::new(0.into())
} }
pub fn zones(&self) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ { pub fn zone_nodes(&self) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
self.drawing.rtree().iter().filter_map(|wrapper| { self.drawing.rtree().iter().filter_map(|wrapper| {
if let NodeIndex::Compound(zone) = wrapper.data { if let NodeIndex::Compound(zone) = wrapper.data {
Some(zone) Some(zone)
@ -178,7 +179,10 @@ impl<R: RulesTrait> Layout<R> {
}) })
} }
pub fn layer_zones(&self, layer: u64) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ { pub fn layer_zone_nodes(
&self,
layer: u64,
) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
self.drawing self.drawing
.rtree() .rtree()
.locate_in_envelope_intersecting(&AABB::from_corners( .locate_in_envelope_intersecting(&AABB::from_corners(
@ -206,6 +210,10 @@ impl<R: RulesTrait> Layout<R> {
pub fn drawing(&self) -> &Drawing<ZoneWeight, R> { pub fn drawing(&self) -> &Drawing<ZoneWeight, R> {
&self.drawing &self.drawing
} }
pub fn zone(&self, index: GenericIndex<ZoneWeight>) -> Zone<R> {
Zone::new(index, self)
}
} }
impl<R: RulesTrait> CompoundManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> for Layout<R> { impl<R: RulesTrait> CompoundManagerTrait<ZoneWeight, GenericIndex<ZoneWeight>> for Layout<R> {

View File

@ -11,20 +11,68 @@ use crate::{
rules::RulesTrait, rules::RulesTrait,
Drawing, Drawing,
}, },
geometry::{poly::PolyShape, GetPos}, geometry::{compound::CompoundManagerTrait, poly::PolyShape, GetPos},
graph::{GenericIndex, GetNodeIndex}, graph::{GenericIndex, GetNodeIndex},
layout::Layout,
}; };
#[enum_dispatch] #[enum_dispatch]
pub trait MakePolyShape { pub trait MakePolyShape {
fn shape<R: RulesTrait>( fn shape(&self) -> PolyShape;
&self,
drawing: &Drawing<ZoneWeight, R>,
index: GenericIndex<ZoneWeight>,
) -> PolyShape;
} }
#[enum_dispatch(GetLayer, GetMaybeNet, MakePolyShape)] #[derive(Debug)]
pub struct Zone<'a, R: RulesTrait> {
pub index: GenericIndex<ZoneWeight>,
layout: &'a Layout<R>,
}
impl<'a, R: RulesTrait> Zone<'a, R> {
pub fn new(index: GenericIndex<ZoneWeight>, layout: &'a Layout<R>) -> 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<usize> {
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<Point>>(),
),
vec![],
),
}
}
}
#[enum_dispatch(GetLayer, GetMaybeNet)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum ZoneWeight { pub enum ZoneWeight {
Solid(SolidZoneWeight), Solid(SolidZoneWeight),
@ -49,33 +97,6 @@ impl<'a> GetMaybeNet for SolidZoneWeight {
} }
} }
impl MakePolyShape for SolidZoneWeight {
fn shape<R: RulesTrait>(
&self,
drawing: &Drawing<ZoneWeight, R>,
index: GenericIndex<ZoneWeight>,
) -> 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<Point>>(),
),
vec![],
),
}
}
}
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>; pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -96,31 +117,4 @@ impl<'a> GetMaybeNet for PourZoneWeight {
} }
} }
impl MakePolyShape for PourZoneWeight {
fn shape<R: RulesTrait>(
&self,
drawing: &Drawing<ZoneWeight, R>,
index: GenericIndex<ZoneWeight>,
) -> 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<Point>>(),
),
vec![],
),
}
}
}
pub type PourZoneIndex = GenericIndex<PourZoneWeight>; pub type PourZoneIndex = GenericIndex<PourZoneWeight>;