autorouter: select nodes with pin-layer pairs, not only pins

We call these pairs "selectors".

The command file format has been thus changed. I've upgraded the command
files in tests with the following command:

    jq ".done?.[].Autoroute |= {selectors: ([.pins.[] | {pin: ., layer: \"F.Cu\"}])}" $FILE | sponge $FILE

Where $FILE is the name of the upgraded command file.
This commit is contained in:
Mikolaj Wielgus 2024-06-04 01:47:16 +02:00
parent bb6d975dac
commit 5eeeb5a004
7 changed files with 270 additions and 93 deletions

View File

@ -22,7 +22,7 @@ pub type NodeIndex = GenericNode<PrimitiveIndex, GenericIndex<ZoneWeight>>;
#[derive(Debug)] #[derive(Debug)]
pub struct Board<R: RulesTrait> { pub struct Board<R: RulesTrait> {
layout: Layout<R>, layout: Layout<R>,
node_to_pin: HashMap<NodeIndex, String>, node_to_pinname: HashMap<NodeIndex, String>,
layer_to_layername: HashMap<u64, String>, layer_to_layername: HashMap<u64, String>,
net_to_netname: HashMap<usize, String>, net_to_netname: HashMap<usize, String>,
} }
@ -31,7 +31,7 @@ impl<R: RulesTrait> Board<R> {
pub fn new(layout: Layout<R>) -> Self { pub fn new(layout: Layout<R>) -> Self {
Self { Self {
layout, layout,
node_to_pin: HashMap::new(), node_to_pinname: HashMap::new(),
layer_to_layername: HashMap::new(), layer_to_layername: HashMap::new(),
net_to_netname: HashMap::new(), net_to_netname: HashMap::new(),
} }
@ -45,7 +45,7 @@ impl<R: RulesTrait> Board<R> {
let dot = self.layout.add_fixed_dot(weight)?; let dot = self.layout.add_fixed_dot(weight)?;
if let Some(ref pin) = maybe_pin { if let Some(ref pin) = maybe_pin {
self.node_to_pin self.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin.clone()); .insert(GenericNode::Primitive(dot.into()), pin.clone());
} }
@ -59,8 +59,8 @@ impl<R: RulesTrait> Board<R> {
) -> Result<FixedDotIndex, Infringement> { ) -> Result<FixedDotIndex, Infringement> {
let dot = self.layout.add_zone_fixed_dot(weight, zone)?; let dot = self.layout.add_zone_fixed_dot(weight, zone)?;
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) { if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) {
self.node_to_pin self.node_to_pinname
.insert(GenericNode::Primitive(dot.into()), pin.to_string()); .insert(GenericNode::Primitive(dot.into()), pin.to_string());
} }
@ -77,7 +77,7 @@ impl<R: RulesTrait> Board<R> {
let seg = self.layout.add_fixed_seg(from, to, weight)?; let seg = self.layout.add_fixed_seg(from, to, weight)?;
if let Some(pin) = maybe_pin { if let Some(pin) = maybe_pin {
self.node_to_pin self.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin.to_string()); .insert(GenericNode::Primitive(seg.into()), pin.to_string());
} }
@ -93,8 +93,8 @@ impl<R: RulesTrait> Board<R> {
) -> Result<FixedSegIndex, Infringement> { ) -> Result<FixedSegIndex, Infringement> {
let seg = self.layout.add_zone_fixed_seg(from, to, weight, zone)?; let seg = self.layout.add_zone_fixed_seg(from, to, weight, zone)?;
if let Some(pin) = self.node_pin(GenericNode::Compound(zone)) { if let Some(pin) = self.node_pinname(GenericNode::Compound(zone)) {
self.node_to_pin self.node_to_pinname
.insert(GenericNode::Primitive(seg.into()), pin.to_string()); .insert(GenericNode::Primitive(seg.into()), pin.to_string());
} }
@ -109,7 +109,7 @@ impl<R: RulesTrait> Board<R> {
let zone = self.layout.add_zone(weight); let zone = self.layout.add_zone(weight);
if let Some(pin) = maybe_pin { if let Some(pin) = maybe_pin {
self.node_to_pin self.node_to_pinname
.insert(GenericNode::Compound(zone.into()), pin.to_string()); .insert(GenericNode::Compound(zone.into()), pin.to_string());
} }
@ -143,8 +143,12 @@ impl<R: RulesTrait> Board<R> {
} }
} }
pub fn node_pin(&self, node: NodeIndex) -> Option<&String> { pub fn node_pinname(&self, node: NodeIndex) -> Option<&String> {
self.node_to_pin.get(&node) 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> { pub fn netname(&self, net: usize) -> Option<&String> {

View File

@ -11,7 +11,7 @@ pub enum HistoryError {
NoNextCommand, NoNextCommand,
} }
#[derive(Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct History { pub struct History {
done: Vec<Command>, done: Vec<Command>,
undone: Vec<Command>, undone: Vec<Command>,

View File

@ -1,5 +1,4 @@
use core::fmt; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -26,7 +25,7 @@ pub enum InvokerStatus {
Finished, Finished,
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Command { pub enum Command {
Autoroute(Selection), Autoroute(Selection),
} }

View File

@ -1,49 +1,78 @@
use core::fmt;
use std::collections::HashSet; use std::collections::HashSet;
use serde::{Deserialize, Serialize};
use crate::{ use crate::{
autorouter::board::{Board, NodeIndex}, autorouter::board::{Board, NodeIndex},
drawing::{graph::PrimitiveIndex, rules::RulesTrait}, drawing::{
graph::{GetLayer, MakePrimitive, PrimitiveIndex},
rules::RulesTrait,
},
graph::GenericIndex, 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 { pub struct Selection {
pins: HashSet<String>, selectors: HashSet<Selector>,
} }
impl Selection { impl Selection {
pub fn new() -> Selection { pub fn new() -> Selection {
Self { Self {
pins: HashSet::new(), selectors: HashSet::new(),
} }
} }
pub fn toggle_at_node(&mut self, board: &Board<impl RulesTrait>, node: NodeIndex) { pub fn toggle_at_node(&mut self, board: &Board<impl RulesTrait>, 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) {
if self.contains_node(board, node) { self.deselect(board, &selector);
self.remove_pin(board, pin); } else {
} else { self.select(board, selector);
self.add_pin(board, pin);
}
} }
} }
fn add_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) { fn select(&mut self, board: &Board<impl RulesTrait>, selector: Selector) {
self.pins.insert(pin.clone()); self.selectors.insert(selector);
} }
fn remove_pin(&mut self, board: &Board<impl RulesTrait>, pin: &String) { fn deselect(&mut self, board: &Board<impl RulesTrait>, selector: &Selector) {
self.pins.remove(pin); self.selectors.remove(selector);
} }
pub fn contains_node(&self, board: &Board<impl RulesTrait>, node: NodeIndex) -> bool { pub fn contains_node(&self, board: &Board<impl RulesTrait>, node: NodeIndex) -> bool {
if let Some(pin) = board.node_pin(node) { let Some(selector) = self.node_selector(board, node) else {
self.pins.contains(pin) return false;
};
self.selectors.contains(&selector)
}
fn node_selector(&self, board: &Board<impl RulesTrait>, node: NodeIndex) -> Option<Selector> {
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 { } else {
false None
} }
} }
} }

View File

@ -1,8 +1,9 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::drawing::rules::{Conditions, RulesTrait}; use crate::{
drawing::rules::{Conditions, RulesTrait},
use super::structure::Pcb; dsn::structure::Pcb,
};
#[derive(Debug)] #[derive(Debug)]
pub struct DsnRule { pub struct DsnRule {

View File

@ -2,20 +2,32 @@
"done": [ "done": [
{ {
"Autoroute": { "Autoroute": {
"pins": [ "selectors": [
"R1-2", {
"J1-2" "pin": "R1-2",
"layer": "F.Cu"
},
{
"pin": "J1-2",
"layer": "F.Cu"
}
] ]
} }
}, },
{ {
"Autoroute": { "Autoroute": {
"pins": [ "selectors": [
"J1-1", {
"R1-1" "pin": "J1-1",
"layer": "F.Cu"
},
{
"pin": "R1-1",
"layer": "F.Cu"
}
] ]
} }
} }
], ],
"undone": [] "undone": []
} }

View File

@ -2,72 +2,204 @@
"done": [ "done": [
{ {
"Autoroute": { "Autoroute": {
"pins": [ "selectors": [
"L3-1", {
"L3-2", "pin": "L3-1",
"C3-1", "layer": "F.Cu"
"L1-2", },
"C2-1", {
"L2-2", "pin": "L3-2",
"J2-1", "layer": "F.Cu"
"J1-1", },
"L1-1", {
"C1-1", "pin": "C3-1",
"L2-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": { "Autoroute": {
"pins": [ "selectors": [
"C6-1", {
"J4-1", "pin": "C6-1",
"L5-1", "layer": "F.Cu"
"J3-1", },
"C5-1", {
"L6-2", "pin": "J4-1",
"L5-2", "layer": "F.Cu"
"C4-1", },
"L6-1", {
"L4-1", "pin": "L5-1",
"L4-2" "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": { "Autoroute": {
"pins": [ "selectors": [
"C9-1", {
"J5-1", "pin": "C9-1",
"L7-1", "layer": "F.Cu"
"J6-1", },
"L9-2", {
"C7-1", "pin": "J5-1",
"L8-2", "layer": "F.Cu"
"L9-1", },
"L8-1", {
"L7-2", "pin": "L7-1",
"C8-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": { "Autoroute": {
"pins": [ "selectors": [
"L10-1", {
"L12-1", "pin": "L10-1",
"J7-1", "layer": "F.Cu"
"L10-2", },
"C10-1", {
"C12-1", "pin": "L12-1",
"L12-2", "layer": "F.Cu"
"L11-1", },
"C11-1", {
"L11-2", "pin": "J7-1",
"J8-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": [] "undone": []
} }