aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de>2024-03-13 12:47:21 +0100
committerCharlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de>2024-03-24 17:20:04 +0100
commit6a7d3ec46347d06d70e08577f688ec5b534e2c08 (patch)
tree2c599c12e22975b5d830282f400ae25442af00f9
parentc7be7ca0188e8edd19afd880f393d5622451fef5 (diff)
downloaddcel-6a7d3ec46347d06d70e08577f688ec5b534e2c08.tar.xz
-rw-r--r--src/main.rs70
-rw-r--r--src/mev.rs140
-rw-r--r--src/mevvlfs.rs16
-rw-r--r--src/tests.rs23
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 {