diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index 58a87e6..981fd9b 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -65,9 +65,9 @@ pub enum GenericNode { Compound(C), } -pub trait AccessDotWeight: GetPos + SetPos + GetWidth + Into + Copy {} -pub trait AccessSegWeight: GetWidth + Into + Copy {} -pub trait AccessBendWeight: GetOffset + SetOffset + GetWidth + Into + Copy {} +pub trait AccessDotWeight: GetPos + SetPos + GetWidth + Into + Copy {} +pub trait AccessSegWeight: GetWidth + Into + Copy {} +pub trait AccessBendWeight: GetOffset + SetOffset + GetWidth + Into + Copy {} #[derive(Debug, Getters)] pub struct Geometry< @@ -82,7 +82,7 @@ pub struct Geometry< BI: GetPetgraphIndex + Into + Copy, > { graph: StableDiGraph, GeometryLabel, usize>, - weight_marker: PhantomData, + primitive_weight_marker: PhantomData, dot_weight_marker: PhantomData, seg_weight_marker: PhantomData, bend_weight_marker: PhantomData, @@ -108,7 +108,7 @@ impl< pub fn new() -> Self { Self { graph: StableDiGraph::default(), - weight_marker: PhantomData, + primitive_weight_marker: PhantomData, dot_weight_marker: PhantomData, seg_weight_marker: PhantomData, bend_weight_marker: PhantomData, diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index e906d7b..5913872 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -3,6 +3,7 @@ mod geometry; pub mod compound; pub mod poly; pub mod primitive; +pub mod recording_with_rtree; pub mod shape; pub mod with_rtree; diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs new file mode 100644 index 0000000..4da5203 --- /dev/null +++ b/src/geometry/recording_with_rtree.rs @@ -0,0 +1,355 @@ +use std::{collections::HashMap, hash::Hash, marker::PhantomData}; + +use geo::Point; +use petgraph::stable_graph::StableDiGraph; + +use crate::{ + drawing::graph::{GetLayer, Retag}, + graph::{GenericIndex, GetPetgraphIndex}, +}; + +use super::{ + compound::ManageCompounds, with_rtree::GeometryWithRtree, AccessBendWeight, AccessDotWeight, + AccessSegWeight, GenericNode, GeometryLabel, GetWidth, +}; + +pub struct GeometryEdit< + 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, +> { + dots: HashMap, Option)>, + segs: HashMap, Option<((DI, DI), SW)>)>, + bends: HashMap, Option<((DI, DI, DI), BW)>)>, + compounds: HashMap, (Option<(Vec, CW)>, Option<(Vec, CW)>)>, + primitive_weight_marker: PhantomData, +} + +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 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 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 graph(&self) -> &StableDiGraph, GeometryLabel, usize> { + self.geometry_with_rtree.graph() + } +} diff --git a/src/geometry/with_rtree.rs b/src/geometry/with_rtree.rs index d8f5b81..f70d3b1 100644 --- a/src/geometry/with_rtree.rs +++ b/src/geometry/with_rtree.rs @@ -1,5 +1,3 @@ -use std::marker::PhantomData; - use contracts_try::debug_invariant; use derive_getters::Getters; use geo::Point; @@ -52,14 +50,6 @@ pub struct GeometryWithRtree< geometry: Geometry, rtree: RTree>>>, layer_count: usize, - weight_marker: PhantomData, - dot_weight_marker: PhantomData, - seg_weight_marker: PhantomData, - bend_weight_marker: PhantomData, - index_marker: PhantomData, - dot_index_marker: PhantomData, - seg_index_marker: PhantomData, - bend_index_marker: PhantomData, } #[debug_invariant(self.test_envelopes())] @@ -81,14 +71,6 @@ impl< geometry: Geometry::::new(), rtree: RTree::new(), layer_count, - weight_marker: PhantomData, - dot_weight_marker: PhantomData, - seg_weight_marker: PhantomData, - bend_weight_marker: PhantomData, - index_marker: PhantomData, - dot_index_marker: PhantomData, - seg_index_marker: PhantomData, - bend_index_marker: PhantomData, } }