diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 814e79b..8ad0718 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -27,7 +27,13 @@ pub trait ApplyGeometryEdit< pub struct GeometryEdit { pub(super) dots: BTreeMap, Option)>, pub(super) segs: BTreeMap, Option<((DI, DI), SW)>)>, - pub(super) bends: BTreeMap, Option<((DI, DI, DI), BW)>)>, + pub(super) bends: BTreeMap< + BI, + ( + Option<((DI, DI, DI, Option), BW)>, + Option<((DI, DI, DI, Option), BW)>, + ), + >, pub(super) compounds: BTreeMap, (Option<(Vec<(Cel, PI)>, CW)>, Option<(Vec<(Cel, PI)>, CW)>)>, } diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index 7774e28..917ff8c 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -302,6 +302,18 @@ impl< ); } + pub(super) fn init_bend_inner>( + &mut self, + bend: GenericIndex, + 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()); } diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index f23562e..da7915f 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -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( diff --git a/src/geometry/with_rtree.rs b/src/geometry/with_rtree.rs index 821fdc6..ef41661 100644 --- a/src/geometry/with_rtree.rs +++ b/src/geometry/with_rtree.rs @@ -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::::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);