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".
This commit is contained in:
Mikolaj Wielgus 2023-12-27 20:39:04 +00:00
parent 4596ec6a7d
commit 90972136da
3 changed files with 36 additions and 55 deletions

View File

@ -58,9 +58,9 @@ impl<'a> Draw<'a> {
.extend_head(head, tangent.start_point()) .extend_head(head, tangent.start_point())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .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) => { DotIndex::Fixed(dot) => {
self.layout self.layout
.add_fixed_seg(into.into(), dot, FixedSegWeight { net, width }) .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()))] #[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))]
fn extend_head(&mut self, head: Head, to: Point) -> Result<Head, Infringement> { fn extend_head(&mut self, head: Head, to: Point) -> Result<Head, Infringement> {
if let Head::Segbend(head) = head { if let Head::Segbend(head) = head {
self.layout.move_dot(head.dot, to)?; self.layout.move_dot(head.face, to)?;
Ok(Head::Segbend(head)) Ok(Head::Segbend(head))
} else { } else {
Ok(head) Ok(head)
@ -197,7 +197,7 @@ impl<'a> Draw<'a> {
width: f64, width: f64,
) -> Result<SegbendHead, LayoutException> { ) -> Result<SegbendHead, LayoutException> {
let segbend = self.layout.insert_segbend( let segbend = self.layout.insert_segbend(
head.dot(), head.face(),
around, around,
LooseDotWeight { LooseDotWeight {
band: head.band(), band: head.band(),
@ -214,7 +214,7 @@ impl<'a> Draw<'a> {
}, },
)?; )?;
Ok::<SegbendHead, LayoutException>(SegbendHead { Ok::<SegbendHead, LayoutException>(SegbendHead {
dot: self.layout.primitive(segbend.bend).other_end(segbend.dot), face: self.layout.primitive(segbend.bend).other_end(segbend.dot),
segbend, segbend,
band: head.band(), band: head.band(),
}) })
@ -229,9 +229,7 @@ impl<'a> Draw<'a> {
.other_end(head.segbend.dot.into()); .other_end(head.segbend.dot.into());
let band = head.band; let band = head.band;
self.layout.remove_interior(&head.segbend); self.layout.remove_segbend(&head.segbend, head.face);
self.layout.remove(head.dot().into());
Some(self.guide(&Default::default()).head(prev_dot, band)) Some(self.guide(&Default::default()).head(prev_dot, band))
} }

View File

@ -13,7 +13,7 @@ use crate::{
#[enum_dispatch] #[enum_dispatch]
pub trait HeadTrait { pub trait HeadTrait {
fn dot(&self) -> DotIndex; fn face(&self) -> DotIndex;
fn band(&self) -> usize; fn band(&self) -> usize;
} }
@ -31,7 +31,7 @@ pub struct BareHead {
} }
impl HeadTrait for BareHead { impl HeadTrait for BareHead {
fn dot(&self) -> DotIndex { fn face(&self) -> DotIndex {
self.dot.into() self.dot.into()
} }
@ -42,14 +42,14 @@ impl HeadTrait for BareHead {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct SegbendHead { pub struct SegbendHead {
pub dot: LooseDotIndex, pub face: LooseDotIndex,
pub segbend: Segbend, pub segbend: Segbend,
pub band: usize, pub band: usize,
} }
impl HeadTrait for SegbendHead { impl HeadTrait for SegbendHead {
fn dot(&self) -> DotIndex { fn face(&self) -> DotIndex {
self.dot.into() self.face.into()
} }
fn band(&self) -> usize { fn band(&self) -> usize {
@ -164,7 +164,7 @@ impl<'a, 'b> Guide<'a, 'b> {
match *head { match *head {
Head::Bare(head) => Circle { 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, r: 0.0,
}, },
Head::Segbend(head) => { Head::Segbend(head) => {
@ -202,7 +202,7 @@ impl<'a, 'b> Guide<'a, 'b> {
pub fn segbend_head(&self, dot: LooseDotIndex) -> SegbendHead { pub fn segbend_head(&self, dot: LooseDotIndex) -> SegbendHead {
SegbendHead { SegbendHead {
dot, face: dot,
segbend: self.layout.segbend(dot), segbend: self.layout.segbend(dot),
band: self.layout.primitive(dot).weight().band(), band: self.layout.primitive(dot).weight().band(),
} }

View File

@ -91,38 +91,31 @@ impl Layout {
} }
} }
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - path.interior().len()))] #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 4))]
pub fn remove_interior(&mut self, path: &impl GetInterior<Index>) { pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) {
for index in path let maybe_outer = self.primitive(segbend.bend).outer();
.interior()
.into_iter() // Removing a loose bend affects its outer bends.
.filter(|index| !matches!(index, Index::LooseDot(..))) if let Some(outer) = maybe_outer {
{ self.reattach_bend(outer, self.primitive(segbend.bend).inner());
self.remove(index);
} }
// We must remove the dots only after the segs and bends because we need dots to calculate self.remove(segbend.bend.into());
// the shapes, which we need to remove the segs and bends from the R-tree. self.remove(segbend.seg.into());
for index in path // We must remove the dots only after the segs and bends because we need dots to calculate
.interior() // the shapes, which we first need unchanged to remove the segs and bends from the R-tree.
.into_iter()
.filter(|index| matches!(index, Index::LooseDot(..))) self.remove(face.into());
{ self.remove(segbend.dot.into());
self.remove(index);
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))] #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() - 1))]
pub fn remove(&mut self, index: Index) { 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.
}
}
// Unnecessary retag. It should be possible to elide it. // Unnecessary retag. It should be possible to elide it.
let weight = *self.graph.node_weight(index.node_index()).unwrap(); let weight = *self.graph.node_weight(index.node_index()).unwrap();
@ -219,8 +212,7 @@ impl Layout {
// Segs must not cross. // Segs must not cross.
if let Some(collision) = self.detect_collision(segbend.seg.into()) { if let Some(collision) = self.detect_collision(segbend.seg.into()) {
let end = self.primitive(segbend.bend).other_end(segbend.dot); let end = self.primitive(segbend.bend).other_end(segbend.dot);
self.remove_interior(&segbend); self.remove_segbend(&segbend, end.into());
self.remove(end.into());
return Err(collision.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.node_count() == old(self.graph.node_count()))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
fn inner_and_outer_bows(&self, bend: LooseBendIndex) -> Vec<Index> { fn inner_bow_and_outer_bow(&self, bend: LooseBendIndex) -> Vec<Index> {
let bend_primitive = self.primitive(bend); let bend_primitive = self.primitive(bend);
let mut v = vec![]; let mut v = vec![];
@ -730,17 +722,8 @@ impl Layout {
self.move_dot_infringably( self.move_dot_infringably(
dot, dot,
to, 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()))] #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
@ -763,7 +746,7 @@ impl Layout {
dot_weight.circle.pos = to; dot_weight.circle.pos = to;
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(dot_weight); *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. // Restore original state.
*self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight); *self.graph.node_weight_mut(dot.node_index()).unwrap() = Weight::LooseDot(old_weight);
@ -772,7 +755,7 @@ impl Layout {
self.primitive(dot) self.primitive(dot)
.seg() .seg()
.map(|seg| self.insert_into_rtree(seg.into())); .map(|seg| self.insert_into_rtree(seg.into()));
return Err(()); return Err(infringement);
}*/ }*/
self.insert_into_rtree(dot.into()); self.insert_into_rtree(dot.into());