diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index ca878d0..dd83062 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -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 { - layout: Layout, + board: Board, ratsnest: Ratsnest, } impl Autorouter { - pub fn new(layout: Layout) -> Result { - let ratsnest = Ratsnest::new(&layout)?; - Ok(Self { layout, ratsnest }) + pub fn new(board: Board) -> Result { + let ratsnest = Ratsnest::new(board.layout())?; + Ok(Self { board, ratsnest }) } pub fn autoroute( @@ -195,7 +196,7 @@ impl Autorouter { .unwrap() .band .unwrap(); - self.layout.remove_band(band); + self.board.layout_mut().remove_band(band); } } @@ -219,14 +220,14 @@ impl Autorouter { .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 { - &self.layout + pub fn board(&self) -> &Board { + &self.board } pub fn ratsnest(&self) -> &Ratsnest { diff --git a/src/autorouter/board.rs b/src/autorouter/board.rs new file mode 100644 index 0000000..bf0fa8c --- /dev/null +++ b/src/autorouter/board.rs @@ -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>; + +#[derive(Debug)] +pub struct Board { + layout: Layout, + node_to_pin: HashMap, +} + +impl Board { + pub fn new(layout: Layout) -> Self { + Self { + layout, + node_to_pin: HashMap::new(), + } + } + + pub fn add_fixed_dot( + &mut self, + weight: FixedDotWeight, + maybe_pin: Option, + ) -> Result { + 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, + ) -> Result { + 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, + ) -> Result { + 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, + ) -> Result { + 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, + ) -> GenericIndex { + 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 { + &self.layout + } + + pub fn layout_mut(&mut self) -> &mut Layout { + &mut self.layout + } +} diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index 41fb8d7..fe4857d 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -1,4 +1,5 @@ mod autorouter; +pub mod board; pub mod history; pub mod invoker; pub mod ratsnest; diff --git a/src/autorouter/selection.rs b/src/autorouter/selection.rs index cef6698..b4fa476 100644 --- a/src/autorouter/selection.rs +++ b/src/autorouter/selection.rs @@ -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, node: NodeIndex) { - let maybe_pin = layout.node_pin(node); + pub fn toggle_at_node(&mut self, board: &Board, 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, pin: &String) { + fn add_pin(&mut self, board: &Board, pin: &String) { self.pins.insert(pin.clone()); } - fn remove_pin(&mut self, layout: &Layout, pin: &String) { + fn remove_pin(&mut self, board: &Board, pin: &String) { self.pins.remove(pin); } - pub fn contains_node(&self, layout: &Layout, node: NodeIndex) -> bool { - if let Some(pin) = layout.node_pin(node) { + pub fn contains_node(&self, board: &Board, node: NodeIndex) -> bool { + if let Some(pin) = board.node_pin(node) { self.pins.contains(pin) } else { false diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 13ca75c..fe0cb35 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -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), diff --git a/src/bin/topola-egui/overlay.rs b/src/bin/topola-egui/overlay.rs index d0464ff..84b0aad 100644 --- a/src/bin/topola-egui/overlay.rs +++ b/src/bin/topola-egui/overlay.rs @@ -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) -> Result { + pub fn new(board: &Board) -> Result { Ok(Self { - ratsnest: Ratsnest::new(layout)?, + ratsnest: Ratsnest::new(board.layout())?, selection: Selection::new(), active_layer: 0, }) } - pub fn click(&mut self, layout: &Layout, at: Point) { - let geoms: Vec<_> = layout + pub fn click(&mut self, board: &Board, 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, + board: &Board, 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 diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 8c7343c..083d3f1 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -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 { diff --git a/src/dsn/design.rs b/src/dsn/design.rs index f3acc47..5ffc49d 100644 --- a/src/dsn/design.rs +++ b/src/dsn/design.rs @@ -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 { + pub fn make_board(&self) -> Board { 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::::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, + board: &Board, layer_vec: &Vec, 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, + board: &mut Board, 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, + board: &mut Board, place_pos: Point, place_rot: f64, pin_pos: Point, @@ -359,7 +385,7 @@ impl DsnDesign { net: usize, maybe_pin: Option, ) { - 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, + board: &mut Board, 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, + board: &mut Board, place_pos: Point, place_rot: f64, pin_pos: Point, @@ -567,7 +593,7 @@ impl DsnDesign { net: usize, maybe_pin: Option, ) { - 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, diff --git a/src/layout/layout.rs b/src/layout/layout.rs index d1bc613..c51ab5d 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -33,15 +33,11 @@ pub type NodeIndex = GenericNode>; #[derive(Debug)] pub struct Layout { drawing: Drawing, - node_to_pin: HashMap, } impl Layout { pub fn new(drawing: Drawing) -> Self { - Self { - drawing, - node_to_pin: HashMap::new(), - } + Self { drawing } } pub fn remove_band(&mut self, band: BandIndex) { @@ -65,19 +61,8 @@ impl Layout { .insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw) } - pub fn add_fixed_dot( - &mut self, - weight: FixedDotWeight, - maybe_pin: Option, - ) -> Result { - 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 { + self.drawing.add_fixed_dot(weight) } pub fn add_zone_fixed_dot( @@ -85,7 +70,6 @@ impl Layout { weight: FixedDotWeight, zone: GenericIndex, ) -> Result { - 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 Layout { from: FixedDotIndex, to: FixedDotIndex, weight: FixedSegWeight, - maybe_pin: Option, ) -> Result { - 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 Layout { weight: FixedSegWeight, zone: GenericIndex, ) -> Result { - 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 Layout { self.drawing.move_dot(dot, to) } - pub fn add_zone( - &mut self, - weight: ZoneWeight, - maybe_pin: Option, - ) -> GenericIndex { - 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 { + self.drawing.add_compound(weight) } pub fn zones( @@ -173,10 +137,6 @@ impl Layout { 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 diff --git a/src/router/router.rs b/src/router/router.rs index ff7d94f..68691b1 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -171,7 +171,6 @@ impl<'a, R: RulesTrait> Router<'a, R> { ) -> Result { 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 { - Tracer::new(self.layout) - }*/ - pub fn layout(&mut self) -> &mut Layout { self.layout } diff --git a/tests/0603_breakout.rs b/tests/0603_breakout.rs index 82a50ec..09074b9 100644 --- a/tests/0603_breakout.rs +++ b/tests/0603_breakout.rs @@ -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()