From e0cfc521ef3b114b757fcda4022a8702bc2bbf18 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 13 Sep 2025 23:59:56 +0200 Subject: [PATCH] refactor(geometry/geometry): Replace `NodeIndex` with just `usize` This is a step towards ceasing to use Petgraph as internal storage for geometry. --- src/autorouter/ratsnest.rs | 3 +- src/drawing/bend.rs | 2 - src/drawing/dot.rs | 2 - src/drawing/drawing.rs | 6 +- src/drawing/gear.rs | 2 +- src/drawing/graph.rs | 3 +- src/drawing/loose.rs | 1 - src/drawing/primitive.rs | 5 +- src/drawing/seg.rs | 2 - src/geometry/geometry.rs | 175 +++++++++++++++++++++-------------- src/graph.rs | 18 ++-- src/layout/collect_bands.rs | 7 +- src/layout/layout.rs | 7 +- src/math/polygon_tangents.rs | 64 ++++++------- src/router/navmesh.rs | 22 +++-- src/router/prenavmesh.rs | 2 +- src/triangulation.rs | 14 +-- tests/common/mod.rs | 4 +- 18 files changed, 186 insertions(+), 153 deletions(-) diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 628baaf..317d020 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -8,7 +8,6 @@ use enum_dispatch::enum_dispatch; use geo::Point; use petgraph::{ data::Element, - graph::NodeIndex, prelude::StableUnGraph, unionfind::UnionFind, visit::{EdgeRef, IntoEdgeReferences, NodeIndexable}, @@ -78,7 +77,7 @@ impl Ratsnest { let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound()); for edge in layout.drawing().geometry().graph().edge_references() { - unionfind.union(edge.source(), edge.target()); + unionfind.union(edge.source().index(), edge.target().index()); } let mut this = Self { diff --git a/src/drawing/bend.rs b/src/drawing/bend.rs index 564e022..cf5acb5 100644 --- a/src/drawing/bend.rs +++ b/src/drawing/bend.rs @@ -15,8 +15,6 @@ use crate::{ graph::{GenericIndex, GetIndex}, }; -use petgraph::stable_graph::NodeIndex; - #[enum_dispatch(GetIndex, MakePrimitiveRef)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum BendIndex { diff --git a/src/drawing/dot.rs b/src/drawing/dot.rs index 5d9cb68..6141257 100644 --- a/src/drawing/dot.rs +++ b/src/drawing/dot.rs @@ -5,8 +5,6 @@ use enum_dispatch::enum_dispatch; use geo::Point; -use petgraph::stable_graph::NodeIndex; - use crate::{ drawing::{ graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex, PrimitiveWeight}, diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 8b69572..fd9b873 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -570,7 +570,7 @@ impl Drawing { let core = *self .recording_geometry_with_rtree .graph() - .neighbors(inner.index()) + .neighbors(inner.index().into()) .filter(|ni| { matches!( self.recording_geometry_with_rtree @@ -578,14 +578,14 @@ impl Drawing { .edge_weight( self.recording_geometry_with_rtree .graph() - .find_edge(inner.index(), *ni) + .find_edge(inner.index().into(), *ni) .unwrap() ) .unwrap(), GeometryLabel::Core ) }) - .map(FixedDotIndex::new) + .map(|node| FixedDotIndex::new(node.index())) .collect::>() .first() .unwrap(); diff --git a/src/drawing/gear.rs b/src/drawing/gear.rs index 242dc41..c8eeeae 100644 --- a/src/drawing/gear.rs +++ b/src/drawing/gear.rs @@ -5,7 +5,7 @@ use std::collections::VecDeque; use enum_dispatch::enum_dispatch; -use petgraph::{stable_graph::NodeIndex, visit::Walker}; +use petgraph::visit::Walker; use crate::{ drawing::{ diff --git a/src/drawing/graph.rs b/src/drawing/graph.rs index 86ef5ff..7b0d6f8 100644 --- a/src/drawing/graph.rs +++ b/src/drawing/graph.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; use crate::{ geometry::GetLayer, @@ -115,7 +114,7 @@ pub enum PrimitiveWeight { impl crate::geometry::Retag for PrimitiveWeight { type Index = PrimitiveIndex; - fn retag(&self, index: NodeIndex) -> PrimitiveIndex { + fn retag(&self, index: usize) -> PrimitiveIndex { macro_rules! match_self { ($self:expr, $($kind:ident),*,) => {{ match $self { diff --git a/src/drawing/loose.rs b/src/drawing/loose.rs index 0d53b20..d9bff71 100644 --- a/src/drawing/loose.rs +++ b/src/drawing/loose.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; use crate::{ drawing::Drawing, diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index a80c867..200691c 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; use crate::{ drawing::{ @@ -200,7 +199,7 @@ impl<'a, W, CW, Cel, R> GenericPrimitive<'a, W, CW, Cel, R> { .drawing .geometry() .graph() - .node_weight(self.index.index()) + .node_weight(self.index.index().into()) .unwrap() { *weight @@ -226,7 +225,7 @@ impl GetDrawing for GenericPrimitive<'_, W, CW, Cel, R> { } impl GetIndex for GenericPrimitive<'_, W, CW, Cel, R> { - fn index(&self) -> NodeIndex { + fn index(&self) -> usize { self.index.index() } } diff --git a/src/drawing/seg.rs b/src/drawing/seg.rs index ab4047c..4417f58 100644 --- a/src/drawing/seg.rs +++ b/src/drawing/seg.rs @@ -16,8 +16,6 @@ use crate::{ graph::{GenericIndex, GetIndex}, }; -use petgraph::stable_graph::NodeIndex; - #[enum_dispatch(GetIndex, MakePrimitiveRef)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] pub enum SegIndex { diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index 885b702..7adfd71 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -6,7 +6,7 @@ use core::marker::PhantomData; use enum_dispatch::enum_dispatch; use geo::Point; use petgraph::{ - stable_graph::{NodeIndex, StableDiGraph}, + stable_graph::StableDiGraph, visit::{EdgeRef, Walker}, Direction::{Incoming, Outgoing}, }; @@ -31,7 +31,7 @@ use crate::{ pub trait Retag { type Index: Sized + GetIndex + PartialEq + Copy; - fn retag(&self, index: NodeIndex) -> Self::Index; + fn retag(&self, index: usize) -> Self::Index; } #[enum_dispatch] @@ -75,7 +75,7 @@ pub enum GenericNode { } impl GetIndex for GenericNode { - fn index(&self) -> NodeIndex { + fn index(&self) -> usize { match self { Self::Primitive(x) => x.index(), Self::Compound(x) => x.index(), @@ -149,11 +149,11 @@ impl Geometry) -> PW + fn primitive_weight(&self, index: usize) -> PW where PW: Copy, { - if let GenericNode::Primitive(weight) = self.graph.node_weight(index).unwrap() { + if let GenericNode::Primitive(weight) = self.graph.node_weight(index.into()).unwrap() { *weight } else { unreachable!() @@ -175,7 +175,11 @@ impl< > Geometry { pub fn add_dot>(&mut self, weight: W) -> GenericIndex { - GenericIndex::::new(self.graph.add_node(GenericNode::Primitive(weight.into()))) + GenericIndex::::new( + self.graph + .add_node(GenericNode::Primitive(weight.into())) + .index(), + ) } pub(super) fn add_dot_at_index>( @@ -184,7 +188,7 @@ impl< weight: W, ) { self.graph - .update_node(dot.index(), GenericNode::Primitive(weight.into())); + .update_node(dot.index().into(), GenericNode::Primitive(weight.into())); } pub fn add_seg>( @@ -193,8 +197,11 @@ impl< to: DI, weight: W, ) -> GenericIndex { - let seg = - GenericIndex::::new(self.graph.add_node(GenericNode::Primitive(weight.into()))); + let seg = GenericIndex::::new( + self.graph + .add_node(GenericNode::Primitive(weight.into())) + .index(), + ); self.init_seg_joints(seg, from, to); seg } @@ -207,7 +214,7 @@ impl< weight: W, ) { self.graph - .update_node(seg.index(), GenericNode::Primitive(weight.into())); + .update_node(seg.index().into(), GenericNode::Primitive(weight.into())); self.init_seg_joints(seg, from, to); } @@ -217,10 +224,13 @@ impl< from: DI, to: DI, ) { + self.graph.update_edge( + from.index().into(), + seg.index().into(), + GeometryLabel::Joined, + ); self.graph - .update_edge(from.index(), seg.index(), GeometryLabel::Joined); - self.graph - .update_edge(seg.index(), to.index(), GeometryLabel::Joined); + .update_edge(seg.index().into(), to.index().into(), GeometryLabel::Joined); } pub fn is_joined_with(&self, seg: I, node: GenericNode>) -> bool @@ -232,7 +242,7 @@ impl< match node { GenericNode::Primitive(prim) => self .graph - .find_edge_undirected(seg.index(), prim.index()) + .find_edge_undirected(seg.index().into(), prim.index().into()) .map_or(false, |(eidx, _direction)| { matches!(self.graph.edge_weight(eidx).unwrap(), GeometryLabel::Joined) }), @@ -249,8 +259,11 @@ impl< core: DI, weight: W, ) -> GenericIndex { - let bend = - GenericIndex::::new(self.graph.add_node(GenericNode::Primitive(weight.into()))); + let bend = GenericIndex::::new( + self.graph + .add_node(GenericNode::Primitive(weight.into())) + .index(), + ); self.init_bend_joints_and_core(bend, from, to, core); bend } @@ -264,13 +277,13 @@ impl< weight: W, ) { self.graph - .update_node(bend.index(), GenericNode::Primitive(weight.into())); + .update_node(bend.index().into(), GenericNode::Primitive(weight.into())); self.init_bend_joints_and_core(bend, from, to, core); } pub(super) fn add_compound_at_index(&mut self, compound: GenericIndex, weight: CW) { self.graph - .update_node(compound.index(), GenericNode::Compound(weight)); + .update_node(compound.index().into(), GenericNode::Compound(weight)); } fn init_bend_joints_and_core>( @@ -280,58 +293,80 @@ impl< to: DI, core: DI, ) { - self.graph - .update_edge(from.index(), bend.index(), GeometryLabel::Joined); - self.graph - .update_edge(bend.index(), to.index(), GeometryLabel::Joined); - self.graph - .update_edge(bend.index(), core.index(), GeometryLabel::Core); + self.graph.update_edge( + from.index().into(), + bend.index().into(), + GeometryLabel::Joined, + ); + self.graph.update_edge( + bend.index().into(), + to.index().into(), + GeometryLabel::Joined, + ); + self.graph.update_edge( + bend.index().into(), + core.index().into(), + GeometryLabel::Core, + ); } pub fn remove_primitive(&mut self, primitive: PI) { - debug_assert!(self.graph.remove_node(primitive.index()).is_some()); + debug_assert!(self.graph.remove_node(primitive.index().into()).is_some()); } pub fn move_dot(&mut self, dot: DI, to: Point) { let mut weight = self.dot_weight(dot); weight.set_pos(to); - *self.graph.node_weight_mut(dot.index()).unwrap() = GenericNode::Primitive(weight.into()); + *self.graph.node_weight_mut(dot.index().into()).unwrap() = + GenericNode::Primitive(weight.into()); } pub fn shift_bend(&mut self, bend: BI, offset: f64) { let mut weight = self.bend_weight(bend); weight.set_offset(offset); - *self.graph.node_weight_mut(bend.index()).unwrap() = GenericNode::Primitive(weight.into()); + *self.graph.node_weight_mut(bend.index().into()).unwrap() = + GenericNode::Primitive(weight.into()); } pub fn flip_bend(&mut self, bend: BI) { let (from, to) = self.bend_joints(bend); let from_edge_weight = self .graph - .remove_edge(self.graph.find_edge(from.index(), bend.index()).unwrap()) + .remove_edge( + self.graph + .find_edge(from.index().into(), bend.index().into()) + .unwrap(), + ) .unwrap(); let to_edge_weight = self .graph - .remove_edge(self.graph.find_edge(bend.index(), to.index()).unwrap()) + .remove_edge( + self.graph + .find_edge(bend.index().into(), to.index().into()) + .unwrap(), + ) .unwrap(); self.graph - .update_edge(from.index(), bend.index(), to_edge_weight); + .update_edge(from.index().into(), bend.index().into(), to_edge_weight); self.graph - .update_edge(bend.index(), to.index(), from_edge_weight); + .update_edge(bend.index().into(), to.index().into(), from_edge_weight); } pub fn reattach_bend(&mut self, bend: BI, maybe_new_inner: Option) { if let Some(old_inner_edge) = self .graph - .edges_directed(bend.index(), Incoming) + .edges_directed(bend.index().into(), Incoming) .find(|edge| matches!(edge.weight(), GeometryLabel::Outer)) { debug_assert!(self.graph.remove_edge(old_inner_edge.id()).is_some()); } if let Some(new_inner) = maybe_new_inner { - self.graph - .update_edge(new_inner.index(), bend.index(), GeometryLabel::Outer); + self.graph.update_edge( + new_inner.index().into(), + bend.index().into(), + GeometryLabel::Outer, + ); } } @@ -350,7 +385,7 @@ impl< PrimitiveShape::Seg(SegShape { from: self.dot_weight(from).pos(), to: self.dot_weight(to).pos(), - width: self.primitive_weight(seg.index()).width(), + width: self.primitive_weight(seg.index().into()).width(), }) } @@ -364,7 +399,7 @@ impl< pos: core_weight.pos(), r: self.inner_radius(bend), }, - width: self.primitive_weight(bend.index()).width(), + width: self.primitive_weight(bend.index().into()).width(), }) } @@ -382,25 +417,27 @@ impl< } pub fn dot_weight(&self, dot: DI) -> DW { - self.primitive_weight(dot.index()) + self.primitive_weight(dot.index().into()) .try_into() .unwrap_or_else(|_| unreachable!()) } pub fn seg_weight(&self, seg: SI) -> SW { - self.primitive_weight(seg.index()) + self.primitive_weight(seg.index().into()) .try_into() .unwrap_or_else(|_| unreachable!()) } pub fn bend_weight(&self, bend: BI) -> BW { - self.primitive_weight(bend.index()) + self.primitive_weight(bend.index().into()) .try_into() .unwrap_or_else(|_| unreachable!()) } pub fn compound_weight(&self, compound: GenericIndex) -> &CW { - if let GenericNode::Compound(weight) = self.graph.node_weight(compound.index()).unwrap() { + if let GenericNode::Compound(weight) = + self.graph.node_weight(compound.index().into()).unwrap() + { weight } else { unreachable!() @@ -409,10 +446,10 @@ impl< fn core_weight(&self, bend: BI) -> DW { self.graph - .edges_directed(bend.index(), Outgoing) + .edges_directed(bend.index().into(), Outgoing) .find(|edge| matches!(edge.weight(), GeometryLabel::Core)) .map(|edge| { - self.primitive_weight(edge.target()) + self.primitive_weight(edge.target().index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -421,13 +458,13 @@ impl< pub fn joineds(&self, node: PI) -> impl Iterator + '_ { self.graph - .neighbors_undirected(node.index()) + .neighbors_undirected(node.index().into()) .filter(move |ni| { matches!( self.graph .edge_weight( self.graph - .find_edge_undirected(node.index(), *ni) + .find_edge_undirected(node.index().into(), *ni) .unwrap() .0, ) @@ -435,7 +472,7 @@ impl< GeometryLabel::Joined ) }) - .map(|ni| self.primitive_index(ni)) + .map(|ni| self.primitive_index(ni.index())) } pub fn joined_segs(&self, dot: DI) -> impl Iterator + '_ { @@ -449,24 +486,24 @@ impl< fn joints(&self, node: PI) -> (DI, DI) { let lhs = self .graph - .edges_directed(node.index(), Incoming) + .edges_directed(node.index().into(), Incoming) .find(|edge| matches!(edge.weight(), GeometryLabel::Joined)) .map(|edge| edge.source()); let rhs = self .graph - .edges_directed(node.index(), Outgoing) + .edges_directed(node.index().into(), Outgoing) .find(|edge| matches!(edge.weight(), GeometryLabel::Joined)) .map(|edge| edge.target()); ( lhs.map(|ni| { - self.primitive_index(ni) + self.primitive_index(ni.index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) .unwrap(), rhs.map(|ni| { - self.primitive_index(ni) + self.primitive_index(ni.index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -486,7 +523,7 @@ impl< impl, DW, SW, BW, CW, Cel, PI, DI, SI, BI> Geometry { - fn primitive_index(&self, index: NodeIndex) -> PI { + fn primitive_index(&self, index: usize) -> PI { self.primitive_weight(index).retag(index) } } @@ -543,12 +580,12 @@ impl< BI: GetIndex, > Geometry { - pub fn all_rails(&self, node: NodeIndex) -> impl Iterator + '_ { + pub fn all_rails(&self, index: usize) -> impl Iterator + '_ { self.graph - .edges_directed(node, Incoming) + .edges_directed(index.into(), Incoming) .filter(|edge| matches!(edge.weight(), GeometryLabel::Core)) .map(|edge| { - self.primitive_index(edge.source()) + self.primitive_index(edge.source().index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -556,10 +593,10 @@ impl< pub fn core(&self, bend: BI) -> DI { self.graph - .edges_directed(bend.index(), Outgoing) + .edges_directed(bend.index().into(), Outgoing) .find(|edge| matches!(edge.weight(), GeometryLabel::Core)) .map(|edge| { - self.primitive_index(edge.target()) + self.primitive_index(edge.target().index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -568,10 +605,10 @@ impl< pub fn inner(&self, bend: BI) -> Option { self.graph - .edges_directed(bend.index(), Incoming) + .edges_directed(bend.index().into(), Incoming) .find(|edge| matches!(edge.weight(), GeometryLabel::Outer)) .map(|edge| { - self.primitive_index(edge.source()) + self.primitive_index(edge.source().index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -579,10 +616,10 @@ impl< pub fn outers(&self, bend: BI) -> impl Iterator + '_ { self.graph - .edges_directed(bend.index(), Outgoing) + .edges_directed(bend.index().into(), Outgoing) .filter(|edge| matches!(edge.weight(), GeometryLabel::Outer)) .map(|edge| { - self.primitive_index(edge.target()) + self.primitive_index(edge.target().index()) .try_into() .unwrap_or_else(|_| unreachable!()) }) @@ -600,11 +637,11 @@ impl, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D type EntryLabel = Cel; fn add_compound(&mut self, weight: CW) -> GenericIndex { - GenericIndex::::new(self.graph.add_node(GenericNode::Compound(weight))) + GenericIndex::::new(self.graph.add_node(GenericNode::Compound(weight)).index()) } fn remove_compound(&mut self, compound: GenericIndex) { - debug_assert!(self.graph.remove_node(compound.index()).is_some()); + debug_assert!(self.graph.remove_node(compound.index().into()).is_some()); } fn add_to_compound(&mut self, primitive: I, entry_label: Cel, compound: GenericIndex) @@ -612,14 +649,16 @@ impl, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D I: Copy + GetIndex, { self.graph.update_edge( - primitive.index(), - compound.index(), + primitive.index().into(), + compound.index().into(), GeometryLabel::Compound(entry_label), ); } fn compound_weight(&self, compound: GenericIndex) -> &CW { - if let GenericNode::Compound(weight) = self.graph.node_weight(compound.index()).unwrap() { + if let GenericNode::Compound(weight) = + self.graph.node_weight(compound.index().into()).unwrap() + { weight } else { unreachable!() @@ -631,10 +670,10 @@ impl, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D compound: GenericIndex, ) -> impl Iterator + '_ { self.graph - .edges_directed(compound.index(), Incoming) + .edges_directed(compound.index().into(), Incoming) .filter_map(|edge| { if let GeometryLabel::Compound(entry_label) = *edge.weight() { - Some((entry_label, self.primitive_index(edge.source()))) + Some((entry_label, self.primitive_index(edge.source().index()))) } else { None } @@ -646,10 +685,10 @@ impl, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D I: Copy + GetIndex, { self.graph - .edges_directed(node.index(), Outgoing) + .edges_directed(node.index().into(), Outgoing) .filter_map(|edge| { if let GeometryLabel::Compound(entry_label) = *edge.weight() { - Some((entry_label, GenericIndex::new(edge.target()))) + Some((entry_label, GenericIndex::new(edge.target().index()))) } else { None } diff --git a/src/graph.rs b/src/graph.rs index fba5f53..0315091 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -15,13 +15,13 @@ pub trait MakeRef<'a, C> { #[enum_dispatch] pub trait GetIndex { - fn index(&self) -> NodeIndex; + fn index(&self) -> usize; } impl GetIndex for NodeIndex { #[inline(always)] - fn index(&self) -> NodeIndex { - *self + fn index(&self) -> usize { + NodeIndex::index(*self) } } @@ -31,14 +31,14 @@ impl GetIndex for NodeIndex { #[serde(bound = "")] #[serde(transparent)] pub struct GenericIndex { - node_index: NodeIndex, + node_index: usize, #[serde(skip)] marker: PhantomData, } impl GenericIndex { #[inline] - pub fn new(index: NodeIndex) -> Self { + pub fn new(index: usize) -> Self { Self { node_index: index, marker: PhantomData, @@ -58,7 +58,7 @@ impl core::marker::Copy for GenericIndex {} impl core::fmt::Debug for GenericIndex { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - core::fmt::Display::fmt(&self.node_index.index(), f) + core::fmt::Display::fmt(&self.node_index, f) } } @@ -94,7 +94,7 @@ impl core::hash::Hash for GenericIndex { impl GetIndex for GenericIndex { #[inline] - fn index(&self) -> NodeIndex { + fn index(&self) -> usize { self.node_index } } @@ -106,12 +106,12 @@ mod tests { #[test] fn serializable_index() { assert_eq!( - serde_json::to_string(&GenericIndex::<()>::new(NodeIndex::new(0))).unwrap(), + serde_json::to_string(&GenericIndex::<()>::new(0)).unwrap(), "0" ); assert_eq!( serde_json::from_str::>("0").unwrap(), - GenericIndex::new(NodeIndex::new(0)) + GenericIndex::new(0) ); } } diff --git a/src/layout/collect_bands.rs b/src/layout/collect_bands.rs index 783b2d8..1c9fe50 100644 --- a/src/layout/collect_bands.rs +++ b/src/layout/collect_bands.rs @@ -23,7 +23,6 @@ use crate::{ shape::AccessShape, GenericNode, }, - graph::GetIndex, layout::{Layout, NodeIndex}, math::{intersect_linestring_and_ray, LineInGeneralForm, LineIntersection}, }; @@ -121,11 +120,10 @@ impl Layout { .filter(|(_, band_uid, _)| { // filter entries which are connected to either lhs or rhs (and possibly both) let (bts1, bts2) = band_uid.into(); - let (bts1, bts2) = (bts1.index(), bts2.index()); let geometry = self.drawing.geometry(); [(bts1, left), (bts1, right), (bts2, left), (bts2, right)] .iter() - .all(|&(x, y)| !geometry.is_joined_with(x, y)) + .all(|&(x, y)| !geometry.is_joined_with(*x, y)) }) .collect(); bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0)); @@ -162,11 +160,10 @@ impl Layout { .filter(|(_, band_uid, _)| { // filter entries which are connected to rhs let (bts1, bts2) = band_uid.into(); - let (bts1, bts2) = (bts1.index(), bts2.index()); let geometry = self.drawing.geometry(); [(bts1, right), (bts2, right)] .iter() - .all(|&(x, y)| !geometry.is_joined_with(x, y)) + .all(|&(x, y)| !geometry.is_joined_with(*x, y)) }) .collect(); bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0)); diff --git a/src/layout/layout.rs b/src/layout/layout.rs index fffe39c..2d09d54 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -360,8 +360,11 @@ impl Layout { let PrimitiveIndex::FixedDot(dot) = index else { return None; }; - if let GenericNode::Primitive(PrimitiveWeight::FixedDot(weight)) = - drawing.geometry().graph().node_weight(dot.index()).unwrap() + if let GenericNode::Primitive(PrimitiveWeight::FixedDot(weight)) = drawing + .geometry() + .graph() + .node_weight(dot.index().into()) + .unwrap() { Some((dot, weight)) } else { diff --git a/src/math/polygon_tangents.rs b/src/math/polygon_tangents.rs index bf45f97..eaa19ea 100644 --- a/src/math/polygon_tangents.rs +++ b/src/math/polygon_tangents.rs @@ -284,98 +284,98 @@ mod tests { #[test] fn petp00() { let poly_ext = &[ - (point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), - (point! { x: 1., y: 0. }, FixedDotIndex::new(1.into())), - (point! { x: 1., y: 1. }, FixedDotIndex::new(2.into())), - (point! { x: 0., y: 1. }, FixedDotIndex::new(3.into())), + (point! { x: 0., y: 0. }, FixedDotIndex::new(0)), + (point! { x: 1., y: 0. }, FixedDotIndex::new(1)), + (point! { x: 1., y: 1. }, FixedDotIndex::new(2)), + (point! { x: 0., y: 1. }, FixedDotIndex::new(3)), ]; let origin = point! { x: 0.5, y: -1.0 }; assert_eq!( petp(poly_ext, false, origin), - Ok((FixedDotIndex::new(1.into()), FixedDotIndex::new(0.into()))) + Ok((FixedDotIndex::new(1), FixedDotIndex::new(0))) ); } #[test] fn petp00cw() { let poly_ext = &[ - (point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), - (point! { x: 0., y: 1. }, FixedDotIndex::new(3.into())), - (point! { x: 1., y: 1. }, FixedDotIndex::new(2.into())), - (point! { x: 1., y: 0. }, FixedDotIndex::new(1.into())), + (point! { x: 0., y: 0. }, FixedDotIndex::new(0)), + (point! { x: 0., y: 1. }, FixedDotIndex::new(3)), + (point! { x: 1., y: 1. }, FixedDotIndex::new(2)), + (point! { x: 1., y: 0. }, FixedDotIndex::new(1)), ]; let origin = point! { x: 0.5, y: -1.0 }; assert_eq!( petp(poly_ext, true, origin), - Ok((FixedDotIndex::new(1.into()), FixedDotIndex::new(0.into()))) + Ok((FixedDotIndex::new(1), FixedDotIndex::new(0))) ); } #[test] fn triangle() { let poly_ext = &[ - (point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), - (point! { x: 1., y: 1. }, FixedDotIndex::new(1.into())), - (point! { x: 0., y: 2. }, FixedDotIndex::new(2.into())), + (point! { x: 0., y: 0. }, FixedDotIndex::new(0)), + (point! { x: 1., y: 1. }, FixedDotIndex::new(1)), + (point! { x: 0., y: 2. }, FixedDotIndex::new(2)), ]; let origin = point! { x: 2., y: 1. }; assert_eq!( petp(poly_ext, false, origin), - Ok((FixedDotIndex::new(2.into()), FixedDotIndex::new(0.into()))) + Ok((FixedDotIndex::new(2), FixedDotIndex::new(0))) ); } #[test] fn triangle_cw() { let poly_ext = &[ - (point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), - (point! { x: 0., y: 2. }, FixedDotIndex::new(2.into())), - (point! { x: 1., y: 1. }, FixedDotIndex::new(1.into())), + (point! { x: 0., y: 0. }, FixedDotIndex::new(0)), + (point! { x: 0., y: 2. }, FixedDotIndex::new(2)), + (point! { x: 1., y: 1. }, FixedDotIndex::new(1)), ]; let origin = point! { x: 2., y: 1. }; assert_eq!( petp(poly_ext, true, origin), - Ok((FixedDotIndex::new(2.into()), FixedDotIndex::new(0.into()))) + Ok((FixedDotIndex::new(2), FixedDotIndex::new(0))) ); } #[test] fn handover00() { let poly_ext_src = &[ - (point! { x: 4., y: 0. }, FixedDotIndex::new(0.into())), - (point! { x: 3., y: 3. }, FixedDotIndex::new(1.into())), - (point! { x: 1., y: 2. }, FixedDotIndex::new(2.into())), - (point! { x: 1., y: -2. }, FixedDotIndex::new(3.into())), - (point! { x: 3., y: -3. }, FixedDotIndex::new(4.into())), + (point! { x: 4., y: 0. }, FixedDotIndex::new(0)), + (point! { x: 3., y: 3. }, FixedDotIndex::new(1)), + (point! { x: 1., y: 2. }, FixedDotIndex::new(2)), + (point! { x: 1., y: -2. }, FixedDotIndex::new(3)), + (point! { x: 3., y: -3. }, FixedDotIndex::new(4)), ]; let source = CachedPolyExt::new(poly_ext_src, false); let source = &source; let poly_ext_trg = &[ - (point! { x: -4., y: 0. }, FixedDotIndex::new(10.into())), - (point! { x: -3., y: 3. }, FixedDotIndex::new(11.into())), - (point! { x: -1., y: 2. }, FixedDotIndex::new(12.into())), - (point! { x: -1., y: -2. }, FixedDotIndex::new(13.into())), - (point! { x: -3., y: -3. }, FixedDotIndex::new(14.into())), + (point! { x: -4., y: 0. }, FixedDotIndex::new(10)), + (point! { x: -3., y: 3. }, FixedDotIndex::new(11)), + (point! { x: -1., y: 2. }, FixedDotIndex::new(12)), + (point! { x: -1., y: -2. }, FixedDotIndex::new(13)), + (point! { x: -3., y: -3. }, FixedDotIndex::new(14)), ]; let target = CachedPolyExt::new(poly_ext_trg, true); let target = ⌖ assert_eq!( pehov(source, CoCw, target, CoCw), - Some((FixedDotIndex::new(1.into()), FixedDotIndex::new(11.into()))) + Some((FixedDotIndex::new(1), FixedDotIndex::new(11))) ); assert_eq!( pehov(source, CoCw, target, Cw), - Some((FixedDotIndex::new(2.into()), FixedDotIndex::new(13.into()))) + Some((FixedDotIndex::new(2), FixedDotIndex::new(13))) ); assert_eq!( pehov(source, Cw, target, CoCw), - Some((FixedDotIndex::new(3.into()), FixedDotIndex::new(12.into()))) + Some((FixedDotIndex::new(3), FixedDotIndex::new(12))) ); assert_eq!( pehov(source, Cw, target, Cw), - Some((FixedDotIndex::new(4.into()), FixedDotIndex::new(14.into()))) + Some((FixedDotIndex::new(4), FixedDotIndex::new(14))) ); } } diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index 3e92b7a..4e4f3f4 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -48,8 +48,8 @@ impl core::fmt::Debug for NavnodeIndex { } impl GetIndex for NavnodeIndex { - fn index(&self) -> NodeIndex { - self.0 + fn index(&self) -> usize { + self.0.index() } } @@ -319,7 +319,7 @@ impl Navmesh { fn unionize_with_overlapees( layout: &Layout, - overlapping_prenavnodes_unions: &mut UnionFind>, + overlapping_prenavnodes_unions: &mut UnionFind, prenavnode: PrenavmeshNodeIndex, ) { // Ignore overlaps of a fillet. @@ -382,17 +382,17 @@ impl Navmesh { PrenavmeshNodeIndex, Vec<(NodeIndex, NodeIndex)>, >, - overlapping_prenavnodes_unions: &UnionFind>, + overlapping_prenavnodes_unions: &UnionFind, from_prenavnode: PrenavmeshNodeIndex, to_prenavnode: PrenavmeshNodeIndex, ) { // We assume prenavmesh nodes are fixed dots. This is an ugly shortcut, // since fixed bends also can be prenavnodes, but it works for now. let from_prenavnode_repr = PrenavmeshNodeIndex::FixedDot(GenericIndex::new( - overlapping_prenavnodes_unions.find(from_prenavnode.index()), + overlapping_prenavnodes_unions.find(from_prenavnode.index().into()), )); let to_prenavnode_repr = PrenavmeshNodeIndex::FixedDot(GenericIndex::new( - overlapping_prenavnodes_unions.find(to_prenavnode.index()), + overlapping_prenavnodes_unions.find(to_prenavnode.index().into()), )); Self::add_prenavedge_as_quadrinavedges( @@ -455,7 +455,7 @@ impl Data for Navmesh { impl DataMap for Navmesh { fn node_weight(&self, vertex: Self::NodeId) -> Option<&Self::NodeWeight> { - self.graph.node_weight(vertex.index()) + self.graph.node_weight(vertex.index().into()) } fn edge_weight(&self, _edge: Self::EdgeId) -> Option<&Self::EdgeWeight> { @@ -495,7 +495,11 @@ impl<'a> IntoNeighbors for &'a Navmesh { type Neighbors = Box + 'a>; fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors { - Box::new(self.graph.neighbors(vertex.index()).map(NavnodeIndex)) + Box::new( + self.graph + .neighbors(vertex.index().into()) + .map(NavnodeIndex), + ) } } @@ -521,7 +525,7 @@ impl<'a> IntoEdges for &'a Navmesh { fn edges(self, vertex: Self::NodeId) -> Self::Edges { Box::new( self.graph - .edges(vertex.index()) + .edges(vertex.index().into()) .map(|edge| NavmeshEdgeReference { from: NavnodeIndex(edge.source()), to: NavnodeIndex(edge.target()), diff --git a/src/router/prenavmesh.rs b/src/router/prenavmesh.rs index 5e099b1..83956b5 100644 --- a/src/router/prenavmesh.rs +++ b/src/router/prenavmesh.rs @@ -5,7 +5,7 @@ use derive_getters::Getters; use enum_dispatch::enum_dispatch; use geo::Point; -use petgraph::{stable_graph::NodeIndex, visit::NodeIndexable}; +use petgraph::visit::NodeIndexable; use spade::{HasPosition, InsertionError, Point2}; use crate::{ diff --git a/src/triangulation.rs b/src/triangulation.rs index 753f7ad..d13196f 100644 --- a/src/triangulation.rs +++ b/src/triangulation.rs @@ -39,15 +39,15 @@ impl + HasPosition, EW: Default> } pub fn add_vertex(&mut self, weight: VW) -> Result<(), InsertionError> { - let index = weight.node_index().index().index(); + let index = weight.node_index().index(); self.trianvertex_to_handle[index] = Some(spade::Triangulation::insert(&mut self.cdt, weight)?); Ok(()) } pub fn add_constraint_edge(&mut self, from: VW, to: VW) -> Result { - let from_index = from.node_index().index().index(); - let to_index = to.node_index().index().index(); + let from_index = from.node_index().index(); + let to_index = to.node_index().index(); // It is possible for one or both constraint edge endpoint vertices to // not exist in the triangulation even after everything has been added. @@ -75,13 +75,13 @@ impl + HasPosition, EW: Default> pub fn weight(&self, vertex: I) -> &VW { spade::Triangulation::s(&self.cdt) - .vertex_data(self.trianvertex_to_handle[vertex.index().index()].unwrap()) + .vertex_data(self.trianvertex_to_handle[vertex.index()].unwrap()) } pub fn weight_mut(&mut self, vertex: I) -> &mut VW { spade::Triangulation::vertex_data_mut( &mut self.cdt, - self.trianvertex_to_handle[vertex.index().index()].unwrap(), + self.trianvertex_to_handle[vertex.index()].unwrap(), ) } @@ -92,7 +92,7 @@ impl + HasPosition, EW: Default> } fn handle(&self, vertex: I) -> FixedVertexHandle { - self.trianvertex_to_handle[vertex.index().index()].unwrap() + self.trianvertex_to_handle[vertex.index()].unwrap() } pub fn position(&self, vertex: I) -> Point<::Scalar> @@ -328,7 +328,7 @@ impl< } fn to_index(&self, node: I) -> usize { - node.index().index() + node.index() } fn from_index(&self, index: usize) -> I { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 08b4aa3..b3b1deb 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -4,7 +4,7 @@ use std::{fs::File, io::BufReader}; -use petgraph::{stable_graph::NodeIndex, unionfind::UnionFind, visit::NodeIndexable}; +use petgraph::{unionfind::UnionFind, visit::NodeIndexable}; use topola::{ autorouter::{ history::{History, HistoryError}, @@ -257,7 +257,7 @@ pub fn assert_band_length( ); } -fn unionfind(autorouter: &mut Autorouter) -> UnionFind> { +fn unionfind(autorouter: &mut Autorouter) -> UnionFind { for ratline in autorouter.ratsnest().graph().edge_indices() { // Accessing endpoints may create new dots because apex construction is lazy, so we access // tem all before starting unionfind, as it requires a constant index bound.