overlay: move overlay to new autorouter module

This commit is contained in:
Mikolaj Wielgus 2024-04-26 02:34:25 +02:00
parent 5ff9a27403
commit 81f9f82f40
8 changed files with 139 additions and 52 deletions

View File

@ -0,0 +1,72 @@
use geo::Point;
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use spade::InsertionError;
use crate::{
autorouter::{overlay::Overlay, ratsnest::RatsnestVertexIndex},
drawing::rules::RulesTrait,
layout::Layout,
router::Router,
triangulation::GetVertexIndex,
};
pub struct Autorouter<R: RulesTrait> {
overlay: Overlay,
router: Router<R>,
}
impl<R: RulesTrait> Autorouter<R> {
pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> {
Ok(Self {
overlay: Overlay::new(&layout)?,
router: Router::new(layout),
})
}
pub fn autoroute(&mut self) {
//for ratline in self.overlay.ratsnest().graph().edge_references() {
// For now, let's only take the first ratline.
let ratline = self
.overlay
.ratsnest()
.graph()
.edge_references()
.next()
.unwrap();
self.route(
self.overlay
.ratsnest()
.graph()
.node_weight(ratline.source())
.unwrap()
.vertex_index(),
self.overlay
.ratsnest()
.graph()
.node_weight(ratline.target())
.unwrap()
.vertex_index(),
);
//}
}
fn route(&mut self, from: RatsnestVertexIndex, to: RatsnestVertexIndex) {
todo!();
}
// TODO: Move somewhere higher in abstraction.
pub fn click(&mut self, at: Point) {
self.overlay.click(self.router.layout(), at);
}
pub fn overlay(&self) -> &Overlay {
&self.overlay
}
pub fn router(&self) -> &Router<R> {
&self.router
}
}

5
src/autorouter/mod.rs Normal file
View File

@ -0,0 +1,5 @@
mod autorouter;
pub mod overlay;
pub mod ratsnest;
pub use autorouter::*;

View File

