mirror of https://codeberg.org/topola/topola.git
overlay: move overlay to new autorouter module
This commit is contained in:
parent
5ff9a27403
commit
81f9f82f40
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
mod autorouter;
|
||||||
|
pub mod overlay;
|
||||||
|
pub mod ratsnest;
|
||||||
|
|
||||||
|
pub use autorouter::*;
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
mod overlay;
|
|
||||||
pub mod ratsnest;
|
|
||||||
|
|
||||||
pub use overlay::*;
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue