layout: move pin information to a new parent object, `Board`

This commit is contained in:
Mikolaj Wielgus 2024-05-31 01:42:48 +02:00
parent b22e3dce1a
commit de17adb01c
11 changed files with 280 additions and 163 deletions

View File

@ -14,6 +14,7 @@ use thiserror::Error;
use crate::{
autorouter::{
board::Board,
ratsnest::{Ratsnest, RatsnestVertexIndex},
selection::Selection,
},
@ -22,7 +23,7 @@ use crate::{
graph::{GetLayer, GetMaybeNet},
rules::RulesTrait,
},
layout::{Layout, NodeIndex},
layout::Layout,
router::{
navmesh::{Navmesh, NavmeshError},
Router, RouterError, RouterObserverTrait,
@ -63,7 +64,7 @@ impl Autoroute {
};
let (source, target) = Self::ratline_endpoints(autorouter, cur_ratline);
let navmesh = Some(Navmesh::new(&autorouter.layout, source, target)?);
let navmesh = Some(Navmesh::new(autorouter.board.layout(), source, target)?);
let this = Self {
ratlines_iter,
@ -84,7 +85,7 @@ impl Autoroute {
(
Some(
Navmesh::new(&autorouter.layout, source, target)
Navmesh::new(autorouter.board.layout(), source, target)
.ok()
.unwrap(),
),
@ -95,7 +96,7 @@ impl Autoroute {
};
let mut router = Router::new_from_navmesh(
&mut autorouter.layout,
autorouter.board.layout_mut(),
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
);
@ -130,7 +131,7 @@ impl Autoroute {
.vertex_index()
{
RatsnestVertexIndex::FixedDot(dot) => dot,
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
RatsnestVertexIndex::Zone(zone) => autorouter.board.layout_mut().zone_apex(zone),
};
let target_dot = match autorouter
@ -141,7 +142,7 @@ impl Autoroute {
.vertex_index()
{
RatsnestVertexIndex::FixedDot(dot) => dot,
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
RatsnestVertexIndex::Zone(zone) => autorouter.board.layout_mut().zone_apex(zone),
};
(source_dot, target_dot)
@ -153,14 +154,14 @@ impl Autoroute {
}
pub struct Autorouter<R: RulesTrait> {
layout: Layout<R>,
board: Board<R>,
ratsnest: Ratsnest,
}
impl<R: RulesTrait> Autorouter<R> {
pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> {
let ratsnest = Ratsnest::new(&layout)?;
Ok(Self { layout, ratsnest })
pub fn new(board: Board<R>) -> Result<Self, InsertionError> {
let ratsnest = Ratsnest::new(board.layout())?;
Ok(Self { board, ratsnest })
}
pub fn autoroute(
@ -195,7 +196,7 @@ impl<R: RulesTrait> Autorouter<R> {
.unwrap()
.band
.unwrap();
self.layout.remove_band(band);
self.board.layout_mut().remove_band(band);
}
}
@ -219,14 +220,14 @@ impl<R: RulesTrait> Autorouter<R> {
.unwrap()
.vertex_index();
selection.contains_node(&self.layout, source_vertex.into())
&& selection.contains_node(&self.layout, to_vertex.into())
selection.contains_node(&self.board, source_vertex.into())
&& selection.contains_node(&self.board, to_vertex.into())
})
.collect()
}
pub fn layout(&self) -> &Layout<R> {
&self.layout
pub fn board(&self) -> &Board<R> {
&self.board
}
pub fn ratsnest(&self) -> &Ratsnest {

122
src/autorouter/board.rs Normal file
View File

@ -0,0 +1,122 @@
use std::collections::HashMap;
use crate::{
drawing::{
dot::{FixedDotIndex, FixedDotWeight},
graph::PrimitiveIndex,
rules::RulesTrait,
seg::{FixedSegIndex, FixedSegWeight},
Infringement,
},
geometry::GenericNode,
graph::GenericIndex,
layout::{zone::ZoneWeight, Layout},
};
pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)]
pub struct Board<R: RulesTrait> {
layout: Layout<R>,
node_to_pin: HashMap<NodeIndex, String>,
}
impl<R: RulesTrait> Board<R> {
pub fn new(layout: Layout<R>) -> Self {
Self {
layout,
node_to_pin: HashMap::new(),
}
}
pub fn add_fixed_dot(
&mut self,
weight: FixedDotWeight,
maybe_pin: Option<String>,
) -> Result<FixedDotIndex, Infringement> {
let dot = self.layout.add_fixed_dot(weight)?;
if let Some(ref pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(dot.into()), pin.clone());
}
Ok(dot)
}
pub fn add_zone_fixed_dot(
&mut self,
weight: FixedDotWeight,
zone: GenericIndex<ZoneWeight>,
) -> Result<FixedDotIndex, Infringement> {
let dot = self.layout.add_zone_fixed_dot(weight, zone)?;
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) {
self.node_to_pin
.insert(GenericNode::Primitive(dot.into()), pin.to_string());
}
Ok(dot)
}
pub fn add_fixed_seg(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
maybe_pin: Option<String>,
) -> Result<FixedSegIndex, Infringement> {
let seg = self.layout.add_fixed_seg(from, to, weight)?;
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
}
Ok(seg)
}
pub fn add_zone_fixed_seg(
&mut self,
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
zone: GenericIndex<ZoneWeight>,
) -> Result<FixedSegIndex, Infringement> {
let seg = self.layout.add_zone_fixed_seg(from, to, weight, zone)?;
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) {
self.node_to_pin
.insert(GenericNode::Primitive(seg.into()), pin.to_string());
}
Ok(seg)
}
pub fn add_zone(
&mut self,
weight: ZoneWeight,
maybe_pin: Option<String>,
) -> GenericIndex<ZoneWeight> {
let zone = self.layout.add_zone(weight);
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Compound(zone.into()), pin.to_string());
}
zone
}
pub fn node_pin(&self, node: NodeIndex) -> Option<&String> {
self.node_to_pin.get(&node)
}
pub fn layout(&self) -> &Layout<R> {
&self.layout
}
pub fn layout_mut(&mut self) -> &mut Layout<R> {
&mut self.layout
}
}

View File

@ -1,4 +1,5 @@
mod autorouter;
pub mod board;
pub mod history;
pub mod invoker;
pub mod ratsnest;

View File

@ -2,9 +2,9 @@ use core::fmt;
use std::collections::HashSet;
use crate::{
autorouter::board::{Board, NodeIndex},
drawing::{graph::PrimitiveIndex, rules::RulesTrait},
graph::GenericIndex,
layout::{zone::ZoneWeight, Layout, NodeIndex},
};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@ -19,28 +19,28 @@ impl Selection {
}
}
pub fn toggle_at_node(&mut self, layout: &Layout<impl RulesTrait>, node: NodeIndex) {
let maybe_pin = layout.node_pin(node);
pub fn toggle_at_node(&mut self, board: &Board<impl RulesTrait>, node: NodeIndex) {
let maybe_pin = board.node_pin(node);
if let Some(ref pin) = maybe_pin {
if self.contains_node(layout, node) {
self.remove_pin(layout, pin);
if self.contains_node(board, node) {
self.remove_pin(board, pin);
} else {
self.add_pin(layout, pin);
self.add_pin(board, pin);
}
}
}
fn add_pin(&mut self, layout: &Layout<impl RulesTrait>, pin: &String) {
fn add_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) {
self.pins.insert(pin.clone());
}
fn remove_pin(&mut self, layout: &Layout<impl RulesTrait>, pin: &String) {
fn remove_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) {
self.pins.remove(pin);
}
pub fn contains_node(&self, layout: &Layout<impl RulesTrait>, node: NodeIndex) -> bool {
if let Some(pin) = layout.node_pin(node) {
pub fn contains_node(&self, board: &Board<impl RulesTrait>, node: NodeIndex) -> bool {
if let Some(pin) = board.node_pin(node) {
self.pins.contains(pin)
} else {
false

View File

@ -160,19 +160,19 @@ impl eframe::App for App {
if cfg!(target_arch = "wasm32") {
if let Ok(file_contents) = self.text_channel.1.try_recv() {
let design = DsnDesign::load_from_string(file_contents).unwrap();
let layout = design.make_layout();
self.overlay = Some(Overlay::new(&layout).unwrap());
let board = design.make_board();
self.overlay = Some(Overlay::new(&board).unwrap());
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
Autorouter::new(layout).unwrap(),
Autorouter::new(board).unwrap(),
))));
}
} else {
if let Ok(path) = self.text_channel.1.try_recv() {
let design = DsnDesign::load_from_file(&path).unwrap();
let layout = design.make_layout();
self.overlay = Some(Overlay::new(&layout).unwrap());
let board = design.make_board();
self.overlay = Some(Overlay::new(&board).unwrap());
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
Autorouter::new(layout).unwrap(),
Autorouter::new(board).unwrap(),
))));
}
}
@ -359,22 +359,22 @@ impl eframe::App for App {
self.shared_data.lock().unwrap(),
&mut self.overlay,
) {
let layout = &invoker.autorouter().layout();
let board = invoker.autorouter().board();
if ctx.input(|i| i.pointer.any_click()) {
overlay.click(
layout,
board,
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
);
}
for primitive in layout.drawing().layer_primitive_nodes(1) {
let shape = primitive.primitive(layout.drawing()).shape();
for primitive in board.layout().drawing().layer_primitive_nodes(1) {
let shape = primitive.primitive(board.layout().drawing()).shape();
let color = if shared_data.highlighteds.contains(&primitive)
|| overlay
.selection()
.contains_node(&layout, GenericNode::Primitive(primitive))
.contains_node(board, GenericNode::Primitive(primitive))
{
egui::Color32::from_rgb(100, 100, 255)
} else {
@ -383,25 +383,25 @@ impl eframe::App for App {
painter.paint_primitive(&shape, color);
}
for zone in layout.layer_zone_nodes(1) {
for zone in board.layout().layer_zone_nodes(1) {
let color = if overlay
.selection()
.contains_node(&layout, GenericNode::Compound(zone))
.contains_node(board, GenericNode::Compound(zone))
{
egui::Color32::from_rgb(100, 100, 255)
} else {
egui::Color32::from_rgb(52, 52, 200)
};
painter.paint_polygon(&layout.zone(zone).shape().polygon, color)
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
}
for primitive in layout.drawing().layer_primitive_nodes(0) {
let shape = primitive.primitive(layout.drawing()).shape();
for primitive in board.layout().drawing().layer_primitive_nodes(0) {
let shape = primitive.primitive(board.layout().drawing()).shape();
let color = if shared_data.highlighteds.contains(&primitive)
|| overlay
.selection()
.contains_node(&layout, GenericNode::Primitive(primitive))
.contains_node(board, GenericNode::Primitive(primitive))
{
egui::Color32::from_rgb(255, 100, 100)
} else {
@ -410,16 +410,16 @@ impl eframe::App for App {
painter.paint_primitive(&shape, color);
}
for zone in layout.layer_zone_nodes(0) {
for zone in board.layout().layer_zone_nodes(0) {
let color = if overlay
.selection()
.contains_node(&layout, GenericNode::Compound(zone))
.contains_node(board, GenericNode::Compound(zone))
{
egui::Color32::from_rgb(255, 100, 100)
} else {
egui::Color32::from_rgb(200, 52, 52)
};
painter.paint_polygon(&layout.zone(zone).shape().polygon, color)
painter.paint_polygon(&board.layout().zone(zone).shape().polygon, color)
}
if self.show_ratsnest {
@ -447,9 +447,16 @@ impl eframe::App for App {
if let Some(navmesh) = &shared_data.navmesh {
for edge in navmesh.edge_references() {
let from =
edge.source().primitive(layout.drawing()).shape().center();
let to = edge.target().primitive(layout.drawing()).shape().center();
let from = edge
.source()
.primitive(board.layout().drawing())
.shape()
.center();
let to = edge
.target()
.primitive(board.layout().drawing())
.shape()
.center();
let stroke = 'blk: {
if let (Some(source_pos), Some(target_pos)) = (
@ -486,14 +493,14 @@ impl eframe::App for App {
if let (Some(from), Some(to)) = (shared_data.from, shared_data.to) {
painter.paint_dot(
Circle {
pos: layout.drawing().primitive(from).shape().center(),
pos: board.layout().drawing().primitive(from).shape().center(),
r: 20.0,
},
egui::Color32::from_rgb(255, 255, 100),
);
painter.paint_dot(
Circle {
pos: layout.drawing().primitive(to).shape().center(),
pos: board.layout().drawing().primitive(to).shape().center(),
r: 20.0,
},
egui::Color32::from_rgb(255, 255, 100),

View File

@ -5,7 +5,7 @@ use rstar::AABB;
use spade::InsertionError;
use topola::{
autorouter::{ratsnest::Ratsnest, selection::Selection},
autorouter::{board::Board, ratsnest::Ratsnest, selection::Selection},
drawing::{
graph::{GetLayer, MakePrimitive},
primitive::MakePrimitiveShape,
@ -25,16 +25,17 @@ pub struct Overlay {
}
impl Overlay {
pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> {
pub fn new(board: &Board<impl RulesTrait>) -> Result<Self, InsertionError> {
Ok(Self {
ratsnest: Ratsnest::new(layout)?,
ratsnest: Ratsnest::new(board.layout())?,
selection: Selection::new(),
active_layer: 0,
})
}
pub fn click(&mut self, layout: &Layout<impl RulesTrait>, at: Point) {
let geoms: Vec<_> = layout
pub fn click(&mut self, board: &Board<impl RulesTrait>, at: Point) {
let geoms: Vec<_> = board
.layout()
.drawing()
.rtree()
.locate_in_envelope_intersecting(&AABB::<[f64; 3]>::from_corners(
@ -45,17 +46,17 @@ impl Overlay {
if let Some(geom) = geoms.iter().find(|&&geom| match geom.data {
NodeIndex::Primitive(primitive) => {
primitive.primitive(layout.drawing()).layer() == self.active_layer
primitive.primitive(board.layout().drawing()).layer() == self.active_layer
}
NodeIndex::Compound(compound) => false,
}) {
if self.toggle_selection_if_contains_point(layout, geom.data, at) {
if self.toggle_selection_if_contains_point(board, geom.data, at) {
return;
}
}
for geom in geoms {
if self.toggle_selection_if_contains_point(layout, geom.data, at) {
if self.toggle_selection_if_contains_point(board, geom.data, at) {
return;
}
}
@ -63,17 +64,19 @@ impl Overlay {
fn toggle_selection_if_contains_point(
&mut self,
layout: &Layout<impl RulesTrait>,
board: &Board<impl RulesTrait>,
node: NodeIndex,
p: Point,
) -> bool {
let shape: Shape = match node {
NodeIndex::Primitive(primitive) => primitive.primitive(layout.drawing()).shape().into(),
NodeIndex::Compound(compound) => layout.zone(compound).shape().into(),
NodeIndex::Primitive(primitive) => {
primitive.primitive(board.layout().drawing()).shape().into()
}
NodeIndex::Compound(compound) => board.layout().zone(compound).shape().into(),
};
if shape.contains_point(p) {
self.selection.toggle_at_node(layout, node);
self.selection.toggle_at_node(board, node);
return true;
}
false

View File

@ -251,7 +251,7 @@ fn main() -> Result<(), anyhow::Error> {
)?;
//let design = DsnDesign::load_from_file("tests/data/test/test.dsn")?;
//dbg!(&design);
let layout = Arc::new(Mutex::new(design.make_layout()));
let layout = Arc::new(Mutex::new(design.make_board()));
//let mut router = Router::new(layout);
let mut view = View {

View File

@ -4,6 +4,7 @@ use geo::{point, Point, Rotate, Translate};
use thiserror::Error;
use crate::{
autorouter::board::Board,
drawing::{dot::FixedDotWeight, seg::FixedSegWeight, Drawing},
dsn::{
de,
@ -43,9 +44,9 @@ impl DsnDesign {
Ok(Self { pcb })
}
pub fn make_layout(&self) -> Layout<DsnRules> {
pub fn make_board(&self) -> Board<DsnRules> {
let rules = DsnRules::from_pcb(&self.pcb);
let mut layout = Layout::new(Drawing::new(rules));
let mut board = Board::new(Layout::new(Drawing::new(rules)));
// mapping of pin id -> net id prepared for adding pins
let pin_nets = HashMap::<String, usize>::from_iter(
@ -55,7 +56,13 @@ impl DsnDesign {
.iter()
.map(|net| {
// resolve the id so we don't work with strings
let net_id = layout.drawing().rules().net_ids.get(&net.name).unwrap();
let net_id = board
.layout()
.drawing()
.rules()
.net_ids
.get(&net.name)
.unwrap();
// take the list of pins
// and for each pin id output (pin id, net id)
@ -92,13 +99,13 @@ impl DsnDesign {
match shape {
Shape::Circle(circle) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&circle.layer,
place.side == "front",
);
Self::add_circle(
&mut layout,
&mut board,
(place.x as f64, place.y as f64).into(),
place.rotation as f64,
(pin.x as f64, pin.y as f64).into(),
@ -111,13 +118,13 @@ impl DsnDesign {
}
Shape::Rect(rect) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&rect.layer,
place.side == "front",
);
Self::add_rect(
&mut layout,
&mut board,
(place.x as f64, place.y as f64).into(),
place.rotation as f64,
(pin.x as f64, pin.y as f64).into(),
@ -133,13 +140,13 @@ impl DsnDesign {
}
Shape::Path(path) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&path.layer,
place.side == "front",
);
Self::add_path(
&mut layout,
&mut board,
(place.x as f64, place.y as f64).into(),
place.rotation as f64,
(pin.x as f64, pin.y as f64).into(),
@ -153,13 +160,13 @@ impl DsnDesign {
}
Shape::Polygon(polygon) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&polygon.layer,
place.side == "front",
);
Self::add_polygon(
&mut layout,
&mut board,
(place.x as f64, place.y as f64).into(),
place.rotation as f64,
(pin.x as f64, pin.y as f64).into(),
@ -178,7 +185,13 @@ impl DsnDesign {
}
for via in &self.pcb.wiring.via_vec {
let net_id = *layout.drawing().rules().net_ids.get(&via.net).unwrap();
let net_id = *board
.layout()
.drawing()
.rules()
.net_ids
.get(&via.net)
.unwrap();
// find the padstack referenced by this via placement
let padstack = &self
@ -193,13 +206,13 @@ impl DsnDesign {
match shape {
Shape::Circle(circle) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&circle.layer,
true,
);
Self::add_circle(
&mut layout,
&mut board,
(0.0, 0.0).into(),
0.0,
(0.0, 0.0).into(),
@ -212,13 +225,13 @@ impl DsnDesign {
}
Shape::Rect(rect) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&rect.layer,
true,
);
Self::add_rect(
&mut layout,
&mut board,
(0.0, 0.0).into(),
0.0,
(0.0, 0.0).into(),
@ -234,13 +247,13 @@ impl DsnDesign {
}
Shape::Path(path) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&path.layer,
true,
);
Self::add_path(
&mut layout,
&mut board,
(0.0, 0.0).into(),
0.0,
(0.0, 0.0).into(),
@ -254,13 +267,13 @@ impl DsnDesign {
}
Shape::Polygon(polygon) => {
let layer = Self::layer(
&mut layout,
&mut board,
&self.pcb.structure.layer_vec,
&polygon.layer,
true,
);
Self::add_polygon(
&mut layout,
&mut board,
(0.0, 0.0).into(),
0.0,
(0.0, 0.0).into(),
@ -277,16 +290,23 @@ impl DsnDesign {
}
for wire in self.pcb.wiring.wire_vec.iter() {
let layer_id = *layout
let layer_id = *board
.layout()
.drawing()
.rules()
.layer_ids
.get(&wire.path.layer)
.unwrap();
let net_id = *layout.drawing().rules().net_ids.get(&wire.net).unwrap();
let net_id = *board
.layout()
.drawing()
.rules()
.net_ids
.get(&wire.net)
.unwrap();
Self::add_path(
&mut layout,
&mut board,
(0.0, 0.0).into(),
0.0,
(0.0, 0.0).into(),
@ -299,16 +319,22 @@ impl DsnDesign {
);
}
layout
board
}
fn layer(
layout: &Layout<DsnRules>,
board: &Board<DsnRules>,
layer_vec: &Vec<Layer>,
layer_name: &str,
front: bool,
) -> usize {
let image_layer = *layout.drawing().rules().layer_ids.get(layer_name).unwrap();
let image_layer = *board
.layout()
.drawing()
.rules()
.layer_ids
.get(layer_name)
.unwrap();
if front {
image_layer as usize
@ -318,7 +344,7 @@ impl DsnDesign {
}
fn add_circle(
layout: &mut Layout<DsnRules>,
board: &mut Board<DsnRules>,
place_pos: Point,
place_rot: f64,
pin_pos: Point,
@ -333,7 +359,7 @@ impl DsnDesign {
r,
};
layout
board
.add_fixed_dot(
FixedDotWeight {
circle,
@ -346,7 +372,7 @@ impl DsnDesign {
}
fn add_rect(
layout: &mut Layout<DsnRules>,
board: &mut Board<DsnRules>,
place_pos: Point,
place_rot: f64,
pin_pos: Point,
@ -359,7 +385,7 @@ impl DsnDesign {
net: usize,
maybe_pin: Option<String>,
) {
let zone = layout.add_zone(
let zone = board.add_zone(
SolidZoneWeight {
layer,
maybe_net: Some(net),
@ -369,7 +395,7 @@ impl DsnDesign {
);
// Corners.
let dot_1_1 = layout
let dot_1_1 = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -382,7 +408,7 @@ impl DsnDesign {
zone,
)
.unwrap();
let dot_2_1 = layout
let dot_2_1 = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -395,7 +421,7 @@ impl DsnDesign {
zone,
)
.unwrap();
let dot_2_2 = layout
let dot_2_2 = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -408,7 +434,7 @@ impl DsnDesign {
zone,
)
.unwrap();
let dot_1_2 = layout
let dot_1_2 = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -422,7 +448,7 @@ impl DsnDesign {
)
.unwrap();
// Sides.
layout
board
.add_zone_fixed_seg(
dot_1_1,
dot_2_1,
@ -434,7 +460,7 @@ impl DsnDesign {
zone,
)
.unwrap();
layout
board
.add_zone_fixed_seg(
dot_2_1,
dot_2_2,
@ -446,7 +472,7 @@ impl DsnDesign {
zone,
)
.unwrap();
layout
board
.add_zone_fixed_seg(
dot_2_2,
dot_1_2,
@ -458,7 +484,7 @@ impl DsnDesign {
zone,
)
.unwrap();
layout
board
.add_zone_fixed_seg(
dot_1_2,
dot_1_1,
@ -473,7 +499,7 @@ impl DsnDesign {
}
fn add_path(
layout: &mut Layout<DsnRules>,
board: &mut Board<DsnRules>,
place_pos: Point,
place_rot: f64,
pin_pos: Point,
@ -493,7 +519,7 @@ impl DsnDesign {
coords[0].x as f64,
coords[0].y as f64,
);
let mut prev_index = layout
let mut prev_index = board
.add_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -522,7 +548,7 @@ impl DsnDesign {
continue;
}
let index = layout
let index = board
.add_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -537,7 +563,7 @@ impl DsnDesign {
.unwrap();
// add a seg between the current and previous coords
let _ = layout
let _ = board
.add_fixed_seg(
prev_index,
index,
@ -556,7 +582,7 @@ impl DsnDesign {
}
fn add_polygon(
layout: &mut Layout<DsnRules>,
board: &mut Board<DsnRules>,
place_pos: Point,
place_rot: f64,
pin_pos: Point,
@ -567,7 +593,7 @@ impl DsnDesign {
net: usize,
maybe_pin: Option<String>,
) {
let zone = layout.add_zone(
let zone = board.add_zone(
SolidZoneWeight {
layer,
maybe_net: Some(net),
@ -577,7 +603,7 @@ impl DsnDesign {
);
// add the first coordinate in the wire path as a dot and save its index
let mut prev_index = layout
let mut prev_index = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -602,7 +628,7 @@ impl DsnDesign {
// iterate through path coords starting from the second
for coord in coords.iter().skip(1) {
let index = layout
let index = board
.add_zone_fixed_dot(
FixedDotWeight {
circle: Circle {
@ -626,7 +652,7 @@ impl DsnDesign {
.unwrap();
// add a seg between the current and previous coords
let _ = layout
let _ = board
.add_zone_fixed_seg(
prev_index,
index,

View File

@ -33,15 +33,11 @@ pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)]
pub struct Layout<R: RulesTrait> {
drawing: Drawing<ZoneWeight, R>,
node_to_pin: HashMap<NodeIndex, String>,
}
impl<R: RulesTrait> Layout<R> {
pub fn new(drawing: Drawing<ZoneWeight, R>) -> Self {
Self {
drawing,
node_to_pin: HashMap::new(),
}
Self { drawing }
}
pub fn remove_band(&mut self, band: BandIndex) {
@ -65,19 +61,8 @@ impl<R: RulesTrait> Layout<R> {
.insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw)
}
pub fn add_fixed_dot(
&mut self,
weight: FixedDotWeight,
maybe_pin: Option<String>,
) -> Result<FixedDotIndex, Infringement> {
let dot = self.drawing.add_fixed_dot(weight)?;
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(dot.into()), pin);
}
Ok(dot)
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, Infringement> {
self.drawing.add_fixed_dot(weight)
}
pub fn add_zone_fixed_dot(
@ -85,7 +70,6 @@ impl<R: RulesTrait> Layout<R> {
weight: FixedDotWeight,
zone: GenericIndex<ZoneWeight>,
) -> Result<FixedDotIndex, Infringement> {
let pin = self.node_pin(GenericNode::Compound(zone));
let maybe_dot = self.drawing.add_fixed_dot(weight);
if let Ok(dot) = maybe_dot {
@ -100,16 +84,8 @@ impl<R: RulesTrait> Layout<R> {
from: FixedDotIndex,
to: FixedDotIndex,
weight: FixedSegWeight,
maybe_pin: Option<String>,
) -> Result<FixedSegIndex, Infringement> {
let seg = self.drawing.add_fixed_seg(from, to, weight)?;
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Primitive(seg.into()), pin);
}
Ok(seg)
self.drawing.add_fixed_seg(from, to, weight)
}
pub fn add_zone_fixed_seg(
@ -119,8 +95,7 @@ impl<R: RulesTrait> Layout<R> {
weight: FixedSegWeight,
zone: GenericIndex<ZoneWeight>,
) -> Result<FixedSegIndex, Infringement> {
let pin = self.node_pin(GenericNode::Compound(zone));
let maybe_seg = self.add_fixed_seg(from, to, weight, pin.cloned());
let maybe_seg = self.add_fixed_seg(from, to, weight);
if let Ok(seg) = maybe_seg {
self.drawing.add_to_compound(seg, zone);
@ -151,19 +126,8 @@ impl<R: RulesTrait> Layout<R> {
self.drawing.move_dot(dot, to)
}
pub fn add_zone(
&mut self,
weight: ZoneWeight,
maybe_pin: Option<String>,
) -> GenericIndex<ZoneWeight> {
let zone = self.drawing.add_compound(weight);
if let Some(pin) = maybe_pin {
self.node_to_pin
.insert(GenericNode::Compound(zone.into()), pin);
}
zone
pub fn add_zone(&mut self, weight: ZoneWeight) -> GenericIndex<ZoneWeight> {
self.drawing.add_compound(weight)
}
pub fn zones<W: 'static>(
@ -173,10 +137,6 @@ impl<R: RulesTrait> Layout<R> {
self.drawing.compounds(node)
}
pub fn node_pin(&self, node: NodeIndex) -> Option<&String> {
self.node_to_pin.get(&node)
}
pub fn band_length(&self, face: DotIndex) -> f64 {
// TODO.
0.0

View File

@ -171,7 +171,6 @@ impl<'a, R: RulesTrait> Router<'a, R> {
) -> Result<BandIndex, RouterError> {
let from = self.navmesh.from();
let to = self.navmesh.to();
//let mut tracer = self.tracer();
let mut tracer = Tracer::new(self.layout);
let trace = tracer.start(from, width);
@ -201,10 +200,6 @@ impl<'a, R: RulesTrait> Router<'a, R> {
self.route_band(width, observer)
}*/
/*fn tracer(&mut self) -> Tracer<R> {
Tracer::new(self.layout)
}*/
pub fn layout(&mut self) -> &mut Layout<R> {
self.layout
}

View File

@ -18,13 +18,14 @@ use topola::{
#[test]
fn test() {
let design = DsnDesign::load_from_file("tests/data/0603_breakout/0603_breakout.dsn").unwrap();
let mut invoker = Invoker::new(Autorouter::new(design.make_layout()).unwrap());
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
let file = File::open("tests/data/0603_breakout/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let mut unionfind = UnionFind::new(
invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()
@ -34,6 +35,7 @@ fn test() {
for edge in invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()