mirror of https://codeberg.org/topola/topola.git
layout: implement storage for vias
This commit is contained in:
parent
e5829d929a
commit
fc1f7e2613
|
|
@ -114,7 +114,7 @@ impl Ratsnest {
|
|||
}
|
||||
|
||||
for zone in layout.layer_zone_nodes(layer) {
|
||||
if let Some(net) = layout.drawing().compound_weight(zone).maybe_net() {
|
||||
if let Some(net) = layout.drawing().compound_weight(zone.into()).maybe_net() {
|
||||
if !triangulations.contains_key(&(layer, net)) {
|
||||
triangulations.insert(
|
||||
(layer, net),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::{
|
||||
board::{mesadata::MesadataTrait, Board},
|
||||
drawing::graph::{GetLayer, MakePrimitive, PrimitiveIndex},
|
||||
graph::GenericIndex,
|
||||
layout::NodeIndex,
|
||||
geometry::compound::CompoundManagerTrait,
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{zone::ZoneWeight, CompoundWeight, NodeIndex},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||
|
|
@ -64,7 +65,17 @@ impl Selection {
|
|||
NodeIndex::Primitive(primitive) => {
|
||||
primitive.primitive(board.layout().drawing()).layer()
|
||||
}
|
||||
NodeIndex::Compound(compound) => board.layout().zone(compound).layer(),
|
||||
NodeIndex::Compound(compound) => {
|
||||
if let CompoundWeight::Zone(..) = board.layout().drawing().compound_weight(compound)
|
||||
{
|
||||
board
|
||||
.layout()
|
||||
.zone(GenericIndex::<ZoneWeight>::new(compound.node_index()))
|
||||
.layer()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let (Some(pinname), Some(layername)) = (
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ impl eframe::App for App {
|
|||
for zone in board.layout().layer_zone_nodes(1) {
|
||||
let color = if overlay
|
||||
.selection()
|
||||
.contains_node(board, GenericNode::Compound(zone))
|
||||
.contains_node(board, GenericNode::Compound(zone.into()))
|
||||
{
|
||||
egui::Color32::from_rgb(100, 100, 255)
|
||||
} else {
|
||||
|
|
@ -413,7 +413,7 @@ impl eframe::App for App {
|
|||
for zone in board.layout().layer_zone_nodes(0) {
|
||||
let color = if overlay
|
||||
.selection()
|
||||
.contains_node(board, GenericNode::Compound(zone))
|
||||
.contains_node(board, GenericNode::Compound(zone.into()))
|
||||
{
|
||||
egui::Color32::from_rgb(255, 100, 100)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ use topola::{
|
|||
compound::CompoundManagerTrait,
|
||||
shape::{Shape, ShapeTrait},
|
||||
},
|
||||
layout::{zone::MakePolyShape, Layout, NodeIndex},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{
|
||||
zone::{MakePolyShape, Zone, ZoneWeight},
|
||||
CompoundWeight, Layout, NodeIndex,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct Overlay {
|
||||
|
|
@ -72,7 +76,17 @@ impl Overlay {
|
|||
NodeIndex::Primitive(primitive) => {
|
||||
primitive.primitive(board.layout().drawing()).shape().into()
|
||||
}
|
||||
NodeIndex::Compound(compound) => board.layout().zone(compound).shape().into(),
|
||||
NodeIndex::Compound(compound) => {
|
||||
match board.layout().drawing().compound_weight(compound) {
|
||||
CompoundWeight::Zone(zone) => Zone::new(
|
||||
GenericIndex::<ZoneWeight>::new(compound.node_index()),
|
||||
board.layout(),
|
||||
)
|
||||
.shape()
|
||||
.into(),
|
||||
CompoundWeight::Via(via) => unreachable!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if shape.contains_point(p) {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl<M: MesadataTrait> Board<M> {
|
|||
) -> Result<FixedDotIndex, Infringement> {
|
||||
let dot = self.layout.add_zone_fixed_dot(weight, zone)?;
|
||||
|
||||
if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) {
|
||||
if let Some(pin) = self.node_pinname(GenericNode::Compound(zone.into())) {
|
||||
self.node_to_pinname
|
||||
.insert(GenericNode::Primitive(dot.into()), pin.to_string());
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ impl<M: MesadataTrait> Board<M> {
|
|||
) -> Result<FixedSegIndex, Infringement> {
|
||||
let seg = self.layout.add_zone_fixed_seg(from, to, weight, zone)?;
|
||||
|
||||
if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) {
|
||||
if let Some(pin) = self.node_pinname(GenericNode::Compound(zone.into())) {
|
||||
self.node_to_pinname
|
||||
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use geo::Point;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
use rstar::AABB;
|
||||
|
|
@ -26,19 +27,29 @@ use crate::{
|
|||
GetWidth, SegWeightTrait,
|
||||
},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::zone::{GetMaybeApex, MakePolyShape, PourZoneIndex, SolidZoneIndex, Zone, ZoneWeight},
|
||||
layout::{
|
||||
via::ViaWeight,
|
||||
zone::{GetMaybeApex, MakePolyShape, Zone, ZoneWeight},
|
||||
},
|
||||
math::Circle,
|
||||
};
|
||||
|
||||
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[enum_dispatch(GetMaybeNet)]
|
||||
pub enum CompoundWeight {
|
||||
Zone(ZoneWeight),
|
||||
Via(ViaWeight),
|
||||
}
|
||||
|
||||
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<CompoundWeight>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Layout<R: RulesTrait> {
|
||||
drawing: Drawing<ZoneWeight, R>,
|
||||
drawing: Drawing<CompoundWeight, R>,
|
||||
}
|
||||
|
||||
impl<R: RulesTrait> Layout<R> {
|
||||
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
|
||||
pub fn new(drawing: Drawing<CompoundWeight, R>) -> Self {
|
||||
Self { drawing }
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +74,21 @@ impl<R: RulesTrait> Layout<R> {
|
|||
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
|
||||
}
|
||||
|
||||
pub fn add_via(&mut self, weight: ViaWeight) -> Result<GenericIndex<ViaWeight>, Infringement> {
|
||||
let compound = self.drawing.add_compound(weight.into());
|
||||
|
||||
for layer in weight.from_layer..weight.to_layer {
|
||||
let dot = self.drawing.add_fixed_dot(FixedDotWeight {
|
||||
circle: weight.circle,
|
||||
layer,
|
||||
maybe_net: weight.maybe_net,
|
||||
})?;
|
||||
self.drawing.add_to_compound(dot, compound);
|
||||
}
|
||||
|
||||
Ok(GenericIndex::<ViaWeight>::new(compound.node_index()))
|
||||
}
|
||||
|
||||
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
|
||||
self.drawing.add_fixed_dot(weight)
|
||||
}
|
||||
|
|
@ -75,7 +101,7 @@ impl<R: RulesTrait> Layout<R> {
|
|||
let maybe_dot = self.drawing.add_fixed_dot(weight);
|
||||
|
||||
if let Ok(dot) = maybe_dot {
|
||||
self.drawing.add_to_compound(dot, zone);
|
||||
self.drawing.add_to_compound(dot, zone.into());
|
||||
}
|
||||
|
||||
maybe_dot
|
||||
|
|
@ -100,7 +126,7 @@ impl<R: RulesTrait> Layout<R> {
|
|||
let maybe_seg = self.add_fixed_seg(from, to, weight);
|
||||
|
||||
if let Ok(seg) = maybe_seg {
|
||||
self.drawing.add_to_compound(seg, zone);
|
||||
self.drawing.add_to_compound(seg, zone.into());
|
||||
}
|
||||
|
||||
maybe_seg
|
||||
|
|
@ -129,13 +155,17 @@ impl<R: RulesTrait> Layout<R> {
|
|||
}
|
||||
|
||||
pub fn add_zone(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> {
|
||||
self.drawing.add_compound(weight)
|
||||
GenericIndex::<ZoneWeight>::new(
|
||||
self.drawing
|
||||
.add_compound(CompoundWeight::Zone(weight))
|
||||
.node_index(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn zones<W: 'static>(
|
||||
&self,
|
||||
node: GenericIndex<W>,
|
||||
) -> impl Iterator<Item = GenericIndex<ZoneWeight>> + '_ {
|
||||
) -> impl Iterator<Item = GenericIndex<CompoundWeight>> + '_ {
|
||||
self.drawing.compounds(node)
|
||||
}
|
||||
|
||||
|
|
@ -171,11 +201,13 @@ impl<R: RulesTrait> Layout<R> {
|
|||
|
||||
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)
|
||||
} else {
|
||||
None
|
||||
if let NodeIndex::Compound(compound) = wrapper.data {
|
||||
if let CompoundWeight::Zone(..) = self.drawing.compound_weight(compound) {
|
||||
return Some(GenericIndex::<ZoneWeight>::new(compound.node_index()));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -190,11 +222,13 @@ impl<R: RulesTrait> Layout<R> {
|
|||
[f64::INFINITY, f64::INFINITY, layer as f64],
|
||||
))
|
||||
.filter_map(|wrapper| {
|
||||
if let NodeIndex::Compound(zone) = wrapper.data {
|
||||
Some(zone)
|
||||
} else {
|
||||
None
|
||||
if let NodeIndex::Compound(compound) = wrapper.data {
|
||||
if let CompoundWeight::Zone(..) = self.drawing.compound_weight(compound) {
|
||||
return Some(GenericIndex::<ZoneWeight>::new(compound.node_index()));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +241,7 @@ impl<R: RulesTrait> Layout<R> {
|
|||
.compound_members(GenericIndex::new(zone.node_index()))
|
||||
}
|
||||
|
||||
pub fn drawing(&self) -> &Drawing<ZoneWeight, R> {
|
||||
pub fn drawing(&self) -> &Drawing<CompoundWeight, R> {
|
||||
&self.drawing
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
mod layout;
|
||||
pub mod via;
|
||||
pub mod zone;
|
||||
|
||||
pub use layout::*;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
use crate::{
|
||||
drawing::{graph::GetMaybeNet, rules::RulesTrait},
|
||||
geometry::compound::CompoundManagerTrait,
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::{CompoundWeight, Layout},
|
||||
math::Circle,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Via<'a, R: RulesTrait> {
|
||||
pub index: GenericIndex<ViaWeight>,
|
||||
layout: &'a Layout<R>,
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> Via<'a, R> {
|
||||
pub fn new(index: GenericIndex<ViaWeight>, layout: &'a Layout<R>) -> Self {
|
||||
Self { index, layout }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> GetMaybeNet for Via<'a, R> {
|
||||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.layout
|
||||
.drawing()
|
||||
.compound_weight(self.index.into())
|
||||
.maybe_net()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ViaWeight {
|
||||
pub from_layer: u64,
|
||||
pub to_layer: u64,
|
||||
pub circle: Circle,
|
||||
pub maybe_net: Option<usize>,
|
||||
}
|
||||
|
||||
impl GetMaybeNet for ViaWeight {
|
||||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.maybe_net
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericIndex<ViaWeight>> for GenericIndex<CompoundWeight> {
|
||||
fn from(via: GenericIndex<ViaWeight>) -> Self {
|
||||
GenericIndex::<CompoundWeight>::new(via.node_index())
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
},
|
||||
geometry::{compound::CompoundManagerTrait, poly::PolyShape, GetPos},
|
||||
graph::{GenericIndex, GetNodeIndex},
|
||||
layout::Layout,
|
||||
layout::{CompoundWeight, Layout},
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -52,7 +52,13 @@ impl<'a, R: RulesTrait> Zone<'a, R> {
|
|||
|
||||
impl<'a, R: RulesTrait> GetLayer for Zone<'a, R> {
|
||||
fn layer(&self) -> u64 {
|
||||
self.layout.drawing().compound_weight(self.index).layer()
|
||||
if let CompoundWeight::Zone(weight) =
|
||||
self.layout.drawing().compound_weight(self.index.into())
|
||||
{
|
||||
weight.layer()
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +66,7 @@ impl<'a, R: RulesTrait> GetMaybeNet for Zone<'a, R> {
|
|||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.layout
|
||||
.drawing()
|
||||
.compound_weight(self.index)
|
||||
.compound_weight(self.index.into())
|
||||
.maybe_net()
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +79,7 @@ impl<'a, R: RulesTrait> MakePolyShape for Zone<'a, R> {
|
|||
self.layout
|
||||
.drawing()
|
||||
.geometry()
|
||||
.compound_members(self.index)
|
||||
.compound_members(self.index.into())
|
||||
.filter_map(|primitive_node| {
|
||||
let PrimitiveIndex::FixedDot(dot) = primitive_node else {
|
||||
return None;
|
||||
|
|
@ -104,7 +110,7 @@ impl<'a, R: RulesTrait> GetMaybeApex for Zone<'a, R> {
|
|||
self.layout
|
||||
.drawing()
|
||||
.geometry()
|
||||
.compound_members(self.index)
|
||||
.compound_members(self.index.into())
|
||||
.find_map(|primitive_node| {
|
||||
if let PrimitiveIndex::FixedDot(dot) = primitive_node {
|
||||
if self.is_apex(dot) {
|
||||
|
|
@ -124,25 +130,35 @@ pub enum ZoneWeight {
|
|||
Pour(PourZoneWeight),
|
||||
}
|
||||
|
||||
impl From<GenericIndex<ZoneWeight>> for GenericIndex<CompoundWeight> {
|
||||
fn from(zone: GenericIndex<ZoneWeight>) -> Self {
|
||||
GenericIndex::<CompoundWeight>::new(zone.node_index())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct SolidZoneWeight {
|
||||
pub layer: u64,
|
||||
pub maybe_net: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a> GetLayer for SolidZoneWeight {
|
||||
impl GetLayer for SolidZoneWeight {
|
||||
fn layer(&self) -> u64 {
|
||||
self.layer
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetMaybeNet for SolidZoneWeight {
|
||||
impl GetMaybeNet for SolidZoneWeight {
|
||||
fn maybe_net(&self) -> Option<usize> {
|
||||
self.maybe_net
|
||||
}
|
||||
}
|
||||
|
||||
pub type SolidZoneIndex = GenericIndex<SolidZoneWeight>;
|
||||
impl From<GenericIndex<SolidZoneWeight>> for GenericIndex<CompoundWeight> {
|
||||
fn from(zone: GenericIndex<SolidZoneWeight>) -> Self {
|
||||
GenericIndex::<CompoundWeight>::new(zone.node_index())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct PourZoneWeight {
|
||||
|
|
@ -162,4 +178,8 @@ impl<'a> GetMaybeNet for PourZoneWeight {
|
|||
}
|
||||
}
|
||||
|
||||
pub type PourZoneIndex = GenericIndex<PourZoneWeight>;
|
||||
impl From<GenericIndex<PourZoneWeight>> for GenericIndex<CompoundWeight> {
|
||||
fn from(zone: GenericIndex<PourZoneWeight>) -> Self {
|
||||
GenericIndex::<CompoundWeight>::new(zone.node_index())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue