diff options
author | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-14 21:55:49 +0100 |
---|---|---|
committer | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-24 17:20:05 +0100 |
commit | 0a922773a37f6a6a0d73ee0c1fa884e90e5f0f1d (patch) | |
tree | 58c745136e4cda545a28437816ad495c1be5ae7f | |
parent | 6a7d3ec46347d06d70e08577f688ec5b534e2c08 (diff) | |
download | dcel-0a922773a37f6a6a0d73ee0c1fa884e90e5f0f1d.tar.xz |
-rw-r--r-- | src/depth_search_iterator.rs | 83 | ||||
-rw-r--r-- | src/main.rs | 160 | ||||
-rw-r--r-- | src/melf.rs | 174 | ||||
-rw-r--r-- | src/mev.rs | 4 | ||||
-rw-r--r-- | src/msev.rs | 3 | ||||
-rw-r--r-- | src/mve.rs | 172 | ||||
-rw-r--r-- | src/tests.rs | 89 |
7 files changed, 460 insertions, 225 deletions
diff --git a/src/depth_search_iterator.rs b/src/depth_search_iterator.rs deleted file mode 100644 index cc10df8..0000000 --- a/src/depth_search_iterator.rs +++ /dev/null @@ -1,83 +0,0 @@ -use crate::*; - -pub(crate) struct DepthSearchIterator<'tok, 'brand, 'arena, V> { - token: &'tok GhostToken<'brand>, - seen_vertices: Option<HashMap<usize, ptr!(Vertex)>>, - seen_edges: HashMap<usize, ptr!(Edge)>, - seen_faces: HashMap<usize, ptr!(Face)>, - edge_stack: Vec<ptr!(Edge)>, - face_stack: Vec<ptr!(Face)>, -} - -impl<'tok, 'brand, 'arena, V> DepthSearchIterator<'tok, 'brand, 'arena, V> { - pub(crate) fn new( - edge: ptr!(Edge), - collect_vertices: bool, - token: &'tok impl ReflAsRef<GhostToken<'brand>>, - ) -> Self { - Self { - token: token.as_ref(), - seen_vertices: collect_vertices.then(|| HashMap::new()), - seen_edges: HashMap::from([(edge.id(token), edge)]), - seen_faces: HashMap::new(), - edge_stack: Vec::from([edge]), - face_stack: Vec::new(), - } - } - - fn add_edge(&mut self, edge: ptr!(Edge)) { - if self.seen_edges.insert(edge.id(self.token), edge).is_none() { - self.edge_stack.push(edge); - } - } - - pub(crate) fn collect_seen( - edge: ptr!(Edge), - token: &'tok impl ReflAsRef<GhostToken<'brand>>, - ) -> ( - HashMap<usize, ptr!(Vertex)>, - HashMap<usize, ptr!(Edge)>, - HashMap<usize, ptr!(Face)>, - ) - where - 'brand: 'tok, - { - let mut x = Self::new(edge, true, token); - for _ in &mut x {} - (x.seen_vertices.unwrap(), x.seen_edges, x.seen_faces) - } -} - -impl<'tok, 'brand, 'arena, V> Iterator for DepthSearchIterator<'tok, 'brand, 'arena, V> { - type Item = ptr!(Edge); - - fn next(&mut self) -> Option<Self::Item> { - let Some(edge) = self.edge_stack.pop() else { - let face = self.face_stack.pop()?; - - for loop_ in std::iter::once(face.lens(self.token).outer_loop()) - .chain(face.iter_inner_loops(self.token)) - { - self.add_edge(loop_.half_edges().edge().item); - } - - return self.next(); - }; - - for h in edge.half_edges(self.token) { - let face = h.loop_(self.token).face(self.token); - if self.seen_faces.insert(face.id(self.token), face).is_none() { - self.face_stack.push(face); - } - - let origin = h.origin(self.token); - if let Some(seen_vertices) = self.seen_vertices.as_mut() { - seen_vertices.insert(origin.id(self.token), origin); - } - - self.add_edge(h.next(self.token).edge(self.token)); - } - - Some(edge) - } -} diff --git a/src/main.rs b/src/main.rs index 4a308aa..c3a3f4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,11 +40,11 @@ pub use mevvlfs::*; mod mev; pub use mev::*; -// mod mve; -// pub use mve::*; +mod mve; +pub use mve::*; -// mod melf; -// pub use melf::*; +mod melf; +pub use melf::*; mod mekh; pub use mekh::*; @@ -626,22 +626,6 @@ impl<'brand, 'arena, T: Entity<'brand, 'arena>> Allocator<'brand, 'arena, T> { } } -pub struct Melf<'brand, 'arena, V> { - pub shell: ptr!(Shell), - pub vertices: [ptr!(Vertex); 2], - pub old_loop: ptr!(Loop), - pub new_loop: own!(Loop), - pub edge: own!(Edge), - pub face: own!(Face), -} - -pub struct Mve<'brand, 'arena, V> { - pub shell: ptr!(Shell), - pub old_edge: ptr!(Edge), - pub new_edge: own!(Edge), - pub vertex: own!(Vertex), -} - pub struct OperatorErr<T, E> { pub op: T, pub err: E, @@ -817,121 +801,35 @@ impl<'brand, 'arena, V> Dcel<'brand, 'arena, V> { pub fn melf( &mut self, - shell: ptr!(Shell), vertices: [ptr!(Vertex); 2], - old_loop: ptr!(Loop), - ) -> Melf<'brand, 'arena, V> { - // before: - // > > - // a0 \ / a2 - // v1 v2 - // b0 / \ b2 - // < < - // - // after: - // > > - // a0 \ a1 -> / a2 - // v1 v2 - // b0 / <- b1 \ b2 - // < < - // - - let (edge, [a1, b1]) = Edge::create(shell, self); - let face = shell.add_new_face(self); - let new_loop = Loop::new(self); // face.add_new_outer_loop(self); - - let [v1, v2] = vertices; - let [b0, a2] = vertices.map(|v| v.find_outgoing(old_loop, self).unwrap()); - - let a0 = b0.prev(self); - let b2 = a2.prev(self); - - new_loop.set_face(*face, self); - face.set_outer_loop(*new_loop, self); - - a1.update_origin(v1, self); - self.follow(a0, a1); - self.follow(a1, a2); - old_loop.set_half_edges(a1, self); - a1.set_loop_(old_loop, self); - - b1.update_origin(v2, self); - self.follow(b2, b1); - self.follow(b1, b0); - new_loop.set_half_edges(b1, self); - new_loop.update_connectivity(self); - // new_loop.iter_mut_half_edges(self, |x, dcel| x.set_loop_(*new_loop, dcel)); - - Melf { - shell, - vertices, - old_loop, - new_loop, - edge, - face, - } + loop_: ptr!(Loop), + ) -> Result<Kelf<'brand, 'arena, V>, OperatorErr<Melf<'brand, 'arena, V>, MelfError>> { + Melf::new(vertices, loop_).apply(self) + } + + pub fn kelf( + &mut self, + edge: own!(Edge), + loop_: own!(Loop), + face: own!(Face), + ) -> Result<Melf<'brand, 'arena, V>, OperatorErr<Kelf<'brand, 'arena, V>, KelfError>> { + Kelf::new(edge, loop_, face).apply(self) } pub fn mve( &mut self, - shell: ptr!(Shell), - old_edge: ptr!(Edge), + edge: ptr!(Edge), data: V, - ) -> Mve<'brand, 'arena, V> { - // before: - // - // > - // / a3 - // a1 -> - // v1 v2 - // <- b1 - // \ b3 - // < - // - // after: - // - // > - // / a3 - // a1 -> a2 -> - // v1 v v2 - // <- b1 <- b2 - // \ b3 - // < - - let (new_edge, [a2, b2]) = Edge::create(shell, self); - let v = shell.add_new_vertex(data, self); - - let [a1, b1] = old_edge.half_edges(self); - let [v1, v2] = old_edge.vertices(self); - - let mut a3 = a1.next(self); - let mut b3 = b1.prev(self); - - if a3.eq(b1, self) { - a3 = b2; - } - if b3.eq(a1, self) { - b3 = a2; - } - - a2.update_origin(*v, self); - b1.update_origin(*v, self); - b2.update_origin(v2, self); - - self.follow(a1, a2); - self.follow(a2, a3); - self.follow(b3, b2); - self.follow(b2, b1); - - a2.set_loop_(a1.loop_(self), self); - b2.set_loop_(b1.loop_(self), self); + ) -> Result<Kve<'brand, 'arena, V>, OperatorErr<Mve<'brand, 'arena, V>, Infallible>> { + Mve::new(edge, data).apply(self) + } - Mve { - shell, - old_edge, - new_edge, - vertex: v, - } + pub fn kve( + &mut self, + edge: own!(Edge), + vertex: own!(Vertex), + ) -> Result<Mve<'brand, 'arena, V>, OperatorErr<Kve<'brand, 'arena, V>, KveError>> { + Kve::new(edge, vertex).apply(self) } pub fn mekh( @@ -1029,8 +927,10 @@ fn main() { let op2 = dcel.mev(*op.loop_, *op.vertices[1], ("E", [4, 0])).unwrap(); let op3 = dcel.mev(*op.loop_, *op2.vertex, ("S", [0, -4])).unwrap(); - dcel.melf(*op.shell, [*op3.vertex, *op.vertices[0]], *op.loop_); - dcel.melf(*op.shell, [*op.vertices[0], *op2.vertex], *op.loop_); + dcel.melf([*op3.vertex, *op.vertices[0]], *op.loop_) + .unwrap(); + dcel.melf([*op.vertices[0], *op2.vertex], *op.loop_) + .unwrap(); show("cool_stuff.dot", &dcel); diff --git a/src/melf.rs b/src/melf.rs new file mode 100644 index 0000000..2b8df3f --- /dev/null +++ b/src/melf.rs @@ -0,0 +1,174 @@ +use crate::*; + +// Make Edge-Vertex + +pub struct Melf<'brand, 'arena, V> { + pub vertices: [ptr!(Vertex); 2], + pub loop_: ptr!(Loop), +} + +impl<'brand, 'arena, V> Melf<'brand, 'arena, V> { + pub fn new(vertices: [ptr!(Vertex); 2], loop_: ptr!(Loop)) -> Self { + Self { vertices, loop_ } + } +} + +#[derive(Debug, Error)] +pub enum MelfError { + #[error("vertex is not part of loop")] + VertexLoopMismatch, +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Melf<'brand, 'arena, V> { + type Inverse = Kelf<'brand, 'arena, V>; + type Error = MelfError; + type Check = [ptr!(HalfEdge); 2]; + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + let b0 = self.vertices[0] + .find_outgoing(self.loop_, dcel) + .ok_or(MelfError::VertexLoopMismatch)?; + let a2 = self.vertices[1] + .find_outgoing(self.loop_, dcel) + .ok_or(MelfError::VertexLoopMismatch)?; + + Ok([b0, a2]) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + // before: + // > > + // a0 \ / a2 + // v1 v2 + // b0 / \ b2 + // < < + // + // after: + // > > + // a0 \ a1 -> / a2 + // v1 v2 + // b0 / <- b1 \ b2 + // < < + // + + let [b0, a2] = try_check!(self, dcel); + let a0 = b0.prev(dcel); + let b2 = a2.prev(dcel); + + let old_loop = self.loop_; + let [v1, v2] = self.vertices; + let shell = old_loop.face(dcel).shell(dcel); + + let (edge, [a1, b1]) = Edge::create(shell, dcel); + let face = shell.add_new_face(dcel); + let new_loop = Loop::new(dcel); // face.add_new_outer_loop(self); + new_loop.set_face(*face, dcel); + face.set_outer_loop(*new_loop, dcel); + + a1.update_origin(v1, dcel); + dcel.follow(a0, a1); + dcel.follow(a1, a2); + old_loop.set_half_edges(a1, dcel); + a1.set_loop_(old_loop, dcel); + + b1.update_origin(v2, dcel); + dcel.follow(b2, b1); + dcel.follow(b1, b0); + new_loop.set_half_edges(b1, dcel); + new_loop.update_connectivity(dcel); + + Ok(Kelf { + loop_: new_loop, + edge, + face, + }) + } +} + +pub struct Kelf<'brand, 'arena, V> { + pub edge: own!(Edge), + pub loop_: own!(Loop), + pub face: own!(Face), +} + +impl<'brand, 'arena, V> Kelf<'brand, 'arena, V> { + pub fn new(edge: own!(Edge), loop_: own!(Loop), face: own!(Face)) -> Self { + Self { edge, loop_, face } + } +} + +#[derive(Debug, Error)] +pub enum KelfError { + #[error("edge is not part of loop")] + EdgeLoopMismatch, + #[error("loop is not outer loop of face")] + FaceLoopMismatch, + #[error("face has inner loops")] + HasInnerLoops, +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kelf<'brand, 'arena, V> { + type Inverse = Melf<'brand, 'arena, V>; + type Error = KelfError; + type Check = [ptr!(HalfEdge); 2]; + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + use KelfError::*; + + let [mut a1, mut b1] = self.edge.lens(dcel).half_edges(); + + if a1.loop_().eq(*self.loop_) { + [a1, b1] = [b1, a1]; + } + + or_err(b1.loop_().eq(*self.loop_), EdgeLoopMismatch)?; + or_err( + self.face.outer_loop(dcel).eq(*self.loop_, dcel), + FaceLoopMismatch, + )?; + or_err(self.face.maybe_inner_loops(dcel).is_none(), HasInnerLoops)?; + + Ok([a1.item, b1.item]) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + let [a1, b1] = try_check!(self, dcel); + + let Kelf { edge, loop_, face } = self; + let shell = face.shell(dcel); + + let a0 = a1.prev(dcel); + let b0 = b1.next(dcel); + let a2 = a1.next(dcel); + let b2 = b1.prev(dcel); + + let v1 = a1.origin(dcel); + let v2 = b1.origin(dcel); + + let old_loop = a1.loop_(dcel); + + dcel.follow(a0, b0); + dcel.follow(b2, a2); + + old_loop.set_half_edges(a0, dcel); + old_loop.update_connectivity(dcel); + + shell.remove_edge(*edge, dcel); + shell.remove_face(*face, dcel); + + edge.destroy(dcel); + face.free(dcel); + loop_.free(dcel); + + Ok(Melf { + vertices: [v1, v2], + loop_: old_loop, + }) + } +} @@ -128,6 +128,10 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kev<'brand, 'arena, V> { let d = c.prev(dcel); dcel.follow(d, a); + let shell = a.loop_(dcel).face(dcel).shell(dcel); + shell.remove_edge(*self.edge, dcel); + shell.remove_vertex(*self.vertex, dcel); + self.edge.destroy(dcel); let data = self.vertex.destroy(dcel); diff --git a/src/msev.rs b/src/msev.rs index 9abc5a4..16d18e4 100644 --- a/src/msev.rs +++ b/src/msev.rs @@ -173,6 +173,9 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Ksev<'brand, 'arena, V> loops[0].set_half_edges(a0, dcel); loops[1].set_half_edges(b0, dcel); + shell.remove_edge(*edge, dcel); + shell.remove_vertex(*new_vertex, dcel); + edge.destroy(dcel); let data = new_vertex.destroy(dcel); diff --git a/src/mve.rs b/src/mve.rs new file mode 100644 index 0000000..19785d9 --- /dev/null +++ b/src/mve.rs @@ -0,0 +1,172 @@ +use crate::*; + +// Make Vertex-Edge + +pub struct Mve<'brand, 'arena, V> { + pub edge: ptr!(Edge), + pub data: V, +} + +impl<'brand, 'arena, V> Mve<'brand, 'arena, V> { + pub fn new(edge: ptr!(Edge), data: V) -> Self { + Self { edge, data } + } +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Mve<'brand, 'arena, V> { + type Inverse = Kve<'brand, 'arena, V>; + type Error = Infallible; + type Check = (); + + fn check(&self, _dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + Ok(()) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + // before: + // + // > + // / a3 + // a1 -> + // v1 v2 + // <- b1 + // \ b3 + // < + // + // after: + // + // > + // / a3 + // a1 -> a2 -> + // v1 v v2 + // <- b1 <- b2 + // \ b3 + // < + + try_check!(self, dcel); + + let Mve { edge, data } = self; + + let shell = edge.lens(dcel).half_edges()[0].loop_().face().shell().item; + + let (new_edge, [a2, b2]) = Edge::create(shell, dcel); + let v = shell.add_new_vertex(data, dcel); + + let [a1, b1] = edge.half_edges(dcel); + let v2 = edge.vertices(dcel)[1]; + + let mut a3 = a1.next(dcel); + let mut b3 = b1.prev(dcel); + + if a3.eq(b1, dcel) { + a3 = b2; + } + if b3.eq(a1, dcel) { + b3 = a2; + } + + a2.update_origin(*v, dcel); + b1.update_origin(*v, dcel); + b2.update_origin(v2, dcel); + + dcel.follow(a1, a2); + dcel.follow(a2, a3); + dcel.follow(b3, b2); + dcel.follow(b2, b1); + + a2.set_loop_(a1.loop_(dcel), dcel); + b2.set_loop_(b1.loop_(dcel), dcel); + + Ok(Kve { + edge: new_edge, + vertex: v, + }) + } +} + +pub struct Kve<'brand, 'arena, V> { + pub edge: own!(Edge), + pub vertex: own!(Vertex), +} + +impl<'brand, 'arena, V> Kve<'brand, 'arena, V> { + pub fn new(edge: own!(Edge), vertex: own!(Vertex)) -> Self { + Self { edge, vertex } + } +} + +#[derive(Debug, Error)] +pub enum KveError { + #[error("vertex is not part of edge")] + VertexEdgeMismatch, + #[error("vertex has more than two outgoing edges")] + TooManyOutgoing, + #[error("vertex is turning point, use KEV")] + VertexTurningPoint, +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kve<'brand, 'arena, V> { + type Inverse = Mve<'brand, 'arena, V>; + type Error = KveError; + type Check = [ptr!(HalfEdge); 2]; + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + use KveError::*; + + let [mut a2, mut b2] = self.edge.lens(dcel).half_edges(); + if b2.origin().eq(*self.vertex) { + [a2, b2] = [b2, a2]; + } + + or_err(a2.origin().eq(*self.vertex), VertexEdgeMismatch)?; + or_err( + self.vertex.iter_outgoing(dcel).count() == 2, + TooManyOutgoing, + )?; + or_err(b2.next() != a2, VertexTurningPoint)?; + + Ok([a2.item, b2.item]) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + let [a2, b2] = try_check!(self, dcel); + + let a1 = a2.prev(dcel); + let b1 = b2.next(dcel); + + let v2 = b2.origin(dcel); + + let mut a3 = a2.next(dcel); + if a3.eq(b2, dcel) { + a3 = b1; + } + let mut b3 = b2.prev(dcel); + if b3.eq(a2, dcel) { + b3 = a1; + } + + dcel.follow(a1, a3); + dcel.follow(b3, b1); + + b1.update_origin(v2, dcel); + a1.loop_(dcel).set_half_edges(a1, dcel); + b1.loop_(dcel).set_half_edges(b1, dcel); + + let shell = a1.loop_(dcel).face(dcel).shell(dcel); + shell.remove_edge(*self.edge, dcel); + shell.remove_vertex(*self.vertex, dcel); + + self.edge.destroy(dcel); + + Ok(Mve { + edge: a1.edge(dcel), + data: self.vertex.destroy(dcel), + }) + } +} diff --git a/src/tests.rs b/src/tests.rs index 5dc0a78..4102add 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,4 +1,5 @@ use crate::*; +use std::collections::HashSet; #[test] fn mev_cycle() { @@ -7,7 +8,8 @@ fn mev_cycle() { let op = dcel.mevvlfs(*body, [0, 1]).unwrap(); let op2 = dcel.mev(*op.loop_, *op.vertices[1], 2).unwrap(); let op3 = dcel.mev(*op.loop_, *op2.vertex, 3).unwrap(); - dcel.melf(*op.shell, [*op3.vertex, *op.vertices[0]], *op.loop_); + dcel.melf([*op3.vertex, *op.vertices[0]], *op.loop_) + .unwrap(); let mut vertices = op .loop_ @@ -23,6 +25,71 @@ fn mev_cycle() { }) } +fn assert_verts<'brand, 'arena, V: Eq + Copy + Debug + Hash>( + loop_: ptr!(Loop), + dcel: &Dcel<'brand, 'arena, V>, + want: impl Into<HashSet<V>>, +) { + assert_eq!( + loop_ + .iter_half_edges(dcel) + .map(|x| *x.origin().data()) + .collect::<HashSet<_>>(), + want.into() + ); +} + +#[test] +fn mev_kve() { + Dcel::<u32>::new(|mut dcel| { + let body = dcel.new_body(); + let Kevvlfs { + vertices: [v0, v1], + edge: old_edge, + loop_, + .. + } = dcel.mevvlfs(*body, [0, 1]).unwrap(); + assert_verts(*loop_, &dcel, [0, 1]); + + dcel.mev(*loop_, *v1, 2).unwrap(); + assert_verts(*loop_, &dcel, [0, 1, 2]); + + let undo = dcel.kve(old_edge, v1).unwrap(); + assert_verts(*loop_, &dcel, [0, 2]); + + undo.apply(&mut dcel).unwrap(); + assert_verts(*loop_, &dcel, [0, 1, 2]); + }) +} + +#[test] +fn mve_kev() { + Dcel::<u32>::new(|mut dcel| { + let body = dcel.new_body(); + let Kevvlfs { + vertices: [v0, v1], + edge: old_edge, + loop_, + .. + } = dcel.mevvlfs(*body, [0, 1]).unwrap(); + assert_verts(*loop_, &dcel, [0, 1]); + + let mut edge = dcel.mve(*old_edge, 2).unwrap().edge; + assert_verts(*loop_, &dcel, [0, 2, 1]); + + let verts = edge.lens(&dcel).vertices(); + if !verts[0].eq(*v1) && !verts[1].eq(*v1) { + edge = old_edge; + } + + let undo = dcel.kev(edge, v1).unwrap(); + assert_verts(*loop_, &dcel, [0, 2]); + + undo.apply(&mut dcel).unwrap(); + assert_verts(*loop_, &dcel, [0, 2, 1]); + }) +} + /* makes this shape: @@ -51,7 +118,7 @@ fn make_hourglass<'brand, 'arena, V>( } = dcel.mevvlfs(*body, [d0, d1]).unwrap(); let inner_2 = dcel.mev(*loop_0, *inner_1, d2).unwrap().vertex; - let mut outer_loop = dcel.melf(*shell, [*inner_0, *inner_2], *loop_0).new_loop; + let mut outer_loop = dcel.melf([*inner_0, *inner_2], *loop_0).unwrap().loop_; let Kev { vertex: outer_0, @@ -61,9 +128,7 @@ fn make_hourglass<'brand, 'arena, V>( let outer_1 = dcel.mev(*outer_loop, *outer_0, d4).unwrap().vertex; let outer_2 = dcel.mev(*outer_loop, *outer_1, d5).unwrap().vertex; - let mut loop_2 = dcel - .melf(*shell, [*outer_0, *outer_2], *outer_loop) - .new_loop; + let mut loop_2 = dcel.melf([*outer_0, *outer_2], *outer_loop).unwrap().loop_; if edge.lens(dcel).half_edges()[0].loop_().eq(*loop_2) { [outer_loop, loop_2] = [loop_2, outer_loop]; } @@ -183,25 +248,25 @@ fn msev_ksev() { let out_2 = dcel.mev(*loop_0, *out_1, 2).unwrap().vertex; let out_3 = dcel.mev(*loop_0, *out_2, 3).unwrap().vertex; - dcel.melf(*shell, [*out_0, *out_3], *loop_0); + dcel.melf([*out_0, *out_3], *loop_0).unwrap(); - let Melf { - new_loop: mut loop_2, + let Kelf { + loop_: mut loop_2, edge, .. - } = dcel.melf(*shell, [*out_0, *out_2], *loop_0); + } = dcel.melf([*out_0, *out_2], *loop_0).unwrap(); if out_1.find_outgoing(*loop_0, &dcel).is_none() { [loop_0, loop_2] = [loop_2, loop_0]; } - let in_0 = dcel.mve(*shell, *edge, 4).vertex; + let in_0 = dcel.mve(*edge, 4).unwrap().vertex; - let mut loop_1 = dcel.melf(*shell, [*out_1, *in_0], *loop_0).new_loop; + let mut loop_1 = dcel.melf([*out_1, *in_0], *loop_0).unwrap().loop_; if out_0.find_outgoing(*loop_0, &dcel).is_none() { [loop_0, loop_1] = [loop_1, loop_0]; } - let mut loop_3 = dcel.melf(*shell, [*out_3, *in_0], *loop_2).new_loop; + let mut loop_3 = dcel.melf([*out_3, *in_0], *loop_2).unwrap().loop_; if out_2.find_outgoing(*loop_2, &dcel).is_none() { [loop_2, loop_3] = [loop_3, loop_2]; } |