From 861869ab7c815a8b75b12a808ee3378c46af7fab Mon Sep 17 00:00:00 2001 From: Ellen Emilia Anna Zscheile Date: Tue, 22 Apr 2025 13:34:45 +0200 Subject: [PATCH] refactor(geometry): introduce CompoundEntryKind to suppport entry metadata example usages would be marking the apex of a polygon explicitly, or marking the nodes of a polygon which are part of the convex hull - make ManageCompounds more generic - removes unnecessary bounds on handles/refs --- src/autorouter/ratsnest.rs | 2 +- src/board/mod.rs | 3 +- src/drawing/band.rs | 18 +- src/drawing/cane.rs | 5 +- src/drawing/collect.rs | 4 +- src/drawing/drawing.rs | 197 ++++++++++-------- src/drawing/gear.rs | 25 +-- src/drawing/graph.rs | 12 +- src/drawing/guide.rs | 4 +- src/drawing/head.rs | 17 +- src/drawing/loose.rs | 22 +- src/drawing/primitive.rs | 134 ++++++------ src/geometry/compound.rs | 22 +- src/geometry/edit.rs | 23 ++- src/geometry/geometry.rs | 297 +++++++++++++++------------ src/geometry/recording_with_rtree.rs | 112 +++++----- src/geometry/with_rtree.rs | 76 ++++--- src/graph.rs | 5 +- src/layout/layout.rs | 25 +-- src/layout/poly.rs | 31 +-- src/layout/via.rs | 9 +- 21 files changed, 580 insertions(+), 463 deletions(-) diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 8187d96..f33c69d 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -108,7 +108,7 @@ impl Ratsnest { for node in layout.drawing().layer_primitive_nodes(layer) { if let PrimitiveIndex::FixedDot(dot) = node { - if layout.polys(dot).next().is_none() { + if layout.drawing().compounds(dot).next().is_none() { handle_rvw( layout.drawing().primitive(dot).maybe_net(), RatvertexIndex::FixedDot(dot), diff --git a/src/board/mod.rs b/src/board/mod.rs index b8a1c41..c6129b3 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -23,7 +23,7 @@ use crate::{ }, geometry::{edit::ApplyGeometryEdit, GenericNode, GetLayer}, graph::{GenericIndex, MakeRef}, - layout::{poly::PolyWeight, CompoundWeight, Layout, LayoutEdit, NodeIndex}, + layout::{poly::PolyWeight, CompoundEntryKind, CompoundWeight, Layout, LayoutEdit, NodeIndex}, }; /// Represents a band between two pins. @@ -225,6 +225,7 @@ impl SegWeight, BendWeight, CompoundWeight, + CompoundEntryKind, PrimitiveIndex, DotIndex, SegIndex, diff --git a/src/drawing/band.rs b/src/drawing/band.rs index d4e3cec..024c4a2 100644 --- a/src/drawing/band.rs +++ b/src/drawing/band.rs @@ -37,24 +37,28 @@ impl From for LooseIndex { } } -impl<'a, CW, R> MakeRef<'a, BandRef<'a, CW, R>, Drawing> for BandTermsegIndex { - fn ref_(&self, drawing: &'a Drawing) -> BandRef<'a, CW, R> { +impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing> for BandTermsegIndex { + type Output = BandRef<'a, CW, Cek, R>; + fn ref_(&self, drawing: &'a Drawing) -> BandRef<'a, CW, Cek, R> { BandRef::new(*self, drawing) } } -pub struct BandRef<'a, CW, R> { +pub struct BandRef<'a, CW, Cek, R> { first_seg: BandTermsegIndex, - drawing: &'a Drawing, + drawing: &'a Drawing, } -impl<'a, CW, R> BandRef<'a, CW, R> { - pub fn new(first_seg: BandTermsegIndex, drawing: &'a Drawing) -> BandRef<'a, CW, R> { +impl<'a, CW: 'a, Cek: 'a, R: 'a> BandRef<'a, CW, Cek, R> { + pub fn new( + first_seg: BandTermsegIndex, + drawing: &'a Drawing, + ) -> BandRef<'a, CW, Cek, R> { Self { first_seg, drawing } } } -impl MeasureLength for BandRef<'_, CW, R> { +impl MeasureLength for BandRef<'_, CW, Cek, R> { fn length(&self) -> f64 { match self.first_seg { BandTermsegIndex::Straight(seg) => { diff --git a/src/drawing/cane.rs b/src/drawing/cane.rs index 71481a5..408a1c3 100644 --- a/src/drawing/cane.rs +++ b/src/drawing/cane.rs @@ -26,7 +26,10 @@ pub struct Cane { } impl Cane { - pub fn from_dot(dot: LooseDotIndex, drawing: &Drawing) -> Self { + pub fn from_dot( + dot: LooseDotIndex, + drawing: &Drawing, + ) -> Self { let bend = LooseDot::new(dot, drawing).bend(); let dot = LooseBend::new(bend, drawing).other_joint(dot); let seg = LooseDot::new(dot, drawing).seg().unwrap(); diff --git a/src/drawing/collect.rs b/src/drawing/collect.rs index 116094d..042d66a 100644 --- a/src/drawing/collect.rs +++ b/src/drawing/collect.rs @@ -25,7 +25,7 @@ pub trait Collect { fn wraparounded_bows(&self, around: GearIndex) -> Vec; } -impl Collect for Drawing { +impl Collect for Drawing { fn loose_band_uid(&self, start_loose: LooseIndex) -> BandUid { BandUid::from(( self.loose_band_first_seg(start_loose), @@ -92,7 +92,7 @@ trait CollectPrivate { fn loose_band_last_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex; } -impl CollectPrivate for Drawing { +impl CollectPrivate for Drawing { fn loose_band_first_seg(&self, start_loose: LooseIndex) -> BandTermsegIndex { if let LooseIndex::LoneSeg(seg) = start_loose { return BandTermsegIndex::Straight(seg); diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 87833ef..88a90a9 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -93,11 +93,12 @@ pub struct Collision(pub PrimitiveShape, pub PrimitiveIndex); #[error("{1:?} is already connected to net {0}")] pub struct AlreadyConnected(pub usize, pub PrimitiveIndex); -pub type DrawingEdit = GeometryEdit< +pub type DrawingEdit = GeometryEdit< DotWeight, SegWeight, BendWeight, CW, + Cek, PrimitiveIndex, DotIndex, SegIndex, @@ -105,13 +106,14 @@ pub type DrawingEdit = GeometryEdit< >; #[derive(Clone, Debug, Getters)] -pub struct Drawing { +pub struct Drawing { recording_geometry_with_rtree: RecordingGeometryWithRtree< PrimitiveWeight, DotWeight, SegWeight, BendWeight, CW, + Cek, PrimitiveIndex, DotIndex, SegIndex, @@ -120,8 +122,64 @@ pub struct Drawing { rules: R, } +impl Drawing { + pub fn geometry( + &self, + ) -> &Geometry< + PrimitiveWeight, + DotWeight, + SegWeight, + BendWeight, + CW, + Cek, + PrimitiveIndex, + DotIndex, + SegIndex, + BendIndex, + > { + self.recording_geometry_with_rtree.geometry() + } + + pub fn rtree(&self) -> &RTree>>> { + self.recording_geometry_with_rtree.rtree() + } + + pub fn rules_mut(&mut self) -> &mut R { + &mut self.rules + } + + pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive<'_, W, CW, Cek, R> { + GenericPrimitive::new(index, self) + } + + pub fn loose(&self, index: LooseIndex) -> Loose<'_, CW, Cek, R> { + Loose::new(index, self) + } + + pub fn layer_count(&self) -> usize { + self.recording_geometry_with_rtree.layer_count() + } + + pub fn node_count(&self) -> usize { + self.recording_geometry_with_rtree.graph().node_count() + } +} + +impl Drawing { + pub fn compound_weight(&self, compound: GenericIndex) -> &CW { + self.recording_geometry_with_rtree.compound_weight(compound) + } + + pub fn compounds<'a, W: 'a>( + &'a self, + node: GenericIndex, + ) -> impl Iterator)> + 'a { + self.recording_geometry_with_rtree.compounds(node) + } +} + #[debug_invariant(self.test_if_looses_dont_infringe_each_other())] -impl Drawing { +impl Drawing { pub fn new(rules: R, layer_count: usize) -> Self { Self { recording_geometry_with_rtree: RecordingGeometryWithRtree::new(layer_count), @@ -131,7 +189,7 @@ impl Drawing { pub fn remove_band( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, band: BandTermsegIndex, ) -> Result<(), DrawingException> { match band { @@ -208,7 +266,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_fixed_dot( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, weight: FixedDotWeight, ) -> Result { self.add_dot_with_infringables(recorder, weight, Some(&[])) @@ -216,7 +274,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 1))] #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] - pub fn remove_fixed_dot(&mut self, recorder: &mut DrawingEdit, dot: FixedDotIndex) { + pub fn remove_fixed_dot(&mut self, recorder: &mut DrawingEdit, dot: FixedDotIndex) { self.recording_geometry_with_rtree .remove_dot(recorder, dot.into()); } @@ -225,7 +283,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_fixed_dot_infringably( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, weight: FixedDotWeight, ) -> FixedDotIndex { self.add_dot_infringably(recorder, weight) @@ -235,7 +293,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))] fn add_dot_with_infringables + GetLayer>( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, weight: W, infringables: Option<&[PrimitiveIndex]>, ) -> Result, Infringement> @@ -253,7 +311,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_fixed_seg( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: FixedDotIndex, to: FixedDotIndex, weight: FixedSegWeight, @@ -265,7 +323,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 2))] pub fn add_fixed_seg_infringably( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: FixedDotIndex, to: FixedDotIndex, weight: FixedSegWeight, @@ -279,7 +337,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_lone_loose_seg( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: FixedDotIndex, to: FixedDotIndex, weight: LoneLooseSegWeight, @@ -295,7 +353,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_seq_loose_seg( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, to: LooseDotIndex, weight: SeqLooseSegWeight, @@ -310,7 +368,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_seg_with_infringables + GetLayer>( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, to: DotIndex, weight: W, @@ -332,7 +390,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_loose_bend_with_infringables( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: LooseDotIndex, to: LooseDotIndex, around: GearIndex, @@ -397,7 +455,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_core_bend_with_infringables + GetLayer>( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, to: DotIndex, core: FixedDotIndex, @@ -421,7 +479,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_outer_bend_with_infringables( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: LooseDotIndex, to: LooseDotIndex, inner: BendIndex, @@ -467,7 +525,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))] #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] - pub fn flip_bend(&mut self, recorder: &mut DrawingEdit, bend: FixedBendIndex) { + pub fn flip_bend(&mut self, recorder: &mut DrawingEdit, bend: FixedBendIndex) { self.recording_geometry_with_rtree .flip_bend(recorder, bend.into()); } @@ -478,7 +536,7 @@ impl Drawing { || self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 1))] fn reattach_bend( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, bend: LooseBendIndex, maybe_new_inner: Option, ) { @@ -495,7 +553,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn insert_cane( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, around: GearIndex, dot_weight: LooseDotWeight, @@ -539,7 +597,7 @@ impl Drawing { fn update_this_and_outward_bows_intern( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, around: LooseBendIndex, ) -> Result<(), DrawingException> { let mut maybe_rail = Some(around); @@ -618,7 +676,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn update_this_and_outward_bows( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, around: LooseBendIndex, ) -> Result<(), DrawingException> { let mut temp_recorder = DrawingEdit::new(); @@ -638,7 +696,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn add_cane( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, around: GearIndex, dot_weight: LooseDotWeight, @@ -664,7 +722,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_cane_with_infringables( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, around: GearIndex, dot_weight: LooseDotWeight, @@ -723,7 +781,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 4))] pub fn remove_cane( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, cane: &Cane, face: LooseDotIndex, ) { @@ -760,7 +818,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] pub fn move_dot( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, dot: DotIndex, to: Point, ) -> Result<(), Infringement> { @@ -774,7 +832,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn move_dot_with_infringables( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, dot: DotIndex, to: Point, infringables: Option<&[PrimitiveIndex]>, @@ -810,7 +868,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn shift_bend_with_infringables( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, bend: BendIndex, offset: f64, infringables: Option<&[PrimitiveIndex]>, @@ -852,12 +910,12 @@ impl Drawing { } } -impl Drawing { +impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() + 1))] #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] fn add_dot_infringably + GetLayer>( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, weight: W, ) -> GenericIndex where @@ -870,7 +928,7 @@ impl Drawing { #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count() + 2))] fn add_seg_infringably + GetLayer>( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, from: DotIndex, to: DotIndex, weight: W, @@ -882,24 +940,33 @@ impl Drawing { .add_seg(recorder, from, to, weight) } - pub fn add_compound(&mut self, recorder: &mut DrawingEdit, weight: CW) -> GenericIndex { + pub fn add_compound( + &mut self, + recorder: &mut DrawingEdit, + weight: CW, + ) -> GenericIndex { self.recording_geometry_with_rtree .add_compound(recorder, weight) } - pub fn remove_compound(&mut self, recorder: &mut DrawingEdit, compound: GenericIndex) { + pub fn remove_compound( + &mut self, + recorder: &mut DrawingEdit, + compound: GenericIndex, + ) { self.recording_geometry_with_rtree .remove_compound(recorder, compound); } pub fn add_to_compound( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, primitive: GenericIndex, + entry_kind: Cek, compound: GenericIndex, ) { self.recording_geometry_with_rtree - .add_to_compound(recorder, primitive, compound); + .add_to_compound(recorder, primitive, entry_kind, compound); } #[debug_ensures(ret.is_ok() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))] @@ -907,7 +974,7 @@ impl Drawing { #[debug_ensures(ret.is_err() -> self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count() - 1))] fn fail_and_remove_if_infringes_except( &mut self, - recorder: &mut DrawingEdit, + recorder: &mut DrawingEdit, node: PrimitiveIndex, maybe_except: Option<&[PrimitiveIndex]>, ) -> Result<(), Infringement> { @@ -1022,17 +1089,6 @@ impl Drawing { }) } - pub fn compound_weight(&self, compound: GenericIndex) -> CW { - self.recording_geometry_with_rtree.compound_weight(compound) - } - - pub fn compounds<'a, W: 'a>( - &'a self, - node: GenericIndex, - ) -> impl Iterator> + 'a { - self.recording_geometry_with_rtree.compounds(node) - } - pub fn is_node_in_layer( &self, index: GenericNode>, @@ -1078,48 +1134,6 @@ impl Drawing { } } - pub fn geometry( - &self, - ) -> &Geometry< - PrimitiveWeight, - DotWeight, - SegWeight, - BendWeight, - CW, - PrimitiveIndex, - DotIndex, - SegIndex, - BendIndex, - > { - self.recording_geometry_with_rtree.geometry() - } - - pub fn rtree(&self) -> &RTree>>> { - self.recording_geometry_with_rtree.rtree() - } - - #[debug_ensures(self.recording_geometry_with_rtree.graph().node_count() == old(self.recording_geometry_with_rtree.graph().node_count()))] - #[debug_ensures(self.recording_geometry_with_rtree.graph().edge_count() == old(self.recording_geometry_with_rtree.graph().edge_count()))] - pub fn rules_mut(&mut self) -> &mut R { - &mut self.rules - } - - pub fn primitive(&self, index: GenericIndex) -> GenericPrimitive { - GenericPrimitive::new(index, self) - } - - pub fn loose(&self, index: LooseIndex) -> Loose { - Loose::new(index, self) - } - - pub fn layer_count(&self) -> usize { - self.recording_geometry_with_rtree.layer_count() - } - - pub fn node_count(&self) -> usize { - self.recording_geometry_with_rtree.graph().node_count() - } - fn test_if_looses_dont_infringe_each_other(&self) -> bool { !self .primitive_nodes() @@ -1158,19 +1172,20 @@ impl Drawing { } } -impl +impl ApplyGeometryEdit< DotWeight, SegWeight, BendWeight, CW, + Cek, PrimitiveIndex, DotIndex, SegIndex, BendIndex, - > for Drawing + > for Drawing { - fn apply(&mut self, edit: &DrawingEdit) { + fn apply(&mut self, edit: &DrawingEdit) { self.recording_geometry_with_rtree.apply(edit); } } diff --git a/src/drawing/gear.rs b/src/drawing/gear.rs index 9258106..c3bcffe 100644 --- a/src/drawing/gear.rs +++ b/src/drawing/gear.rs @@ -30,9 +30,10 @@ pub enum GearIndex { LooseBend(LooseBendIndex), } -impl<'a, CW: Copy, R: AccessRules> MakeRef<'a, GearRef<'a, CW, R>, Drawing> for GearIndex { - fn ref_(&self, drawing: &'a Drawing) -> GearRef<'a, CW, R> { - GearRef::new(*self, drawing) +impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing> for GearIndex { + type Output = GearRef<'a, CW, Cek, R>; + fn ref_(&self, drawing: &'a Drawing) -> GearRef<'a, CW, Cek, R> { + GearRef::<'a, CW, Cek, R>::new(*self, drawing) } } @@ -56,14 +57,14 @@ impl From for GearIndex { } #[enum_dispatch(GetNextGear, GetDrawing, GetPetgraphIndex)] -pub enum GearRef<'a, CW: Copy, R: AccessRules> { - FixedDot(FixedDot<'a, CW, R>), - FixedBend(FixedBend<'a, CW, R>), - LooseBend(LooseBend<'a, CW, R>), +pub enum GearRef<'a, CW, Cek, R> { + FixedDot(FixedDot<'a, CW, Cek, R>), + FixedBend(FixedBend<'a, CW, Cek, R>), + LooseBend(LooseBend<'a, CW, Cek, R>), } -impl<'a, CW: Copy, R: AccessRules> GearRef<'a, CW, R> { - pub fn new(index: GearIndex, drawing: &'a Drawing) -> Self { +impl<'a, CW, Cek, R> GearRef<'a, CW, Cek, R> { + pub fn new(index: GearIndex, drawing: &'a Drawing) -> Self { match index { GearIndex::FixedDot(dot) => drawing.primitive(dot).into(), GearIndex::FixedBend(bend) => drawing.primitive(bend).into(), @@ -72,19 +73,19 @@ impl<'a, CW: Copy, R: AccessRules> GearRef<'a, CW, R> { } } -impl GetNextGear for FixedDot<'_, CW, R> { +impl GetNextGear for FixedDot<'_, CW, Cek, R> { fn next_gear(&self) -> Option { self.first_gear() } } -impl GetNextGear for LooseBend<'_, CW, R> { +impl GetNextGear for LooseBend<'_, CW, Cek, R> { fn next_gear(&self) -> Option { self.outer() } } -impl GetNextGear for FixedBend<'_, CW, R> { +impl GetNextGear for FixedBend<'_, CW, Cek, R> { fn next_gear(&self) -> Option { self.first_gear() } diff --git a/src/drawing/graph.rs b/src/drawing/graph.rs index af092ad..b4c2795 100644 --- a/src/drawing/graph.rs +++ b/src/drawing/graph.rs @@ -47,10 +47,10 @@ pub trait GetMaybeNet { #[enum_dispatch] pub trait MakePrimitive { - fn primitive<'a, CW: Copy, R: AccessRules>( + fn primitive<'a, CW: Clone, Cek: Copy, R: AccessRules>( &self, - drawing: &'a Drawing, - ) -> Primitive<'a, CW, R>; + drawing: &'a Drawing, + ) -> Primitive<'a, CW, Cek, R>; } macro_rules! impl_weight_forward { @@ -76,10 +76,10 @@ macro_rules! impl_weight_forward { pub type $index_struct = GenericIndex<$weight_struct>; impl MakePrimitive for $index_struct { - fn primitive<'a, CW: Copy, R: AccessRules>( + fn primitive<'a, CW: Clone, Cek: Copy, R: AccessRules>( &self, - drawing: &'a Drawing, - ) -> Primitive<'a, CW, R> { + drawing: &'a crate::drawing::Drawing, + ) -> Primitive<'a, CW, Cek, R> { Primitive::$weight_variant(GenericPrimitive::new(*self, drawing)) } } diff --git a/src/drawing/guide.rs b/src/drawing/guide.rs index 05101cc..7c571a3 100644 --- a/src/drawing/guide.rs +++ b/src/drawing/guide.rs @@ -73,7 +73,7 @@ pub trait Guide { fn head(&self, face: DotIndex) -> Head; } -impl Guide for Drawing { +impl Guide for Drawing { fn head_into_dot_segment( &self, head: &Head, @@ -223,7 +223,7 @@ trait GuidePrivate { fn conditions(&self, node: PrimitiveIndex) -> Option>; } -impl GuidePrivate for Drawing { +impl GuidePrivate for Drawing { fn clearance(&self, lhs: Option<&Conditions<'_>>, rhs: Option<&Conditions<'_>>) -> f64 { match (lhs, rhs) { (None, _) | (_, None) => 0.0, diff --git a/src/drawing/head.rs b/src/drawing/head.rs index 3ef4122..8974fb0 100644 --- a/src/drawing/head.rs +++ b/src/drawing/head.rs @@ -29,8 +29,9 @@ pub enum Head { Cane(CaneHead), } -impl<'a, CW, R> MakeRef<'a, HeadRef<'a, CW, R>, Drawing> for Head { - fn ref_(&self, drawing: &'a Drawing) -> HeadRef<'a, CW, R> { +impl<'a, CW: 'a, Cek: 'a, R: 'a> MakeRef<'a, Drawing> for Head { + type Output = HeadRef<'a, CW, Cek, R>; + fn ref_(&self, drawing: &'a Drawing) -> HeadRef<'a, CW, Cek, R> { HeadRef::new(*self, drawing) } } @@ -71,24 +72,24 @@ impl GetFace for CaneHead { } } -pub struct HeadRef<'a, CW, R> { +pub struct HeadRef<'a, CW, Cek, R> { head: Head, - drawing: &'a Drawing, + drawing: &'a Drawing, } -impl<'a, CW, R> HeadRef<'a, CW, R> { - pub fn new(head: Head, drawing: &'a Drawing) -> Self { +impl<'a, CW, Cek, R> HeadRef<'a, CW, Cek, R> { + pub fn new(head: Head, drawing: &'a Drawing) -> Self { Self { drawing, head } } } -impl GetFace for HeadRef<'_, CW, R> { +impl GetFace for HeadRef<'_, CW, Cek, R> { fn face(&self) -> DotIndex { self.head.face() } } -impl MeasureLength for HeadRef<'_, CW, R> { +impl MeasureLength for HeadRef<'_, CW, Cek, R> { fn length(&self) -> f64 { match self.head { Head::Bare(..) => 0.0, diff --git a/src/drawing/loose.rs b/src/drawing/loose.rs index b59fd31..cc94e58 100644 --- a/src/drawing/loose.rs +++ b/src/drawing/loose.rs @@ -70,15 +70,15 @@ impl TryFrom for LooseIndex { } #[enum_dispatch(GetPrevNextLoose, GetDrawing, GetPetgraphIndex)] -pub enum Loose<'a, CW: Copy, R: AccessRules> { - Dot(LooseDot<'a, CW, R>), - LoneSeg(LoneLooseSeg<'a, CW, R>), - SeqSeg(SeqLooseSeg<'a, CW, R>), - Bend(LooseBend<'a, CW, R>), +pub enum Loose<'a, CW, Cek, R> { + Dot(LooseDot<'a, CW, Cek, R>), + LoneSeg(LoneLooseSeg<'a, CW, Cek, R>), + SeqSeg(SeqLooseSeg<'a, CW, Cek, R>), + Bend(LooseBend<'a, CW, Cek, R>), } -impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> { - pub fn new(index: LooseIndex, drawing: &'a Drawing) -> Self { +impl<'a, CW, Cek, R> Loose<'a, CW, Cek, R> { + pub fn new(index: LooseIndex, drawing: &'a Drawing) -> Self { match index { LooseIndex::Dot(dot) => drawing.primitive(dot).into(), LooseIndex::LoneSeg(seg) => drawing.primitive(seg).into(), @@ -88,7 +88,7 @@ impl<'a, CW: Copy, R: AccessRules> Loose<'a, CW, R> { } } -impl GetPrevNextLoose for LooseDot<'_, CW, R> { +impl GetPrevNextLoose for LooseDot<'_, CW, Cek, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let bend = self.bend(); @@ -104,13 +104,13 @@ impl GetPrevNextLoose for LooseDot<'_, CW, R> { } } -impl GetPrevNextLoose for LoneLooseSeg<'_, CW, R> { +impl GetPrevNextLoose for LoneLooseSeg<'_, CW, Cek, R> { fn next_loose(&self, _maybe_prev: Option) -> Option { None } } -impl GetPrevNextLoose for SeqLooseSeg<'_, CW, R> { +impl GetPrevNextLoose for SeqLooseSeg<'_, CW, Cek, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let joints = self.joints(); let Some(prev) = maybe_prev else { @@ -128,7 +128,7 @@ impl GetPrevNextLoose for SeqLooseSeg<'_, CW, R> { } } -impl GetPrevNextLoose for LooseBend<'_, CW, R> { +impl GetPrevNextLoose for LooseBend<'_, CW, Cek, R> { fn next_loose(&self, maybe_prev: Option) -> Option { let joints = self.joints(); diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index 11d133c..7dd847d 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -19,8 +19,10 @@ use crate::{ }; pub trait GetDrawing { - type Rules: AccessRules; - fn drawing(&self) -> &Drawing; + type CompoundWeight; + type CompoundEntryKind; + type Rules; + fn drawing(&self) -> &Drawing; } #[enum_dispatch] @@ -106,7 +108,7 @@ impl GetCore for S { macro_rules! impl_primitive { ($primitive_struct:ident, $weight_struct:ident) => { - impl GetWeight<$weight_struct> for $primitive_struct<'_, CW, R> { + impl GetWeight<$weight_struct> for $primitive_struct<'_, CW, Cek, R> { fn weight(&self) -> $weight_struct { if let PrimitiveWeight::$primitive_struct(weight) = self.tagged_weight() { weight @@ -116,13 +118,13 @@ macro_rules! impl_primitive { } } - impl GetLayer for $primitive_struct<'_, CW, R> { + impl GetLayer for $primitive_struct<'_, CW, Cek, R> { fn layer(&self) -> usize { self.weight().layer() } } - impl GetMaybeNet for $primitive_struct<'_, CW, R> { + impl GetMaybeNet for $primitive_struct<'_, CW, Cek, R> { fn maybe_net(&self) -> Option { self.weight().maybe_net() } @@ -150,17 +152,17 @@ macro_rules! impl_loose_primitive { MakePrimitiveShape, GetLimbs )] -pub enum Primitive<'a, CW: Copy, R: AccessRules> { - FixedDot(FixedDot<'a, CW, R>), - LooseDot(LooseDot<'a, CW, R>), - FixedSeg(FixedSeg<'a, CW, R>), - LoneLooseSeg(LoneLooseSeg<'a, CW, R>), - SeqLooseSeg(SeqLooseSeg<'a, CW, R>), - FixedBend(FixedBend<'a, CW, R>), - LooseBend(LooseBend<'a, CW, R>), +pub enum Primitive<'a, CW, Cek, R> { + FixedDot(FixedDot<'a, CW, Cek, R>), + LooseDot(LooseDot<'a, CW, Cek, R>), + FixedSeg(FixedSeg<'a, CW, Cek, R>), + LoneLooseSeg(LoneLooseSeg<'a, CW, Cek, R>), + SeqLooseSeg(SeqLooseSeg<'a, CW, Cek, R>), + FixedBend(FixedBend<'a, CW, Cek, R>), + LooseBend(LooseBend<'a, CW, Cek, R>), } -impl<'a, CW: Copy, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, R> { +impl<'a, CW, Cek, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, Cek, R> { fn conditions(self) -> Option> { match self { Primitive::FixedDot(x) => x.conditions(), @@ -174,63 +176,65 @@ impl<'a, CW: Copy, R: AccessRules> GetConditions<'a> for &Primitive<'a, CW, R> { } } -#[derive(Debug)] -pub struct GenericPrimitive<'a, W, CW: Copy, R: AccessRules> { +#[derive(Clone, Debug)] +pub struct GenericPrimitive<'a, W, CW, Cek, R> { pub index: GenericIndex, - drawing: &'a Drawing, + drawing: &'a Drawing, } -impl<'a, W, CW: Copy, R: AccessRules> GenericPrimitive<'a, W, CW, R> { - pub fn new(index: GenericIndex, drawing: &'a Drawing) -> Self { +impl<'a, W, CW, Cek, R> GenericPrimitive<'a, W, CW, Cek, R> { + pub fn new(index: GenericIndex, drawing: &'a Drawing) -> Self { Self { index, drawing } } fn tagged_weight(&self) -> PrimitiveWeight { - if let GenericNode::Primitive(weight) = *self + if let GenericNode::Primitive(weight) = self .drawing .geometry() .graph() .node_weight(self.index.petgraph_index()) .unwrap() { - weight + *weight } else { unreachable!() } } } -impl GetInterior for GenericPrimitive<'_, W, CW, R> { +impl GetInterior for GenericPrimitive<'_, W, CW, Cek, R> { fn interior(&self) -> Vec { vec![self.tagged_weight().retag(self.index.petgraph_index())] } } -impl GetDrawing for GenericPrimitive<'_, W, CW, R> { +impl GetDrawing for GenericPrimitive<'_, W, CW, Cek, R> { + type CompoundWeight = CW; + type CompoundEntryKind = Cek; type Rules = R; - fn drawing(&self) -> &Drawing { + fn drawing(&self) -> &Drawing { self.drawing } } -impl GetPetgraphIndex for GenericPrimitive<'_, W, CW, R> { +impl GetPetgraphIndex for GenericPrimitive<'_, W, CW, Cek, R> { fn petgraph_index(&self) -> NodeIndex { self.index.petgraph_index() } } -impl<'a, W: GetWidth, CW: Copy, R: AccessRules> GetWidth for GenericPrimitive<'a, W, CW, R> +impl<'a, W: GetWidth, CW, Cek, R> GetWidth for GenericPrimitive<'a, W, CW, Cek, R> where - GenericPrimitive<'a, W, CW, R>: GetWeight, + GenericPrimitive<'a, W, CW, Cek, R>: GetWeight, { fn width(&self) -> f64 { self.weight().width() } } -impl<'a, W, CW: Copy, R: AccessRules> GetConditions<'a> for &GenericPrimitive<'a, W, CW, R> +impl<'a, W, CW, Cek, R> GetConditions<'a> for &GenericPrimitive<'a, W, CW, Cek, R> where - GenericPrimitive<'a, W, CW, R>: GetMaybeNet, + GenericPrimitive<'a, W, CW, Cek, R>: GetMaybeNet, { fn conditions(self) -> Option> { self.maybe_net().map(|net| Conditions { @@ -241,16 +245,16 @@ where } } -pub type FixedDot<'a, CW, R> = GenericPrimitive<'a, FixedDotWeight, CW, R>; +pub type FixedDot<'a, CW, Cek, R> = GenericPrimitive<'a, FixedDotWeight, CW, Cek, R>; impl_fixed_primitive!(FixedDot, FixedDotWeight); -impl MakePrimitiveShape for FixedDot<'_, CW, R> { +impl MakePrimitiveShape for FixedDot<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().dot_shape(self.index.into()) } } -impl GetLimbs for FixedDot<'_, CW, R> { +impl GetLimbs for FixedDot<'_, CW, Cek, R> { fn segs(&self) -> Vec { self.drawing .geometry() @@ -266,12 +270,12 @@ impl GetLimbs for FixedDot<'_, CW, R> { } } -impl GetFirstGear for FixedDot<'_, CW, R> {} +impl GetFirstGear for FixedDot<'_, CW, Cek, R> {} -pub type LooseDot<'a, CW, R> = GenericPrimitive<'a, LooseDotWeight, CW, R>; +pub type LooseDot<'a, CW, Cek, R> = GenericPrimitive<'a, LooseDotWeight, CW, Cek, R>; impl_loose_primitive!(LooseDot, LooseDotWeight); -impl LooseDot<'_, CW, R> { +impl LooseDot<'_, CW, Cek, R> { pub fn seg(&self) -> Option { self.drawing .geometry() @@ -290,13 +294,13 @@ impl LooseDot<'_, CW, R> { } } -impl MakePrimitiveShape for LooseDot<'_, CW, R> { +impl MakePrimitiveShape for LooseDot<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().dot_shape(self.index.into()) } } -impl GetLimbs for LooseDot<'_, CW, R> { +impl GetLimbs for LooseDot<'_, CW, Cek, R> { fn segs(&self) -> Vec { if let Some(seg) = self.seg() { vec![seg.into()] @@ -310,18 +314,18 @@ impl GetLimbs for LooseDot<'_, CW, R> { } } -pub type FixedSeg<'a, CW, R> = GenericPrimitive<'a, FixedSegWeight, CW, R>; +pub type FixedSeg<'a, CW, Cek, R> = GenericPrimitive<'a, FixedSegWeight, CW, Cek, R>; impl_fixed_primitive!(FixedSeg, FixedSegWeight); -impl MakePrimitiveShape for FixedSeg<'_, CW, R> { +impl MakePrimitiveShape for FixedSeg<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().seg_shape(self.index.into()) } } -impl GetLimbs for FixedSeg<'_, CW, R> {} +impl GetLimbs for FixedSeg<'_, CW, Cek, R> {} -impl GetJoints for FixedSeg<'_, CW, R> { +impl GetJoints for FixedSeg<'_, CW, Cek, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.drawing.geometry().seg_joints(self.index.into()); ( @@ -331,18 +335,18 @@ impl GetJoints for Fixed } } -pub type LoneLooseSeg<'a, CW, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, R>; +pub type LoneLooseSeg<'a, CW, Cek, R> = GenericPrimitive<'a, LoneLooseSegWeight, CW, Cek, R>; impl_loose_primitive!(LoneLooseSeg, LoneLooseSegWeight); -impl MakePrimitiveShape for LoneLooseSeg<'_, CW, R> { +impl MakePrimitiveShape for LoneLooseSeg<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().seg_shape(self.index.into()) } } -impl GetLimbs for LoneLooseSeg<'_, CW, R> {} +impl GetLimbs for LoneLooseSeg<'_, CW, Cek, R> {} -impl GetJoints for LoneLooseSeg<'_, CW, R> { +impl GetJoints for LoneLooseSeg<'_, CW, Cek, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.drawing.geometry().seg_joints(self.index.into()); ( @@ -352,18 +356,18 @@ impl GetJoints for LoneL } } -pub type SeqLooseSeg<'a, CW, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, R>; +pub type SeqLooseSeg<'a, CW, Cek, R> = GenericPrimitive<'a, SeqLooseSegWeight, CW, Cek, R>; impl_loose_primitive!(SeqLooseSeg, SeqLooseSegWeight); -impl MakePrimitiveShape for SeqLooseSeg<'_, CW, R> { +impl MakePrimitiveShape for SeqLooseSeg<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().seg_shape(self.index.into()) } } -impl GetLimbs for SeqLooseSeg<'_, CW, R> {} +impl GetLimbs for SeqLooseSeg<'_, CW, Cek, R> {} -impl GetJoints for SeqLooseSeg<'_, CW, R> { +impl GetJoints for SeqLooseSeg<'_, CW, Cek, R> { fn joints(&self) -> (DotIndex, LooseDotIndex) { let joints = self.drawing.geometry().seg_joints(self.index.into()); if let DotWeight::Fixed(..) = self.drawing.geometry().dot_weight(joints.0) { @@ -385,24 +389,24 @@ impl GetJoints for SeqLooseSe } } -pub type FixedBend<'a, CW, R> = GenericPrimitive<'a, FixedBendWeight, CW, R>; +pub type FixedBend<'a, CW, Cek, R> = GenericPrimitive<'a, FixedBendWeight, CW, Cek, R>; impl_fixed_primitive!(FixedBend, FixedBendWeight); -impl GetBendIndex for FixedBend<'_, CW, R> { +impl GetBendIndex for FixedBend<'_, CW, Cek, R> { fn bend_index(&self) -> BendIndex { self.index.into() } } -impl MakePrimitiveShape for FixedBend<'_, CW, R> { +impl MakePrimitiveShape for FixedBend<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().bend_shape(self.index.into()) } } -impl GetLimbs for FixedBend<'_, CW, R> {} +impl GetLimbs for FixedBend<'_, CW, Cek, R> {} -impl GetJoints for FixedBend<'_, CW, R> { +impl GetJoints for FixedBend<'_, CW, Cek, R> { fn joints(&self) -> (FixedDotIndex, FixedDotIndex) { let (from, to) = self.drawing.geometry().bend_joints(self.index.into()); ( @@ -412,39 +416,39 @@ impl GetJoints for Fixed } } -impl GetFirstGear for FixedBend<'_, CW, R> {} -//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, R> {} +impl GetFirstGear for FixedBend<'_, CW, Cek, R> {} +//impl<'a, R: QueryRules> GetInnerOuter for FixedBend<'a, CW, Cek, R> {} -pub type LooseBend<'a, CW, R> = GenericPrimitive<'a, LooseBendWeight, CW, R>; +pub type LooseBend<'a, CW, Cek, R> = GenericPrimitive<'a, LooseBendWeight, CW, Cek, R>; impl_loose_primitive!(LooseBend, LooseBendWeight); -impl GetBendIndex for LooseBend<'_, CW, R> { +impl GetBendIndex for LooseBend<'_, CW, Cek, R> { fn bend_index(&self) -> BendIndex { self.index.into() } } -impl<'a, CW: Copy, R: AccessRules> From> for BendIndex { - fn from(bend: LooseBend<'a, CW, R>) -> BendIndex { +impl<'a, CW: Clone, Cek: Copy, R: AccessRules> From> for BendIndex { + fn from(bend: LooseBend<'a, CW, Cek, R>) -> BendIndex { bend.index.into() } } -impl MakePrimitiveShape for LooseBend<'_, CW, R> { +impl MakePrimitiveShape for LooseBend<'_, CW, Cek, R> { fn shape(&self) -> PrimitiveShape { self.drawing.geometry().bend_shape(self.index.into()) } } -impl GetLimbs for LooseBend<'_, CW, R> {} +impl GetLimbs for LooseBend<'_, CW, Cek, R> {} -impl GetOffset for LooseBend<'_, CW, R> { +impl GetOffset for LooseBend<'_, CW, Cek, R> { fn offset(&self) -> f64 { self.weight().offset() } } -impl GetJoints for LooseBend<'_, CW, R> { +impl GetJoints for LooseBend<'_, CW, Cek, R> { fn joints(&self) -> (LooseDotIndex, LooseDotIndex) { let (from, to) = self.drawing.geometry().bend_joints(self.index.into()); ( @@ -454,7 +458,7 @@ impl GetJoints for Loose } } -impl LooseBend<'_, CW, R> { +impl LooseBend<'_, CW, Cek, R> { pub fn inner(&self) -> Option { self.drawing() .geometry() diff --git a/src/geometry/compound.rs b/src/geometry/compound.rs index 454f275..0c5d9a7 100644 --- a/src/geometry/compound.rs +++ b/src/geometry/compound.rs @@ -4,10 +4,24 @@ use crate::graph::{GenericIndex, GetPetgraphIndex}; -pub trait ManageCompounds { +pub trait ManageCompounds { + type GeneralIndex: Copy; + type EntryKind: Copy; + fn add_compound(&mut self, weight: CW) -> GenericIndex; fn remove_compound(&mut self, compound: GenericIndex); - fn add_to_compound(&mut self, node: GenericIndex, compound: GenericIndex); - fn compound_weight(&self, node: GenericIndex) -> CW; - fn compounds(&self, node: GenericIndex) -> impl Iterator>; + fn add_to_compound(&mut self, node: I, kind: Self::EntryKind, compound: GenericIndex) + where + I: Copy + GetPetgraphIndex; + + fn compound_weight(&self, node: GenericIndex) -> &CW; + + fn compound_members( + &self, + compound: GenericIndex, + ) -> impl Iterator + '_; + + fn compounds(&self, node: I) -> impl Iterator)> + where + I: Copy + GetPetgraphIndex; } diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 427d08c..e275e62 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -12,23 +12,24 @@ pub trait ApplyGeometryEdit< DW: AccessDotWeight + GetLayer, SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, DI: GetPetgraphIndex + Into + Eq + Ord + Copy, SI: GetPetgraphIndex + Into + Eq + Ord + Copy, BI: GetPetgraphIndex + Into + Eq + Ord + Copy, > { - fn apply(&mut self, edit: &GeometryEdit); + fn apply(&mut self, edit: &GeometryEdit); } #[derive(Debug, Clone)] -pub struct GeometryEdit { +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) compounds: - BTreeMap, (Option<(Vec, CW)>, Option<(Vec, CW)>)>, + BTreeMap, (Option<(Vec<(Cek, PI)>, CW)>, Option<(Vec<(Cek, PI)>, CW)>)>, } fn swap_tuple_inplace(x: &mut (D, D)) { @@ -39,12 +40,13 @@ impl< DW: AccessDotWeight + GetLayer, SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, DI: GetPetgraphIndex + Into + Eq + Ord + Copy, SI: GetPetgraphIndex + Into + Eq + Ord + Copy, BI: GetPetgraphIndex + Into + Eq + Ord + Copy, - > GeometryEdit + > GeometryEdit { pub fn new() -> Self { Self { @@ -90,15 +92,16 @@ impl< DW: AccessDotWeight + GetLayer, SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, DI: GetPetgraphIndex + Into + Eq + Ord + Copy, SI: GetPetgraphIndex + Into + Eq + Ord + Copy, BI: GetPetgraphIndex + Into + Eq + Ord + Copy, - > ApplyGeometryEdit - for GeometryEdit + > ApplyGeometryEdit + for GeometryEdit { - fn apply(&mut self, edit: &GeometryEdit) { + fn apply(&mut self, edit: &GeometryEdit) { apply_btmap(&mut self.dots, &edit.dots); apply_btmap(&mut self.segs, &edit.segs); apply_btmap(&mut self.bends, &edit.bends); diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index a2013a6..a8dc1aa 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -11,7 +11,6 @@ use petgraph::{ Direction::{self, Incoming}, }; use serde::{Deserialize, Serialize}; -use specctra_core::rules::AccessRules; use crate::{ drawing::{ @@ -60,12 +59,12 @@ pub trait SetOffset: GetOffset { fn set_offset(&mut self, offset: f64); } -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum GeometryLabel { +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum GeometryLabel { Joined, Outer, Core, - Compound, + Compound(Cek), } #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] @@ -84,8 +83,8 @@ pub trait AccessBendWeight: SetOffset + GetWidth + Copy {} impl AccessBendWeight for T {} #[derive(Debug)] -pub struct Geometry { - graph: StableDiGraph, GeometryLabel, usize>, +pub struct Geometry { + graph: StableDiGraph, GeometryLabel, usize>, primitive_weight_marker: PhantomData, dot_weight_marker: PhantomData, seg_weight_marker: PhantomData, @@ -97,8 +96,8 @@ pub struct Geometry { bend_index_marker: PhantomData, } -impl Clone - for Geometry +impl Clone + for Geometry { fn clone(&self) -> Self { Self { @@ -108,13 +107,15 @@ impl Clone } } -impl Default for Geometry { +impl Default + for Geometry +{ fn default() -> Self { Self::new() } } -impl Geometry { +impl Geometry { pub fn new() -> Self { Self { graph: StableDiGraph::default(), @@ -134,9 +135,20 @@ impl Geometry &StableDiGraph, GeometryLabel, usize> { + pub fn graph(&self) -> &StableDiGraph, GeometryLabel, usize> { &self.graph } + + fn primitive_weight(&self, index: NodeIndex) -> PW + where + PW: Copy, + { + if let GenericNode::Primitive(weight) = self.graph.node_weight(index).unwrap() { + *weight + } else { + unreachable!() + } + } } impl< @@ -144,12 +156,13 @@ impl< DW: AccessDotWeight + Into, SW: AccessSegWeight + Into, BW: AccessBendWeight + Into, - CW: Copy, + CW, + Cek, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Copy, DI: GetPetgraphIndex + Into + Copy, SI: GetPetgraphIndex + Into + Copy, BI: GetPetgraphIndex + Into + Copy, - > Geometry + > Geometry { pub fn add_dot>(&mut self, weight: W) -> GenericIndex { GenericIndex::::new(self.graph.add_node(GenericNode::Primitive(weight.into()))) @@ -307,7 +320,7 @@ impl< if let Some(old_inner_edge) = self .graph .edges_directed(bend.petgraph_index(), Incoming) - .find(|edge| *edge.weight() == GeometryLabel::Outer) + .find(|edge| matches!(edge.weight(), GeometryLabel::Outer)) { self.graph.remove_edge(old_inner_edge.id()); } @@ -367,14 +380,6 @@ impl< self.core_weight(bend).width() / 2.0 + r } - fn primitive_weight(&self, index: NodeIndex) -> PW { - if let GenericNode::Primitive(weight) = *self.graph.node_weight(index).unwrap() { - weight - } else { - unreachable!() - } - } - pub fn dot_weight(&self, dot: DI) -> DW { self.primitive_weight(dot.petgraph_index()) .try_into() @@ -393,9 +398,9 @@ impl< .unwrap_or_else(|_| unreachable!()) } - pub fn compound_weight(&self, compound: GenericIndex) -> CW { + pub fn compound_weight(&self, compound: GenericIndex) -> &CW { if let GenericNode::Compound(weight) = - *self.graph.node_weight(compound.petgraph_index()).unwrap() + self.graph.node_weight(compound.petgraph_index()).unwrap() { weight } else { @@ -423,6 +428,96 @@ impl< .unwrap() } + pub fn joineds(&self, node: PI) -> impl Iterator + '_ { + self.graph + .neighbors_undirected(node.petgraph_index()) + .filter(move |ni| { + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(node.petgraph_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + GeometryLabel::Joined + ) + }) + .map(|ni| self.primitive_weight(ni).retag(ni)) + } + + pub fn joined_segs(&self, dot: DI) -> impl Iterator + '_ { + self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok()) + } + + pub fn joined_bends(&self, dot: DI) -> impl Iterator + '_ { + self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok()) + } + + fn joints(&self, node: PI) -> (DI, DI) { + ( + self.graph + .neighbors_directed(node.petgraph_index(), Direction::Incoming) + .find(move |ni| { + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(node.petgraph_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + GeometryLabel::Joined + ) + }) + .map(|ni| self.primitive_weight(ni).retag(ni)) + .map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!())) + .unwrap(), + self.graph + .neighbors_directed(node.petgraph_index(), Direction::Outgoing) + .find(move |ni| { + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(node.petgraph_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + GeometryLabel::Joined + ) + }) + .map(|ni| self.primitive_weight(ni).retag(ni)) + .map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!())) + .unwrap(), + ) + } + + pub fn seg_joints(&self, seg: SI) -> (DI, DI) { + self.joints(seg.into()) + } + + pub fn bend_joints(&self, bend: BI) -> (DI, DI) { + self.joints(bend.into()) + } +} + +impl< + PW: Copy + Retag, + DW, + SW, + BW, + CW, + Cek, + PI: TryInto + TryInto + TryInto, + DI, + SI, + BI: GetPetgraphIndex, + > Geometry +{ pub fn first_rail(&self, node: NodeIndex) -> Option { self.graph .neighbors_directed(node, Incoming) @@ -503,105 +598,14 @@ impl< }) .next() } - - pub fn joineds(&self, node: PI) -> impl Iterator + '_ { - self.graph - .neighbors_undirected(node.petgraph_index()) - .filter(move |ni| { - matches!( - self.graph - .edge_weight( - self.graph - .find_edge_undirected(node.petgraph_index(), *ni) - .unwrap() - .0, - ) - .unwrap(), - GeometryLabel::Joined - ) - }) - .map(|ni| self.primitive_weight(ni).retag(ni)) - } - - pub fn joined_segs(&self, dot: DI) -> impl Iterator + '_ { - self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok()) - } - - pub fn joined_bends(&self, dot: DI) -> impl Iterator + '_ { - self.joineds(dot.into()).filter_map(|ni| ni.try_into().ok()) - } - - fn joints(&self, node: PI) -> (DI, DI) { - ( - self.graph - .neighbors_directed(node.petgraph_index(), Direction::Incoming) - .find(move |ni| { - matches!( - self.graph - .edge_weight( - self.graph - .find_edge_undirected(node.petgraph_index(), *ni) - .unwrap() - .0, - ) - .unwrap(), - GeometryLabel::Joined - ) - }) - .map(|ni| self.primitive_weight(ni).retag(ni)) - .map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!())) - .unwrap(), - self.graph - .neighbors_directed(node.petgraph_index(), Direction::Outgoing) - .find(move |ni| { - matches!( - self.graph - .edge_weight( - self.graph - .find_edge_undirected(node.petgraph_index(), *ni) - .unwrap() - .0, - ) - .unwrap(), - GeometryLabel::Joined - ) - }) - .map(|ni| self.primitive_weight(ni).retag(ni)) - .map(|pi| pi.try_into().unwrap_or_else(|_| unreachable!())) - .unwrap(), - ) - } - - pub fn seg_joints(&self, seg: SI) -> (DI, DI) { - self.joints(seg.into()) - } - - pub fn bend_joints(&self, bend: BI) -> (DI, DI) { - self.joints(bend.into()) - } - - pub fn compound_members(&self, compound: GenericIndex) -> impl Iterator + '_ { - self.graph - .neighbors_directed(compound.petgraph_index(), Incoming) - .filter(move |ni| { - matches!( - self.graph - .edge_weight( - self.graph - .find_edge(*ni, compound.petgraph_index()) - .unwrap() - ) - .unwrap(), - GeometryLabel::Compound - ) - }) - .map(|ni| self.primitive_weight(ni).retag(ni)) - } } -impl ManageCompounds> - for Geometry +impl, DW, SW, BW, CW: Clone, Cek: Copy, PI: Copy, DI, SI, BI> + ManageCompounds for Geometry { + type GeneralIndex = PI; + type EntryKind = Cek; + fn add_compound(&mut self, weight: CW) -> GenericIndex { GenericIndex::::new(self.graph.add_node(GenericNode::Compound(weight))) } @@ -610,17 +614,20 @@ impl ManageCompounds(&mut self, primitive: GenericIndex, compound: GenericIndex) { + fn add_to_compound(&mut self, primitive: I, entry_kind: Cek, compound: GenericIndex) + where + I: Copy + GetPetgraphIndex, + { self.graph.update_edge( primitive.petgraph_index(), compound.petgraph_index(), - GeometryLabel::Compound, + GeometryLabel::Compound(entry_kind), ); } - fn compound_weight(&self, compound: GenericIndex) -> CW { + fn compound_weight(&self, compound: GenericIndex) -> &CW { if let GenericNode::Compound(weight) = - *self.graph.node_weight(compound.petgraph_index()).unwrap() + self.graph.node_weight(compound.petgraph_index()).unwrap() { weight } else { @@ -628,17 +635,41 @@ impl ManageCompounds(&self, node: GenericIndex) -> impl Iterator> { + fn compound_members( + &self, + compound: GenericIndex, + ) -> impl Iterator + '_ { + self.graph + .neighbors_directed(compound.petgraph_index(), Incoming) + .filter_map(move |ni| { + if let GeometryLabel::Compound(entry_kind) = *self + .graph + .edge_weight(self.graph.find_edge(ni, compound.petgraph_index()).unwrap()) + .unwrap() + { + Some((entry_kind, self.primitive_weight(ni).retag(ni))) + } else { + None + } + }) + } + + fn compounds(&self, node: I) -> impl Iterator)> + where + I: Copy + GetPetgraphIndex, + { self.graph .neighbors(node.petgraph_index()) - .filter(move |ni| { - matches!( - self.graph - .edge_weight(self.graph.find_edge(node.petgraph_index(), *ni).unwrap()) - .unwrap(), - GeometryLabel::Compound - ) + .filter_map(move |ni| { + if let GeometryLabel::Compound(entry_kind) = *self + .graph + .edge_weight(self.graph.find_edge(node.petgraph_index(), ni).unwrap()) + .unwrap() + { + Some((entry_kind, GenericIndex::new(ni))) + } else { + None + } }) - .map(|ni| GenericIndex::new(ni)) } } diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index 99700fd..d8ecdd6 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -19,12 +19,12 @@ use super::{ }; #[derive(Debug)] -pub struct RecordingGeometryWithRtree { - geometry_with_rtree: GeometryWithRtree, +pub struct RecordingGeometryWithRtree { + geometry_with_rtree: GeometryWithRtree, } -impl Clone - for RecordingGeometryWithRtree +impl Clone + for RecordingGeometryWithRtree { fn clone(&self) -> Self { Self { @@ -33,29 +33,48 @@ impl Clone } } +impl + RecordingGeometryWithRtree +{ + 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() + } +} + impl< PW: GetWidth + GetLayer + TryInto + TryInto + TryInto + Retag + Copy, DW: AccessDotWeight + Into + GetLayer, SW: AccessSegWeight + Into + GetLayer, BW: AccessBendWeight + Into + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, DI: GetPetgraphIndex + Into + Eq + Ord + Copy, SI: GetPetgraphIndex + Into + Eq + Ord + Copy, BI: GetPetgraphIndex + Into + Eq + Ord + Copy, - > RecordingGeometryWithRtree + > RecordingGeometryWithRtree { pub fn new(layer_count: usize) -> Self { Self { - geometry_with_rtree: GeometryWithRtree::::new( - layer_count, - ), + geometry_with_rtree: GeometryWithRtree::new(layer_count), } } pub fn add_dot + GetLayer>( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, weight: W, ) -> GenericIndex where @@ -76,7 +95,7 @@ impl< pub fn add_seg + GetLayer>( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, from: DI, to: DI, weight: W, @@ -102,7 +121,7 @@ impl< pub fn add_bend + GetLayer>( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, from: DI, to: DI, core: DI, @@ -129,10 +148,10 @@ impl< pub fn add_compound( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, weight: CW, ) -> GenericIndex { - let compound = self.geometry_with_rtree.add_compound(weight); + let compound = self.geometry_with_rtree.add_compound(weight.clone()); recorder .compounds .insert(compound, (None, Some((vec![], weight)))); @@ -141,20 +160,21 @@ impl< pub fn add_to_compound( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, primitive: GenericIndex, + entry_kind: Cek, compound: GenericIndex, ) { let geometry = self.geometry_with_rtree.geometry(); let old_members = geometry.compound_members(compound).collect(); - let old_weight = geometry.compound_weight(compound); + let old_weight = geometry.compound_weight(compound).clone(); self.geometry_with_rtree - .add_to_compound(primitive, compound); + .add_to_compound(primitive, entry_kind, compound); let geometry = self.geometry_with_rtree.geometry(); let new_members = geometry.compound_members(compound).collect(); - let new_weight = geometry.compound_weight(compound); + let new_weight = geometry.compound_weight(compound).clone(); recorder .compounds @@ -165,7 +185,7 @@ impl< pub fn remove_dot( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, dot: DI, ) -> Result<(), ()> { let weight = self.geometry_with_rtree.geometry().dot_weight(dot); @@ -176,7 +196,7 @@ impl< pub fn remove_seg( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, seg: SI, ) { let geometry = self.geometry_with_rtree.geometry(); @@ -188,7 +208,7 @@ impl< pub fn remove_bend( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, bend: BI, ) { let geometry = self.geometry_with_rtree.geometry(); @@ -205,11 +225,11 @@ impl< pub fn remove_compound( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, compound: GenericIndex, ) { let geometry = self.geometry_with_rtree.geometry(); - let weight = geometry.compound_weight(compound); + let weight = geometry.compound_weight(compound).clone(); let members = geometry.compound_members(compound).collect(); self.geometry_with_rtree.remove_compound(compound); edit_remove_from_map(&mut recorder.compounds, compound, (members, weight)); @@ -217,7 +237,7 @@ impl< pub fn move_dot( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, dot: DI, to: Point, ) { @@ -234,11 +254,11 @@ impl< fn modify_bend( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, bend: BI, f: F, ) where - F: FnOnce(&mut GeometryWithRtree, BI), + F: FnOnce(&mut GeometryWithRtree, BI), { let geometry = self.geometry_with_rtree.geometry(); let old_joints = geometry.bend_joints(bend); @@ -264,7 +284,7 @@ impl< pub fn shift_bend( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, bend: BI, offset: f64, ) { @@ -275,7 +295,7 @@ impl< pub fn flip_bend( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, bend: BI, ) { self.modify_bend(recorder, bend, |geometry_with_rtree, bend| { @@ -285,7 +305,7 @@ impl< pub fn reattach_bend( &mut self, - recorder: &mut GeometryEdit, + recorder: &mut GeometryEdit, bend: BI, maybe_new_inner: Option, ) { @@ -294,32 +314,16 @@ impl< }); } - pub fn compound_weight(&self, compound: GenericIndex) -> CW { + 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 { + ) -> 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() - } } fn edit_remove_from_map( @@ -347,15 +351,16 @@ impl< DW: AccessDotWeight + Into + GetLayer, SW: AccessSegWeight + Into + GetLayer, BW: AccessBendWeight + Into + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, DI: GetPetgraphIndex + Into + Eq + Ord + Copy, SI: GetPetgraphIndex + Into + Eq + Ord + Copy, BI: GetPetgraphIndex + Into + Eq + Ord + Copy, - > ApplyGeometryEdit - for RecordingGeometryWithRtree + > ApplyGeometryEdit + for RecordingGeometryWithRtree { - fn apply(&mut self, edit: &GeometryEdit) { + fn apply(&mut self, edit: &GeometryEdit) { for (compound, (maybe_old_data, ..)) in &edit.compounds { if maybe_old_data.is_some() { self.geometry_with_rtree.remove_compound(*compound); @@ -403,11 +408,12 @@ impl< for (compound, (.., maybe_new_data)) in &edit.compounds { if let Some((members, weight)) = maybe_new_data { self.geometry_with_rtree - .add_compound_at_index(*compound, *weight); + .add_compound_at_index(*compound, weight.clone()); - for member in members { + for (entry_kind, member) in members { self.geometry_with_rtree.add_to_compound( GenericIndex::::new(member.petgraph_index()), + *entry_kind, *compound, ); } diff --git a/src/geometry/with_rtree.rs b/src/geometry/with_rtree.rs index 80c9338..4eed640 100644 --- a/src/geometry/with_rtree.rs +++ b/src/geometry/with_rtree.rs @@ -39,14 +39,14 @@ impl RTreeObject for Bbox { pub type BboxedIndex = GeomWithData; #[derive(Debug, Getters)] -pub struct GeometryWithRtree { - geometry: Geometry, +pub struct GeometryWithRtree { + geometry: Geometry, rtree: RTree>>>, layer_count: usize, } -impl Clone - for GeometryWithRtree +impl Clone + for GeometryWithRtree { fn clone(&self) -> Self { Self { @@ -57,6 +57,14 @@ impl Clone } } +impl + GeometryWithRtree +{ + pub fn graph(&self) -> &StableDiGraph, GeometryLabel, usize> { + self.geometry.graph() + } +} + #[debug_invariant(self.test_envelopes())] #[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())] impl< @@ -64,16 +72,17 @@ impl< DW: AccessDotWeight + Into + GetLayer, SW: AccessSegWeight + Into + GetLayer, BW: AccessBendWeight + Into + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + PartialEq + Copy, DI: GetPetgraphIndex + Into + Copy, SI: GetPetgraphIndex + Into + Copy, BI: GetPetgraphIndex + Into + Copy, - > GeometryWithRtree + > GeometryWithRtree { pub fn new(layer_count: usize) -> Self { Self { - geometry: Geometry::::new(), + geometry: Geometry::new(), rtree: RTree::new(), layer_count, } @@ -169,9 +178,15 @@ impl< .add_compound_at_index(GenericIndex::::new(compound.petgraph_index()), weight); } - pub fn add_to_compound(&mut self, primitive: GenericIndex, compound: GenericIndex) { + pub fn add_to_compound( + &mut self, + primitive: GenericIndex, + entry_kind: Cek, + compound: GenericIndex, + ) { self.rtree.remove(&self.make_compound_bbox(compound)); - self.geometry.add_to_compound(primitive, compound); + self.geometry + .add_to_compound(primitive, entry_kind, compound); self.rtree.insert(self.make_compound_bbox(compound)); } @@ -277,12 +292,13 @@ impl< DW: AccessDotWeight + Into + GetLayer, SW: AccessSegWeight + Into + GetLayer, BW: AccessBendWeight + Into + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + PartialEq + Copy, DI: GetPetgraphIndex + Into + Copy, SI: GetPetgraphIndex + Into + Copy, BI: GetPetgraphIndex + Into + Copy, - > GeometryWithRtree + > GeometryWithRtree { fn init_dot_bbox(&mut self, dot: DI) { self.rtree.insert(self.make_dot_bbox(dot)); @@ -347,7 +363,9 @@ impl< ) -> BboxedIndex>> { let mut aabb = AABB::<[f64; 3]>::new_empty(); - for member in self.geometry.compound_members(compound) { + // NOTE(fogti): perhaps allow `entry_kind` to specify if it + // should be considered part of the bounding box or not + for (_, member) in self.geometry.compound_members(compound) { aabb.merge(&self.make_bbox(member).geom().aabb); } @@ -378,10 +396,6 @@ impl< } } - pub fn graph(&self) -> &StableDiGraph, GeometryLabel, usize> { - self.geometry.graph() - } - fn test_envelopes(&self) -> bool { !self.rtree.iter().any(|wrapper| { // TODO: Test envelopes of compounds too. @@ -407,14 +421,17 @@ impl< DW: AccessDotWeight + Into + GetLayer, SW: AccessSegWeight + Into + GetLayer, BW: AccessBendWeight + Into + GetLayer, - CW: Copy, + CW: Clone, + Cek: Copy, PI: GetPetgraphIndex + TryInto + TryInto + TryInto + PartialEq + Copy, DI: GetPetgraphIndex + Into + Copy, SI: GetPetgraphIndex + Into + Copy, BI: GetPetgraphIndex + Into + Copy, - > ManageCompounds> - for GeometryWithRtree + > ManageCompounds for GeometryWithRtree { + type GeneralIndex = PI; + type EntryKind = Cek; + fn add_compound(&mut self, weight: CW) -> GenericIndex { let compound = self.geometry.add_compound(weight); self.rtree.insert(self.make_compound_bbox(compound)); @@ -426,15 +443,28 @@ impl< self.geometry.remove_compound(compound); } - fn add_to_compound(&mut self, primitive: GenericIndex, compound: GenericIndex) { - self.geometry.add_to_compound(primitive, compound); + fn add_to_compound(&mut self, primitive: I, kind: Cek, compound: GenericIndex) + where + I: Copy + GetPetgraphIndex, + { + self.geometry.add_to_compound(primitive, kind, compound); } - fn compound_weight(&self, compound: GenericIndex) -> CW { + fn compound_weight(&self, compound: GenericIndex) -> &CW { self.geometry.compound_weight(compound) } - fn compounds(&self, node: GenericIndex) -> impl Iterator> { + fn compound_members( + &self, + compound: GenericIndex, + ) -> impl Iterator { + self.geometry.compound_members(compound) + } + + fn compounds(&self, node: I) -> impl Iterator)> + where + I: Copy + GetPetgraphIndex, + { self.geometry.compounds(node) } } diff --git a/src/graph.rs b/src/graph.rs index 12f19bb..d87ae9d 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -8,8 +8,9 @@ use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; use serde::{Deserialize, Serialize}; -pub trait MakeRef<'a, R: 'a, C> { - fn ref_(&self, context: &'a C) -> R; +pub trait MakeRef<'a, C> { + type Output: 'a; + fn ref_(&self, context: &'a C) -> Self::Output; } #[enum_dispatch] diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 9e98797..99d6c2e 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -52,18 +52,20 @@ pub enum CompoundWeight { Via(ViaWeight), } +pub type CompoundEntryKind = (); + /// The alias to differ node types pub type NodeIndex = GenericNode>; -pub type LayoutEdit = DrawingEdit; +pub type LayoutEdit = DrawingEdit; #[derive(Clone, Debug, Getters)] /// Structure for managing the Layout design pub struct Layout { - drawing: Drawing, + drawing: Drawing, } impl Layout { - pub fn new(drawing: Drawing) -> Self { + pub fn new(drawing: Drawing) -> Self { Self { drawing } } } @@ -117,12 +119,11 @@ impl Layout { }), ) { Ok(dot) => { - self.drawing.add_to_compound(recorder, dot, compound); + self.drawing.add_to_compound(recorder, dot, (), compound); dots.push(dot); } Err(err) => { // Remove inserted dots. - self.drawing.remove_compound(recorder, compound); for dot in dots.iter().rev() { @@ -232,6 +233,7 @@ impl Layout { self.drawing.add_to_compound( recorder, GenericIndex::<()>::new(i.petgraph_index()), + (), poly_compound, ); } @@ -250,7 +252,8 @@ impl Layout { ); // maybe this should be a different edge kind - self.drawing.add_to_compound(recorder, apex, poly_compound); + self.drawing + .add_to_compound(recorder, apex, (), poly_compound); assert!(is_apex(&self.drawing, apex)); @@ -265,13 +268,6 @@ impl Layout { self.drawing.remove_band(recorder, band) } - pub fn polys( - &self, - node: GenericIndex, - ) -> impl Iterator> + '_ { - self.drawing.compounds(node) - } - pub fn poly_nodes(&self) -> impl Iterator> + '_ { self.drawing.rtree().iter().filter_map(|wrapper| { if let NodeIndex::Compound(compound) = wrapper.data { @@ -308,7 +304,7 @@ impl Layout { pub fn poly_members( &self, poly: GenericIndex, - ) -> impl Iterator + '_ { + ) -> impl Iterator + '_ { self.drawing .geometry() .compound_members(GenericIndex::new(poly.petgraph_index())) @@ -464,6 +460,7 @@ impl SegWeight, BendWeight, CompoundWeight, + CompoundEntryKind, PrimitiveIndex, DotIndex, SegIndex, diff --git a/src/layout/poly.rs b/src/layout/poly.rs index e0805d0..9150600 100644 --- a/src/layout/poly.rs +++ b/src/layout/poly.rs @@ -13,13 +13,12 @@ use crate::{ dot::FixedDotIndex, graph::{GetMaybeNet, PrimitiveIndex}, primitive::GetLimbs, - rules::AccessRules, seg::SegIndex, Drawing, }, - geometry::{GetLayer, GetSetPos}, + geometry::{compound::ManageCompounds, GetLayer, GetSetPos}, graph::{GenericIndex, GetPetgraphIndex, MakeRef}, - layout::CompoundWeight, + layout::{CompoundEntryKind, CompoundWeight}, }; use super::Layout; @@ -32,17 +31,18 @@ pub trait MakePolygon { #[derive(Debug)] pub struct PolyRef<'a, R> { pub index: GenericIndex, - drawing: &'a Drawing, + drawing: &'a Drawing, } -impl<'a, R: AccessRules> MakeRef<'a, PolyRef<'a, R>, Layout> for GenericIndex { +impl<'a, R: 'a> MakeRef<'a, Layout> for GenericIndex { + type Output = PolyRef<'a, R>; fn ref_(&self, layout: &'a Layout) -> PolyRef<'a, R> { PolyRef::new(*self, layout.drawing()) } } -pub(super) fn is_apex<'a, R: AccessRules>( - drawing: &'a Drawing, +pub(super) fn is_apex( + drawing: &Drawing, dot: FixedDotIndex, ) -> bool { !drawing @@ -53,8 +53,11 @@ pub(super) fn is_apex<'a, R: AccessRules>( && drawing.primitive(dot).bends().is_empty() } -impl<'a, R: AccessRules> PolyRef<'a, R> { - pub fn new(index: GenericIndex, drawing: &'a Drawing) -> Self { +impl<'a, R> PolyRef<'a, R> { + pub fn new( + index: GenericIndex, + drawing: &'a Drawing, + ) -> Self { Self { index, drawing } } @@ -66,7 +69,7 @@ impl<'a, R: AccessRules> PolyRef<'a, R> { self.drawing .geometry() .compound_members(self.index.into()) - .find_map(|primitive_node| { + .find_map(|(_kind, primitive_node)| { if let PrimitiveIndex::FixedDot(dot) = primitive_node { if self.is_apex(dot) { return Some(dot); @@ -79,7 +82,7 @@ impl<'a, R: AccessRules> PolyRef<'a, R> { } } -impl GetLayer for PolyRef<'_, R> { +impl GetLayer for PolyRef<'_, R> { fn layer(&self) -> usize { if let CompoundWeight::Poly(weight) = self.drawing.compound_weight(self.index.into()) { weight.layer() @@ -89,20 +92,20 @@ impl GetLayer for PolyRef<'_, R> { } } -impl GetMaybeNet for PolyRef<'_, R> { +impl GetMaybeNet for PolyRef<'_, R> { fn maybe_net(&self) -> Option { self.drawing.compound_weight(self.index.into()).maybe_net() } } -impl MakePolygon for PolyRef<'_, R> { +impl MakePolygon for PolyRef<'_, R> { fn shape(&self) -> Polygon { Polygon::new( LineString::from( self.drawing .geometry() .compound_members(self.index.into()) - .filter_map(|primitive_node| { + .filter_map(|(_kind, primitive_node)| { let PrimitiveIndex::FixedDot(dot) = primitive_node else { return None; }; diff --git a/src/layout/via.rs b/src/layout/via.rs index b394fbe..c7a1872 100644 --- a/src/layout/via.rs +++ b/src/layout/via.rs @@ -15,18 +15,21 @@ use crate::{ }, geometry::primitive::{DotShape, PrimitiveShape}, graph::{GenericIndex, GetPetgraphIndex}, - layout::CompoundWeight, + layout::{CompoundEntryKind, CompoundWeight}, math::Circle, }; #[derive(Debug)] pub struct Via<'a, R> { pub index: GenericIndex, - drawing: &'a Drawing, + drawing: &'a Drawing, } impl<'a, R> Via<'a, R> { - pub fn new(index: GenericIndex, drawing: &'a Drawing) -> Self { + pub fn new( + index: GenericIndex, + drawing: &'a Drawing, + ) -> Self { Self { index, drawing } } }