From 63d3e345aafa2c3bc69aa5c52d78e46e13338bf2 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 23 Aug 2024 04:14:06 +0200 Subject: [PATCH] egui,autorouter: add action and command to measure length of bands --- locales/en-US/main.ftl | 1 + src/autorouter/autorouter.rs | 8 ++++ src/autorouter/invoker.rs | 32 ++++++++++---- src/autorouter/measure_length.rs | 76 ++++++++++++++++++++++++++++++++ src/autorouter/mod.rs | 1 + src/bin/topola-egui/top.rs | 22 +++++++++ 6 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 src/autorouter/measure_length.rs diff --git a/locales/en-US/main.ftl b/locales/en-US/main.ftl index 78ad085..e8d8237 100644 --- a/locales/en-US/main.ftl +++ b/locales/en-US/main.ftl @@ -11,6 +11,7 @@ action-autoroute = Autoroute action-place-via = Place Via action-remove-bands = Remove Bands action-compare-detours = Compare Detours +action-measure-length = Measure Length action-undo = Undo action-redo = Redo diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 28cfab3..b736ada 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -13,6 +13,7 @@ use crate::{ use super::{ autoroute::Autoroute, compare_detours::CompareDetours, + measure_length::MeasureLength, place_via::PlaceVia, ratsnest::{Ratsnest, RatvertexIndex}, remove_bands::RemoveBands, @@ -110,6 +111,13 @@ impl Autorouter { CompareDetours::new(self, ratline1, ratline2) } + pub fn measure_length( + &mut self, + selection: &BandSelection, + ) -> Result { + MeasureLength::new(selection) + } + pub fn ratline_endpoints( &mut self, ratline: EdgeIndex, diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index e472226..b0c3248 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -16,6 +16,7 @@ use super::{ autoroute::{Autoroute, AutorouteStatus}, compare_detours::{CompareDetours, CompareDetoursStatus}, history::{History, HistoryError}, + measure_length::MeasureLength, place_via::PlaceVia, remove_bands::RemoveBands, selection::{BandSelection, PinSelection}, @@ -72,6 +73,7 @@ pub enum Command { PlaceVia(ViaWeight), RemoveBands(BandSelection), CompareDetours(PinSelection), + MeasureLength(BandSelection), } #[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)] @@ -80,6 +82,7 @@ pub enum Execute { PlaceVia(PlaceVia), RemoveBands(RemoveBands), CompareDetours(CompareDetours), + MeasureLength(MeasureLength), } impl Execute { @@ -107,15 +110,24 @@ impl Execute { "finished removing bands", ))) } - Execute::CompareDetours(compare) => match compare.step(&mut invoker.autorouter)? { - CompareDetoursStatus::Running => Ok(InvokerStatus::Running), - CompareDetoursStatus::Finished(total_length1, total_length2) => { - Ok(InvokerStatus::Finished(String::from(format!( - "total detour lengths are {} and {}", - total_length1, total_length2 - )))) + Execute::CompareDetours(compare_detours) => { + match compare_detours.step(&mut invoker.autorouter)? { + CompareDetoursStatus::Running => Ok(InvokerStatus::Running), + CompareDetoursStatus::Finished(total_length1, total_length2) => { + Ok(InvokerStatus::Finished(String::from(format!( + "total detour lengths are {} and {}", + total_length1, total_length2 + )))) + } } - }, + } + Execute::MeasureLength(measure_length) => { + let length = measure_length.doit(&mut invoker.autorouter)?; + Ok(InvokerStatus::Finished(format!( + "Total length of selected bands: {}", + length + ))) + } } } } @@ -261,6 +273,9 @@ impl Invoker { Command::CompareDetours(selection) => Ok::( Execute::CompareDetours(self.autorouter.compare_detours(selection)?), ), + Command::MeasureLength(selection) => Ok::( + Execute::MeasureLength(self.autorouter.measure_length(selection)?), + ), } } @@ -273,6 +288,7 @@ impl Invoker { Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight), Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection), Command::CompareDetours(..) => (), + Command::MeasureLength(..) => (), } Ok::<(), InvokerError>(self.history.undo()?) diff --git a/src/autorouter/measure_length.rs b/src/autorouter/measure_length.rs new file mode 100644 index 0000000..da53d44 --- /dev/null +++ b/src/autorouter/measure_length.rs @@ -0,0 +1,76 @@ +use crate::{ + board::mesadata::AccessMesadata, + drawing::{band::BandUid, graph::PrimitiveIndex}, + geometry::{primitive::PrimitiveShape, shape::MeasureLength as MeasureLengthTrait}, + graph::MakeRef, + router::{navmesh::Navmesh, trace::Trace}, +}; + +use super::{ + invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles}, + selection::BandSelection, + Autorouter, AutorouterError, +}; + +pub struct MeasureLength { + selection: BandSelection, + maybe_length: Option, +} + +impl MeasureLength { + pub fn new(selection: &BandSelection) -> Result { + Ok(Self { + selection: selection.clone(), + maybe_length: None, + }) + } + + pub fn doit( + &mut self, + autorouter: &mut Autorouter, + ) -> Result { + let length = if let Some(length) = self.maybe_length { + length + } else { + let mut length = 0.0; + + for selector in self.selection.selectors() { + let band = autorouter + .board + .bandname_band(selector.band.clone()) + .unwrap() + .0; + length += band.ref_(autorouter.board.layout().drawing()).length(); + } + + self.maybe_length = Some(length); + length + }; + + Ok(length) + } +} + +impl GetMaybeNavmesh for MeasureLength { + fn maybe_navmesh(&self) -> Option<&Navmesh> { + None + } +} + +impl GetMaybeTrace for MeasureLength { + fn maybe_trace(&self) -> Option<&Trace> { + None + } +} + +impl GetGhosts for MeasureLength { + fn ghosts(&self) -> &[PrimitiveShape] { + &[] + } +} + +impl GetObstacles for MeasureLength { + fn obstacles(&self) -> &[PrimitiveIndex] { + &[] + } +} diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index dd32e30..b7f8d98 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -3,6 +3,7 @@ mod autorouter; pub mod compare_detours; pub mod history; pub mod invoker; +pub mod measure_length; pub mod place_via; pub mod ratsnest; pub mod remove_bands; diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 1e73663..58b7054 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -94,6 +94,11 @@ impl Top { egui::Modifiers::NONE, egui::Key::Minus, )); + let mut measure_length = Trigger::new(Action::new( + tr.text("action-measure-length"), + egui::Modifiers::NONE, + egui::Key::Plus, + )); let mut undo = Trigger::new(Action::new( tr.text("action-undo"), egui::Modifiers::CTRL, @@ -132,6 +137,7 @@ impl Top { place_via.toggle_widget(ctx, ui, &mut self.is_placing_via); remove_bands.button(ctx, ui); + measure_length.button(ctx, ui); ui.separator(); @@ -151,6 +157,7 @@ impl Top { ui.separator(); compare_detours.button(ctx, ui); + measure_length.button(ctx, ui); }); ui.separator(); @@ -263,6 +270,21 @@ impl Top { )?)); } } + } else if measure_length.consume_key_triggered(ctx, ui) { + if maybe_execute.as_mut().map_or(true, |execute| { + matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..))) + }) { + if let (Some(invoker), Some(ref mut overlay)) = ( + arc_mutex_maybe_invoker.lock().unwrap().as_mut(), + maybe_overlay, + ) { + let selection = overlay.selection().clone(); + overlay.clear_selection(); + maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper( + Command::MeasureLength(selection.band_selection), + )?)); + } + } } else if undo.consume_key_triggered(ctx, ui) { if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() { invoker.undo();