board: make layout private

Also add board/ directory, as I forgot to add it in the previous commit.
This commit is contained in:
Mikolaj Wielgus 2024-02-29 02:28:15 +00:00
parent 8d55fbc837
commit 2f6b40410c
9 changed files with 221 additions and 52 deletions

View File

@ -127,7 +127,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
self.window, self.window,
self.renderer, self.renderer,
self.font_context, self.font_context,
RouterOrLayout::Layout(&tracer.board.layout), RouterOrLayout::Layout(tracer.board.layout()),
None, None,
Some(tracer.mesh.clone()), Some(tracer.mesh.clone()),
&trace.path, &trace.path,
@ -145,7 +145,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
self.window, self.window,
self.renderer, self.renderer,
self.font_context, self.font_context,
RouterOrLayout::Layout(&tracer.board.layout), RouterOrLayout::Layout(tracer.board.layout()),
None, None,
Some(tracer.mesh.clone()), Some(tracer.mesh.clone()),
&path, &path,
@ -176,7 +176,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
self.window, self.window,
self.renderer, self.renderer,
self.font_context, self.font_context,
RouterOrLayout::Layout(&tracer.board.layout), RouterOrLayout::Layout(tracer.board.layout()),
None, None,
Some(tracer.mesh.clone()), Some(tracer.mesh.clone()),
&trace.path, &trace.path,
@ -257,7 +257,7 @@ fn main() -> Result<(), anyhow::Error> {
&window, &window,
&mut renderer, &mut renderer,
&font_context, &font_context,
RouterOrLayout::Layout(&router.board.layout), RouterOrLayout::Layout(router.board.layout()),
None, None,
None, None,
&[], &[],
@ -280,7 +280,7 @@ fn main() -> Result<(), anyhow::Error> {
&window, &window,
&mut renderer, &mut renderer,
&font_context, &font_context,
RouterOrLayout::Layout(&router.board.layout), RouterOrLayout::Layout(router.board.layout()),
None, None,
None, None,
&[], &[],
@ -347,7 +347,7 @@ fn render_times(
maybe_mesh = None; maybe_mesh = None;
} }
&router.board.layout router.board.layout()
} }
RouterOrLayout::Layout(layout) => layout, RouterOrLayout::Layout(layout) => layout,
}; };

118
src/board/board.rs Normal file
View File

@ -0,0 +1,118 @@
use geo::Point;
use petgraph::stable_graph::StableDiGraph;
use crate::{
graph::GetNodeIndex,
layout::{
bend::LooseBendWeight,
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
rules::RulesTrait,
seg::{LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight},
segbend::Segbend,
Infringement, Layout, LayoutException,
},
wraparoundable::WraparoundableIndex,
};
use super::connectivity::{
BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex,
};
pub struct Board<R: RulesTrait> {
layout: Layout<R>, // Shouldn't be public, but is for now because `Draw` needs it.
connectivity: StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>,
}
impl<R: RulesTrait> Board<R> {
pub fn new(layout: Layout<R>) -> Self {
Self {
layout,
connectivity: StableDiGraph::default(),
}
}
pub fn remove_band(&mut self, band: BandIndex) {
todo!()
}
pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) {
self.layout.remove_segbend(segbend, face)
}
pub fn start_band(&mut self, from: FixedDotIndex) -> BandIndex {
let band = self
.connectivity
.add_node(ConnectivityWeight::Band(BandWeight { from, to: None }));
self.connectivity.update_edge(
self.continent(from.into()).node_index(),
band,
ConnectivityLabel::Band,
);
BandIndex::new(band)
}
pub fn finish_band(&mut self, band: BandIndex, to: FixedDotIndex) {
self.connectivity.update_edge(
band.node_index(),
self.continent(to.into()).node_index(),
ConnectivityLabel::Band,
);
}
pub fn insert_segbend(
&mut self,
from: DotIndex,
around: WraparoundableIndex,
dot_weight: LooseDotWeight,
seg_weight: SeqLooseSegWeight,
bend_weight: LooseBendWeight,
cw: bool,
) -> Result<Segbend, LayoutException> {
self.layout
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
}
pub fn add_lone_loose_seg(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: LoneLooseSegWeight,
) -> Result<LoneLooseSegIndex, Infringement> {
self.layout.add_lone_loose_seg(from, to, weight)
}
pub fn add_seq_loose_seg(
&mut self,
from: DotIndex,
to: LooseDotIndex,
weight: SeqLooseSegWeight,
) -> Result<SeqLooseSegIndex, Infringement> {
self.layout.add_seq_loose_seg(from, to, weight)
}
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> {
self.layout.move_dot(dot, to)
}
pub fn band_from(&self, band: BandIndex) -> FixedDotIndex {
todo!()
}
pub fn band_to(&self, band: BandIndex) -> Option<FixedDotIndex> {
todo!()
}
pub fn band_length(&self, band: BandIndex) -> f64 {
// TODO.
0.0
}
pub fn layout(&self) -> &Layout<R> {
&self.layout
}
pub fn continent(&self, dot: FixedDotIndex) -> ContinentIndex {
// TODO.
ContinentIndex::new(0.into())
}
}

