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 !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(),
})?
}
}

View File

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

View File

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

View File

@ -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<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)]
pub struct Layout<R: RulesTrait> {
drawing: Drawing<ZoneWeight, R>,
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
@ -168,7 +169,7 @@ impl<R: RulesTrait> Layout<R> {
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| {
if let NodeIndex::Compound(zone) = wrapper.data {
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
.rtree()
.locate_in_envelope_intersecting(&AABB::from_corners(
@ -206,6 +210,10 @@ impl<R: RulesTrait> Layout<R> {
pub fn drawing(&self) -> &Drawing<ZoneWeight, R> {
&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> {

View File

@ -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<R: RulesTrait>(
&self,
drawing: &Drawing<ZoneWeight, R>,
index: GenericIndex<ZoneWeight>,
) -> PolyShape;
fn shape(&self) -> 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)]
pub enum ZoneWeight {
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>;
#[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>;