refactor(geometry): use more ergonomic petgraph methods where appropriate

This commit is contained in:
Ellen Emilia Anna Zscheile 2025-04-22 20:27:19 +02:00
parent 861869ab7c
commit f416958936
1 changed files with 61 additions and 118 deletions

View File

@ -8,7 +8,7 @@ use geo::Point;
use petgraph::{ use petgraph::{
stable_graph::{NodeIndex, StableDiGraph}, stable_graph::{NodeIndex, StableDiGraph},
visit::EdgeRef, visit::EdgeRef,
Direction::{self, Incoming}, Direction::{Incoming, Outgoing},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -410,21 +410,13 @@ impl<
fn core_weight(&self, bend: BI) -> DW { fn core_weight(&self, bend: BI) -> DW {
self.graph self.graph
.neighbors(bend.petgraph_index()) .edges_directed(bend.petgraph_index(), Outgoing)
.filter(|ni| { .find(|edge| matches!(edge.weight(), GeometryLabel::Core))
matches!( .map(|edge| {
self.graph self.primitive_weight(edge.target())
.edge_weight(self.graph.find_edge(bend.petgraph_index(), *ni).unwrap())
.unwrap(),
GeometryLabel::Core
)
})
.map(|ni| {
self.primitive_weight(ni)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.next()
.unwrap() .unwrap()
} }
@ -444,7 +436,7 @@ impl<
GeometryLabel::Joined GeometryLabel::Joined
) )
}) })
.map(|ni| self.primitive_weight(ni).retag(ni)) .map(|ni| self.primitive_index(ni))
} }
pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ { pub fn joined_segs(&self, dot: DI) -> impl Iterator<Item = SI> + '_ {
@ -456,43 +448,30 @@ impl<
} }
fn joints(&self, node: PI) -> (DI, DI) { fn joints(&self, node: PI) -> (DI, DI) {
let lhs = self
.graph
.edges_directed(node.petgraph_index(), Incoming)
.find(|edge| matches!(edge.weight(), GeometryLabel::Joined))
.map(|edge| edge.source());
let rhs = self
.graph
.edges_directed(node.petgraph_index(), Outgoing)
.find(|edge| matches!(edge.weight(), GeometryLabel::Joined))
.map(|edge| edge.target());
( (
self.graph lhs.map(|ni| {
.neighbors_directed(node.petgraph_index(), Direction::Incoming) self.primitive_index(ni)
.find(move |ni| { .try_into()
matches!( .unwrap_or_else(|_| unreachable!())
self.graph })
.edge_weight( .unwrap(),
self.graph rhs.map(|ni| {
.find_edge_undirected(node.petgraph_index(), *ni) self.primitive_index(ni)
.unwrap() .try_into()
.0, .unwrap_or_else(|_| unreachable!())
) })
.unwrap(), .unwrap(),
GeometryLabel::Joined
)
})
.map(|ni| self.primitive_weight(ni).retag(ni))
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
.unwrap(),
self.graph
.neighbors_directed(node.petgraph_index(), Direction::Outgoing)
.find(move |ni| {
matches!(
self.graph
.edge_weight(
self.graph
.find_edge_undirected(node.petgraph_index(), *ni)
.unwrap()
.0,
)
.unwrap(),
GeometryLabel::Joined
)
})
.map(|ni| self.primitive_weight(ni).retag(ni))
.map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!()))
.unwrap(),
) )
} }
@ -505,6 +484,14 @@ impl<
} }
} }
impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
Geometry<PW, DW, SW, BW, CW, Cek, PI, DI, SI, BI>
{
fn primitive_index(&self, index: NodeIndex<usize>) -> PI {
self.primitive_weight(index).retag(index)
}
}
impl< impl<
PW: Copy + Retag<Index = PI>, PW: Copy + Retag<Index = PI>,
DW, DW,
@ -520,83 +507,47 @@ impl<
{ {
pub fn first_rail(&self, node: NodeIndex<usize>) -> Option<BI> { pub fn first_rail(&self, node: NodeIndex<usize>) -> Option<BI> {
self.graph self.graph
.neighbors_directed(node, Incoming) .edges_directed(node, Incoming)
.filter(|ni| { .find(|edge| matches!(edge.weight(), GeometryLabel::Core))
matches!( .map(|edge| {
self.graph self.primitive_index(edge.source())
.edge_weight(self.graph.find_edge(*ni, node).unwrap())
.unwrap(),
GeometryLabel::Core
)
})
.map(|ni| {
self.primitive_weight(ni)
.retag(ni)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.next()
} }
pub fn core(&self, bend: BI) -> DI { pub fn core(&self, bend: BI) -> DI {
self.graph self.graph
.neighbors(bend.petgraph_index()) .edges_directed(bend.petgraph_index(), Outgoing)
.filter(|ni| { .find(|edge| matches!(edge.weight(), GeometryLabel::Core))
matches!( .map(|edge| {
self.graph self.primitive_index(edge.target())
.edge_weight(self.graph.find_edge(bend.petgraph_index(), *ni).unwrap())
.unwrap(),
GeometryLabel::Core
)
})
.map(|ni| {
self.primitive_weight(ni)
.retag(ni)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.next()
.unwrap() .unwrap()
} }
pub fn inner(&self, bend: BI) -> Option<BI> { pub fn inner(&self, bend: BI) -> Option<BI> {
self.graph self.graph
.neighbors_directed(bend.petgraph_index(), Incoming) .edges_directed(bend.petgraph_index(), Incoming)
.filter(|ni| { .find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
matches!( .map(|edge| {
self.graph self.primitive_index(edge.source())
.edge_weight(self.graph.find_edge(*ni, bend.petgraph_index()).unwrap())
.unwrap(),
GeometryLabel::Outer
)
})
.map(|ni| {
self.primitive_weight(ni)
.retag(ni)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.next()
} }
pub fn outer(&self, bend: BI) -> Option<BI> { pub fn outer(&self, bend: BI) -> Option<BI> {
self.graph self.graph
.neighbors(bend.petgraph_index()) .edges_directed(bend.petgraph_index(), Outgoing)
.filter(|ni| { .find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
matches!( .map(|edge| {
self.graph self.primitive_index(edge.target())
.edge_weight(self.graph.find_edge(bend.petgraph_index(), *ni).unwrap())
.unwrap(),
GeometryLabel::Outer
)
})
.map(|ni| {
self.primitive_weight(ni)
.retag(ni)
.try_into() .try_into()
.unwrap_or_else(|_| unreachable!()) .unwrap_or_else(|_| unreachable!())
}) })
.next()
} }
} }
@ -640,14 +591,10 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cek: Copy, PI: Copy, D
compound: GenericIndex<CW>, compound: GenericIndex<CW>,
) -> impl Iterator<Item = (Cek, Self::GeneralIndex)> + '_ { ) -> impl Iterator<Item = (Cek, Self::GeneralIndex)> + '_ {
self.graph self.graph
.neighbors_directed(compound.petgraph_index(), Incoming) .edges_directed(compound.petgraph_index(), Incoming)
.filter_map(move |ni| { .filter_map(|edge| {
if let GeometryLabel::Compound(entry_kind) = *self if let GeometryLabel::Compound(entry_kind) = *edge.weight() {
.graph Some((entry_kind, self.primitive_index(edge.source())))
.edge_weight(self.graph.find_edge(ni, compound.petgraph_index()).unwrap())
.unwrap()
{
Some((entry_kind, self.primitive_weight(ni).retag(ni)))
} else { } else {
None None
} }
@ -659,14 +606,10 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cek: Copy, PI: Copy, D
I: Copy + GetPetgraphIndex, I: Copy + GetPetgraphIndex,
{ {
self.graph self.graph
.neighbors(node.petgraph_index()) .edges_directed(node.petgraph_index(), Outgoing)
.filter_map(move |ni| { .filter_map(|edge| {
if let GeometryLabel::Compound(entry_kind) = *self if let GeometryLabel::Compound(entry_kind) = *edge.weight() {
.graph Some((entry_kind, GenericIndex::new(edge.target())))
.edge_weight(self.graph.find_edge(node.petgraph_index(), ni).unwrap())
.unwrap()
{
Some((entry_kind, GenericIndex::new(ni)))
} else { } else {
None None
} }