41
src/board/connectivity.rs Normal file
View File

@ -0,0 +1,41 @@
use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::StableDiGraph;
use crate::{
graph::GenericIndex,
layout::{dot::FixedDotIndex, graph::GetNet, primitive::Primitive, rules::RulesTrait},
};
pub type ConnectivityGraph = StableDiGraph<ConnectivityWeight, ConnectivityLabel, usize>;
#[derive(Debug, Clone, Copy)]
pub enum ConnectivityWeight {
Continent(ContinentWeight),
Band(BandWeight),
}
#[derive(Debug, Clone, Copy)]
pub struct ContinentWeight {
pub net: i64,
}
impl GetNet for ContinentWeight {
fn net(&self) -> i64 {
self.net
}
}
pub type ContinentIndex = GenericIndex<ContinentWeight>;
#[derive(Debug, Clone, Copy)]
pub struct BandWeight {
pub from: FixedDotIndex,
pub to: Option<FixedDotIndex>,
}
pub type BandIndex = GenericIndex<BandWeight>;
#[derive(Debug, Clone, Copy)]
pub enum ConnectivityLabel {
Band,
}

4
src/board/mod.rs Normal file
View File

@ -0,0 +1,4 @@
mod board;
pub mod connectivity;
pub use board::*;

View File

