diff --git a/src/autorouter/selection.rs b/src/autorouter/selection.rs index c6aabc6..ea200da 100644 --- a/src/autorouter/selection.rs +++ b/src/autorouter/selection.rs @@ -4,7 +4,10 @@ use serde::{Deserialize, Serialize}; use crate::{ board::{mesadata::AccessMesadata, Board}, - drawing::graph::{GetLayer, MakePrimitive}, + drawing::{ + band::BandUid, + graph::{GetLayer, MakePrimitive, PrimitiveIndex}, + }, geometry::{compound::ManageCompounds, GenericNode}, graph::{GenericIndex, GetPetgraphIndex}, layout::{poly::PolyWeight, CompoundWeight, NodeIndex}, @@ -19,12 +22,15 @@ pub struct Selector { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Selection { selectors: HashSet, + #[serde(skip)] + selected_bands: HashSet, } impl Selection { pub fn new() -> Self { Self { selectors: HashSet::new(), + selected_bands: HashSet::new(), } } @@ -57,14 +63,18 @@ impl Selection { } pub fn toggle_at_node(&mut self, board: &Board, node: NodeIndex) { - let Some(selector) = self.node_selector(board, node) else { - return; - }; - - if self.contains_node(board, node) { - self.deselect(board, &selector); - } else { - self.select(board, selector); + if let Some(selector) = self.node_selector(board, node) { + if self.contains_node(board, node) { + self.deselect(board, &selector); + } else { + self.select(board, selector); + } + } else if let Some(band) = self.node_band(board, node) { + if self.contains_node(board, node) { + self.deselect_band(board, band); + } else { + self.select_band(board, band); + } } } @@ -76,12 +86,38 @@ impl Selection { self.selectors.remove(selector); } + fn select_band(&mut self, board: &Board, band: BandUid) { + self.selected_bands.insert(band); + } + + fn deselect_band(&mut self, board: &Board, band: BandUid) { + self.selected_bands.remove(&band); + } + pub fn contains_node(&self, board: &Board, node: NodeIndex) -> bool { - let Some(selector) = self.node_selector(board, node) else { - return false; + if let Some(selector) = self.node_selector(board, node) { + self.selectors.contains(&selector) + } else if let Some(band) = self.node_band(board, node) { + self.selected_bands.contains(&band) + } else { + false + } + } + + fn node_band(&self, board: &Board, node: NodeIndex) -> Option { + let NodeIndex::Primitive(primitive) = node else { + return None; }; - self.selectors.contains(&selector) + let loose = match primitive { + PrimitiveIndex::LooseDot(dot) => dot.into(), + PrimitiveIndex::LoneLooseSeg(seg) => seg.into(), + PrimitiveIndex::SeqLooseSeg(seg) => seg.into(), + PrimitiveIndex::LooseBend(bend) => bend.into(), + _ => return None, + }; + + Some(board.layout().drawing().collect().loose_band_uid(loose)) } fn node_selector( diff --git a/src/drawing/band.rs b/src/drawing/band.rs index a826dd6..3d49a27 100644 --- a/src/drawing/band.rs +++ b/src/drawing/band.rs @@ -28,6 +28,15 @@ impl BandUid { } } +impl PartialEq for BandUid { + fn eq(&self, other: &Self) -> bool { + self.0.petgraph_index() == other.0.petgraph_index() + && self.1.petgraph_index() == other.1.petgraph_index() + } +} + +impl Eq for BandUid {} + #[enum_dispatch(GetPetgraphIndex)] #[derive(Debug, Hash, Clone, Copy)] pub enum BandTerminatingSegIndex { diff --git a/src/drawing/collect.rs b/src/drawing/collect.rs index 8270d70..f052bd1 100644 --- a/src/drawing/collect.rs +++ b/src/drawing/collect.rs @@ -29,6 +29,10 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { } fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { + if let LooseIndex::LoneSeg(seg) = start_loose { + return BandTerminatingSegIndex::Straight(seg); + } + let mut loose = start_loose; let mut prev = None; @@ -43,6 +47,10 @@ impl<'a, CW: Copy, R: AccessRules> Collect<'a, CW, R> { } fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTerminatingSegIndex { + if let LooseIndex::LoneSeg(seg) = start_loose { + return BandTerminatingSegIndex::Straight(seg); + } + let mut loose = start_loose; let mut next = None; diff --git a/src/drawing/loose.rs b/src/drawing/loose.rs index 70b90c1..347d776 100644 --- a/src/drawing/loose.rs +++ b/src/drawing/loose.rs @@ -70,14 +70,15 @@ impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> { impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseDot<'a, CW, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let bend = self.bend(); - let Some(prev) = maybe_prev else { - unreachable!(); - }; - if bend.petgraph_index() != prev.petgraph_index() { - Some(bend.into()) + if let Some(prev) = maybe_prev { + if bend.petgraph_index() != prev.petgraph_index() { + Some(bend.into()) + } else { + self.seg().map(Into::into) + } } else { - self.seg().map(Into::into) + Some(bend.into()) } } } @@ -109,14 +110,15 @@ impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for SeqLooseSeg<'a, CW, R> { impl<'a, CW: Copy, R: AccessRules> GetPrevNextLoose for LooseBend<'a, CW, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let joints = self.joints(); - let Some(prev) = maybe_prev else { - unreachable!(); - }; - if joints.0.petgraph_index() != prev.petgraph_index() { - Some(joints.0.into()) + if let Some(prev) = maybe_prev { + if joints.0.petgraph_index() != prev.petgraph_index() { + Some(joints.0.into()) + } else { + Some(joints.1.into()) + } } else { - Some(joints.1.into()) + Some(joints.0.into()) } } }