fix(geometry/recording_with_rtree): Attach bends applied from edit

This was unimplemented, which made both redo and cane removal not work
correctly.
This commit is contained in:
Mikolaj Wielgus 2025-07-16 15:27:56 +02:00
parent 1f8ace9c77
commit f75bae0666
4 changed files with 43 additions and 7 deletions

View File

@ -27,7 +27,13 @@ pub trait ApplyGeometryEdit<
pub struct GeometryEdit<DW, SW, BW, CW, Cel, PI, DI, SI, BI> {
pub(super) dots: BTreeMap<DI, (Option<DW>, Option<DW>)>,
pub(super) segs: BTreeMap<SI, (Option<((DI, DI), SW)>, Option<((DI, DI), SW)>)>,
pub(super) bends: BTreeMap<BI, (Option<((DI, DI, DI), BW)>, Option<((DI, DI, DI), BW)>)>,
pub(super) bends: BTreeMap<
BI,
(
Option<((DI, DI, DI, Option<BI>), BW)>,
Option<((DI, DI, DI, Option<BI>), BW)>,
),
>,
pub(super) compounds:
BTreeMap<GenericIndex<CW>, (Option<(Vec<(Cel, PI)>, CW)>, Option<(Vec<(Cel, PI)>, CW)>)>,
}

View File

@ -302,6 +302,18 @@ impl<
);
}
pub(super) fn init_bend_inner<W: AccessBendWeight + Into<PW>>(
&mut self,
bend: GenericIndex<W>,
inner: BI,
) {
self.graph.update_edge(
inner.petgraph_index(),
bend.petgraph_index(),
GeometryLabel::Outer,
);
}
pub fn remove_primitive(&mut self, primitive: PI) {
self.graph.remove_node(primitive.petgraph_index());
}

View File

@ -138,7 +138,7 @@ impl<
(
None,
Some((
(from, to, core),
(from, to, core, None),
weight.into().try_into().unwrap_or_else(|_| unreachable!()),
)),
),
@ -215,11 +215,13 @@ impl<
let weight = geometry.bend_weight(bend);
let joints = geometry.bend_joints(bend);
let core = geometry.core(bend);
let maybe_inner = geometry.inner(bend);
self.geometry_with_rtree.remove_bend(bend);
edit_remove_from_map(
&mut recorder.bends,
bend,
((joints.0, joints.1, core), weight),
((joints.0, joints.1, core, maybe_inner), weight),
);
}
@ -263,6 +265,7 @@ impl<
let geometry = self.geometry_with_rtree.geometry();
let old_joints = geometry.bend_joints(bend);
let old_core = geometry.core(bend);
let old_maybe_inner = geometry.inner(bend);
let old_weight = geometry.bend_weight(bend);
f(&mut self.geometry_with_rtree, bend);
@ -270,16 +273,23 @@ impl<
let geometry = self.geometry_with_rtree.geometry();
let new_joints = geometry.bend_joints(bend);
let new_core = geometry.core(bend);
let new_maybe_inner = geometry.inner(bend);
let new_weight = geometry.bend_weight(bend);
recorder
.bends
.entry(bend)
.or_insert((
Some(((old_joints.0, old_joints.1, old_core), old_weight)),
Some((
(old_joints.0, old_joints.1, old_core, old_maybe_inner),
old_weight,
)),
None,
))
.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight));
.1 = Some((
(new_joints.0, new_joints.1, new_core, new_maybe_inner),
new_weight,
));
}
pub fn shift_bend(

View File

@ -508,7 +508,6 @@ impl<
// Because removal of a bend will invalidate bboxes of the bends wrapped
// around it, we first remove the bends from the R-tree, and their nodes
// from the graph only afterwards.
for (bend, (maybe_old_data, ..)) in &edit.bends {
if maybe_old_data.is_some() {
Self::rtree_remove_must_be_successful(
@ -556,7 +555,7 @@ impl<
// separately to prevent failures from inadvertent bbox invalidation.
for (bend, (.., maybe_new_data)) in &edit.bends {
if let Some(((from, to, core), weight)) = maybe_new_data {
if let Some(((from, to, core, ..), weight)) = maybe_new_data {
self.geometry.add_bend_at_index(
GenericIndex::<BW>::new(bend.petgraph_index()),
*from,
@ -567,6 +566,15 @@ impl<
}
}
// We attach bends to other bends only after all bends have been
// created, since we cannot guarantee that their inner bends will exist,
// and attaching to an inexistent bend will result in a crash.
for (bend, (.., maybe_new_data)) in &edit.bends {
if let Some(((.., maybe_inner), ..)) = maybe_new_data {
self.geometry.reattach_bend(*bend, *maybe_inner);
}
}
for (bend, (.., maybe_new_data)) in &edit.bends {
if let Some(..) = maybe_new_data {
self.init_bend_bbox(*bend);