refactor(geometry/geometry): Replace `NodeIndex<usize>` with just `usize`

This is a step towards ceasing to use Petgraph as internal storage for
geometry.
This commit is contained in:
Mikolaj Wielgus 2025-09-13 23:59:56 +02:00
parent 6a2102e0a2
commit e0cfc521ef
18 changed files with 186 additions and 153 deletions

View File

@ -8,7 +8,6 @@ use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::{ use petgraph::{
data::Element, data::Element,
graph::NodeIndex,
prelude::StableUnGraph, prelude::StableUnGraph,
unionfind::UnionFind, unionfind::UnionFind,
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable}, visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
@ -78,7 +77,7 @@ impl Ratsnest {
let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound()); let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound());
for edge in layout.drawing().geometry().graph().edge_references() { 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 { let mut this = Self {

View File

@ -15,8 +15,6 @@ use crate::{
graph::{GenericIndex, GetIndex}, graph::{GenericIndex, GetIndex},
}; };
use petgraph::stable_graph::NodeIndex;
#[enum_dispatch(GetIndex, MakePrimitiveRef)] #[enum_dispatch(GetIndex, MakePrimitiveRef)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum BendIndex { pub enum BendIndex {

View File

@ -5,8 +5,6 @@
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::stable_graph::NodeIndex;
use crate::{ use crate::{
drawing::{ drawing::{
graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex, PrimitiveWeight}, graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex, PrimitiveWeight},

View File

@ -570,7 +570,7 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
let core = *self let core = *self
.recording_geometry_with_rtree .recording_geometry_with_rtree
.graph() .graph()
.neighbors(inner.index()) .neighbors(inner.index().into())
.filter(|ni| { .filter(|ni| {
matches!( matches!(
self.recording_geometry_with_rtree self.recording_geometry_with_rtree
@ -578,14 +578,14 @@ impl<CW: Clone, Cel: Copy, R: AccessRules> Drawing<CW, Cel, R> {
.edge_weight( .edge_weight(
self.recording_geometry_with_rtree self.recording_geometry_with_rtree
.graph() .graph()
.find_edge(inner.index(), *ni) .find_edge(inner.index().into(), *ni)
.unwrap() .unwrap()
) )
.unwrap(), .unwrap(),
GeometryLabel::Core GeometryLabel::Core
) )
}) })
.map(FixedDotIndex::new) .map(|node| FixedDotIndex::new(node.index()))
.collect::<Vec<FixedDotIndex>>() .collect::<Vec<FixedDotIndex>>()
.first() .first()
.unwrap(); .unwrap();

View File

@ -5,7 +5,7 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::{stable_graph::NodeIndex, visit::Walker}; use petgraph::visit::Walker;
use crate::{ use crate::{
drawing::{ drawing::{

View File

@ -3,7 +3,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use crate::{ use crate::{
geometry::GetLayer, geometry::GetLayer,
@ -115,7 +114,7 @@ pub enum PrimitiveWeight {
impl crate::geometry::Retag for PrimitiveWeight { impl crate::geometry::Retag for PrimitiveWeight {
type Index = PrimitiveIndex; type Index = PrimitiveIndex;
fn retag(&self, index: NodeIndex<usize>) -> PrimitiveIndex { fn retag(&self, index: usize) -> PrimitiveIndex {
macro_rules! match_self { macro_rules! match_self {
($self:expr, $($kind:ident),*,) => {{ ($self:expr, $($kind:ident),*,) => {{
match $self { match $self {

View File

@ -3,7 +3,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use crate::{ use crate::{
drawing::Drawing, drawing::Drawing,

View File

@ -3,7 +3,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex;
use crate::{ use crate::{
drawing::{ drawing::{
@ -200,7 +199,7 @@ impl<'a, W, CW, Cel, R> GenericPrimitive<'a, W, CW, Cel, R> {
.drawing .drawing
.geometry() .geometry()
.graph() .graph()
.node_weight(self.index.index()) .node_weight(self.index.index().into())
.unwrap() .unwrap()
{ {
*weight *weight
@ -226,7 +225,7 @@ impl<W, CW, Cel, R> GetDrawing for GenericPrimitive<'_, W, CW, Cel, R> {
} }
impl<W, CW, Cel, R> GetIndex for GenericPrimitive<'_, W, CW, Cel, R> { impl<W, CW, Cel, R> GetIndex for GenericPrimitive<'_, W, CW, Cel, R> {
fn index(&self) -> NodeIndex<usize> { fn index(&self) -> usize {
self.index.index() self.index.index()
} }
} }

View File

@ -16,8 +16,6 @@ use crate::{
graph::{GenericIndex, GetIndex}, graph::{GenericIndex, GetIndex},
}; };
use petgraph::stable_graph::NodeIndex;
#[enum_dispatch(GetIndex, MakePrimitiveRef)] #[enum_dispatch(GetIndex, MakePrimitiveRef)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub enum SegIndex { pub enum SegIndex {

View File

@ -6,7 +6,7 @@ use core::marker::PhantomData;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::{ use petgraph::{
stable_graph::{NodeIndex, StableDiGraph}, stable_graph::StableDiGraph,
visit::{EdgeRef, Walker}, visit::{EdgeRef, Walker},
Direction::{Incoming, Outgoing}, Direction::{Incoming, Outgoing},
}; };
@ -31,7 +31,7 @@ use crate::{
pub trait Retag { pub trait Retag {
type Index: Sized + GetIndex + PartialEq + Copy; type Index: Sized + GetIndex + PartialEq + Copy;
fn retag(&self, index: NodeIndex<usize>) -> Self::Index; fn retag(&self, index: usize) -> Self::Index;
} }
#[enum_dispatch] #[enum_dispatch]
@ -75,7 +75,7 @@ pub enum GenericNode<P, C> {
} }
impl<P: GetIndex, C: GetIndex> GetIndex for GenericNode<P, C> { impl<P: GetIndex, C: GetIndex> GetIndex for GenericNode<P, C> {
fn index(&self) -> NodeIndex<usize> { fn index(&self) -> usize {
match self { match self {
Self::Primitive(x) => x.index(), Self::Primitive(x) => x.index(),
Self::Compound(x) => x.index(), Self::Compound(x) => x.index(),
@ -149,11 +149,11 @@ impl<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI> Geometry<PW, DW, SW, BW, CW, Cel,
&self.graph &self.graph
} }
fn primitive_weight(&self, index: NodeIndex<usize>) -> PW fn primitive_weight(&self, index: usize) -> PW
where where
PW: Copy, 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 *weight
} else { } else {
unreachable!() unreachable!()
@ -175,7 +175,11 @@ impl<
> Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI> > Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
{ {
pub fn add_dot<W: AccessDotWeight + Into<PW>>(&mut self, weight: W) -> GenericIndex<W> { pub fn add_dot<W: AccessDotWeight + Into<PW>>(&mut self, weight: W) -> GenericIndex<W> {
GenericIndex::<W>::new(self.graph.add_node(GenericNode::Primitive(weight.into()))) GenericIndex::<W>::new(
self.graph
.add_node(GenericNode::Primitive(weight.into()))
.index(),
)
} }
pub(super) fn add_dot_at_index<W: AccessDotWeight + Into<PW>>( pub(super) fn add_dot_at_index<W: AccessDotWeight + Into<PW>>(
@ -184,7 +188,7 @@ impl<
weight: W, weight: W,
) { ) {
self.graph self.graph
.update_node(dot.index(), GenericNode::Primitive(weight.into())); .update_node(dot.index().into(), GenericNode::Primitive(weight.into()));
} }
pub fn add_seg<W: AccessSegWeight + Into<PW>>( pub fn add_seg<W: AccessSegWeight + Into<PW>>(
@ -193,8 +197,11 @@ impl<
to: DI, to: DI,
weight: W, weight: W,
) -> GenericIndex<W> { ) -> GenericIndex<W> {
let seg = let seg = GenericIndex::<W>::new(
GenericIndex::<W>::new(self.graph.add_node(GenericNode::Primitive(weight.into()))); self.graph
.add_node(GenericNode::Primitive(weight.into()))
.index(),
);
self.init_seg_joints(seg, from, to); self.init_seg_joints(seg, from, to);
seg seg
} }
@ -207,7 +214,7 @@ impl<
weight: W, weight: W,
) { ) {
self.graph 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); self.init_seg_joints(seg, from, to);
} }
@ -217,10 +224,13 @@ impl<
from: DI, from: DI,
to: DI, to: DI,
) { ) {
self.graph.update_edge(
from.index().into(),
seg.index().into(),
GeometryLabel::Joined,
);
self.graph self.graph
.update_edge(from.index(), seg.index(), GeometryLabel::Joined); .update_edge(seg.index().into(), to.index().into(), GeometryLabel::Joined);
self.graph
.update_edge(seg.index(), to.index(), GeometryLabel::Joined);
} }
pub fn is_joined_with<I>(&self, seg: I, node: GenericNode<PI, GenericIndex<CW>>) -> bool pub fn is_joined_with<I>(&self, seg: I, node: GenericNode<PI, GenericIndex<CW>>) -> bool
@ -232,7 +242,7 @@ impl<
match node { match node {
GenericNode::Primitive(prim) => self GenericNode::Primitive(prim) => self
.graph .graph
.find_edge_undirected(seg.index(), prim.index()) .find_edge_undirected(seg.index().into(), prim.index().into())
.map_or(false, |(eidx, _direction)| { .map_or(false, |(eidx, _direction)| {
matches!(self.graph.edge_weight(eidx).unwrap(), GeometryLabel::Joined) matches!(self.graph.edge_weight(eidx).unwrap(), GeometryLabel::Joined)
}), }),
@ -249,8 +259,11 @@ impl<
core: DI, core: DI,
weight: W, weight: W,
) -> GenericIndex<W> { ) -> GenericIndex<W> {
let bend = let bend = GenericIndex::<W>::new(
GenericIndex::<W>::new(self.graph.add_node(GenericNode::Primitive(weight.into()))); self.graph
.add_node(GenericNode::Primitive(weight.into()))
.index(),
);
self.init_bend_joints_and_core(bend, from, to, core); self.init_bend_joints_and_core(bend, from, to, core);
bend bend
} }
@ -264,13 +277,13 @@ impl<
weight: W, weight: W,
) { ) {
self.graph 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); self.init_bend_joints_and_core(bend, from, to, core);
} }
pub(super) fn add_compound_at_index(&mut self, compound: GenericIndex<CW>, weight: CW) { pub(super) fn add_compound_at_index(&mut self, compound: GenericIndex<CW>, weight: CW) {
self.graph self.graph
.update_node(compound.index(), GenericNode::Compound(weight)); .update_node(compound.index().into(), GenericNode::Compound(weight));
} }
fn init_bend_joints_and_core<W: AccessBendWeight + Into<PW>>( fn init_bend_joints_and_core<W: AccessBendWeight + Into<PW>>(
@ -280,58 +293,80 @@ impl<
to: DI, to: DI,
core: DI, core: DI,
) { ) {
self.graph self.graph.update_edge(
.update_edge(from.index(), bend.index(), GeometryLabel::Joined); from.index().into(),
self.graph bend.index().into(),
.update_edge(bend.index(), to.index(), GeometryLabel::Joined); GeometryLabel::Joined,
self.graph );
.update_edge(bend.index(), core.index(), GeometryLabel::Core); 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) { 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) { pub fn move_dot(&mut self, dot: DI, to: Point) {
let mut weight = self.dot_weight(dot); let mut weight = self.dot_weight(dot);
weight.set_pos(to); 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) { pub fn shift_bend(&mut self, bend: BI, offset: f64) {
let mut weight = self.bend_weight(bend); let mut weight = self.bend_weight(bend);
weight.set_offset(offset); 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) { pub fn flip_bend(&mut self, bend: BI) {
let (from, to) = self.bend_joints(bend); let (from, to) = self.bend_joints(bend);
let from_edge_weight = self let from_edge_weight = self
.graph .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(); .unwrap();
let to_edge_weight = self let to_edge_weight = self
.graph .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(); .unwrap();
self.graph self.graph
.update_edge(from.index(), bend.index(), to_edge_weight); .update_edge(from.index().into(), bend.index().into(), to_edge_weight);
self.graph 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<BI>) { pub fn reattach_bend(&mut self, bend: BI, maybe_new_inner: Option<BI>) {
if let Some(old_inner_edge) = self if let Some(old_inner_edge) = self
.graph .graph
.edges_directed(bend.index(), Incoming) .edges_directed(bend.index().into(), Incoming)
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer)) .find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
{ {
debug_assert!(self.graph.remove_edge(old_inner_edge.id()).is_some()); debug_assert!(self.graph.remove_edge(old_inner_edge.id()).is_some());
} }
if let Some(new_inner) = maybe_new_inner { if let Some(new_inner) = maybe_new_inner {
self.graph self.graph.update_edge(
.update_edge(new_inner.index(), bend.index(), GeometryLabel::Outer); new_inner.index().into(),
bend.index().into(),
GeometryLabel::Outer,
);
} }
} }
@ -350,7 +385,7 @@ impl<
PrimitiveShape::Seg(SegShape { PrimitiveShape::Seg(SegShape {
from: self.dot_weight(from).pos(), from: self.dot_weight(from).pos(),
to: self.dot_weight(to).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(), pos: core_weight.pos(),
r: self.inner_radius(bend), 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 { pub fn dot_weight(&self, dot: DI) -> DW {
self.primitive_weight(dot.index()) self.primitive_weight(dot.index().into())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
} }
pub fn seg_weight(&self, seg: SI) -> SW { pub fn seg_weight(&self, seg: SI) -> SW {
self.primitive_weight(seg.index()) self.primitive_weight(seg.index().into())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
} }
pub fn bend_weight(&self, bend: BI) -> BW { pub fn bend_weight(&self, bend: BI) -> BW {
self.primitive_weight(bend.index()) self.primitive_weight(bend.index().into())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
} }
pub fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW { pub fn compound_weight(&self, compound: GenericIndex<CW>) -> &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 weight
} else { } else {
unreachable!() unreachable!()
@ -409,10 +446,10 @@ impl<
fn core_weight(&self, bend: BI) -> DW { fn core_weight(&self, bend: BI) -> DW {
self.graph self.graph
.edges_directed(bend.index(), Outgoing) .edges_directed(bend.index().into(), Outgoing)
.find(|edge| matches!(edge.weight(), GeometryLabel::Core)) .find(|edge| matches!(edge.weight(), GeometryLabel::Core))
.map(|edge| { .map(|edge| {
self.primitive_weight(edge.target()) self.primitive_weight(edge.target().index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -421,13 +458,13 @@ impl<
pub fn joineds(&self, node: PI) -> impl Iterator<Item = PI> + '_ { pub fn joineds(&self, node: PI) -> impl Iterator<Item = PI> + '_ {
self.graph self.graph
.neighbors_undirected(node.index()) .neighbors_undirected(node.index().into())
.filter(move |ni| { .filter(move |ni| {
matches!( matches!(
self.graph self.graph
.edge_weight( .edge_weight(
self.graph self.graph
.find_edge_undirected(node.index(), *ni) .find_edge_undirected(node.index().into(), *ni)
.unwrap() .unwrap()
.0, .0,
) )
@ -435,7 +472,7 @@ impl<
GeometryLabel::Joined GeometryLabel::Joined
) )
}) })
.map(|ni| self.primitive_index(ni)) .map(|ni| self.primitive_index(ni.index()))
} }
pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ { pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ {
@ -449,24 +486,24 @@ impl<
fn joints(&self, node: PI) -> (DI, DI) { fn joints(&self, node: PI) -> (DI, DI) {
let lhs = self let lhs = self
.graph .graph
.edges_directed(node.index(), Incoming) .edges_directed(node.index().into(), Incoming)
.find(|edge| matches!(edge.weight(), GeometryLabel::Joined)) .find(|edge| matches!(edge.weight(), GeometryLabel::Joined))
.map(|edge| edge.source()); .map(|edge| edge.source());
let rhs = self let rhs = self
.graph .graph
.edges_directed(node.index(), Outgoing) .edges_directed(node.index().into(), Outgoing)
.find(|edge| matches!(edge.weight(), GeometryLabel::Joined)) .find(|edge| matches!(edge.weight(), GeometryLabel::Joined))
.map(|edge| edge.target()); .map(|edge| edge.target());
( (
lhs.map(|ni| { lhs.map(|ni| {
self.primitive_index(ni) self.primitive_index(ni.index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.unwrap(), .unwrap(),
rhs.map(|ni| { rhs.map(|ni| {
self.primitive_index(ni) self.primitive_index(ni.index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -486,7 +523,7 @@ impl<
impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW, Cel, PI, DI, SI, BI> impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI> Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
{ {
fn primitive_index(&self, index: NodeIndex<usize>) -> PI { fn primitive_index(&self, index: usize) -> PI {
self.primitive_weight(index).retag(index) self.primitive_weight(index).retag(index)
} }
} }
@ -543,12 +580,12 @@ impl<
BI: GetIndex, BI: GetIndex,
> Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI> > Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
{ {
pub fn all_rails(&self, node: NodeIndex<usize>) -> impl Iterator<Item = BI> + '_ { pub fn all_rails(&self, index: usize) -> impl Iterator<Item = BI> + '_ {
self.graph self.graph
.edges_directed(node, Incoming) .edges_directed(index.into(), Incoming)
.filter(|edge| matches!(edge.weight(), GeometryLabel::Core)) .filter(|edge| matches!(edge.weight(), GeometryLabel::Core))
.map(|edge| { .map(|edge| {
self.primitive_index(edge.source()) self.primitive_index(edge.source().index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -556,10 +593,10 @@ impl<
pub fn core(&self, bend: BI) -> DI { pub fn core(&self, bend: BI) -> DI {
self.graph self.graph
.edges_directed(bend.index(), Outgoing) .edges_directed(bend.index().into(), Outgoing)
.find(|edge| matches!(edge.weight(), GeometryLabel::Core)) .find(|edge| matches!(edge.weight(), GeometryLabel::Core))
.map(|edge| { .map(|edge| {
self.primitive_index(edge.target()) self.primitive_index(edge.target().index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -568,10 +605,10 @@ impl<
pub fn inner(&self, bend: BI) -> Option<BI> { pub fn inner(&self, bend: BI) -> Option<BI> {
self.graph self.graph
.edges_directed(bend.index(), Incoming) .edges_directed(bend.index().into(), Incoming)
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer)) .find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
.map(|edge| { .map(|edge| {
self.primitive_index(edge.source()) self.primitive_index(edge.source().index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -579,10 +616,10 @@ impl<
pub fn outers(&self, bend: BI) -> impl Iterator<Item = BI> + '_ { pub fn outers(&self, bend: BI) -> impl Iterator<Item = BI> + '_ {
self.graph self.graph
.edges_directed(bend.index(), Outgoing) .edges_directed(bend.index().into(), Outgoing)
.filter(|edge| matches!(edge.weight(), GeometryLabel::Outer)) .filter(|edge| matches!(edge.weight(), GeometryLabel::Outer))
.map(|edge| { .map(|edge| {
self.primitive_index(edge.target()) self.primitive_index(edge.target().index())
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
@ -600,11 +637,11 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D
type EntryLabel = Cel; type EntryLabel = Cel;
fn add_compound(&mut self, weight: CW) -> GenericIndex<CW> { fn add_compound(&mut self, weight: CW) -> GenericIndex<CW> {
GenericIndex::<CW>::new(self.graph.add_node(GenericNode::Compound(weight))) GenericIndex::<CW>::new(self.graph.add_node(GenericNode::Compound(weight)).index())
} }
fn remove_compound(&mut self, compound: GenericIndex<CW>) { fn remove_compound(&mut self, compound: GenericIndex<CW>) {
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<I>(&mut self, primitive: I, entry_label: Cel, compound: GenericIndex<CW>) fn add_to_compound<I>(&mut self, primitive: I, entry_label: Cel, compound: GenericIndex<CW>)
@ -612,14 +649,16 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D
I: Copy + GetIndex, I: Copy + GetIndex,
{ {
self.graph.update_edge( self.graph.update_edge(
primitive.index(), primitive.index().into(),
compound.index(), compound.index().into(),
GeometryLabel::Compound(entry_label), GeometryLabel::Compound(entry_label),
); );
} }
fn compound_weight(&self, compound: GenericIndex<CW>) -> &CW { fn compound_weight(&self, compound: GenericIndex<CW>) -> &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 weight
} else { } else {
unreachable!() unreachable!()
@ -631,10 +670,10 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D
compound: GenericIndex<CW>, compound: GenericIndex<CW>,
) -> impl Iterator<Item = (Cel, Self::GeneralIndex)> + '_ { ) -> impl Iterator<Item = (Cel, Self::GeneralIndex)> + '_ {
self.graph self.graph
.edges_directed(compound.index(), Incoming) .edges_directed(compound.index().into(), Incoming)
.filter_map(|edge| { .filter_map(|edge| {
if let GeometryLabel::Compound(entry_label) = *edge.weight() { 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 { } else {
None None
} }
@ -646,10 +685,10 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, D
I: Copy + GetIndex, I: Copy + GetIndex,
{ {
self.graph self.graph
.edges_directed(node.index(), Outgoing) .edges_directed(node.index().into(), Outgoing)
.filter_map(|edge| { .filter_map(|edge| {
if let GeometryLabel::Compound(entry_label) = *edge.weight() { if let GeometryLabel::Compound(entry_label) = *edge.weight() {
Some((entry_label, GenericIndex::new(edge.target()))) Some((entry_label, GenericIndex::new(edge.target().index())))
} else { } else {
None None
} }

View File

@ -15,13 +15,13 @@ pub trait MakeRef<'a, C> {
#[enum_dispatch] #[enum_dispatch]
pub trait GetIndex { pub trait GetIndex {
fn index(&self) -> NodeIndex<usize>; fn index(&self) -> usize;
} }
impl GetIndex for NodeIndex<usize> { impl GetIndex for NodeIndex<usize> {
#[inline(always)] #[inline(always)]
fn index(&self) -> NodeIndex<usize> { fn index(&self) -> usize {
*self NodeIndex::index(*self)
} }
} }
@ -31,14 +31,14 @@ impl GetIndex for NodeIndex<usize> {
#[serde(bound = "")] #[serde(bound = "")]
#[serde(transparent)] #[serde(transparent)]
pub struct GenericIndex<W> { pub struct GenericIndex<W> {
node_index: NodeIndex<usize>, node_index: usize,
#[serde(skip)] #[serde(skip)]
marker: PhantomData<W>, marker: PhantomData<W>,
} }
impl<W> GenericIndex<W> { impl<W> GenericIndex<W> {
#[inline] #[inline]
pub fn new(index: NodeIndex<usize>) -> Self { pub fn new(index: usize) -> Self {
Self { Self {
node_index: index, node_index: index,
marker: PhantomData, marker: PhantomData,
@ -58,7 +58,7 @@ impl<W> core::marker::Copy for GenericIndex<W> {}
impl<W> core::fmt::Debug for GenericIndex<W> { impl<W> core::fmt::Debug for GenericIndex<W> {
#[inline] #[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 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<W> core::hash::Hash for GenericIndex<W> {
impl<W> GetIndex for GenericIndex<W> { impl<W> GetIndex for GenericIndex<W> {
#[inline] #[inline]
fn index(&self) -> NodeIndex<usize> { fn index(&self) -> usize {
self.node_index self.node_index
} }
} }
@ -106,12 +106,12 @@ mod tests {
#[test] #[test]
fn serializable_index() { fn serializable_index() {
assert_eq!( assert_eq!(
serde_json::to_string(&GenericIndex::<()>::new(NodeIndex::new(0))).unwrap(), serde_json::to_string(&GenericIndex::<()>::new(0)).unwrap(),
"0" "0"
); );
assert_eq!( assert_eq!(
serde_json::from_str::<GenericIndex<()>>("0").unwrap(), serde_json::from_str::<GenericIndex<()>>("0").unwrap(),
GenericIndex::new(NodeIndex::new(0)) GenericIndex::new(0)
); );
} }
} }

View File

@ -23,7 +23,6 @@ use crate::{
shape::AccessShape, shape::AccessShape,
GenericNode, GenericNode,
}, },
graph::GetIndex,
layout::{Layout, NodeIndex}, layout::{Layout, NodeIndex},
math::{intersect_linestring_and_ray, LineInGeneralForm, LineIntersection}, math::{intersect_linestring_and_ray, LineInGeneralForm, LineIntersection},
}; };
@ -121,11 +120,10 @@ impl<R: AccessRules> Layout<R> {
.filter(|(_, band_uid, _)| { .filter(|(_, band_uid, _)| {
// filter entries which are connected to either lhs or rhs (and possibly both) // filter entries which are connected to either lhs or rhs (and possibly both)
let (bts1, bts2) = band_uid.into(); let (bts1, bts2) = band_uid.into();
let (bts1, bts2) = (bts1.index(), bts2.index());
let geometry = self.drawing.geometry(); let geometry = self.drawing.geometry();
[(bts1, left), (bts1, right), (bts2, left), (bts2, right)] [(bts1, left), (bts1, right), (bts2, left), (bts2, right)]
.iter() .iter()
.all(|&(x, y)| !geometry.is_joined_with(x, y)) .all(|&(x, y)| !geometry.is_joined_with(*x, y))
}) })
.collect(); .collect();
bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0)); bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0));
@ -162,11 +160,10 @@ impl<R: AccessRules> Layout<R> {
.filter(|(_, band_uid, _)| { .filter(|(_, band_uid, _)| {
// filter entries which are connected to rhs // filter entries which are connected to rhs
let (bts1, bts2) = band_uid.into(); let (bts1, bts2) = band_uid.into();
let (bts1, bts2) = (bts1.index(), bts2.index());
let geometry = self.drawing.geometry(); let geometry = self.drawing.geometry();
[(bts1, right), (bts2, right)] [(bts1, right), (bts2, right)]
.iter() .iter()
.all(|&(x, y)| !geometry.is_joined_with(x, y)) .all(|&(x, y)| !geometry.is_joined_with(*x, y))
}) })
.collect(); .collect();
bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0)); bands.sort_by(|a, b| f64::total_cmp(&a.0, &b.0));

View File

@ -360,8 +360,11 @@ impl<R: AccessRules> Layout<R> {
let PrimitiveIndex::FixedDot(dot) = index else { let PrimitiveIndex::FixedDot(dot) = index else {
return None; return None;
}; };
if let GenericNode::Primitive(PrimitiveWeight::FixedDot(weight)) = if let GenericNode::Primitive(PrimitiveWeight::FixedDot(weight)) = drawing
drawing.geometry().graph().node_weight(dot.index()).unwrap() .geometry()
.graph()
.node_weight(dot.index().into())
.unwrap()
{ {
Some((dot, weight)) Some((dot, weight))
} else { } else {

View File

@ -284,98 +284,98 @@ mod tests {
#[test] #[test]
fn petp00() { fn petp00() {
let poly_ext = &[ let poly_ext = &[
(point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), (point! { x: 0., y: 0. }, FixedDotIndex::new(0)),
(point! { x: 1., y: 0. }, FixedDotIndex::new(1.into())), (point! { x: 1., y: 0. }, FixedDotIndex::new(1)),
(point! { x: 1., y: 1. }, FixedDotIndex::new(2.into())), (point! { x: 1., y: 1. }, FixedDotIndex::new(2)),
(point! { x: 0., y: 1. }, FixedDotIndex::new(3.into())), (point! { x: 0., y: 1. }, FixedDotIndex::new(3)),
]; ];
let origin = point! { x: 0.5, y: -1.0 }; let origin = point! { x: 0.5, y: -1.0 };
assert_eq!( assert_eq!(
petp(poly_ext, false, origin), petp(poly_ext, false, origin),
Ok((FixedDotIndex::new(1.into()), FixedDotIndex::new(0.into()))) Ok((FixedDotIndex::new(1), FixedDotIndex::new(0)))
); );
} }
#[test] #[test]
fn petp00cw() { fn petp00cw() {
let poly_ext = &[ let poly_ext = &[
(point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), (point! { x: 0., y: 0. }, FixedDotIndex::new(0)),
(point! { x: 0., y: 1. }, FixedDotIndex::new(3.into())), (point! { x: 0., y: 1. }, FixedDotIndex::new(3)),
(point! { x: 1., y: 1. }, FixedDotIndex::new(2.into())), (point! { x: 1., y: 1. }, FixedDotIndex::new(2)),
(point! { x: 1., y: 0. }, FixedDotIndex::new(1.into())), (point! { x: 1., y: 0. }, FixedDotIndex::new(1)),
]; ];
let origin = point! { x: 0.5, y: -1.0 }; let origin = point! { x: 0.5, y: -1.0 };
assert_eq!( assert_eq!(
petp(poly_ext, true, origin), petp(poly_ext, true, origin),
Ok((FixedDotIndex::new(1.into()), FixedDotIndex::new(0.into()))) Ok((FixedDotIndex::new(1), FixedDotIndex::new(0)))
); );
} }
#[test] #[test]
fn triangle() { fn triangle() {
let poly_ext = &[ let poly_ext = &[
(point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), (point! { x: 0., y: 0. }, FixedDotIndex::new(0)),
(point! { x: 1., y: 1. }, FixedDotIndex::new(1.into())), (point! { x: 1., y: 1. }, FixedDotIndex::new(1)),
(point! { x: 0., y: 2. }, FixedDotIndex::new(2.into())), (point! { x: 0., y: 2. }, FixedDotIndex::new(2)),
]; ];
let origin = point! { x: 2., y: 1. }; let origin = point! { x: 2., y: 1. };
assert_eq!( assert_eq!(
petp(poly_ext, false, origin), petp(poly_ext, false, origin),
Ok((FixedDotIndex::new(2.into()), FixedDotIndex::new(0.into()))) Ok((FixedDotIndex::new(2), FixedDotIndex::new(0)))
); );
} }
#[test] #[test]
fn triangle_cw() { fn triangle_cw() {
let poly_ext = &[ let poly_ext = &[
(point! { x: 0., y: 0. }, FixedDotIndex::new(0.into())), (point! { x: 0., y: 0. }, FixedDotIndex::new(0)),
(point! { x: 0., y: 2. }, FixedDotIndex::new(2.into())), (point! { x: 0., y: 2. }, FixedDotIndex::new(2)),
(point! { x: 1., y: 1. }, FixedDotIndex::new(1.into())), (point! { x: 1., y: 1. }, FixedDotIndex::new(1)),
]; ];
let origin = point! { x: 2., y: 1. }; let origin = point! { x: 2., y: 1. };
assert_eq!( assert_eq!(
petp(poly_ext, true, origin), petp(poly_ext, true, origin),
Ok((FixedDotIndex::new(2.into()), FixedDotIndex::new(0.into()))) Ok((FixedDotIndex::new(2), FixedDotIndex::new(0)))
); );
} }
#[test] #[test]
fn handover00() { fn handover00() {
let poly_ext_src = &[ let poly_ext_src = &[
(point! { x: 4., y: 0. }, FixedDotIndex::new(0.into())), (point! { x: 4., y: 0. }, FixedDotIndex::new(0)),
(point! { x: 3., y: 3. }, FixedDotIndex::new(1.into())), (point! { x: 3., y: 3. }, FixedDotIndex::new(1)),
(point! { x: 1., y: 2. }, FixedDotIndex::new(2.into())), (point! { x: 1., y: 2. }, FixedDotIndex::new(2)),
(point! { x: 1., y: -2. }, FixedDotIndex::new(3.into())), (point! { x: 1., y: -2. }, FixedDotIndex::new(3)),
(point! { x: 3., y: -3. }, FixedDotIndex::new(4.into())), (point! { x: 3., y: -3. }, FixedDotIndex::new(4)),
]; ];
let source = CachedPolyExt::new(poly_ext_src, false); let source = CachedPolyExt::new(poly_ext_src, false);
let source = &source; let source = &source;
let poly_ext_trg = &[ let poly_ext_trg = &[
(point! { x: -4., y: 0. }, FixedDotIndex::new(10.into())), (point! { x: -4., y: 0. }, FixedDotIndex::new(10)),
(point! { x: -3., y: 3. }, FixedDotIndex::new(11.into())), (point! { x: -3., y: 3. }, FixedDotIndex::new(11)),
(point! { x: -1., y: 2. }, FixedDotIndex::new(12.into())), (point! { x: -1., y: 2. }, FixedDotIndex::new(12)),
(point! { x: -1., y: -2. }, FixedDotIndex::new(13.into())), (point! { x: -1., y: -2. }, FixedDotIndex::new(13)),
(point! { x: -3., y: -3. }, FixedDotIndex::new(14.into())), (point! { x: -3., y: -3. }, FixedDotIndex::new(14)),
]; ];
let target = CachedPolyExt::new(poly_ext_trg, true); let target = CachedPolyExt::new(poly_ext_trg, true);
let target = &target; let target = &target;
assert_eq!( assert_eq!(
pehov(source, CoCw, target, CoCw), pehov(source, CoCw, target, CoCw),
Some((FixedDotIndex::new(1.into()), FixedDotIndex::new(11.into()))) Some((FixedDotIndex::new(1), FixedDotIndex::new(11)))
); );
assert_eq!( assert_eq!(
pehov(source, CoCw, target, Cw), pehov(source, CoCw, target, Cw),
Some((FixedDotIndex::new(2.into()), FixedDotIndex::new(13.into()))) Some((FixedDotIndex::new(2), FixedDotIndex::new(13)))
); );
assert_eq!( assert_eq!(
pehov(source, Cw, target, CoCw), pehov(source, Cw, target, CoCw),
Some((FixedDotIndex::new(3.into()), FixedDotIndex::new(12.into()))) Some((FixedDotIndex::new(3), FixedDotIndex::new(12)))
); );
assert_eq!( assert_eq!(
pehov(source, Cw, target, Cw), pehov(source, Cw, target, Cw),
Some((FixedDotIndex::new(4.into()), FixedDotIndex::new(14.into()))) Some((FixedDotIndex::new(4), FixedDotIndex::new(14)))
); );
} }
} }

View File

@ -48,8 +48,8 @@ impl core::fmt::Debug for NavnodeIndex {
} }
impl GetIndex for NavnodeIndex { impl GetIndex for NavnodeIndex {
fn index(&self) -> NodeIndex<usize> { fn index(&self) -> usize {
self.0 self.0.index()
} }
} }
@ -319,7 +319,7 @@ impl Navmesh {
fn unionize_with_overlapees( fn unionize_with_overlapees(
layout: &Layout<impl AccessRules>, layout: &Layout<impl AccessRules>,
overlapping_prenavnodes_unions: &mut UnionFind<NodeIndex<usize>>, overlapping_prenavnodes_unions: &mut UnionFind<usize>,
prenavnode: PrenavmeshNodeIndex, prenavnode: PrenavmeshNodeIndex,
) { ) {
// Ignore overlaps of a fillet. // Ignore overlaps of a fillet.
@ -382,17 +382,17 @@ impl Navmesh {
PrenavmeshNodeIndex, PrenavmeshNodeIndex,
Vec<(NodeIndex<usize>, NodeIndex<usize>)>, Vec<(NodeIndex<usize>, NodeIndex<usize>)>,
>, >,
overlapping_prenavnodes_unions: &UnionFind<NodeIndex<usize>>, overlapping_prenavnodes_unions: &UnionFind<usize>,
from_prenavnode: PrenavmeshNodeIndex, from_prenavnode: PrenavmeshNodeIndex,
to_prenavnode: PrenavmeshNodeIndex, to_prenavnode: PrenavmeshNodeIndex,
) { ) {
// We assume prenavmesh nodes are fixed dots. This is an ugly shortcut, // We assume prenavmesh nodes are fixed dots. This is an ugly shortcut,
// since fixed bends also can be prenavnodes, but it works for now. // since fixed bends also can be prenavnodes, but it works for now.
let from_prenavnode_repr = PrenavmeshNodeIndex::FixedDot(GenericIndex::new( 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( 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( Self::add_prenavedge_as_quadrinavedges(
@ -455,7 +455,7 @@ impl Data for Navmesh {
impl DataMap for Navmesh { impl DataMap for Navmesh {
fn node_weight(&self, vertex: Self::NodeId) -> Option<&Self::NodeWeight> { 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> { fn edge_weight(&self, _edge: Self::EdgeId) -> Option<&Self::EdgeWeight> {
@ -495,7 +495,11 @@ impl<'a> IntoNeighbors for &'a Navmesh {
type Neighbors = Box<dyn Iterator<Item = NavnodeIndex> + 'a>; type Neighbors = Box<dyn Iterator<Item = NavnodeIndex> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors { 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 { fn edges(self, vertex: Self::NodeId) -> Self::Edges {
Box::new( Box::new(
self.graph self.graph
.edges(vertex.index()) .edges(vertex.index().into())
.map(|edge| NavmeshEdgeReference { .map(|edge| NavmeshEdgeReference {
from: NavnodeIndex(edge.source()), from: NavnodeIndex(edge.source()),
to: NavnodeIndex(edge.target()), to: NavnodeIndex(edge.target()),

View File

@ -5,7 +5,7 @@
use derive_getters::Getters; use derive_getters::Getters;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::Point; use geo::Point;
use petgraph::{stable_graph::NodeIndex, visit::NodeIndexable}; use petgraph::visit::NodeIndexable;
use spade::{HasPosition, InsertionError, Point2}; use spade::{HasPosition, InsertionError, Point2};
use crate::{ use crate::{

View File

@ -39,15 +39,15 @@ impl<I: GetIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Default>
} }
pub fn add_vertex(&mut self, weight: VW) -> Result<(), InsertionError> { 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] = self.trianvertex_to_handle[index] =
Some(spade::Triangulation::insert(&mut self.cdt, weight)?); Some(spade::Triangulation::insert(&mut self.cdt, weight)?);
Ok(()) Ok(())
} }
pub fn add_constraint_edge(&mut self, from: VW, to: VW) -> Result<bool, InsertionError> { pub fn add_constraint_edge(&mut self, from: VW, to: VW) -> Result<bool, InsertionError> {
let from_index = from.node_index().index().index(); let from_index = from.node_index().index();
let to_index = to.node_index().index().index(); let to_index = to.node_index().index();
// It is possible for one or both constraint edge endpoint vertices to // It is possible for one or both constraint edge endpoint vertices to
// not exist in the triangulation even after everything has been added. // not exist in the triangulation even after everything has been added.
@ -75,13 +75,13 @@ impl<I: GetIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Default>
pub fn weight(&self, vertex: I) -> &VW { pub fn weight(&self, vertex: I) -> &VW {
spade::Triangulation::s(&self.cdt) 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 { pub fn weight_mut(&mut self, vertex: I) -> &mut VW {
spade::Triangulation::vertex_data_mut( spade::Triangulation::vertex_data_mut(
&mut self.cdt, &mut self.cdt,
self.trianvertex_to_handle[vertex.index().index()].unwrap(), self.trianvertex_to_handle[vertex.index()].unwrap(),
) )
} }
@ -92,7 +92,7 @@ impl<I: GetIndex, VW: GetTrianvertexNodeIndex<I> + HasPosition, EW: Default>
} }
fn handle(&self, vertex: I) -> FixedVertexHandle { 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<<VW as HasPosition>::Scalar> pub fn position(&self, vertex: I) -> Point<<VW as HasPosition>::Scalar>
@ -328,7 +328,7 @@ impl<
} }
fn to_index(&self, node: I) -> usize { fn to_index(&self, node: I) -> usize {
node.index().index() node.index()
} }
fn from_index(&self, index: usize) -> I { fn from_index(&self, index: usize) -> I {

View File

@ -4,7 +4,7 @@
use std::{fs::File, io::BufReader}; use std::{fs::File, io::BufReader};
use petgraph::{stable_graph::NodeIndex, unionfind::UnionFind, visit::NodeIndexable}; use petgraph::{unionfind::UnionFind, visit::NodeIndexable};
use topola::{ use topola::{
autorouter::{ autorouter::{
history::{History, HistoryError}, history::{History, HistoryError},
@ -257,7 +257,7 @@ pub fn assert_band_length(
); );
} }
fn unionfind(autorouter: &mut Autorouter<impl AccessMesadata>) -> UnionFind<NodeIndex<usize>> { fn unionfind(autorouter: &mut Autorouter<impl AccessMesadata>) -> UnionFind<usize> {
for ratline in autorouter.ratsnest().graph().edge_indices() { for ratline in autorouter.ratsnest().graph().edge_indices() {
// Accessing endpoints may create new dots because apex construction is lazy, so we access // 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. // tem all before starting unionfind, as it requires a constant index bound.