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> {
|
pub fn outer(&self) -> Option<LooseBendIndex> {
|
||||||
self.drawing()
|
self.drawing()
|
||||||
.geometry()
|
.geometry()
|
||||||
.outer(self.bend_index())
|
.outers(self.bend_index())
|
||||||
.map(|ni| LooseBendIndex::new(ni.petgraph_index()))
|
.next()
|
||||||
|
.map(|node| LooseBendIndex::new(node.petgraph_index()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,11 @@ use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::{
|
use petgraph::{
|
||||||
stable_graph::{NodeIndex, StableDiGraph},
|
stable_graph::{NodeIndex, StableDiGraph},
|
||||||
visit::EdgeRef,
|
visit::{EdgeRef, Walker},
|
||||||
Direction::{Incoming, Outgoing},
|
Direction::{Incoming, Outgoing},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{
|
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<
|
impl<
|
||||||
PW: Copy + Retag<Index = PI>,
|
PW: Copy + Retag<Index = PI>,
|
||||||
DW,
|
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
|
self.graph
|
||||||
.edges_directed(bend.petgraph_index(), Outgoing)
|
.edges_directed(bend.petgraph_index(), Outgoing)
|
||||||
.find(|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())
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap_or_else(|_| unreachable!())
|
.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>
|
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 contracts_try::debug_invariant;
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::{stable_graph::StableDiGraph, visit::Walker};
|
||||||
use rstar::{primitives::GeomWithData, Envelope, RTree, RTreeObject, AABB};
|
use rstar::{primitives::GeomWithData, Envelope, RTree, RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -194,21 +194,17 @@ impl<
|
||||||
// here because it starts iteration from the bend we currently operate
|
// here because it starts iteration from the bend we currently operate
|
||||||
// on, which obviously does not exist after deletion.
|
// on, which obviously does not exist after deletion.
|
||||||
|
|
||||||
let mut rail = bend;
|
let mut outwards = self.geometry.outwards(bend);
|
||||||
|
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||||
while let Some(outer) = self.geometry.outer(rail) {
|
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(outer)));
|
|
||||||
rail = outer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut maybe_rail = self.geometry.outer(bend);
|
|
||||||
|
|
||||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(bend)));
|
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(bend)));
|
||||||
self.geometry.remove_primitive(bend.into());
|
self.geometry.remove_primitive(bend.into());
|
||||||
|
|
||||||
while let Some(outer) = maybe_rail {
|
let mut outwards = self.geometry.outwards(bend);
|
||||||
self.rtree.insert(self.make_bend_bbox(outer));
|
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||||
maybe_rail = Some(outer);
|
self.rtree.insert(self.make_bend_bbox(next));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,11 +269,9 @@ impl<
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>, BI),
|
F: FnOnce(&mut Geometry<PW, DW, SW, BW, CW, Cel, PI, DI, SI, BI>, BI),
|
||||||
{
|
{
|
||||||
let mut rail = bend;
|
let mut outwards = self.geometry.outwards(bend);
|
||||||
|
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||||
while let Some(outer) = self.geometry.outer(rail) {
|
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(outer)));
|
|
||||||
rail = outer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::rtree_remove_must_be_successful(self.rtree.remove(&self.make_bend_bbox(bend)));
|
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));
|
self.rtree.insert(self.make_bend_bbox(bend));
|
||||||
|
|
||||||
rail = bend;
|
let mut outwards = self.geometry.outwards(bend);
|
||||||
|
while let Some(next) = outwards.walk_next(&self.geometry) {
|
||||||
while let Some(outer) = self.geometry.outer(rail) {
|
self.rtree.insert(self.make_bend_bbox(next));
|
||||||
self.rtree.insert(self.make_bend_bbox(outer));
|
|
||||||
rail = outer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue