egui,autorouter: add action and command to measure length of bands

This commit is contained in:
Mikolaj Wielgus 2024-08-23 04:14:06 +02:00
parent 541b7acb04
commit 63d3e345aa
6 changed files with 132 additions and 8 deletions

View File

@ -11,6 +11,7 @@ action-autoroute = Autoroute
action-place-via = Place Via action-place-via = Place Via
action-remove-bands = Remove Bands action-remove-bands = Remove Bands
action-compare-detours = Compare Detours action-compare-detours = Compare Detours
action-measure-length = Measure Length
action-undo = Undo action-undo = Undo
action-redo = Redo action-redo = Redo

View File

@ -13,6 +13,7 @@ use crate::{
use super::{ use super::{
autoroute::Autoroute, autoroute::Autoroute,
compare_detours::CompareDetours, compare_detours::CompareDetours,
measure_length::MeasureLength,
place_via::PlaceVia, place_via::PlaceVia,
ratsnest::{Ratsnest, RatvertexIndex}, ratsnest::{Ratsnest, RatvertexIndex},
remove_bands::RemoveBands, remove_bands::RemoveBands,
@ -110,6 +111,13 @@ impl<M: AccessMesadata> Autorouter<M> {
CompareDetours::new(self, ratline1, ratline2) CompareDetours::new(self, ratline1, ratline2)
} }
pub fn measure_length(
&mut self,
selection: &BandSelection,
) -> Result<MeasureLength, AutorouterError> {
MeasureLength::new(selection)
}
pub fn ratline_endpoints( pub fn ratline_endpoints(
&mut self, &mut self,
ratline: EdgeIndex<usize>, ratline: EdgeIndex<usize>,

View File

@ -16,6 +16,7 @@ use super::{
autoroute::{Autoroute, AutorouteStatus}, autoroute::{Autoroute, AutorouteStatus},
compare_detours::{CompareDetours, CompareDetoursStatus}, compare_detours::{CompareDetours, CompareDetoursStatus},
history::{History, HistoryError}, history::{History, HistoryError},
measure_length::MeasureLength,
place_via::PlaceVia, place_via::PlaceVia,
remove_bands::RemoveBands, remove_bands::RemoveBands,
selection::{BandSelection, PinSelection}, selection::{BandSelection, PinSelection},
@ -72,6 +73,7 @@ pub enum Command {
PlaceVia(ViaWeight), PlaceVia(ViaWeight),
RemoveBands(BandSelection), RemoveBands(BandSelection),
CompareDetours(PinSelection), CompareDetours(PinSelection),
MeasureLength(BandSelection),
} }
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)] #[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
@ -80,6 +82,7 @@ pub enum Execute {
PlaceVia(PlaceVia), PlaceVia(PlaceVia),
RemoveBands(RemoveBands), RemoveBands(RemoveBands),
CompareDetours(CompareDetours), CompareDetours(CompareDetours),
MeasureLength(MeasureLength),
} }
impl Execute { impl Execute {
@ -107,7 +110,8 @@ impl Execute {
"finished removing bands", "finished removing bands",
))) )))
} }
Execute::CompareDetours(compare) => match compare.step(&mut invoker.autorouter)? { Execute::CompareDetours(compare_detours) => {
match compare_detours.step(&mut invoker.autorouter)? {
CompareDetoursStatus::Running => Ok(InvokerStatus::Running), CompareDetoursStatus::Running => Ok(InvokerStatus::Running),
CompareDetoursStatus::Finished(total_length1, total_length2) => { CompareDetoursStatus::Finished(total_length1, total_length2) => {
Ok(InvokerStatus::Finished(String::from(format!( Ok(InvokerStatus::Finished(String::from(format!(
@ -115,7 +119,15 @@ impl Execute {
total_length1, total_length2 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<M: AccessMesadata> Invoker<M> {
Command::CompareDetours(selection) => Ok::<Execute, InvokerError>( Command::CompareDetours(selection) => Ok::<Execute, InvokerError>(
Execute::CompareDetours(self.autorouter.compare_detours(selection)?), Execute::CompareDetours(self.autorouter.compare_detours(selection)?),
), ),
Command::MeasureLength(selection) => Ok::<Execute, InvokerError>(
Execute::MeasureLength(self.autorouter.measure_length(selection)?),
),
} }
} }
@ -273,6 +288,7 @@ impl<M: AccessMesadata> Invoker<M> {
Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight), Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight),
Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection), Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection),
Command::CompareDetours(..) => (), Command::CompareDetours(..) => (),
Command::MeasureLength(..) => (),
} }
Ok::<(), InvokerError>(self.history.undo()?) Ok::<(), InvokerError>(self.history.undo()?)

View File

@ -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<f64>,
}
impl MeasureLength {
pub fn new(selection: &BandSelection) -> Result<Self, AutorouterError> {
Ok(Self {
selection: selection.clone(),
maybe_length: None,
})
}
pub fn doit(
&mut self,
autorouter: &mut Autorouter<impl AccessMesadata>,
) -> Result<f64, AutorouterError> {
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] {
&[]
}
}

View File

@ -3,6 +3,7 @@ mod autorouter;
pub mod compare_detours; pub mod compare_detours;
pub mod history; pub mod history;
pub mod invoker; pub mod invoker;
pub mod measure_length;
pub mod place_via; pub mod place_via;
pub mod ratsnest; pub mod ratsnest;
pub mod remove_bands; pub mod remove_bands;

View File

@ -94,6 +94,11 @@ impl Top {
egui::Modifiers::NONE, egui::Modifiers::NONE,
egui::Key::Minus, 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( let mut undo = Trigger::new(Action::new(
tr.text("action-undo"), tr.text("action-undo"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
@ -132,6 +137,7 @@ impl Top {
place_via.toggle_widget(ctx, ui, &mut self.is_placing_via); place_via.toggle_widget(ctx, ui, &mut self.is_placing_via);
remove_bands.button(ctx, ui); remove_bands.button(ctx, ui);
measure_length.button(ctx, ui);
ui.separator(); ui.separator();
@ -151,6 +157,7 @@ impl Top {
ui.separator(); ui.separator();
compare_detours.button(ctx, ui); compare_detours.button(ctx, ui);
measure_length.button(ctx, ui);
}); });
ui.separator(); 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) { } else if undo.consume_key_triggered(ctx, ui) {
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() { if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
invoker.undo(); invoker.undo();