From 90972136da708b4926b978e2b28af3aaeadd991a Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 27 Dec 2023 20:39:04 +0000 Subject: [PATCH] layout: create `.remove_segbend()`, new and now only way to remove `.remove()` is now private. The dot that terminates a segbend is renamed to "face". --- src/draw.rs | 14 +++++------- src/guide.rs | 14 ++++++------ src/layout.rs | 63 +++++++++++++++++++-------------------------------- 3 files changed, 36 insertions(+), 55 deletions(-) diff --git a/src/draw.rs b/src/draw.rs index e52d6c0..6bc7811 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -58,9 +58,9 @@ impl<'a> Draw<'a> { .extend_head(head, tangent.start_point()) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; - let net = head.dot().primitive(self.layout).net(); + let net = head.face().primitive(self.layout).net(); - match head.dot() { + match head.face() { DotIndex::Fixed(dot) => { self.layout .add_fixed_seg(into.into(), dot, FixedSegWeight { net, width }) @@ -179,7 +179,7 @@ impl<'a> Draw<'a> { #[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))] fn extend_head(&mut self, head: Head, to: Point) -> Result { if let Head::Segbend(head) = head { - self.layout.move_dot(head.dot, to)?; + self.layout.move_dot(head.face, to)?; Ok(Head::Segbend(head)) } else { Ok(head) @@ -197,7 +197,7 @@ impl<'a> Draw<'a> { width: f64, ) -> Result { let segbend = self.layout.insert_segbend( - head.dot(), + head.face(), around, LooseDotWeight { band: head.band(), @@ -214,7 +214,7 @@ impl<'a> Draw<'a> { }, )?; Ok::(SegbendHead { - dot: self.layout.primitive(segbend.bend).other_end(segbend.dot), + face: self.layout.primitive(segbend.bend).other_end(segbend.dot), segbend, band: head.band(), }) @@ -229,9 +229,7 @@ impl<'a> Draw<'a> { .other_end(head.segbend.dot.into()); let band = head.band; - self.layout.remove_interior(&head.segbend); - self.layout.remove(head.dot().into()); - + self.layout.remove_segbend(&head.segbend, head.face); Some(self.guide(&Default::default()).head(prev_dot, band)) } diff --git a/src/guide.rs b/src/guide.rs index ef5bec0..de96ad4 100644 --- a/src/guide.rs +++ b/src/guide.rs @@ -13,7 +13,7 @@ use crate::{ #[enum_dispatch] pub trait HeadTrait { - fn dot(&self) -> DotIndex; + fn face(&self) -> DotIndex; fn band(&self) -> usize; } @@ -31,7 +31,7 @@ pub struct BareHead { } impl HeadTrait for BareHead { - fn dot(&self) -> DotIndex { + fn face(&self) -> DotIndex { self.dot.into() } @@ -42,14 +42,14 @@ impl HeadTrait for BareHead { #[derive(Debug, Clone, Copy)] pub struct SegbendHead { - pub dot: LooseDotIndex, + pub face: LooseDotIndex, pub segbend: Segbend, pub band: usize, } impl HeadTrait for SegbendHead { - fn dot(&self) -> DotIndex { - self.dot.into() + fn face(&self) -> DotIndex { + self.face.into() } fn band(&self) -> usize { @@ -164,7 +164,7 @@ impl<'a, 'b> Guide<'a, 'b> { match *head { Head::Bare(head) => Circle { - pos: head.dot().primitive(self.layout).shape().center(), // TODO. + pos: head.face().primitive(self.layout).shape().center(), // TODO. r: 0.0, }, Head::Segbend(head) => { @@ -202,7 +202,7 @@ impl<'a, 'b> Guide<'a, 'b> { pub fn segbend_head(&self, dot: LooseDotIndex) -> SegbendHead { SegbendHead { - dot, + face: dot, segbend: self.layout.segbend(dot), band: self.layout.primitive(dot).weight().band(), } diff --git a/src/layout.rs b/src/layout.rs index 00bef0b..e5da269 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -91,38 +91,31 @@ impl Layout { } } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - path.interior().len()))] - pub fn remove_interior(&mut self, path: &impl GetInterior) { - for index in path - .interior() - .into_iter() - .filter(|index| !matches!(index, Index::LooseDot(..))) - { - self.remove(index); + #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 4))] + pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) { + let maybe_outer = self.primitive(segbend.bend).outer(); + + // Removing a loose bend affects its outer bends. + if let Some(outer) = maybe_outer { + self.reattach_bend(outer, self.primitive(segbend.bend).inner()); } - // We must remove the dots only after the segs and bends because we need dots to calculate - // the shapes, which we need to remove the segs and bends from the R-tree. + self.remove(segbend.bend.into()); + self.remove(segbend.seg.into()); - for index in path - .interior() - .into_iter() - .filter(|index| matches!(index, Index::LooseDot(..))) - { - self.remove(index); + // We must remove the dots only after the segs and bends because we need dots to calculate + // the shapes, which we first need unchanged to remove the segs and bends from the R-tree. + + self.remove(face.into()); + self.remove(segbend.dot.into()); + + if let Some(outer) = maybe_outer { + self.update_this_and_outward_bows(outer).unwrap(); // Must never fail. } } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))] - pub fn remove(&mut self, index: Index) { - // Removing a loose bend affects its outer bends. - if let Index::LooseBend(bend) = index { - if let Some(outer) = self.primitive(bend).outer() { - self.reattach_bend(outer, self.primitive(bend).inner()); - self.update_this_and_outward_bows(outer).unwrap(); // Must never fail. - } - } - + fn remove(&mut self, index: Index) { // Unnecessary retag. It should be possible to elide it. let weight = *self.graph.node_weight(index.node_index()).unwrap(); @@ -219,8 +212,7 @@ impl Layout { // Segs must not cross. if let Some(collision) = self.detect_collision(segbend.seg.into()) { let end = self.primitive(segbend.bend).other_end(segbend.dot); - self.remove_interior(&segbend); - self.remove(end.into()); + self.remove_segbend(&segbend, end.into()); return Err(collision.into()); } @@ -229,7 +221,7 @@ impl Layout { #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] - fn inner_and_outer_bows(&self, bend: LooseBendIndex) -> Vec { + fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec { let bend_primitive = self.primitive(bend); let mut v = vec![]; @@ -730,17 +722,8 @@ impl Layout { self.move_dot_infringably( dot, to, - &self.inner_and_outer_bows(self.primitive(dot).bend()), + &self.inner_bow_and_outer_bow(self.primitive(dot).bend()), ) - - //let bend_primitive = self.primitive(self.primitive(dot).bend()); - - /*if let Some(inner) = bend_primitive.inner() { - } else { - let core = bend_primitive.core(); - //let v = vec![]; - //self.move_dot_infringably(dot, to, &self.this_and_wraparound_bow(core.into())) - }*/ } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] @@ -763,7 +746,7 @@ impl Layout { dot_weight.circle.pos = to; *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight); - /*if let Some(..) = dbg!(self.detect_infringement_except(dot.into(), infringables)) { + /*if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) { // Restore original state. *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight); @@ -772,7 +755,7 @@ impl Layout { self.primitive(dot) .seg() .map(|seg| self.insert_into_rtree(seg.into())); - return Err(()); + return Err(infringement); }*/ self.insert_into_rtree(dot.into());