@ -3,7 +3,7 @@ use geo::{EuclideanLength, Point};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
geometry::GetWidth, board::Board,
layout::{ layout::{
bend::{BendIndex, LooseBendWeight}, bend::{BendIndex, LooseBendWeight},
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
@ -12,7 +12,7 @@ use crate::{
primitive::GetOtherJoint, primitive::GetOtherJoint,
rules::RulesTrait, rules::RulesTrait,
seg::{LoneLooseSegWeight, SeqLooseSegWeight}, seg::{LoneLooseSegWeight, SeqLooseSegWeight},
Infringement, Layout, LayoutException, Infringement, LayoutException,
}, },
math::{Circle, NoTangents}, math::{Circle, NoTangents},
wraparoundable::WraparoundableIndex, wraparoundable::WraparoundableIndex,
@ -31,20 +31,20 @@ pub enum DrawException {
} }
pub struct Draw<'a, R: RulesTrait> { pub struct Draw<'a, R: RulesTrait> {
layout: &'a mut Layout<R>, board: &'a mut Board<R>,
} }
impl<'a, R: RulesTrait> Draw<'a, R> { impl<'a, R: RulesTrait> Draw<'a, R> {
pub fn new(layout: &'a mut Layout<R>) -> Self { pub fn new(board: &'a mut Board<R>) -> Self {
Self { layout } Self { board }
} }
pub fn start(&mut self, from: LooseDotIndex) -> Head { pub fn start(&mut self, from: LooseDotIndex) -> Head {
self.guide().segbend_head(from).into() self.guide().segbend_head(from).into()
} }
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
pub fn finish_in_dot( pub fn finish_in_dot(
&mut self, &mut self,
head: Head, head: Head,
@ -58,16 +58,16 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
let head = self let head = self
.extend_head(head, tangent.start_point()) .extend_head(head, tangent.start_point())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
let net = head.face().primitive(self.layout).net(); let net = head.face().primitive(self.board.layout()).net();
match head.face() { match head.face() {
DotIndex::Fixed(dot) => { DotIndex::Fixed(dot) => {
self.layout self.board
.add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { net, width }) .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { net, width })
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
} }
DotIndex::Loose(dot) => { DotIndex::Loose(dot) => {
self.layout self.board
.add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { net, width }) .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { net, width })
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
} }
@ -75,8 +75,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
Ok::<(), DrawException>(()) Ok::<(), DrawException>(())
} }
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))]
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
pub fn segbend_around_dot( pub fn segbend_around_dot(
&mut self, &mut self,
head: Head, head: Head,
@ -120,8 +120,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
)) ))
} }
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))]
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
pub fn segbend_around_bend( pub fn segbend_around_bend(
&mut self, &mut self,
head: Head, head: Head,
@ -165,8 +165,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
)) ))
} }
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))]
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
fn segbend_around( fn segbend_around(
&mut self, &mut self,
head: Head, head: Head,
@ -181,18 +181,18 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
self.segbend(head, around, to, cw, width, offset) self.segbend(head, around, to, cw, width, offset)
} }
#[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(self.board.layout().node_count() == old(self.board.layout().node_count()))]
fn extend_head(&mut self, head: Head, to: Point) -> Result<Head, Infringement> { fn extend_head(&mut self, head: Head, to: Point) -> Result<Head, Infringement> {
if let Head::Segbend(head) = head { if let Head::Segbend(head) = head {
self.layout.move_dot(head.face.into(), to)?; self.board.move_dot(head.face.into(), to)?;
Ok(Head::Segbend(head)) Ok(Head::Segbend(head))
} else { } else {
Ok(head) Ok(head)
} }
} }
#[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))]
#[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
fn segbend( fn segbend(
&mut self, &mut self,
head: Head, head: Head,
@ -202,8 +202,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
width: f64, width: f64,
offset: f64, offset: f64,
) -> Result<SegbendHead, LayoutException> { ) -> Result<SegbendHead, LayoutException> {
let net = head.face().primitive(self.layout).net(); let net = head.face().primitive(self.board.layout()).net();
let segbend = self.layout.insert_segbend( let segbend = self.board.insert_segbend(
head.face(), head.face(),
around, around,
LooseDotWeight { LooseDotWeight {
@ -218,24 +218,29 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
cw, cw,
)?; )?;
Ok::<SegbendHead, LayoutException>(SegbendHead { Ok::<SegbendHead, LayoutException>(SegbendHead {
face: self.layout.primitive(segbend.bend).other_joint(segbend.dot), face: self
.board
.layout()
.primitive(segbend.bend)
.other_joint(segbend.dot),
segbend, segbend,
}) })
} }
#[debug_ensures(ret.is_some() -> self.layout.node_count() == old(self.layout.node_count() - 4))] #[debug_ensures(ret.is_some() -> self.board.layout().node_count() == old(self.board.layout().node_count() - 4))]
#[debug_ensures(ret.is_none() -> self.layout.node_count() == old(self.layout.node_count()))] #[debug_ensures(ret.is_none() -> self.board.layout().node_count() == old(self.board.layout().node_count()))]
pub fn undo_segbend(&mut self, head: SegbendHead) -> Option<Head> { pub fn undo_segbend(&mut self, head: SegbendHead) -> Option<Head> {
let prev_dot = self let prev_dot = self
.layout .board
.layout()
.primitive(head.segbend.seg) .primitive(head.segbend.seg)
.other_joint(head.segbend.dot.into()); .other_joint(head.segbend.dot.into());
self.layout.remove_segbend(&head.segbend, head.face); self.board.remove_segbend(&head.segbend, head.face);
Some(self.guide().head(prev_dot)) Some(self.guide().head(prev_dot))
} }
fn guide(&self) -> Guide<R> { fn guide(&self) -> Guide<R> {
Guide::new(self.layout) Guide::new(self.board.layout())
} }
} }

View File

