diff --git a/src/autorouter/board.rs b/src/autorouter/board.rs index e944694..b7bbc5d 100644 --- a/src/autorouter/board.rs +++ b/src/autorouter/board.rs @@ -22,7 +22,7 @@ pub type NodeIndex = GenericNode>; #[derive(Debug)] pub struct Board { layout: Layout, - node_to_pin: HashMap, + node_to_pinname: HashMap, layer_to_layername: HashMap, net_to_netname: HashMap, } @@ -31,7 +31,7 @@ impl Board { pub fn new(layout: Layout) -> Self { Self { layout, - node_to_pin: HashMap::new(), + node_to_pinname: HashMap::new(), layer_to_layername: HashMap::new(), net_to_netname: HashMap::new(), } @@ -45,7 +45,7 @@ impl Board { let dot = self.layout.add_fixed_dot(weight)?; if let Some(ref pin) = maybe_pin { - self.node_to_pin + self.node_to_pinname .insert(GenericNode::Primitive(dot.into()), pin.clone()); } @@ -59,8 +59,8 @@ impl Board { ) -> 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 + if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) { + self.node_to_pinname .insert(GenericNode::Primitive(dot.into()), pin.to_string()); } @@ -77,7 +77,7 @@ impl Board { let seg = self.layout.add_fixed_seg(from, to, weight)?; if let Some(pin) = maybe_pin { - self.node_to_pin + self.node_to_pinname .insert(GenericNode::Primitive(seg.into()), pin.to_string()); } @@ -93,8 +93,8 @@ impl Board { ) -> 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 + if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) { + self.node_to_pinname .insert(GenericNode::Primitive(seg.into()), pin.to_string()); } @@ -109,7 +109,7 @@ impl Board { let zone = self.layout.add_zone(weight); if let Some(pin) = maybe_pin { - self.node_to_pin + self.node_to_pinname .insert(GenericNode::Compound(zone.into()), pin.to_string()); } @@ -143,8 +143,12 @@ impl Board { } } - pub fn node_pin(&self, node: NodeIndex) -> Option<&String> { - self.node_to_pin.get(&node) + pub fn node_pinname(&self, node: NodeIndex) -> Option<&String> { + self.node_to_pinname.get(&node) + } + + pub fn layername(&self, layer: u64) -> Option<&String> { + self.layer_to_layername.get(&layer) } pub fn netname(&self, net: usize) -> Option<&String> { diff --git a/src/autorouter/history.rs b/src/autorouter/history.rs index bf400e9..ebe819b 100644 --- a/src/autorouter/history.rs +++ b/src/autorouter/history.rs @@ -11,7 +11,7 @@ pub enum HistoryError { NoNextCommand, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct History { done: Vec, undone: Vec, diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index d86ab22..6ba43e6 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -1,5 +1,4 @@ -use core::fmt; - +use serde::{Deserialize, Serialize}; use thiserror::Error; use crate::{ @@ -26,7 +25,7 @@ pub enum InvokerStatus { Finished, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum Command { Autoroute(Selection), } diff --git a/src/autorouter/selection.rs b/src/autorouter/selection.rs index b4fa476..16037d7 100644 --- a/src/autorouter/selection.rs +++ b/src/autorouter/selection.rs @@ -1,49 +1,78 @@ -use core::fmt; use std::collections::HashSet; +use serde::{Deserialize, Serialize}; + use crate::{ autorouter::board::{Board, NodeIndex}, - drawing::{graph::PrimitiveIndex, rules::RulesTrait}, + drawing::{ + graph::{GetLayer, MakePrimitive, PrimitiveIndex}, + rules::RulesTrait, + }, graph::GenericIndex, }; -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] +pub struct Selector { + pin: String, + layer: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Selection { - pins: HashSet, + selectors: HashSet, } impl Selection { pub fn new() -> Selection { Self { - pins: HashSet::new(), + selectors: HashSet::new(), } } pub fn toggle_at_node(&mut self, board: &Board, node: NodeIndex) { - let maybe_pin = board.node_pin(node); + let Some(selector) = self.node_selector(board, node) else { + return; + }; - if let Some(ref pin) = maybe_pin { - if self.contains_node(board, node) { - self.remove_pin(board, pin); - } else { - self.add_pin(board, pin); - } + if self.contains_node(board, node) { + self.deselect(board, &selector); + } else { + self.select(board, selector); } } - fn add_pin(&mut self, board: &Board, pin: &String) { - self.pins.insert(pin.clone()); + fn select(&mut self, board: &Board, selector: Selector) { + self.selectors.insert(selector); } - fn remove_pin(&mut self, board: &Board, pin: &String) { - self.pins.remove(pin); + fn deselect(&mut self, board: &Board, selector: &Selector) { + self.selectors.remove(selector); } pub fn contains_node(&self, board: &Board, node: NodeIndex) -> bool { - if let Some(pin) = board.node_pin(node) { - self.pins.contains(pin) + let Some(selector) = self.node_selector(board, node) else { + return false; + }; + + self.selectors.contains(&selector) + } + + fn node_selector(&self, board: &Board, node: NodeIndex) -> Option { + let layer = match node { + NodeIndex::Primitive(primitive) => { + primitive.primitive(board.layout().drawing()).layer() + } + NodeIndex::Compound(compound) => board.layout().zone(compound).layer(), + }; + + if let (Some(pinname), Some(layername)) = (board.node_pinname(node), board.layername(layer)) + { + Some(Selector { + pin: pinname.to_string(), + layer: layername.to_string(), + }) } else { - false + None } } } diff --git a/src/dsn/rules.rs b/src/dsn/rules.rs index 5c8880d..beba63d 100644 --- a/src/dsn/rules.rs +++ b/src/dsn/rules.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; -use crate::drawing::rules::{Conditions, RulesTrait}; - -use super::structure::Pcb; +use crate::{ + drawing::rules::{Conditions, RulesTrait}, + dsn::structure::Pcb, +}; #[derive(Debug)] pub struct DsnRule { diff --git a/tests/data/0603_breakout/autoroute_all.cmd b/tests/data/0603_breakout/autoroute_all.cmd index 145fe4b..488f390 100644 --- a/tests/data/0603_breakout/autoroute_all.cmd +++ b/tests/data/0603_breakout/autoroute_all.cmd @@ -2,20 +2,32 @@ "done": [ { "Autoroute": { - "pins": [ - "R1-2", - "J1-2" + "selectors": [ + { + "pin": "R1-2", + "layer": "F.Cu" + }, + { + "pin": "J1-2", + "layer": "F.Cu" + } ] } }, { "Autoroute": { - "pins": [ - "J1-1", - "R1-1" + "selectors": [ + { + "pin": "J1-1", + "layer": "F.Cu" + }, + { + "pin": "R1-1", + "layer": "F.Cu" + } ] } } ], "undone": [] -} \ No newline at end of file +} diff --git a/tests/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd b/tests/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd index 66bd152..fd8ef4c 100644 --- a/tests/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd +++ b/tests/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd @@ -2,72 +2,204 @@ "done": [ { "Autoroute": { - "pins": [ - "L3-1", - "L3-2", - "C3-1", - "L1-2", - "C2-1", - "L2-2", - "J2-1", - "J1-1", - "L1-1", - "C1-1", - "L2-1" + "selectors": [ + { + "pin": "L3-1", + "layer": "F.Cu" + }, + { + "pin": "L3-2", + "layer": "F.Cu" + }, + { + "pin": "C3-1", + "layer": "F.Cu" + }, + { + "pin": "L1-2", + "layer": "F.Cu" + }, + { + "pin": "C2-1", + "layer": "F.Cu" + }, + { + "pin": "L2-2", + "layer": "F.Cu" + }, + { + "pin": "J2-1", + "layer": "F.Cu" + }, + { + "pin": "J1-1", + "layer": "F.Cu" + }, + { + "pin": "L1-1", + "layer": "F.Cu" + }, + { + "pin": "C1-1", + "layer": "F.Cu" + }, + { + "pin": "L2-1", + "layer": "F.Cu" + } ] } }, { "Autoroute": { - "pins": [ - "C6-1", - "J4-1", - "L5-1", - "J3-1", - "C5-1", - "L6-2", - "L5-2", - "C4-1", - "L6-1", - "L4-1", - "L4-2" + "selectors": [ + { + "pin": "C6-1", + "layer": "F.Cu" + }, + { + "pin": "J4-1", + "layer": "F.Cu" + }, + { + "pin": "L5-1", + "layer": "F.Cu" + }, + { + "pin": "J3-1", + "layer": "F.Cu" + }, + { + "pin": "C5-1", + "layer": "F.Cu" + }, + { + "pin": "L6-2", + "layer": "F.Cu" + }, + { + "pin": "L5-2", + "layer": "F.Cu" + }, + { + "pin": "C4-1", + "layer": "F.Cu" + }, + { + "pin": "L6-1", + "layer": "F.Cu" + }, + { + "pin": "L4-1", + "layer": "F.Cu" + }, + { + "pin": "L4-2", + "layer": "F.Cu" + } ] } }, { "Autoroute": { - "pins": [ - "C9-1", - "J5-1", - "L7-1", - "J6-1", - "L9-2", - "C7-1", - "L8-2", - "L9-1", - "L8-1", - "L7-2", - "C8-1" + "selectors": [ + { + "pin": "C9-1", + "layer": "F.Cu" + }, + { + "pin": "J5-1", + "layer": "F.Cu" + }, + { + "pin": "L7-1", + "layer": "F.Cu" + }, + { + "pin": "J6-1", + "layer": "F.Cu" + }, + { + "pin": "L9-2", + "layer": "F.Cu" + }, + { + "pin": "C7-1", + "layer": "F.Cu" + }, + { + "pin": "L8-2", + "layer": "F.Cu" + }, + { + "pin": "L9-1", + "layer": "F.Cu" + }, + { + "pin": "L8-1", + "layer": "F.Cu" + }, + { + "pin": "L7-2", + "layer": "F.Cu" + }, + { + "pin": "C8-1", + "layer": "F.Cu" + } ] } }, { "Autoroute": { - "pins": [ - "L10-1", - "L12-1", - "J7-1", - "L10-2", - "C10-1", - "C12-1", - "L12-2", - "L11-1", - "C11-1", - "L11-2", - "J8-1" + "selectors": [ + { + "pin": "L10-1", + "layer": "F.Cu" + }, + { + "pin": "L12-1", + "layer": "F.Cu" + }, + { + "pin": "J7-1", + "layer": "F.Cu" + }, + { + "pin": "L10-2", + "layer": "F.Cu" + }, + { + "pin": "C10-1", + "layer": "F.Cu" + }, + { + "pin": "C12-1", + "layer": "F.Cu" + }, + { + "pin": "L12-2", + "layer": "F.Cu" + }, + { + "pin": "L11-1", + "layer": "F.Cu" + }, + { + "pin": "C11-1", + "layer": "F.Cu" + }, + { + "pin": "L11-2", + "layer": "F.Cu" + }, + { + "pin": "J8-1", + "layer": "F.Cu" + } ] } } ], "undone": [] -} \ No newline at end of file +}