mirror of https://codeberg.org/topola/topola.git
feat(geometry/geometry): Create outward bend walker, use it for R-tree updates
Drawing and above abstraction layers do not use it yet, but this will change soon.
This commit is contained in:
parent
8cf26d1799
commit
6317d8b08a
|
|
@ -488,7 +488,8 @@ impl<CW, Cel, R> LooseBend<'_, CW, Cel, R> {
|
|||
pub fn outer(&self) -> Option<LooseBendIndex> {
|
||||
self.drawing()
|
||||
.geometry()
|
||||
.outer(self.bend_index())
|
||||
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
||||
.outers(self.bend_index())
|
||||
.next()
|
||||
.map(|node| LooseBendIndex::new(node.petgraph_index()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ use enum_dispatch::enum_dispatch;
|
|||
use geo::Point;
|
||||
use petgraph::{
|
||||
stable_graph::{NodeIndex, StableDiGraph},
|
||||
visit::EdgeRef,
|
||||
visit::{EdgeRef, Walker},
|
||||
Direction::{Incoming, Outgoing},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::{
|
||||
drawing::{
|
||||
|
|
@ -520,6 +521,45 @@ impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW, Cel, PI, DI, SI, BI>
|
|||
}
|
||||
}
|
||||
|
||||
pub struct OutwardWalker<BI> {
|
||||
frontier: VecDeque<BI>,
|
||||
}
|
||||
|
||||
impl<BI: GetPetgraphIndex> OutwardWalker<BI> {
|
||||
pub fn new(initial_frontier: impl Iterator<Item = BI>) -> Self {
|
||||
let mut frontier = VecDeque::new();
|
||||
frontier.extend(initial_frontier);
|
||||
|
||||
Self { frontier }
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
PW: Copy + Retag<Index = PI>,
|
||||
DW,
|
||||
SW,
|
||||
BW,
|
||||
CW,
|
||||
Cel,
|
||||
PI: TryInto<DI> + TryInto<SI> + TryInto<BI>,
|
||||
DI,
|
||||
SI,
|
||||
BI: Copy + GetPetgraphIndex,
|
||||
> Walker<&Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>> for OutwardWalker<BI>
|
||||
{
|
||||
type Item = BI;
|
||||
|
||||
fn walk_next(
|
||||
&mut self,
|
||||
geometry: &Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>,
|
||||
) -> Option<Self::Item> {
|
||||
let front = self.frontier.pop_front()?;
|
||||
self.frontier.extend(geometry.outers(front));
|
||||
|
||||
Some(front)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
PW: Copy + Retag<Index = PI>,
|
||||
DW,
|
||||
|
|
@ -576,16 +616,20 @@ impl<
|
|||
})
|
||||
}
|
||||
|
||||
pub fn outer(&self, bend: BI) -> Option<BI> {
|
||||
pub fn outers(&self, bend: BI) -> impl Iterator<Item = BI> + '_ {
|
||||
self.graph
|
||||
.edges_directed(bend.petgraph_index(), Outgoing)
|
||||
.find(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
||||
.filter(|edge| matches!(edge.weight(), GeometryLabel::Outer))
|
||||
.map(|edge| {
|
||||
self.primitive_index(edge.target())
|
||||
.try_into()
|
||||
.unwrap_or_else(|_| unreachable!())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn outwards(&self, bend: BI) -> OutwardWalker<BI> {
|
||||
OutwardWalker::new(self.outers(bend))
|
||||
}
|
||||
}
|
||||
|
||||
impl<PW: Copy + Retag<Index = PI>, DW, SW, BW, CW: Clone, Cel: Copy, PI: Copy, DI, SI, BI>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
use contracts_try::debug_invariant;
|
||||
use derive_getters::Getters;
|
||||
use geo::Point;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
use petgraph::{stable_graph::StableDiGraph, visit::Walker};
|
||||
use rstar::{primitives::GeomWithData, Envelope, RTree, RTreeObject, AABB};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -194,21 +194,17 @@ impl<
|
|||
// here because it starts iteration from the bend we currently operate
|
||||
// on, which obviously does not exist after deletion.
|
||||
|
||||
let mut rail = bend;
|
||||
|
||||
while let Some(outer) = self.geometry.outer(rail) {
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(outer)));
|
||||
rail = outer;
|
||||
let mut outwards = self.geometry.outwards(bend);
|
||||
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(next)));
|
||||
}
|
||||
|
||||
let mut maybe_rail = self.geometry.outer(bend);
|
||||
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(bend)));
|
||||
self.geometry.remove_primitive(bend.into());
|
||||
|
||||
while let Some(outer) = maybe_rail {
|
||||
self.rtree.insert(self.make_bend_bbox(outer));
|
||||
maybe_rail = Some(outer);
|
||||
let mut outwards = self.geometry.outwards(bend);
|
||||
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||
self.rtree.insert(self.make_bend_bbox(next));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,11 +269,9 @@ impl<
|
|||
where
|
||||
F: FnOnce(&mut Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>, BI),
|
||||
{
|
||||
let mut rail = bend;
|
||||
|
||||
while let Some(outer) = self.geometry.outer(rail) {
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(outer)));
|
||||
rail = outer;
|
||||
let mut outwards = self.geometry.outwards(bend);
|
||||
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(next)));
|
||||
}
|
||||
|
||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(bend)));
|
||||
|
|
@ -286,11 +280,9 @@ impl<
|
|||
|
||||
self.rtree.insert(self.make_bend_bbox(bend));
|
||||
|
||||
rail = bend;
|
||||
|
||||
while let Some(outer) = self.geometry.outer(rail) {
|
||||
self.rtree.insert(self.make_bend_bbox(outer));
|
||||
rail = outer;
|
||||
let mut outwards = self.geometry.outwards(bend);
|
||||
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||
self.rtree.insert(self.make_bend_bbox(next));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue