overlay: separately triangulate each net

The way this is done is ineffective of course and we'll have to optimize
it later.
This commit is contained in:
Mikolaj Wielgus 2024-04-24 03:01:50 +02:00
parent d1ae0ec9c6
commit 6f9015106d
3 changed files with 67 additions and 24 deletions

View File

@ -32,7 +32,7 @@ use crate::{
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>; pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
pub struct Layout<R: RulesTrait> { pub struct Layout<R: RulesTrait> {
drawing: Drawing<ZoneWeight, R>, // Shouldn't be public, but is for now because `Draw` needs it. drawing: Drawing<ZoneWeight, R>,
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>, connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
} }

View File

@ -24,7 +24,7 @@ pub trait MakePolyShape {
) -> PolyShape; ) -> PolyShape;
} }
#[enum_dispatch(GetLayer, MakePolyShape)] #[enum_dispatch(GetLayer, GetMaybeNet, MakePolyShape)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum ZoneWeight { pub enum ZoneWeight {
Solid(SolidZoneWeight), Solid(SolidZoneWeight),

View File

@ -1,8 +1,10 @@
use std::collections::HashMap;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::{ use petgraph::{
data::FromElements, data::{Element, FromElements},
stable_graph::{NodeIndex, StableUnGraph}, stable_graph::{NodeIndex, StableGraph, StableUnGraph},
unionfind::UnionFind, unionfind::UnionFind,
visit::{self, EdgeRef, IntoEdgeReferences, NodeIndexable}, visit::{self, EdgeRef, IntoEdgeReferences, NodeIndexable},
}; };
@ -11,7 +13,7 @@ use spade::{HasPosition, InsertionError, Point2};
use crate::{ use crate::{
drawing::{ drawing::{
dot::FixedDotIndex, dot::FixedDotIndex,
graph::{MakePrimitive, PrimitiveIndex}, graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex},
primitive::MakePrimitiveShape, primitive::MakePrimitiveShape,
rules::RulesTrait, rules::RulesTrait,
}, },
@ -56,21 +58,40 @@ pub struct Ratsnest {
impl Ratsnest { impl Ratsnest {
pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> { pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> {
let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound());
for edge in layout.drawing().geometry().graph().edge_references() {
unionfind.union(edge.source(), edge.target());
}
let mut this = Self { let mut this = Self {
graph: StableUnGraph::default(), graph: StableUnGraph::default(),
}; };
let mut triangulation = let mut triangulations = HashMap::new();
Triangulation::new(layout.drawing().geometry().graph().node_bound());
for node in layout.drawing().primitive_nodes() { for node in layout.drawing().primitive_nodes() {
match node { match node {
PrimitiveIndex::FixedDot(dot) => { PrimitiveIndex::FixedDot(dot) => {
if layout.compounds(dot).next().is_none() { if layout.compounds(dot).next().is_none() {
triangulation.add_vertex(VertexWeight { if let Some(net) = layout.drawing().primitive(dot).maybe_net() {
vertex: RatsnestVertexIndex::FixedDot(dot), if !triangulations.contains_key(&net) {
pos: node.primitive(layout.drawing()).shape().center(), triangulations.insert(
})?; net,
Triangulation::new(
layout.drawing().geometry().graph().node_bound(),
),
);
}
triangulations
.get_mut(&net)
.unwrap()
.add_vertex(VertexWeight {
vertex: RatsnestVertexIndex::FixedDot(dot),
pos: node.primitive(layout.drawing()).shape().center(),
})?;
}
} }
} }
_ => (), _ => (),
@ -78,22 +99,44 @@ impl Ratsnest {
} }
for zone in layout.zones() { for zone in layout.zones() {
triangulation.add_vertex(VertexWeight { if let Some(net) = layout.drawing().compound_weight(zone).maybe_net() {
vertex: RatsnestVertexIndex::Zone(zone), if !triangulations.contains_key(&net) {
pos: layout triangulations.insert(
.compound_weight(zone) net,
.shape(&layout.drawing(), zone) Triangulation::new(layout.drawing().geometry().graph().node_bound()),
.center(), );
})? }
triangulations
.get_mut(&net)
.unwrap()
.add_vertex(VertexWeight {
vertex: RatsnestVertexIndex::Zone(zone),
pos: layout
.compound_weight(zone)
.shape(&layout.drawing(), zone)
.center(),
})?
}
} }
this.graph = for (net, triangulation) in triangulations {
StableUnGraph::from_elements(petgraph::algo::min_spanning_tree(&triangulation)); let mut map = Vec::new();
let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound()); for element in petgraph::algo::min_spanning_tree(&triangulation) {
match element {
for edge in layout.drawing().geometry().graph().edge_references() { Element::Node { weight } => {
unionfind.union(edge.source(), edge.target()); map.push(this.graph.add_node(weight));
}
Element::Edge {
source,
target,
weight,
} => {
this.graph.add_edge(map[source], map[target], weight);
}
}
}
} }
this.graph.retain_edges(|g, i| { this.graph.retain_edges(|g, i| {