@ -43,7 +43,8 @@ impl Rules {
let mut net_id_classes = HashMap::new(); let mut net_id_classes = HashMap::new();
let class_rules = HashMap::from_iter( let class_rules = HashMap::from_iter(
pcb.network.classes pcb.network
.classes
.iter() .iter()
.inspect(|class| { .inspect(|class| {
for net in &class.nets { for net in &class.nets {
@ -51,7 +52,7 @@ impl Rules {
net_id_classes.insert(*net_id, class.name.clone()); net_id_classes.insert(*net_id, class.name.clone());
} }
}) })
.map(|class| (class.name.clone(), Rule::from_dsn(&class.rule))) .map(|class| (class.name.clone(), Rule::from_dsn(&class.rule))),
); );
Self { Self {
@ -64,7 +65,9 @@ impl Rules {
pub fn get_rule(&self, net: i64) -> &Rule { pub fn get_rule(&self, net: i64) -> &Rule {
if let Some(netclass) = self.net_id_classes.get(&net) { if let Some(netclass) = self.net_id_classes.get(&net) {
self.class_rules.get(netclass).unwrap_or(&self.structure_rule) self.class_rules
.get(netclass)
.unwrap_or(&self.structure_rule)
} else { } else {
&self.structure_rule &self.structure_rule
} }

View File

@ -173,13 +173,6 @@ impl<R: RulesTrait> Layout<R> {
self.add_dot_infringably(weight, &[]) self.add_dot_infringably(weight, &[])
} }
/*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result<LooseDotIndex, ()> {
self.add_dot_infringably(weight, &[])
}*/
#[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))]
fn add_dot_infringably<W: DotWeightTrait<GeometryWeight>>( fn add_dot_infringably<W: DotWeightTrait<GeometryWeight>>(

View File

@ -8,13 +8,12 @@ use crate::astar::{astar, AstarStrategy, PathTracker};
use crate::board::connectivity::BandIndex; use crate::board::connectivity::BandIndex;
use crate::board::Board; use crate::board::Board;
use crate::draw::DrawException; use crate::draw::DrawException;
use crate::geometry::{shape::ShapeTrait, GetWidth}; use crate::geometry::shape::ShapeTrait;
use crate::layout::{ use crate::layout::{
dot::FixedDotIndex, dot::FixedDotIndex,
graph::{GeometryIndex, MakePrimitive}, graph::{GeometryIndex, MakePrimitive},
primitive::MakeShape, primitive::MakeShape,
rules::RulesTrait, rules::RulesTrait,
Layout,
}; };
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex}; use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
@ -120,10 +119,16 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Mesh, f64>
fn estimate_cost(&mut self, vertex: VertexIndex) -> f64 { fn estimate_cost(&mut self, vertex: VertexIndex) -> f64 {
self.observer.on_estimate(&self.tracer, vertex); self.observer.on_estimate(&self.tracer, vertex);
let start_point = GeometryIndex::from(vertex) let start_point = GeometryIndex::from(vertex)
.primitive(&self.tracer.board.layout) .primitive(self.tracer.board.layout())
.shape()
.center();
let end_point = self
.tracer
.board
.layout()
.primitive(self.to)
.shape() .shape()
.center(); .center();
let end_point = self.tracer.board.layout.primitive(self.to).shape().center();
end_point.euclidean_distance(&start_point) end_point.euclidean_distance(&start_point)
} }
} }
@ -143,8 +148,8 @@ impl<R: RulesTrait> Router<R> {
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
// right. // right.
//self.mesh.triangulate(&self.layout)?; //self.mesh.triangulate(&self.layout)?;
let mut mesh = Mesh::new(&self.board.layout); let mut mesh = Mesh::new(self.board.layout());
mesh.generate(&self.board.layout) mesh.generate(self.board.layout())
.map_err(|err| RoutingError { .map_err(|err| RoutingError {
from, from,
to, to,
@ -179,7 +184,7 @@ impl<R: RulesTrait> Router<R> {
let from_dot = self.board.band_from(band); let from_dot = self.board.band_from(band);
let to_dot = self.board.band_to(band).unwrap(); let to_dot = self.board.band_to(band).unwrap();
self.board.remove_band(band); self.board.remove_band(band);
self.board.layout.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`. self.board.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`.
self.route_band(from_dot, to_dot, width, observer) self.route_band(from_dot, to_dot, width, observer)
} }

View File

@ -158,6 +158,6 @@ impl<'a, R: RulesTrait> Tracer<'a, R> {
} }
fn draw(&mut self) -> Draw<R> { fn draw(&mut self) -> Draw<R> {
Draw::new(&mut self.board.layout) Draw::new(&mut self.board)
} }
} }