@ -5,6 +5,7 @@ use rstar::AABB;
use spade::InsertionError; use spade::InsertionError;
use crate::{ use crate::{
autorouter::ratsnest::Ratsnest,
drawing::{ drawing::{
graph::{GetLayer, MakePrimitive}, graph::{GetLayer, MakePrimitive},
primitive::MakePrimitiveShape, primitive::MakePrimitiveShape,
@ -15,7 +16,6 @@ use crate::{
shape::{Shape, ShapeTrait}, shape::{Shape, ShapeTrait},
}, },
layout::{zone::MakePolyShape, Layout, NodeIndex}, layout::{zone::MakePolyShape, Layout, NodeIndex},
overlay::ratsnest::Ratsnest,
}; };
pub struct Overlay { pub struct Overlay {
@ -82,7 +82,7 @@ impl Overlay {
false false
} }
fn toggle_selection(&mut self, node: NodeIndex) { pub fn toggle_selection(&mut self, node: NodeIndex) {
if !self.selection.insert(node) { if !self.selection.insert(node) {
self.selection.remove(&node); self.selection.remove(&node);
} }

View File

@ -7,6 +7,7 @@ use std::{
}; };
use topola::{ use topola::{
autorouter::{overlay::Overlay, Autorouter},
drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape, Drawing}, drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape, Drawing},
dsn::{design::DsnDesign, rules::DsnRules}, dsn::{design::DsnDesign, rules::DsnRules},
geometry::{ geometry::{
@ -16,7 +17,6 @@ use topola::{
}, },
layout::{zone::MakePolyShape, Layout}, layout::{zone::MakePolyShape, Layout},
math::Circle, math::Circle,
overlay::Overlay,
}; };
use crate::painter::Painter; use crate::painter::Painter;
@ -26,14 +26,11 @@ use crate::painter::Painter;
#[serde(default)] #[serde(default)]
pub struct App { pub struct App {
#[serde(skip)] #[serde(skip)]
maybe_overlay: Option<Overlay>, autorouter: Option<Autorouter<DsnRules>>,
#[serde(skip)] #[serde(skip)]
text_channel: (Sender<String>, Receiver<String>), text_channel: (Sender<String>, Receiver<String>),
#[serde(skip)]
maybe_layout: Option<Layout<DsnRules>>,
#[serde(skip)] #[serde(skip)]
from_rect: egui::emath::Rect, from_rect: egui::emath::Rect,
} }
@ -41,9 +38,8 @@ pub struct App {
impl Default for App { impl Default for App {
fn default() -> Self { fn default() -> Self {
Self { Self {
maybe_overlay: None, autorouter: None,
text_channel: channel(), text_channel: channel(),
maybe_layout: None,
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0), from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
} }
} }
@ -73,15 +69,13 @@ impl eframe::App for App {
if let Ok(file_contents) = self.text_channel.1.try_recv() { if let Ok(file_contents) = self.text_channel.1.try_recv() {
let design = DsnDesign::load_from_string(file_contents).unwrap(); let design = DsnDesign::load_from_string(file_contents).unwrap();
let layout = design.make_layout(); let layout = design.make_layout();
self.maybe_overlay = Some(Overlay::new(&layout).unwrap()); self.autorouter = Some(Autorouter::new(design.make_layout()).unwrap());
self.maybe_layout = Some(layout);
} }
} else { } else {
if let Ok(path) = self.text_channel.1.try_recv() { if let Ok(path) = self.text_channel.1.try_recv() {
let design = DsnDesign::load_from_file(&path).unwrap(); let design = DsnDesign::load_from_file(&path).unwrap();
let layout = design.make_layout(); let layout = design.make_layout();
self.maybe_overlay = Some(Overlay::new(&layout).unwrap()); self.autorouter = Some(Autorouter::new(design.make_layout()).unwrap());
self.maybe_layout = Some(layout);
} }
} }
@ -149,19 +143,23 @@ impl eframe::App for App {
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
let mut painter = Painter::new(ui, transform); let mut painter = Painter::new(ui, transform);
if let (Some(layout), Some(overlay)) = (&self.maybe_layout, &mut self.maybe_overlay) if let Some(ref mut autorouter) = &mut self.autorouter {
{
if ctx.input(|i| i.pointer.any_click()) { if ctx.input(|i| i.pointer.any_click()) {
overlay.click( autorouter.click(point! {x: latest_pos.x as f64, y: -latest_pos.y as f64});
layout,
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
);
} }
for primitive in layout.drawing().layer_primitive_nodes(1) { for primitive in autorouter
let shape = primitive.primitive(layout.drawing()).shape(); .router()
.layout()
.drawing()
.layer_primitive_nodes(1)
{
let shape = primitive
.primitive(autorouter.router().layout().drawing())
.shape();
let color = if overlay let color = if autorouter
.overlay()
.selection() .selection()
.contains(&GenericNode::Primitive(primitive)) .contains(&GenericNode::Primitive(primitive))
{ {
@ -172,25 +170,39 @@ impl eframe::App for App {
painter.paint_shape(&shape, color); painter.paint_shape(&shape, color);
} }
for zone in layout.layer_zones(1) { for zone in autorouter.router().layout().layer_zones(1) {
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) { let color = if autorouter
.overlay()
.selection()
.contains(&GenericNode::Compound(zone))
{
egui::Color32::from_rgb(100, 100, 255) egui::Color32::from_rgb(100, 100, 255)
} else { } else {
egui::Color32::from_rgb(52, 52, 200) egui::Color32::from_rgb(52, 52, 200)
}; };
painter.paint_polygon( painter.paint_polygon(
&layout &autorouter
.router()
.layout()
.compound_weight(zone) .compound_weight(zone)
.shape(&layout.drawing(), zone) .shape(&autorouter.router().layout().drawing(), zone)
.polygon, .polygon,
color, color,
) )
} }
for primitive in layout.drawing().layer_primitive_nodes(0) { for primitive in autorouter
let shape = primitive.primitive(layout.drawing()).shape(); .router()
.layout()
.drawing()
.layer_primitive_nodes(0)
{
let shape = primitive
.primitive(autorouter.router().layout().drawing())
.shape();
let color = if overlay let color = if autorouter
.overlay()
.selection() .selection()
.contains(&GenericNode::Primitive(primitive)) .contains(&GenericNode::Primitive(primitive))
{ {
@ -201,34 +213,32 @@ impl eframe::App for App {
painter.paint_shape(&shape, color); painter.paint_shape(&shape, color);
} }
for zone in layout.layer_zones(0) { for zone in autorouter.router().layout().layer_zones(0) {
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) { let color = if autorouter
.overlay()
.selection()
.contains(&GenericNode::Compound(zone))
{
egui::Color32::from_rgb(255, 100, 100) egui::Color32::from_rgb(255, 100, 100)
} else { } else {
egui::Color32::from_rgb(200, 52, 52) egui::Color32::from_rgb(200, 52, 52)
}; };
painter.paint_polygon( painter.paint_polygon(
&layout &autorouter
.router()
.layout()
.compound_weight(zone) .compound_weight(zone)
.shape(&layout.drawing(), zone) .shape(&autorouter.router().layout().drawing(), zone)
.polygon, .polygon,
color, color,
) )
} }
for edge in overlay.ratsnest().graph().edge_references() { let ratsnest = autorouter.overlay().ratsnest().graph();
let from = overlay
.ratsnest() for ratline in ratsnest.edge_references() {
.graph() let from = ratsnest.node_weight(ratline.source()).unwrap().pos;
.node_weight(edge.source()) let to = ratsnest.node_weight(ratline.target()).unwrap().pos;
.unwrap()
.pos;
let to = overlay
.ratsnest()
.graph()
.node_weight(edge.target())
.unwrap()
.pos;
painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200)); painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200));
} }

View File

@ -3,10 +3,10 @@
pub mod graph; pub mod graph;
#[macro_use] #[macro_use]
pub mod drawing; pub mod drawing;
pub mod autorouter;
pub mod dsn; pub mod dsn;
pub mod geometry; pub mod geometry;
pub mod layout; pub mod layout;
pub mod math; pub mod math;
pub mod overlay;
pub mod router; pub mod router;
pub mod triangulation; pub mod triangulation;

View File

@ -1,4 +0,0 @@
mod overlay;
pub mod ratsnest;
pub use overlay::*;

View File

@ -56,7 +56,7 @@ pub trait RouterObserverTrait<R: RulesTrait> {
} }
pub struct Router<R: RulesTrait> { pub struct Router<R: RulesTrait> {
pub layout: Layout<R>, layout: Layout<R>,
} }
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> { struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
@ -193,4 +193,8 @@ impl<R: RulesTrait> Router<R> {
pub fn tracer<'a>(&'a mut self, mesh: &'a Navmesh) -> Tracer<R> { pub fn tracer<'a>(&'a mut self, mesh: &'a Navmesh) -> Tracer<R> {
Tracer::new(&mut self.layout, mesh) Tracer::new(&mut self.layout, mesh)
} }
pub fn layout(&self) -> &Layout<R> {
&self.layout
}
} }