use std::hash::Hash; use geo::Point; use petgraph::stable_graph::StableDiGraph; use rstar::RTree; use crate::{ drawing::graph::{GetLayer, Retag}, graph::{GenericIndex, GetPetgraphIndex}, }; use super::{ compound::ManageCompounds, edit::GeometryEdit, with_rtree::{BboxedIndex, GeometryWithRtree}, AccessBendWeight, AccessDotWeight, AccessSegWeight, GenericNode, Geometry, GeometryLabel, GetWidth, }; #[derive(Debug)] pub struct RecordingGeometryWithRtree< PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, DW: AccessDotWeight + GetLayer, SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, DI: GetPetgraphIndex + Into + Eq + Hash + Copy, SI: GetPetgraphIndex + Into + Eq + Hash + Copy, BI: GetPetgraphIndex + Into + Eq + Hash + Copy, > { geometry_with_rtree: GeometryWithRtree, } impl< PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, DW: AccessDotWeight + GetLayer, SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, DI: GetPetgraphIndex + Into + Eq + Hash + Copy, SI: GetPetgraphIndex + Into + Eq + Hash + Copy, BI: GetPetgraphIndex + Into + Eq + Hash + Copy, > RecordingGeometryWithRtree { pub fn new(layer_count: usize) -> Self { Self { geometry_with_rtree: GeometryWithRtree::::new( layer_count, ), } } pub fn add_dot + GetLayer>( &mut self, recorder: &mut GeometryEdit, weight: W, ) -> GenericIndex where GenericIndex: Into, { let dot = self.geometry_with_rtree.add_dot(weight); recorder.dots.insert( Into::::into(dot) .try_into() .unwrap_or_else(|_| unreachable!()), ( None, Some(weight.into().try_into().unwrap_or_else(|_| unreachable!())), ), ); dot } pub fn add_seg + GetLayer>( &mut self, recorder: &mut GeometryEdit, from: DI, to: DI, weight: W, ) -> GenericIndex where GenericIndex: Into, { let seg = self.geometry_with_rtree.add_seg(from, to, weight); recorder.segs.insert( Into::::into(seg) .try_into() .unwrap_or_else(|_| unreachable!()), ( None, Some(( (from, to), weight.into().try_into().unwrap_or_else(|_| unreachable!()), )), ), ); seg } pub fn add_bend + GetLayer>( &mut self, recorder: &mut GeometryEdit, from: DI, to: DI, core: DI, weight: W, ) -> GenericIndex where GenericIndex: Into, { let bend = self.geometry_with_rtree.add_bend(from, to, core, weight); recorder.bends.insert( Into::::into(bend) .try_into() .unwrap_or_else(|_| unreachable!()), ( None, Some(( (from, to, core), weight.into().try_into().unwrap_or_else(|_| unreachable!()), )), ), ); bend } pub fn add_compound( &mut self, recorder: &mut GeometryEdit, weight: CW, ) -> GenericIndex { let compound = self.geometry_with_rtree.add_compound(weight); recorder .compounds .insert(compound, (None, Some((vec![], weight)))); compound } pub fn add_to_compound( &mut self, recorder: &mut GeometryEdit, primitive: GenericIndex, compound: GenericIndex, ) { let old_members = self .geometry_with_rtree .geometry() .compound_members(compound) .collect(); let old_weight = self .geometry_with_rtree .geometry() .compound_weight(compound); let new_members = self .geometry_with_rtree .geometry() .compound_members(compound) .collect(); let new_weight = self .geometry_with_rtree .geometry() .compound_weight(compound); if let Some(value) = recorder.compounds.get_mut(&compound) { value.1 = Some((new_members, new_weight)); } else { recorder.compounds.insert( compound, ( Some((old_members, old_weight)), Some((new_members, new_weight)), ), ); } } pub fn remove_dot( &mut self, recorder: &mut GeometryEdit, dot: DI, ) -> Result<(), ()> { let weight = self.geometry_with_rtree.geometry().dot_weight(dot); self.geometry_with_rtree.remove_dot(dot)?; recorder.dots.insert(dot, (Some(weight), None)); Ok(()) } pub fn remove_seg( &mut self, recorder: &mut GeometryEdit, seg: SI, ) { let weight = self.geometry_with_rtree.geometry().seg_weight(seg); let joints = self.geometry_with_rtree.geometry().seg_joints(seg); self.geometry_with_rtree.remove_seg(seg); recorder.segs.insert(seg, (Some((joints, weight)), None)); } pub fn remove_bend( &mut self, recorder: &mut GeometryEdit, bend: BI, ) { let weight = self.geometry_with_rtree.geometry().bend_weight(bend); let joints = self.geometry_with_rtree.geometry().bend_joints(bend); let core = self.geometry_with_rtree.geometry().core(bend); self.geometry_with_rtree.remove_bend(bend); recorder .bends .insert(bend, (Some(((joints.0, joints.1, core), weight)), None)); } pub fn remove_compound( &mut self, recorder: &mut GeometryEdit, compound: GenericIndex, ) { let weight = self .geometry_with_rtree .geometry() .compound_weight(compound); let members = self .geometry_with_rtree .geometry() .compound_members(compound) .collect(); self.geometry_with_rtree.remove_compound(compound); recorder .compounds .insert(compound, (Some((members, weight)), None)); } pub fn move_dot( &mut self, recorder: &mut GeometryEdit, dot: DI, to: Point, ) { let old_weight = self.geometry_with_rtree.geometry().dot_weight(dot); self.geometry_with_rtree.move_dot(dot, to); let new_weight = self.geometry_with_rtree.geometry().dot_weight(dot); if let Some(value) = recorder.dots.get_mut(&dot) { value.1 = Some(new_weight); } else { recorder .dots .insert(dot, (Some(old_weight), Some(new_weight))); } } pub fn shift_bend( &mut self, recorder: &mut GeometryEdit, bend: BI, offset: f64, ) { let old_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let old_core = self.geometry_with_rtree.geometry().core(bend); let old_weight = self.geometry_with_rtree.geometry().bend_weight(bend); self.geometry_with_rtree.shift_bend(bend, offset); let new_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let new_core = self.geometry_with_rtree.geometry().core(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); if let Some(value) = recorder.bends.get_mut(&bend) { value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); } else { recorder.bends.insert( bend, ( Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)), ), ); } } pub fn flip_bend( &mut self, recorder: &mut GeometryEdit, bend: BI, ) { let old_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let old_core = self.geometry_with_rtree.geometry().core(bend); let old_weight = self.geometry_with_rtree.geometry().bend_weight(bend); self.geometry_with_rtree.flip_bend(bend); let new_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let new_core = self.geometry_with_rtree.geometry().core(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); if let Some(value) = recorder.bends.get_mut(&bend) { value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); } else { recorder.bends.insert( bend, ( Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)), ), ); } } pub fn reattach_bend( &mut self, recorder: &mut GeometryEdit, bend: BI, maybe_new_inner: Option, ) { let old_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let old_core = self.geometry_with_rtree.geometry().core(bend); let old_weight = self.geometry_with_rtree.geometry().bend_weight(bend); self.geometry_with_rtree .reattach_bend(bend, maybe_new_inner); let new_joints = self.geometry_with_rtree.geometry().bend_joints(bend); let new_core = self.geometry_with_rtree.geometry().core(bend); let new_weight = self.geometry_with_rtree.geometry().bend_weight(bend); if let Some(value) = recorder.bends.get_mut(&bend) { value.1 = Some(((new_joints.0, new_joints.1, new_core), new_weight)); } else { recorder.bends.insert( bend, ( Some(((old_joints.0, old_joints.1, old_core), old_weight)), Some(((new_joints.0, new_joints.1, new_core), new_weight)), ), ); } } pub fn apply_edit(&mut self, edit: GeometryEdit) { for (compound, ..) in &edit.compounds { self.geometry_with_rtree.remove_compound(*compound); } for (bend, ..) in &edit.bends { self.geometry_with_rtree.remove_bend(*bend); } for (seg, ..) in &edit.segs { self.geometry_with_rtree.remove_seg(*seg); } for (dot, ..) in &edit.dots { self.geometry_with_rtree.remove_dot(*dot); } for (dot, (.., maybe_weight)) in &edit.dots { if let Some(weight) = maybe_weight { self.geometry_with_rtree.add_dot_at_index(*dot, *weight); } } for (seg, (.., maybe_data)) in &edit.segs { if let Some(((from, to), weight)) = maybe_data { self.geometry_with_rtree .add_seg_at_index(*seg, *from, *to, *weight); } } for (bend, (.., maybe_data)) in &edit.bends { if let Some(((from, to, core), weight)) = maybe_data { self.geometry_with_rtree .add_bend_at_index(*bend, *from, *to, *core, *weight); } } for (compound, (.., maybe_data)) in &edit.compounds { if let Some((members, weight)) = maybe_data { self.geometry_with_rtree .add_compound_at_index(*compound, *weight); for member in members { self.geometry_with_rtree.add_to_compound( GenericIndex::::new(member.petgraph_index()), *compound, ); } } } } pub fn compound_weight(&self, compound: GenericIndex) -> CW { self.geometry_with_rtree.compound_weight(compound) } pub fn compounds<'a, W: 'a>( &'a self, node: GenericIndex, ) -> impl Iterator> + 'a { self.geometry_with_rtree.compounds(node) } pub fn geometry(&self) -> &Geometry { self.geometry_with_rtree.geometry() } pub fn rtree(&self) -> &RTree>>> { self.geometry_with_rtree.rtree() } pub fn layer_count(&self) -> usize { *self.geometry_with_rtree.layer_count() } pub fn graph(&self) -> &StableDiGraph, GeometryLabel, usize> { self.geometry_with_rtree.graph() } }