aboutsummaryrefslogtreecommitdiff
path: root/src/mevvlfs.rs
diff options
context:
space:
mode:
authorCharlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de>2024-03-07 21:52:30 +0100
committerCharlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de>2024-03-24 17:20:01 +0100
commit219261b7042fba1a54ecd478b56e902d9ca8787b (patch)
treeedbf297706624f2983e8f73c5e39d831c90ef65a /src/mevvlfs.rs
parent35cddacd85c61fd56032899d68b1c1c885377dda (diff)
downloaddcel-219261b7042fba1a54ecd478b56e902d9ca8787b.tar.xz
Diffstat (limited to 'src/mevvlfs.rs')
-rw-r--r--src/mevvlfs.rs184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/mevvlfs.rs b/src/mevvlfs.rs
new file mode 100644
index 0000000..370ad96
--- /dev/null
+++ b/src/mevvlfs.rs
@@ -0,0 +1,184 @@
+use crate::*;
+
+// Make Edge-Vertex-Vertex-Loop-Face-Shell
+
+pub struct Mevvlfs<'brand, 'arena, V> {
+ body: ptr!(Body),
+ data: [V; 2],
+}
+
+impl<'brand, 'arena, V> Mevvlfs<'brand, 'arena, V> {
+ pub fn new(body: ptr!(Body), data: [V; 2]) -> Self {
+ Self { body, data }
+ }
+}
+
+impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Mevvlfs<'brand, 'arena, V> {
+ type Inverse = Kevvlfs<'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>> {
+ try_check!(self, dcel);
+
+ let Mevvlfs {
+ body,
+ data: [d1, d2],
+ } = self;
+
+ let shell = body.add_new_shell(dcel);
+ let face = shell.add_new_face(dcel);
+ let (edge, [a, b]) = Edge::create(*shell, dcel);
+ let loop_ = Loop::new(dcel);
+ let v1 = shell.add_new_vertex(d1, dcel);
+ let v2 = shell.add_new_vertex(d2, dcel);
+
+ loop_.set_face(*face, dcel);
+ face.set_outer_loop(*loop_, dcel);
+
+ a.update_origin(*v1, dcel);
+ b.update_origin(*v2, dcel);
+
+ loop_.add_half_edge(a, dcel);
+ loop_.add_half_edge(b, dcel);
+
+ Ok(Kevvlfs {
+ body,
+ edge,
+ vertices: [v1, v2],
+ loop_,
+ face,
+ shell,
+ })
+ }
+}
+
+pub struct Kevvlfs<'brand, 'arena, V> {
+ pub body: ptr!(Body),
+ pub edge: own!(Edge),
+ pub vertices: [own!(Vertex); 2],
+ pub loop_: own!(Loop),
+ pub face: own!(Face),
+ pub shell: own!(Shell),
+}
+
+#[derive(Debug, Error)]
+pub enum KevvlfsError {
+ #[error("edge vertices do not equal vertices")]
+ EdgeVerticesMismatch,
+ #[error("half_edge loop does not equal loop")]
+ HalfEdgeLoopMismatch,
+ #[error("loop is not cycle between half edges")]
+ InvalidLoop,
+ #[error("face outer loop does not match loop")]
+ FaceOuterLoopMismatch,
+ #[error("face has inner loops")]
+ FaceHasInnerLoops,
+ #[error("shell has more than one face")]
+ 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),
+ face: own!(Face),
+ shell: own!(Shell),
+ ) -> Self {
+ Self {
+ body,
+ edge,
+ vertices,
+ loop_,
+ face,
+ shell,
+ }
+ }
+}
+
+impl<'brand, 'arena, V> Operator<'brand, 'arena, V> for Kevvlfs<'brand, 'arena, V> {
+ type Inverse = Mevvlfs<'brand, 'arena, V>;
+ type Error = KevvlfsError;
+ type Check = ();
+
+ fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error> {
+ let Kevvlfs {
+ body,
+ edge,
+ vertices: [v1, v2],
+ loop_,
+ face,
+ shell,
+ } = self;
+
+ mklens!(dcel, edge, loop_, face, shell, body, v1, v2);
+
+ let [a, b] = edge.half_edges();
+ let edge_verts = edge.vertices();
+
+ or_err(
+ edge_verts == [v1, v2] || edge_verts == [v2, v1],
+ KevvlfsError::EdgeVerticesMismatch,
+ )?;
+
+ or_err(a.loop_() == loop_, KevvlfsError::HalfEdgeLoopMismatch)?;
+ or_err(a.next() == b, KevvlfsError::InvalidLoop)?;
+ or_err(b.next() == a, KevvlfsError::InvalidLoop)?;
+
+ or_err(
+ face.outer_loop() == loop_,
+ KevvlfsError::FaceOuterLoopMismatch,
+ )?;
+ or_err(
+ face.maybe_inner_loops().is_none(),
+ KevvlfsError::FaceHasInnerLoops,
+ )?;
+
+ or_err(face.next() == face, KevvlfsError::ShellHasMoreThanOneFace)?;
+ or_err(shell.faces() == face, KevvlfsError::ShellFaceMismatch)?;
+ or_err(shell.body() == body, KevvlfsError::ShellBodyMismatch)?;
+
+ Ok(())
+ }
+
+ fn apply(
+ self,
+ dcel: &mut Dcel<'brand, 'arena, V>,
+ ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>> {
+ try_check!(self, dcel);
+
+ let Kevvlfs {
+ body,
+ edge,
+ vertices,
+ loop_,
+ face,
+ shell,
+ } = self;
+
+ body.remove_shell(*shell, dcel);
+
+ edge.destroy(dcel);
+ loop_.free(dcel);
+ face.free(dcel);
+ shell.free(dcel);
+
+ Ok(Mevvlfs {
+ body,
+ data: vertices.map(|v| v.destroy(dcel)),
+ })
+ }
+}