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:
Mikolaj Wielgus 2024-04-21 19:51:47 +02:00
parent 8ac63ea6d1
commit 8d59242f3f
9 changed files with 193 additions and 81 deletions

View File

@ -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!();
} }
}) })
}); });

View File

@ -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),
));
} }
} }

View File

@ -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();

View File

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

View File

@ -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
} }

76
src/overlay/ratsnest.rs Normal file
View File

@ -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
}
}

View File

@ -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(

View File

@ -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;

View File

@ -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()
} }
} }