mirror of https://codeberg.org/topola/topola.git
overlay,egui: impl. incomplete ratsnest generation and drawing
For now only doing Delaunay triangulation, then applying minimum spanning tree (without properly working edge ordering yet).
This commit is contained in:
parent
8ac63ea6d1
commit
8d59242f3f
|
|
@ -1,5 +1,6 @@
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use geo::point;
|
use geo::point;
|
||||||
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
sync::mpsc::{channel, Receiver, Sender},
|
sync::mpsc::{channel, Receiver, Sender},
|
||||||
|
|
@ -10,7 +11,7 @@ use topola::{
|
||||||
dsn::{design::DsnDesign, rules::DsnRules},
|
dsn::{design::DsnDesign, rules::DsnRules},
|
||||||
geometry::{
|
geometry::{
|
||||||
compound::CompoundManagerTrait,
|
compound::CompoundManagerTrait,
|
||||||
primitive::{BendShape, DotShape, PrimitiveShape, SegShape},
|
primitive::{BendShape, DotShape, PrimitiveShape, PrimitiveShapeTrait, SegShape},
|
||||||
GenericNode,
|
GenericNode,
|
||||||
},
|
},
|
||||||
layout::{zone::MakePolyShape, Layout},
|
layout::{zone::MakePolyShape, Layout},
|
||||||
|
|
@ -25,13 +26,13 @@ use crate::painter::Painter;
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
overlay: Overlay,
|
maybe_overlay: Option<Overlay>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
layout: Option<Layout<DsnRules>>,
|
maybe_layout: Option<Layout<DsnRules>>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
from_rect: egui::emath::Rect,
|
from_rect: egui::emath::Rect,
|
||||||
|
|
@ -40,9 +41,9 @@ pub struct App {
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
overlay: Overlay::new(),
|
maybe_overlay: None,
|
||||||
text_channel: channel(),
|
text_channel: channel(),
|
||||||
layout: None,
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,12 +72,16 @@ impl eframe::App for App {
|
||||||
if cfg!(target_arch = "wasm32") {
|
if cfg!(target_arch = "wasm32") {
|
||||||
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();
|
||||||
self.layout = Some(design.make_layout());
|
let layout = design.make_layout();
|
||||||
|
self.maybe_overlay = Some(Overlay::new(&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();
|
||||||
self.layout = Some(design.make_layout());
|
let layout = design.make_layout();
|
||||||
|
self.maybe_overlay = Some(Overlay::new(&layout).unwrap());
|
||||||
|
self.maybe_layout = Some(layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,9 +149,10 @@ 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) = &self.layout {
|
if let (Some(layout), Some(overlay)) = (&self.maybe_layout, &mut self.maybe_overlay)
|
||||||
|
{
|
||||||
if ctx.input(|i| i.pointer.any_click()) {
|
if ctx.input(|i| i.pointer.any_click()) {
|
||||||
self.overlay.click(
|
overlay.click(
|
||||||
layout,
|
layout,
|
||||||
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
||||||
);
|
);
|
||||||
|
|
@ -155,8 +161,7 @@ impl eframe::App for App {
|
||||||
for primitive in layout.drawing().layer_primitive_nodes(1) {
|
for primitive in layout.drawing().layer_primitive_nodes(1) {
|
||||||
let shape = primitive.primitive(layout.drawing()).shape();
|
let shape = primitive.primitive(layout.drawing()).shape();
|
||||||
|
|
||||||
let color = if self
|
let color = if overlay
|
||||||
.overlay
|
|
||||||
.selection()
|
.selection()
|
||||||
.contains(&GenericNode::Primitive(primitive))
|
.contains(&GenericNode::Primitive(primitive))
|
||||||
{
|
{
|
||||||
|
|
@ -168,11 +173,7 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in layout.layer_zones(1) {
|
for zone in layout.layer_zones(1) {
|
||||||
let color = if self
|
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
||||||
.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)
|
||||||
|
|
@ -189,8 +190,7 @@ impl eframe::App for App {
|
||||||
for primitive in layout.drawing().layer_primitive_nodes(0) {
|
for primitive in layout.drawing().layer_primitive_nodes(0) {
|
||||||
let shape = primitive.primitive(layout.drawing()).shape();
|
let shape = primitive.primitive(layout.drawing()).shape();
|
||||||
|
|
||||||
let color = if self
|
let color = if overlay
|
||||||
.overlay
|
|
||||||
.selection()
|
.selection()
|
||||||
.contains(&GenericNode::Primitive(primitive))
|
.contains(&GenericNode::Primitive(primitive))
|
||||||
{
|
{
|
||||||
|
|
@ -202,11 +202,7 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone in layout.layer_zones(0) {
|
for zone in layout.layer_zones(0) {
|
||||||
let color = if self
|
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
||||||
.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)
|
||||||
|
|
@ -219,6 +215,24 @@ impl eframe::App for App {
|
||||||
color,
|
color,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for edge in overlay.ratsnest().graph().edge_references() {
|
||||||
|
let from = overlay
|
||||||
|
.ratsnest()
|
||||||
|
.graph()
|
||||||
|
.node_weight(edge.source())
|
||||||
|
.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));
|
||||||
|
}
|
||||||
|
//unreachable!();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,14 @@ impl<'a> Painter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_edge(&mut self, from: Point, to: Point, color: Color32) {
|
pub fn paint_edge(&mut self, from: Point, to: Point, color: Color32) {
|
||||||
//
|
self.ui.painter().add(epaint::Shape::line_segment(
|
||||||
|
[
|
||||||
|
self.transform
|
||||||
|
.transform_pos([from.x() as f32, -from.y() as f32].into()),
|
||||||
|
self.transform
|
||||||
|
.transform_pos([to.x() as f32, -to.y() as f32].into()),
|
||||||
|
],
|
||||||
|
Stroke::new(1.0, color),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use topola::dsn::design::DsnDesign;
|
||||||
use topola::geometry::primitive::{PrimitiveShape, PrimitiveShapeTrait};
|
use topola::geometry::primitive::{PrimitiveShape, PrimitiveShapeTrait};
|
||||||
use topola::layout::connectivity::BandIndex;
|
use topola::layout::connectivity::BandIndex;
|
||||||
use topola::layout::Layout;
|
use topola::layout::Layout;
|
||||||
use topola::mesh::{Mesh, MeshEdgeReference, VertexIndex};
|
use topola::navmesh::{Navmesh, NavmeshEdgeReference, VertexIndex};
|
||||||
use topola::router::RouterObserverTrait;
|
use topola::router::RouterObserverTrait;
|
||||||
|
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
|
|
@ -87,12 +87,12 @@ struct EmptyRouterObserver;
|
||||||
|
|
||||||
impl<R: RulesTrait> RouterObserverTrait<R> for EmptyRouterObserver {
|
impl<R: RulesTrait> RouterObserverTrait<R> for EmptyRouterObserver {
|
||||||
fn on_rework(&mut self, _tracer: &Tracer<R>, _trace: &Trace) {}
|
fn on_rework(&mut self, _tracer: &Tracer<R>, _trace: &Trace) {}
|
||||||
fn before_probe(&mut self, _tracer: &Tracer<R>, _trace: &Trace, _edge: MeshEdgeReference) {}
|
fn before_probe(&mut self, _tracer: &Tracer<R>, _trace: &Trace, _edge: NavmeshEdgeReference) {}
|
||||||
fn on_probe(
|
fn on_probe(
|
||||||
&mut self,
|
&mut self,
|
||||||
_tracer: &Tracer<R>,
|
_tracer: &Tracer<R>,
|
||||||
_trace: &Trace,
|
_trace: &Trace,
|
||||||
_edge: MeshEdgeReference,
|
_edge: NavmeshEdgeReference,
|
||||||
_result: Result<(), DrawException>,
|
_result: Result<(), DrawException>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +135,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
||||||
self.view,
|
self.view,
|
||||||
RouterOrLayout::Layout(tracer.layout.drawing()),
|
RouterOrLayout::Layout(tracer.layout.drawing()),
|
||||||
None,
|
None,
|
||||||
Some(tracer.mesh.clone()),
|
Some(tracer.navmesh.clone()),
|
||||||
&trace.path,
|
&trace.path,
|
||||||
&[],
|
&[],
|
||||||
&[],
|
&[],
|
||||||
|
|
@ -143,7 +143,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: MeshEdgeReference) {
|
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: NavmeshEdgeReference) {
|
||||||
let mut path = trace.path.clone();
|
let mut path = trace.path.clone();
|
||||||
path.push(edge.target());
|
path.push(edge.target());
|
||||||
render_times(
|
render_times(
|
||||||
|
|
@ -154,7 +154,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
||||||
self.view,
|
self.view,
|
||||||
RouterOrLayout::Layout(tracer.layout.drawing()),
|
RouterOrLayout::Layout(tracer.layout.drawing()),
|
||||||
None,
|
None,
|
||||||
Some(tracer.mesh.clone()),
|
Some(tracer.navmesh.clone()),
|
||||||
&path,
|
&path,
|
||||||
&[],
|
&[],
|
||||||
&[],
|
&[],
|
||||||
|
|
@ -166,7 +166,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
tracer: &Tracer<R>,
|
tracer: &Tracer<R>,
|
||||||
trace: &Trace,
|
trace: &Trace,
|
||||||
_edge: MeshEdgeReference,
|
_edge: NavmeshEdgeReference,
|
||||||
result: Result<(), DrawException>,
|
result: Result<(), DrawException>,
|
||||||
) {
|
) {
|
||||||
let (ghosts, highlighteds, delay) = match result {
|
let (ghosts, highlighteds, delay) = match result {
|
||||||
|
|
@ -186,7 +186,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
|
||||||
self.view,
|
self.view,
|
||||||
RouterOrLayout::Layout(tracer.layout.drawing()),
|
RouterOrLayout::Layout(tracer.layout.drawing()),
|
||||||
None,
|
None,
|
||||||
Some(tracer.mesh.clone()),
|
Some(tracer.navmesh.clone()),
|
||||||
&trace.path,
|
&trace.path,
|
||||||
&ghosts,
|
&ghosts,
|
||||||
&highlighteds,
|
&highlighteds,
|
||||||
|
|
@ -324,7 +324,7 @@ fn render_times(
|
||||||
view: &mut View,
|
view: &mut View,
|
||||||
mut router_or_layout: RouterOrLayout<impl RulesTrait>,
|
mut router_or_layout: RouterOrLayout<impl RulesTrait>,
|
||||||
maybe_band: Option<BandIndex>,
|
maybe_band: Option<BandIndex>,
|
||||||
mut maybe_mesh: Option<Mesh>,
|
mut maybe_navmesh: Option<Navmesh>,
|
||||||
path: &[VertexIndex],
|
path: &[VertexIndex],
|
||||||
ghosts: &[PrimitiveShape],
|
ghosts: &[PrimitiveShape],
|
||||||
highlighteds: &[PrimitiveIndex],
|
highlighteds: &[PrimitiveIndex],
|
||||||
|
|
@ -389,7 +389,7 @@ fn render_times(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
maybe_mesh = None;
|
maybe_navmesh = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.layout.drawing()
|
router.layout.drawing()
|
||||||
|
|
@ -440,8 +440,8 @@ fn render_times(
|
||||||
painter.paint_shape(&ghost, ColorU::new(75, 75, 150, 255), view.zoom);
|
painter.paint_shape(&ghost, ColorU::new(75, 75, 150, 255), view.zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mesh) = maybe_mesh {
|
if let Some(ref navmesh) = maybe_navmesh {
|
||||||
for edge in mesh.edge_references() {
|
for edge in navmesh.edge_references() {
|
||||||
let to = edge.source().primitive(drawing).shape().center();
|
let to = edge.source().primitive(drawing).shape().center();
|
||||||
let from = edge.target().primitive(drawing).shape().center();
|
let from = edge.target().primitive(drawing).shape().center();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
mod overlay;
|
mod overlay;
|
||||||
|
pub mod ratsnest;
|
||||||
|
|
||||||
pub use overlay::*;
|
pub use overlay::*;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use rstar::AABB;
|
use rstar::AABB;
|
||||||
|
use spade::InsertionError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, MakePrimitive, PrimitiveIndex},
|
graph::{GetLayer, MakePrimitive},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
},
|
},
|
||||||
|
|
@ -13,24 +14,23 @@ use crate::{
|
||||||
compound::CompoundManagerTrait,
|
compound::CompoundManagerTrait,
|
||||||
shape::{Shape, ShapeTrait},
|
shape::{Shape, ShapeTrait},
|
||||||
},
|
},
|
||||||
graph::GenericIndex,
|
layout::{zone::MakePolyShape, Layout, NodeIndex},
|
||||||
layout::{
|
overlay::ratsnest::Ratsnest,
|
||||||
zone::{MakePolyShape, ZoneWeight},
|
|
||||||
Layout, NodeIndex,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Overlay {
|
pub struct Overlay {
|
||||||
|
ratsnest: Ratsnest,
|
||||||
selection: HashSet<NodeIndex>,
|
selection: HashSet<NodeIndex>,
|
||||||
active_layer: u64,
|
active_layer: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Overlay {
|
impl Overlay {
|
||||||
pub fn new() -> Self {
|
pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> {
|
||||||
Self {
|
Ok(Self {
|
||||||
|
ratsnest: Ratsnest::new(layout)?,
|
||||||
selection: HashSet::new(),
|
selection: HashSet::new(),
|
||||||
active_layer: 0,
|
active_layer: 0,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn click(&mut self, layout: &Layout<impl RulesTrait>, at: Point) {
|
pub fn click(&mut self, layout: &Layout<impl RulesTrait>, at: Point) {
|
||||||
|
|
@ -88,6 +88,10 @@ impl Overlay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ratsnest(&self) -> &Ratsnest {
|
||||||
|
&self.ratsnest
|
||||||
|
}
|
||||||
|
|
||||||
pub fn selection(&self) -> &HashSet<NodeIndex> {
|
pub fn selection(&self) -> &HashSet<NodeIndex> {
|
||||||
&self.selection
|
&self.selection
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
use geo::Point;
|
||||||
|
use petgraph::{
|
||||||
|
data::FromElements,
|
||||||
|
stable_graph::StableUnGraph,
|
||||||
|
visit::{self, EdgeRef, NodeIndexable},
|
||||||
|
};
|
||||||
|
use spade::{HasPosition, InsertionError, Point2};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
drawing::{
|
||||||
|
dot::FixedDotIndex,
|
||||||
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
|
primitive::MakePrimitiveShape,
|
||||||
|
rules::RulesTrait,
|
||||||
|
},
|
||||||
|
geometry::primitive::PrimitiveShapeTrait,
|
||||||
|
layout::Layout,
|
||||||
|
triangulation::{GetVertexIndex, Triangulation},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct TriangulationWeight {
|
||||||
|
vertex: FixedDotIndex,
|
||||||
|
pub pos: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetVertexIndex<FixedDotIndex> for TriangulationWeight {
|
||||||
|
fn vertex_index(&self) -> FixedDotIndex {
|
||||||
|
self.vertex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasPosition for TriangulationWeight {
|
||||||
|
type Scalar = f64;
|
||||||
|
fn position(&self) -> Point2<Self::Scalar> {
|
||||||
|
Point2::new(self.pos.x(), self.pos.y())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Ratsnest {
|
||||||
|
graph: StableUnGraph<TriangulationWeight, (), usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ratsnest {
|
||||||
|
pub fn new(layout: &Layout<impl RulesTrait>) -> Result<Self, InsertionError> {
|
||||||
|
let mut this = Self {
|
||||||
|
graph: StableUnGraph::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut triangulation =
|
||||||
|
Triangulation::new(layout.drawing().geometry().graph().node_bound());
|
||||||
|
|
||||||
|
for node in layout.drawing().primitive_nodes() {
|
||||||
|
let center = node.primitive(layout.drawing()).shape().center();
|
||||||
|
|
||||||
|
match node {
|
||||||
|
PrimitiveIndex::FixedDot(dot) => {
|
||||||
|
triangulation.add_vertex(TriangulationWeight {
|
||||||
|
vertex: dot,
|
||||||
|
pos: center,
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.graph =
|
||||||
|
StableUnGraph::from_elements(petgraph::algo::min_spanning_tree(&triangulation));
|
||||||
|
|
||||||
|
Ok(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn graph(&self) -> &StableUnGraph<TriangulationWeight, (), usize> {
|
||||||
|
&self.graph
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ struct TriangulationWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetVertexIndex<TriangulationVertexIndex> for TriangulationWeight {
|
impl GetVertexIndex<TriangulationVertexIndex> for TriangulationWeight {
|
||||||
fn vertex(&self) -> TriangulationVertexIndex {
|
fn vertex_index(&self) -> TriangulationVertexIndex {
|
||||||
self.vertex
|
self.vertex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,12 +153,12 @@ impl visit::Data for Navmesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct MeshEdgeReference {
|
pub struct NavmeshEdgeReference {
|
||||||
from: VertexIndex,
|
from: VertexIndex,
|
||||||
to: VertexIndex,
|
to: VertexIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl visit::EdgeRef for MeshEdgeReference {
|
impl visit::EdgeRef for NavmeshEdgeReference {
|
||||||
type NodeId = VertexIndex;
|
type NodeId = VertexIndex;
|
||||||
type EdgeId = (VertexIndex, VertexIndex);
|
type EdgeId = (VertexIndex, VertexIndex);
|
||||||
type Weight = ();
|
type Weight = ();
|
||||||
|
|
@ -203,7 +203,7 @@ impl<'a> visit::IntoNeighbors for &'a Navmesh {
|
||||||
fn edge_with_near_edges(
|
fn edge_with_near_edges(
|
||||||
triangulation: &Triangulation<TriangulationVertexIndex, TriangulationWeight>,
|
triangulation: &Triangulation<TriangulationVertexIndex, TriangulationWeight>,
|
||||||
edge: TriangulationEdgeReference<TriangulationVertexIndex>,
|
edge: TriangulationEdgeReference<TriangulationVertexIndex>,
|
||||||
) -> impl Iterator<Item = MeshEdgeReference> {
|
) -> impl Iterator<Item = NavmeshEdgeReference> {
|
||||||
let mut from_vertices = vec![edge.source().into()];
|
let mut from_vertices = vec![edge.source().into()];
|
||||||
|
|
||||||
// Append rails to the source.
|
// Append rails to the source.
|
||||||
|
|
@ -230,15 +230,15 @@ fn edge_with_near_edges(
|
||||||
from_vertices
|
from_vertices
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.cartesian_product(to_vertices.into_iter())
|
.cartesian_product(to_vertices.into_iter())
|
||||||
.map(|pair| MeshEdgeReference {
|
.map(|pair| NavmeshEdgeReference {
|
||||||
from: pair.0,
|
from: pair.0,
|
||||||
to: pair.1.into(),
|
to: pair.1.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> visit::IntoEdgeReferences for &'a Navmesh {
|
impl<'a> visit::IntoEdgeReferences for &'a Navmesh {
|
||||||
type EdgeRef = MeshEdgeReference;
|
type EdgeRef = NavmeshEdgeReference;
|
||||||
type EdgeReferences = Box<dyn Iterator<Item = MeshEdgeReference> + 'a>;
|
type EdgeReferences = Box<dyn Iterator<Item = NavmeshEdgeReference> + 'a>;
|
||||||
|
|
||||||
fn edge_references(self) -> Self::EdgeReferences {
|
fn edge_references(self) -> Self::EdgeReferences {
|
||||||
Box::new(
|
Box::new(
|
||||||
|
|
@ -253,7 +253,7 @@ fn vertex_edges(
|
||||||
triangulation: &Triangulation<TriangulationVertexIndex, TriangulationWeight>,
|
triangulation: &Triangulation<TriangulationVertexIndex, TriangulationWeight>,
|
||||||
from: VertexIndex,
|
from: VertexIndex,
|
||||||
to: TriangulationVertexIndex,
|
to: TriangulationVertexIndex,
|
||||||
) -> impl Iterator<Item = MeshEdgeReference> {
|
) -> impl Iterator<Item = NavmeshEdgeReference> {
|
||||||
let from_vertices = vec![from];
|
let from_vertices = vec![from];
|
||||||
let mut to_vertices = vec![to.into()];
|
let mut to_vertices = vec![to.into()];
|
||||||
|
|
||||||
|
|
@ -270,14 +270,14 @@ fn vertex_edges(
|
||||||
from_vertices
|
from_vertices
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.cartesian_product(to_vertices.into_iter())
|
.cartesian_product(to_vertices.into_iter())
|
||||||
.map(|pair| MeshEdgeReference {
|
.map(|pair| NavmeshEdgeReference {
|
||||||
from: pair.0,
|
from: pair.0,
|
||||||
to: pair.1,
|
to: pair.1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> visit::IntoEdges for &'a Navmesh {
|
impl<'a> visit::IntoEdges for &'a Navmesh {
|
||||||
type Edges = Box<dyn Iterator<Item = MeshEdgeReference> + 'a>;
|
type Edges = Box<dyn Iterator<Item = NavmeshEdgeReference> + 'a>;
|
||||||
|
|
||||||
fn edges(self, vertex: Self::NodeId) -> Self::Edges {
|
fn edges(self, vertex: Self::NodeId) -> Self::Edges {
|
||||||
Box::new(
|
Box::new(
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::layout::Layout;
|
||||||
use crate::router::{
|
use crate::router::{
|
||||||
astar::{astar, AstarStrategy, PathTracker},
|
astar::{astar, AstarStrategy, PathTracker},
|
||||||
draw::DrawException,
|
draw::DrawException,
|
||||||
navmesh::{MeshEdgeReference, Navmesh, VertexIndex},
|
navmesh::{Navmesh, NavmeshEdgeReference, VertexIndex},
|
||||||
tracer::{Trace, Tracer},
|
tracer::{Trace, Tracer},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,12 +41,12 @@ pub enum RoutingErrorKind {
|
||||||
|
|
||||||
pub trait RouterObserverTrait<R: RulesTrait> {
|
pub trait RouterObserverTrait<R: RulesTrait> {
|
||||||
fn on_rework(&mut self, tracer: &Tracer<R>, trace: &Trace);
|
fn on_rework(&mut self, tracer: &Tracer<R>, trace: &Trace);
|
||||||
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: MeshEdgeReference);
|
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: NavmeshEdgeReference);
|
||||||
fn on_probe(
|
fn on_probe(
|
||||||
&mut self,
|
&mut self,
|
||||||
tracer: &Tracer<R>,
|
tracer: &Tracer<R>,
|
||||||
trace: &Trace,
|
trace: &Trace,
|
||||||
edge: MeshEdgeReference,
|
edge: NavmeshEdgeReference,
|
||||||
result: Result<(), DrawException>,
|
result: Result<(), DrawException>,
|
||||||
);
|
);
|
||||||
fn on_estimate(&mut self, tracer: &Tracer<R>, vertex: VertexIndex);
|
fn on_estimate(&mut self, tracer: &Tracer<R>, vertex: VertexIndex);
|
||||||
|
|
@ -94,7 +94,7 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64>
|
||||||
self.tracer.finish(&mut self.trace, self.to, width).is_ok()
|
self.tracer.finish(&mut self.trace, self.to, width).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<f64> {
|
fn edge_cost(&mut self, edge: NavmeshEdgeReference) -> Option<f64> {
|
||||||
self.observer.before_probe(&self.tracer, &self.trace, edge);
|
self.observer.before_probe(&self.tracer, &self.trace, edge);
|
||||||
if edge.target() == self.to.into() {
|
if edge.target() == self.to.into() {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use spade::{handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, Inse
|
||||||
use crate::graph::GetNodeIndex;
|
use crate::graph::GetNodeIndex;
|
||||||
|
|
||||||
pub trait GetVertexIndex<I> {
|
pub trait GetVertexIndex<I> {
|
||||||
fn vertex(&self) -> I;
|
fn vertex_index(&self) -> I;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -31,7 +31,7 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_vertex(&mut self, weight: W) -> Result<(), InsertionError> {
|
pub fn add_vertex(&mut self, weight: W) -> Result<(), InsertionError> {
|
||||||
let index = weight.vertex().node_index().index();
|
let index = weight.vertex_index().node_index().index();
|
||||||
self.vertex_to_handle[index] = Some(spade::Triangulation::insert(
|
self.vertex_to_handle[index] = Some(spade::Triangulation::insert(
|
||||||
&mut self.triangulation,
|
&mut self.triangulation,
|
||||||
weight,
|
weight,
|
||||||
|
|
@ -60,7 +60,7 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
|
||||||
fn vertex(&self, handle: FixedVertexHandle) -> I {
|
fn vertex(&self, handle: FixedVertexHandle) -> I {
|
||||||
spade::Triangulation::vertex(&self.triangulation, handle)
|
spade::Triangulation::vertex(&self.triangulation, handle)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.vertex()
|
.vertex_index()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle(&self, vertex: I) -> FixedVertexHandle {
|
fn handle(&self, vertex: I) -> FixedVertexHandle {
|
||||||
|
|
@ -78,7 +78,7 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
|
||||||
impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
||||||
visit::Data for Triangulation<I, W>
|
visit::Data for Triangulation<I, W>
|
||||||
{
|
{
|
||||||
type NodeWeight = ();
|
type NodeWeight = W;
|
||||||
type EdgeWeight = ();
|
type EdgeWeight = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,53 +169,62 @@ impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<
|
||||||
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
||||||
spade::Triangulation::s(&self.triangulation)
|
spade::Triangulation::s(&self.triangulation)
|
||||||
.vertex_data(vertex)
|
.vertex_data(vertex)
|
||||||
.vertex()
|
.vertex_index()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
/*#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct TriangulationVertexReference<I> {
|
pub struct TriangulationVertexReference<I: Copy, W> {
|
||||||
index: I,
|
index: I,
|
||||||
|
weight: &'a W,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Copy> visit::NodeRef for TriangulationVertexReference<I> {
|
impl<I: Copy> visit::NodeRef for TriangulationVertexReference<I, W> {
|
||||||
type NodeId = I;
|
type NodeId = I;
|
||||||
type Weight = ();
|
type Weight = W;
|
||||||
|
|
||||||
fn id(&self) -> Self::NodeId {
|
fn id(&self) -> Self::NodeId {
|
||||||
self.index
|
self.index
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weight(&self) -> &Self::Weight {
|
fn weight(&self) -> &Self::Weight {
|
||||||
&()
|
self.weight
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
||||||
visit::IntoNodeReferences for &'a Triangulation<I, W>
|
visit::IntoNodeReferences for &'a Triangulation<I, W>
|
||||||
{
|
{
|
||||||
type NodeRef = TriangulationVertexReference<I>;
|
/*type NodeRef = TriangulationVertexReference<I, W>;
|
||||||
type NodeReferences = Box<dyn Iterator<Item = TriangulationVertexReference<I>> + 'a>;
|
type NodeReferences = Box<dyn Iterator<Item = TriangulationVertexReference<I, W>> + 'a>;*/
|
||||||
|
type NodeRef = (I, &'a W);
|
||||||
|
type NodeReferences = Box<dyn Iterator<Item = (I, &'a W)> + 'a>;
|
||||||
|
|
||||||
fn node_references(self) -> Self::NodeReferences {
|
fn node_references(self) -> Self::NodeReferences {
|
||||||
Box::new(
|
Box::new(
|
||||||
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
spade::Triangulation::fixed_vertices(&self.triangulation).map(|vertex| {
|
||||||
TriangulationVertexReference {
|
let weight = spade::Triangulation::s(&self.triangulation).vertex_data(vertex);
|
||||||
index: spade::Triangulation::s(&self.triangulation)
|
/*TriangulationVertexReference {
|
||||||
.vertex_data(vertex)
|
index: weight.vertex_index(),
|
||||||
.vertex(),
|
weight,
|
||||||
}
|
}*/
|
||||||
|
(weight.vertex_index(), weight)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
|
impl<
|
||||||
visit::NodeIndexable for &'a Triangulation<I, W>
|
'a,
|
||||||
|
I: Copy + PartialEq + GetNodeIndex + std::fmt::Debug,
|
||||||
|
W: GetVertexIndex<I> + HasPosition<Scalar = f64>,
|
||||||
|
> visit::NodeIndexable for &'a Triangulation<I, W>
|
||||||
{
|
{
|
||||||
fn node_bound(&self) -> usize {
|
fn node_bound(&self) -> usize {
|
||||||
spade::Triangulation::num_vertices(&self.triangulation)
|
//spade::Triangulation::num_vertices(&self.triangulation)
|
||||||
|
self.vertex_to_handle.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_index(&self, node: I) -> usize {
|
fn to_index(&self, node: I) -> usize {
|
||||||
|
|
@ -225,6 +234,6 @@ impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<
|
||||||
fn from_index(&self, index: usize) -> I {
|
fn from_index(&self, index: usize) -> I {
|
||||||
spade::Triangulation::s(&self.triangulation)
|
spade::Triangulation::s(&self.triangulation)
|
||||||
.vertex_data(self.vertex_to_handle[index].unwrap())
|
.vertex_data(self.vertex_to_handle[index].unwrap())
|
||||||
.vertex()
|
.vertex_index()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue