diff options
author | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-13 12:47:21 +0100 |
---|---|---|
committer | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-24 17:20:04 +0100 |
commit | 6a7d3ec46347d06d70e08577f688ec5b534e2c08 (patch) | |
tree | 2c599c12e22975b5d830282f400ae25442af00f9 | |
parent | c7be7ca0188e8edd19afd880f393d5622451fef5 (diff) | |
download | dcel-6a7d3ec46347d06d70e08577f688ec5b534e2c08.tar.xz |
-rw-r--r-- | src/main.rs | 70 | ||||
-rw-r--r-- | src/mev.rs | 140 | ||||
-rw-r--r-- | src/mevvlfs.rs | 16 | ||||
-rw-r--r-- | src/tests.rs | 23 |
4 files changed, 172 insertions, 77 deletions
diff --git a/src/main.rs b/src/main.rs index 2fcde6e..4a308aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,8 +37,8 @@ mod tests; mod mevvlfs; pub use mevvlfs::*; -// mod mev; -// pub use mev::*; +mod mev; +pub use mev::*; // mod mve; // pub use mve::*; @@ -635,14 +635,6 @@ pub struct Melf<'brand, 'arena, V> { pub face: own!(Face), } -pub struct Mev<'brand, 'arena, V> { - pub shell: ptr!(Shell), - pub loop_: ptr!(Loop), - pub old_vertex: ptr!(Vertex), - pub new_vertex: own!(Vertex), - pub edge: own!(Edge), -} - pub struct Mve<'brand, 'arena, V> { pub shell: ptr!(Shell), pub old_edge: ptr!(Edge), @@ -796,7 +788,6 @@ impl<'brand, 'arena, V> Dcel<'brand, 'arena, V> { pub fn kevvlfs( &mut self, - body: ptr!(Body), edge: own!(Edge), vertices: [own!(Vertex); 2], loop_: own!(Loop), @@ -804,51 +795,24 @@ impl<'brand, 'arena, V> Dcel<'brand, 'arena, V> { shell: own!(Shell), ) -> Result<Mevvlfs<'brand, 'arena, V>, OperatorErr<Kevvlfs<'brand, 'arena, V>, KevvlfsError>> { - Kevvlfs::new(body, edge, vertices, loop_, face, shell).apply(self) + Kevvlfs::new(edge, vertices, loop_, face, shell).apply(self) } pub fn mev( &mut self, - shell: ptr!(Shell), loop_: ptr!(Loop), - old_vertex: ptr!(Vertex), + vertex: ptr!(Vertex), data: V, - ) -> Mev<'brand, 'arena, V> { - // - // o - // a / \ d - // < < - // - - // < n < - // b | | c - // o - // a / \ d - // < < - - let (edge, [b, c]) = Edge::create(shell, self); - let new_vertex = shell.add_new_vertex(data, self); - - let a = old_vertex.find_outgoing(loop_, self).unwrap(); - let d = a.prev(self); - - self.follow(d, c); - self.follow(c, b); - self.follow(b, a); - - b.set_loop_(loop_, self); - c.set_loop_(loop_, self); - - b.update_origin(*new_vertex, self); - c.update_origin(old_vertex, self); + ) -> Result<Kev<'brand, 'arena, V>, OperatorErr<Mev<'brand, 'arena, V>, MevError>> { + Mev::new(loop_, vertex, data).apply(self) + } - Mev { - shell, - loop_, - old_vertex, - new_vertex, - edge, - } + pub fn kev( + &mut self, + edge: own!(Edge), + vertex: own!(Vertex), + ) -> Result<Mev<'brand, 'arena, V>, OperatorErr<Kev<'brand, 'arena, V>, KevError>> { + Kev::new(edge, vertex).apply(self) } pub fn melf( @@ -1062,11 +1026,11 @@ fn main() { let op = dcel .mevvlfs(*body, [("W", [-4, 0]), ("N", [0, 4])]) .unwrap(); - let op2 = dcel.mev(*op.shell, *op.loop_, *op.vertices[1], ("E", [4, 0])); - let op3 = dcel.mev(*op.shell, *op.loop_, *op2.new_vertex, ("S", [0, -4])); + 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.new_vertex, *op.vertices[0]], *op.loop_); - dcel.melf(*op.shell, [*op.vertices[0], *op2.new_vertex], *op.loop_); + dcel.melf(*op.shell, [*op3.vertex, *op.vertices[0]], *op.loop_); + dcel.melf(*op.shell, [*op.vertices[0], *op2.vertex], *op.loop_); show("cool_stuff.dot", &dcel); diff --git a/src/mev.rs b/src/mev.rs new file mode 100644 index 0000000..41a2ceb --- /dev/null +++ b/src/mev.rs @@ -0,0 +1,140 @@ +use crate::*; + +// Make Edge-Vertex + +pub struct Mev<'brand, 'arena, V> { + pub loop_: ptr!(Loop), + pub vertex: ptr!(Vertex), + pub data: V, +} + +impl<'brand, 'arena, V> Mev<'brand, 'arena, V> { + pub fn new(loop_: ptr!(Loop), vertex: ptr!(Vertex), data: V) -> Self { + Self { + loop_, + vertex, + data, + } + } +} + +#[derive(Debug, Error)] +pub enum MevError { + #[error("vertex is not part of loop")] + VertexLoopMismatch, +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Mev<'brand, 'arena, V> { + type Inverse = Kev<'brand, 'arena, V>; + type Error = MevError; + type Check = ptr!(HalfEdge); + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + self.vertex + .find_outgoing(self.loop_, dcel) + .ok_or(MevError::VertexLoopMismatch) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + // + // o + // a / \ d + // < < + // + + // < n < + // b | | c + // o + // a / \ d + // < < + + let a = try_check!(self, dcel); + let d = a.prev(dcel); + + let shell = self.loop_.face(dcel).shell(dcel); + let (edge, [b, c]) = Edge::create(shell, dcel); + let vertex = shell.add_new_vertex(self.data, dcel); + + dcel.follow(d, c); + dcel.follow(c, b); + dcel.follow(b, a); + + b.set_loop_(self.loop_, dcel); + c.set_loop_(self.loop_, dcel); + + b.update_origin(*vertex, dcel); + c.update_origin(self.vertex, dcel); + + Ok(Kev { edge, vertex }) + } +} + +pub struct Kev<'brand, 'arena, V> { + pub edge: own!(Edge), + pub vertex: own!(Vertex), +} + +impl<'brand, 'arena, V> Kev<'brand, 'arena, V> { + pub fn new(edge: own!(Edge), vertex: own!(Vertex)) -> Self { + Self { edge, vertex } + } +} + +#[derive(Debug, Error)] +pub enum KevError { + #[error("half edges don't go back and forth between new and old vertex")] + NotBackForth, + #[error("new vertex is not the turning point")] + EdgeVertexMismatch, + #[error("vertex has more than one outgoing edge")] + VertexNotSingleton, +} + +impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kev<'brand, 'arena, V> { + type Inverse = Mev<'brand, 'arena, V>; + type Error = KevError; + type Check = [ptr!(HalfEdge); 2]; + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { + use KevError::*; + + let [mut b, mut c] = self.edge.lens(dcel).half_edges(); + + if b.next() == c { + [b, c] = [c, b]; + } + + or_err(c.next() == b, NotBackForth)?; + or_err(b.origin().eq(*self.vertex), EdgeVertexMismatch)?; + + or_err( + self.vertex.iter_outgoing(dcel).count() == 1, + VertexNotSingleton, + )?; + + Ok([b.item, c.item]) + } + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> { + let [b, c] = try_check!(self, dcel); + + let a = b.next(dcel); + let d = c.prev(dcel); + dcel.follow(d, a); + + self.edge.destroy(dcel); + let data = self.vertex.destroy(dcel); + + Ok(Mev { + data, + vertex: a.origin(dcel), + loop_: a.loop_(dcel), + }) + } +} diff --git a/src/mevvlfs.rs b/src/mevvlfs.rs index 370ad96..318a91b 100644 --- a/src/mevvlfs.rs +++ b/src/mevvlfs.rs @@ -3,8 +3,8 @@ use crate::*; // Make Edge-Vertex-Vertex-Loop-Face-Shell pub struct Mevvlfs<'brand, 'arena, V> { - body: ptr!(Body), - data: [V; 2], + pub body: ptr!(Body), + pub data: [V; 2], } impl<'brand, 'arena, V> Mevvlfs<'brand, 'arena, V> { @@ -50,7 +50,6 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Mevvlfs<'brand, 'arena, loop_.add_half_edge(b, dcel); Ok(Kevvlfs { - body, edge, vertices: [v1, v2], loop_, @@ -61,7 +60,6 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Mevvlfs<'brand, 'arena, } pub struct Kevvlfs<'brand, 'arena, V> { - pub body: ptr!(Body), pub edge: own!(Edge), pub vertices: [own!(Vertex); 2], pub loop_: own!(Loop), @@ -85,13 +83,10 @@ pub enum KevvlfsError { ShellHasMoreThanOneFace, #[error("shell face does not match face")] ShellFaceMismatch, - #[error("shell body does not match body")] - ShellBodyMismatch, } impl<'brand, 'arena, V> Kevvlfs<'brand, 'arena, V> { pub fn new( - body: ptr!(Body), edge: own!(Edge), vertices: [own!(Vertex); 2], loop_: own!(Loop), @@ -99,7 +94,6 @@ impl<'brand, 'arena, V> Kevvlfs<'brand, 'arena, V> { shell: own!(Shell), ) -> Self { Self { - body, edge, vertices, loop_, @@ -116,7 +110,6 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> { let Kevvlfs { - body, edge, vertices: [v1, v2], loop_, @@ -124,7 +117,7 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, shell, } = self; - mklens!(dcel, edge, loop_, face, shell, body, v1, v2); + mklens!(dcel, edge, loop_, face, shell, v1, v2); let [a, b] = edge.half_edges(); let edge_verts = edge.vertices(); @@ -149,7 +142,6 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, or_err(face.next() == face, KevvlfsError::ShellHasMoreThanOneFace)?; or_err(shell.faces() == face, KevvlfsError::ShellFaceMismatch)?; - or_err(shell.body() == body, KevvlfsError::ShellBodyMismatch)?; Ok(()) } @@ -161,7 +153,6 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, try_check!(self, dcel); let Kevvlfs { - body, edge, vertices, loop_, @@ -169,6 +160,7 @@ impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, shell, } = self; + let body = shell.body(dcel); body.remove_shell(*shell, dcel); edge.destroy(dcel); diff --git a/src/tests.rs b/src/tests.rs index 52ec2cd..5dc0a78 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -5,9 +5,9 @@ fn mev_cycle() { Dcel::<u32>::new(|mut dcel| { let body = dcel.new_body(); let op = dcel.mevvlfs(*body, [0, 1]).unwrap(); - let op2 = dcel.mev(*op.shell, *op.loop_, *op.vertices[1], 2); - let op3 = dcel.mev(*op.shell, *op.loop_, *op2.new_vertex, 3); - dcel.melf(*op.shell, [*op3.new_vertex, *op.vertices[0]], *op.loop_); + 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_); let mut vertices = op .loop_ @@ -50,17 +50,16 @@ fn make_hourglass<'brand, 'arena, V>( .. } = dcel.mevvlfs(*body, [d0, d1]).unwrap(); - let inner_2 = dcel.mev(*shell, *loop_0, *inner_1, d2).new_vertex; + 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 Mev { - new_vertex: outer_0, + let Kev { + vertex: outer_0, edge, - .. - } = dcel.mev(*shell, *outer_loop, *inner_0, d3); + } = dcel.mev(*outer_loop, *inner_0, d3).unwrap(); - let outer_1 = dcel.mev(*shell, *outer_loop, *outer_0, d4).new_vertex; - let outer_2 = dcel.mev(*shell, *outer_loop, *outer_1, d5).new_vertex; + 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) @@ -182,8 +181,8 @@ fn msev_ksev() { .. } = dcel.mevvlfs(*body, [0, 1]).unwrap(); - let out_2 = dcel.mev(*shell, *loop_0, *out_1, 2).new_vertex; - let out_3 = dcel.mev(*shell, *loop_0, *out_2, 3).new_vertex; + 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); let Melf { |