diff options
author | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-23 16:54:20 +0100 |
---|---|---|
committer | Charlotte Pabst <charlotte.pabst@stud.tu-darmstadt.de> | 2024-03-24 17:20:06 +0100 |
commit | 4b7532ca0d6ff21d5531febb749b43112d0451e8 (patch) | |
tree | 32e0edf6ea7e8af90c475262da8007c1b4e15ca8 /src/lib.rs | |
parent | 0a922773a37f6a6a0d73ee0c1fa884e90e5f0f1d (diff) | |
download | dcel-4b7532ca0d6ff21d5531febb749b43112d0451e8.tar.xz |
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 1044 |
1 files changed, 1044 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6b0542e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,1044 @@ +#![allow(private_bounds)] + +use core::ops::Deref; +pub use ghost_cell::{GhostBorrow, GhostCell, GhostToken}; +use paste::paste; +use std::{ + collections::HashMap, + convert::Infallible, + fmt::{self, Debug, Display, Formatter}, + hash::{Hash, Hasher}, +}; +use thiserror::Error; +pub use typed_arena::Arena; + +macro_rules! try_check { + ($this:ident, $dcel:ident) => { + match $this.check($dcel) { + Ok(x) => x, + Err(e) => return Err(OperatorErr::new($this, e)), + } + }; +} + +#[macro_use] +mod entity; +use entity::*; + +mod entity_iterator; +pub use entity_iterator::*; + +mod dot; +pub use dot::*; + +#[cfg(feature = "img")] +mod img; + +#[cfg(feature = "img")] +pub use img::*; + +mod obj_export; +pub use obj_export::*; + +#[cfg(feature = "obj_import")] +mod obj_import; + +#[cfg(feature = "obj_import")] +pub use obj_import::*; + +#[cfg(test)] +mod tests; + +mod mevvlfs; +pub use mevvlfs::*; + +mod mev; +pub use mev::*; + +mod mve; +pub use mve::*; + +mod melf; +pub use melf::*; + +mod mekh; +pub use mekh::*; + +mod msev; +pub use msev::*; + +mod mpkh; +pub use mpkh::*; + +pub trait ReflAsRef<T> { + fn as_ref(&self) -> &T; +} + +impl<T> ReflAsRef<T> for T { + fn as_ref(&self) -> &T { + self + } +} + +pub trait ReflAsMut<T>: ReflAsRef<T> { + fn as_mut(&mut self) -> &mut T; +} + +impl<T> ReflAsMut<T> for T { + fn as_mut(&mut self) -> &mut T { + self + } +} + +struct DisplayFn<F: Fn(&mut Formatter) -> fmt::Result>(F); +impl<F: Fn(&mut Formatter) -> fmt::Result> Display for DisplayFn<F> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + self.0(f) + } +} +impl<F: Fn(&mut Formatter) -> fmt::Result> Debug for DisplayFn<F> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + self.0(f) + } +} + +#[macro_export] +macro_rules! ptr_t { + ($T:ty) => { + Ptr<'brand, 'arena, $T> + } +} + +#[macro_export] +macro_rules! ptr { + ($T:ident) => { + Ptr<'brand, 'arena, $T<'brand, 'arena, V>> + }; +} + +#[macro_export] +macro_rules! own_t { + ($T:ty) => { + Own<'brand, 'arena, $T> + } +} + +#[macro_export] +macro_rules! own { + ($T:ident) => { + Own<'brand, 'arena, $T<'brand, 'arena, V>> + }; +} + +#[macro_export] +macro_rules! lens_t { + ($T:ty) => { + Lens<'tok, 'brand, 'arena, $T> + } +} + +#[macro_export] +macro_rules! lens { + ($T:ident) => { + Lens<'tok, 'brand, 'arena, $T<'brand, 'arena, V>> + }; +} + +#[macro_export] +macro_rules! mklens { + ($token: expr, $($name:ident),*) => { + $( let $name = $name.lens($token); )* + }; +} + +fn short_debug_(ty: &'static str, id: usize, f: &mut Formatter) -> fmt::Result { + f.debug_tuple(ty).field(&id).finish() +} + +fn short_debug<'tok, 'brand, 'arena, T: Entity<'brand, 'arena>>( + x: lens_t!(T), + f: &mut Formatter, +) -> fmt::Result { + short_debug_(T::type_name(), x.id(), f) +} + +fn short_debug_fn<'tok, 'brand, 'arena, T: Entity<'brand, 'arena>>(x: lens_t!(T)) -> impl Debug { + let id = x.id(); + DisplayFn(move |f| short_debug_(T::type_name(), id, f)) +} + +fn short_debug_list<'tok, 'brand, 'arena, T, I>(iter: I, f: &mut Formatter) -> fmt::Result +where + 'brand: 'tok + 'arena, + T: Entity<'brand, 'arena> + 'arena, + I: Iterator<Item = lens_t!(T)>, +{ + f.debug_list().entries(iter.map(short_debug_fn)).finish() +} + +fn or_err<T>(cond: bool, err: T) -> Result<(), T> { + if cond { + Ok(()) + } else { + Err(err) + } +} + +pub struct Ptr<'brand, 'arena, T>(pub &'arena GhostCell<'brand, T>); + +impl<'brand, 'arena, T> Clone for ptr_t!(T) { + fn clone(&self) -> Self { + Self(self.0) + } +} +impl<'brand, 'arena, T> Copy for ptr_t!(T) {} + +impl<'brand, 'arena, T> ptr_t!(T) { + pub fn borrow<'tok, 'out>(self, token: &'tok impl ReflAsRef<GhostToken<'brand>>) -> &'out T + where + 'arena: 'out, + 'tok: 'out, + { + self.0.borrow(token.as_ref()) + } + + pub fn borrow_mut<'tok, 'out>( + self, + token: &'tok mut impl ReflAsMut<GhostToken<'brand>>, + ) -> &'out mut T + where + 'arena: 'out, + 'tok: 'out, + { + self.0.borrow_mut(token.as_mut()) + } + + pub fn lens<'tok>(self, token: &'tok impl ReflAsRef<GhostToken<'brand>>) -> lens_t!(T) { + Lens::new(self, token) + } +} + +#[allow(unused)] +impl<'brand, 'arena, T: Entity<'brand, 'arena>> ptr_t!(T) { + fn clear(self, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.borrow_mut(token).clear() + } + + pub fn id(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> usize { + self.borrow(token).id() + } + fn maybe_id(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> Option<usize> { + self.borrow(token).maybe_id() + } + fn alive(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> bool { + self.borrow(token).alive() + } + + pub fn eq(self, other: Self, token: &impl ReflAsRef<GhostToken<'brand>>) -> bool { + self.borrow(token) == other.borrow(token) + } + + fn next(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> Self { + self.borrow(token).next() + } + fn maybe_next(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> Option<Self> { + self.borrow(token).maybe_next() + } + fn set_next(self, x: Self, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.borrow_mut(token).set_next(x) + } + fn set_next_opt(self, x: Option<Self>, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.borrow_mut(token).set_next_opt(x) + } + + fn prev(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> Self { + self.borrow(token).prev() + } + fn maybe_prev(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> Option<Self> { + self.borrow(token).maybe_prev() + } + fn set_prev(self, x: Self, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.borrow_mut(token).set_prev(x) + } + fn set_prev_opt(self, x: Option<Self>, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.borrow_mut(token).set_prev_opt(x) + } +} + +pub struct Own<'brand, 'arena, T>(ptr_t!(T)); + +impl<'brand, 'arena, T> Own<'brand, 'arena, T> { + // avoid this + pub fn unsafe_make_owned(this: ptr_t!(T)) -> Self { + Self(this) + } +} + +impl<'brand, 'arena, T> Deref for own_t!(T) { + type Target = ptr_t!(T); + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct Lens<'tok, 'brand, 'arena, T> { + pub item: ptr_t!(T), + pub token: &'tok GhostToken<'brand>, +} + +impl<'tok, 'brand, 'arena, T> Clone for lens_t!(T) { + fn clone(&self) -> Self { + Self::new(self.item, self.token) + } +} +impl<'tok, 'brand, 'arena, T> Copy for lens_t!(T) {} + +impl<'tok, 'brand, 'arena, T: PartialEq> PartialEq for lens_t!(T) { + fn eq(&self, other: &Self) -> bool { + self.item.borrow(self.token) == other.item.borrow(other.token) + } +} +impl<'tok, 'brand, 'arena, T: PartialEq> Eq for lens_t!(T) {} + +impl<'tok, 'brand, 'arena, T: Hash> Hash for lens_t!(T) { + fn hash<H: Hasher>(&self, state: &mut H) { + self.item.borrow(self.token).hash(state); + } +} + +impl<'tok, 'brand, 'arena, T> ReflAsRef<GhostToken<'brand>> for lens_t!(T) { + fn as_ref(&self) -> &GhostToken<'brand> { + &self.token + } +} + +impl<'tok, 'brand, 'arena, T> From<lens_t!(T)> for ptr_t!(T) { + fn from(x: lens_t!(T)) -> Self { + x.item + } +} + +impl<'tok, 'brand, 'arena, T> lens_t!(T) { + pub fn new(item: ptr_t!(T), token: &'tok impl ReflAsRef<GhostToken<'brand>>) -> Self { + Self { + item, + token: token.as_ref(), + } + } +} + +#[allow(unused)] +impl<'tok, 'brand, 'arena, T: Entity<'brand, 'arena>> lens_t!(T) { + pub fn id(self) -> usize { + self.item.id(&self) + } + fn maybe_id(self) -> Option<usize> { + self.item.maybe_id(&self) + } + fn alive(self) -> bool { + self.item.alive(&self) + } + + pub fn eq(self, other: ptr_t!(T)) -> bool { + self.item.eq(other, &self) + } + + fn next(self) -> Self { + self.item.next(&self).lens(self.token) + } + fn maybe_next(self) -> Option<Self> { + self.item.maybe_next(&self).map(|x| x.lens(self.token)) + } + + fn prev(self) -> Self { + self.item.prev(self.token).lens(self.token) + } + fn maybe_prev(self) -> Option<Self> { + self.item.maybe_prev(&self).map(|x| x.lens(self.token)) + } +} + +entity!(vertex: Vertex (init: V), + data: Option<V> = Some(init); + outgoing: HalfEdge +); + +pub struct OutgoingIterator<'tok, 'brand, 'arena, V>(Option<(lens!(HalfEdge), lens!(HalfEdge))>); + +impl<'tok, 'brand, 'arena, V> Clone for OutgoingIterator<'tok, 'brand, 'arena, V> { + fn clone(&self) -> Self { + Self(self.0) + } +} + +impl<'tok, 'brand, 'arena, V> Copy for OutgoingIterator<'tok, 'brand, 'arena, V> {} + +impl<'tok, 'brand, 'arena, V> OutgoingIterator<'tok, 'brand, 'arena, V> { + fn new(start: Option<ptr!(HalfEdge)>, token: &'tok impl ReflAsRef<GhostToken<'brand>>) -> Self { + Self(start.map(|s| { + let l = Lens::new(s, token); + (l, l) + })) + } +} + +impl<'tok, 'brand, 'arena, V> Iterator for OutgoingIterator<'tok, 'brand, 'arena, V> { + type Item = lens!(HalfEdge); + + fn next(&mut self) -> Option<Self::Item> { + let range = self.0.as_mut()?; + let ret = range.0; + + range.0 = range.0.twin().next(); + if range.0 == range.1 { + self.0 = None; + } + + Some(ret) + } +} + +impl<'brand, 'arena, V> own!(Vertex) { + fn destroy(self, dcel: &mut Dcel<'brand, 'arena, V>) -> V { + let data = self.borrow_mut(dcel).data.take().unwrap(); + self.free(dcel); + data + } +} + +impl<'brand, 'arena, V> ptr!(Vertex) { + pub fn data<'tok, 'out>(self, token: &'tok impl ReflAsRef<GhostToken<'brand>>) -> &'out V + where + 'arena: 'out, + 'tok: 'out, + { + self.borrow(token).data.as_ref().unwrap() + } + + pub fn mut_data<'tok, 'out>( + self, + token: &'tok mut impl ReflAsMut<GhostToken<'brand>>, + ) -> &'out mut V + where + 'arena: 'out, + 'tok: 'out, + { + self.borrow_mut(token).data.as_mut().unwrap() + } + + pub fn iter_outgoing<'tok>( + self, + token: &'tok impl ReflAsRef<GhostToken<'brand>>, + ) -> OutgoingIterator<'tok, 'brand, 'arena, V> { + // FIXME: maybe enforce at least one item by using .outgoing() + // there should be no "standalone" vertices (?) + OutgoingIterator::new(self.maybe_outgoing(token), token) + } + + pub fn find_outgoing( + self, + loop_: ptr!(Loop), + token: &impl ReflAsRef<GhostToken<'brand>>, + ) -> Option<ptr!(HalfEdge)> { + self.lens(token).find_outgoing(loop_).map(|x| x.item) + } +} + +impl<'tok, 'brand, 'arena, V> lens!(Vertex) { + pub fn data(&self) -> &V { + self.item.data(self) + } + + pub fn iter_outgoing(self) -> OutgoingIterator<'tok, 'brand, 'arena, V> { + self.item.iter_outgoing(self.token) + } + + pub fn find_outgoing(self, loop_: ptr!(Loop)) -> Option<lens!(HalfEdge)> { + self.iter_outgoing().find(|x| x.loop_().eq(loop_)) + } + + fn debug_data(self, f: &mut Formatter) -> fmt::Result + where + V: Debug, + { + self.data().fmt(f) + } +} + +// TODO: target +entity!(half_edge: HalfEdge; + pub origin: Vertex, + pub twin: HalfEdge, + pub loop_: Loop, + pub edge: Edge +); + +impl<'brand, 'arena, V> ptr!(HalfEdge) { + pub fn target(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> ptr!(Vertex) { + self.twin(token).origin(token) + } + + fn update_origin(self, v: ptr!(Vertex), token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.set_origin(v, token); + v.set_outgoing(self, token); + } +} + +impl<'tok, 'brand, 'arena, V> lens!(HalfEdge) { + pub fn target(self) -> lens!(Vertex) { + self.item.target(&self).lens(self.token) + } +} + +entity!(loop_: Loop; + half_edges[half_edge: half_edge back]: HalfEdge, + pub face: Face +); + +impl<'brand, 'arena, V> ptr!(Loop) { + pub fn is_outer(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> bool { + self.lens(token).is_outer() + } + + fn update_connectivity(self, token: &mut impl ReflAsMut<GhostToken<'brand>>) { + self.iter_mut_half_edges(token, |x, token| x.set_loop_(self, token)); + } +} + +impl<'tok, 'brand, 'arena, V> lens!(Loop) { + pub fn is_outer(self) -> bool { + self.face().outer_loop() == self + } +} + +entity!(edge: Edge, + half_edges: [Option<own!(HalfEdge)>; 2] = [None, None] +); + +impl<'brand, 'arena, V> Edge<'brand, 'arena, V> { + fn create( + shell: ptr!(Shell), + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> (own!(Edge), [ptr!(HalfEdge); 2]) { + let edge = shell.add_new_edge(dcel); + + let he1_own = HalfEdge::new(dcel); + let he2_own = HalfEdge::new(dcel); + + let he1 = *he1_own; + let he2 = *he2_own; + + edge.borrow_mut(dcel).half_edges = [Some(he1_own), Some(he2_own)]; + // edge.set_half_edges([he1_own, he2_own], dcel); + + he1.set_twin(he2, dcel); + he2.set_twin(he1, dcel); + he1.set_edge(*edge, dcel); + he2.set_edge(*edge, dcel); + + (edge, [he1, he2]) + } +} + +impl<'brand, 'arena, V> own!(Edge) { + fn destroy(self, dcel: &mut Dcel<'brand, 'arena, V>) { + for x in self + .borrow_mut(dcel) + .half_edges + .each_mut() + .map(Option::take) + .into_iter() + .flatten() + { + x.free(dcel); + } + self.free(dcel); + } +} + +impl<'brand, 'arena, V> ptr!(Edge) { + pub fn half_edges(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> [ptr!(HalfEdge); 2] { + self.borrow(token) + .half_edges + .each_ref() + .map(|x| *x.as_deref().unwrap()) + } + + pub fn vertices(self, token: &impl ReflAsRef<GhostToken<'brand>>) -> [ptr!(Vertex); 2] { + self.half_edges(token).map(|x| x.origin(token)) + } + + /* + fn set_half_edges( + self, + x: [own!(HalfEdge); 2], + token: &mut impl ReflAsMut<GhostToken<'brand>>, + ) { + self.borrow_mut(token).half_edges = Some(x); + }*/ +} + +impl<'tok, 'brand, 'arena, V> lens!(Edge) { + pub fn half_edges(self) -> [lens!(HalfEdge); 2] { + self.item.half_edges(self.token).map(|x| x.lens(self.token)) + } + + pub fn vertices(self) -> [lens!(Vertex); 2] { + self.item.vertices(self.token).map(|x| x.lens(self.token)) + } + + fn debug_half_edges(self, f: &mut Formatter) -> fmt::Result + where + V: Debug, + { + f.debug_list().entries(self.half_edges()).finish() + } +} + +entity!(face: Face; + pub outer_loop: Loop, + inner_loops[inner_loop: loop_ back]: Loop, + pub shell: Shell +); + +impl<'brand, 'arena, V> own!(Face) { + fn destroy(self, dcel: &mut Dcel<'brand, 'arena, V>) { + Own::unsafe_make_owned(self.outer_loop(dcel)).free(dcel); + self.iter_mut_inner_loops(dcel, |x, dcel| { + Own::unsafe_make_owned(x).free(dcel); + }); + self.free(dcel); + } +} + +entity!(shell: Shell; + faces[face: face back]: Face, + edges[edge: edge]: Edge, + vertices[vertex: vertex (V)]: Vertex, + pub body: Body +); + +impl<'brand, 'arena, V> own!(Shell) { + fn destroy(self, dcel: &mut Dcel<'brand, 'arena, V>) { + self.iter_mut_faces(dcel, |x, dcel| { + Own::unsafe_make_owned(x).destroy(dcel); + }); + self.iter_mut_edges(dcel, |x, dcel| { + Own::unsafe_make_owned(x).destroy(dcel); + }); + self.iter_mut_vertices(dcel, |x, dcel| { + Own::unsafe_make_owned(x).destroy(dcel); + }); + self.free(dcel); + } +} + +entity!(body: Body; + shells[shell: shell back]: Shell +); + +impl<'brand, 'arena, V> own!(Body) { + fn destroy(self, dcel: &mut Dcel<'brand, 'arena, V>) { + self.iter_mut_shells(dcel, |x, dcel| { + Own::unsafe_make_owned(x).destroy(dcel); + }); + dcel.delete_body(self); + } +} + +struct Allocator<'brand, 'arena, T: Entity<'brand, 'arena>> { + next_id: usize, + arena: &'arena Arena<T>, + freelist: Vec<own_t!(T)>, +} + +impl<'brand, 'arena, T: Entity<'brand, 'arena>> Allocator<'brand, 'arena, T> { + fn new(arena: &'arena Arena<T>) -> Self { + Self { + next_id: 0, + arena, + freelist: Vec::new(), + } + } + + fn next_id(&mut self) -> usize { + let id = self.next_id; + self.next_id += 1; + id + } + + fn alloc(&mut self, x: T, token: &mut impl ReflAsMut<GhostToken<'brand>>) -> own_t!(T) { + if let Some(ptr) = self.freelist.pop() { + *ptr.borrow_mut(token) = x; + ptr + } else { + Own::unsafe_make_owned(Ptr(GhostCell::from_mut(self.arena.alloc(x)))) + } + } + + fn free(&mut self, token: &mut impl ReflAsMut<GhostToken<'brand>>, ptr: own_t!(T)) { + debug_assert!(ptr.alive(token), "double free"); + ptr.clear(token); + self.freelist.push(ptr); + } +} + +pub struct OperatorErr<T, E> { + pub op: T, + pub err: E, +} + +impl<T, E> OperatorErr<T, E> { + pub fn new(op: T, err: E) -> Self { + Self { op, err } + } +} + +impl<T, E: std::error::Error> std::error::Error for OperatorErr<T, E> {} +impl<T, E: Debug> Debug for OperatorErr<T, E> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + self.err.fmt(f) + } +} +impl<T, E: Display> Display for OperatorErr<T, E> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + self.err.fmt(f) + } +} + +pub trait Operator<'brand, 'arena, V>: Sized { + type Inverse: Operator<'brand, 'arena, V>; + type Error: std::error::Error; + type Check; + + fn check(&self, dcel: &Dcel<'brand, 'arena, V>) -> Result<Self::Check, Self::Error>; + + fn apply( + self, + dcel: &mut Dcel<'brand, 'arena, V>, + ) -> Result<Self::Inverse, OperatorErr<Self, Self::Error>>; +} + +pub struct DcelArena<'brand, 'arena, V> { + pub vertex: Arena<Vertex<'brand, 'arena, V>>, + pub half_edge: Arena<HalfEdge<'brand, 'arena, V>>, + pub loop_: Arena<Loop<'brand, 'arena, V>>, + pub edge: Arena<Edge<'brand, 'arena, V>>, + pub face: Arena<Face<'brand, 'arena, V>>, + pub shell: Arena<Shell<'brand, 'arena, V>>, + pub body: Arena<Body<'brand, 'arena, V>>, +} + +impl<'brand, 'arena, V> Default for DcelArena<'brand, 'arena, V> { + fn default() -> Self { + Self { + vertex: Default::default(), + half_edge: Default::default(), + loop_: Default::default(), + edge: Default::default(), + face: Default::default(), + shell: Default::default(), + body: Default::default(), + } + } +} + +pub struct Dcel<'brand, 'arena, V> { + pub token: GhostToken<'brand>, + vertex: Allocator<'brand, 'arena, Vertex<'brand, 'arena, V>>, + half_edge: Allocator<'brand, 'arena, HalfEdge<'brand, 'arena, V>>, + loop_: Allocator<'brand, 'arena, Loop<'brand, 'arena, V>>, + edge: Allocator<'brand, 'arena, Edge<'brand, 'arena, V>>, + face: Allocator<'brand, 'arena, Face<'brand, 'arena, V>>, + shell: Allocator<'brand, 'arena, Shell<'brand, 'arena, V>>, + body: Allocator<'brand, 'arena, Body<'brand, 'arena, V>>, + bodies: Option<ptr!(Body)>, +} + +impl<'brand, 'arena, V> ReflAsRef<GhostToken<'brand>> for Dcel<'brand, 'arena, V> { + fn as_ref(&self) -> &GhostToken<'brand> { + &self.token + } +} + +impl<'brand, 'arena, V> ReflAsMut<GhostToken<'brand>> for Dcel<'brand, 'arena, V> { + fn as_mut(&mut self) -> &mut GhostToken<'brand> { + &mut self.token + } +} + +impl<'brand, 'arena, V> Dcel<'brand, 'arena, V> { + pub fn from_token(token: GhostToken<'brand>, ar: &'arena DcelArena<'brand, 'arena, V>) -> Self { + Self { + token, + bodies: None, + vertex: Allocator::new(&ar.vertex), + half_edge: Allocator::new(&ar.half_edge), + loop_: Allocator::new(&ar.loop_), + edge: Allocator::new(&ar.edge), + face: Allocator::new(&ar.face), + shell: Allocator::new(&ar.shell), + body: Allocator::new(&ar.body), + } + } + + pub fn new<R, F>(fun: F) -> R + where + for<'new_brand, 'new_arena> F: FnOnce(Dcel<'new_brand, 'new_arena, V>) -> R, + { + GhostToken::new(|token| { + let arena = DcelArena::default(); + let dcel = Dcel::from_token(token, &arena); + + fun(dcel) + }) + } + + pub fn new_body(&mut self) -> own!(Body) { + let body = Body::new(self); + self.bodies = Some(Entity::list_add(*body, self.bodies, self)); + body + } + + pub fn delete_body(&mut self, body: own!(Body)) { + self.bodies = Entity::list_remove(*body, self); + body.free(self); + } + + pub fn iter_bodies<'tok>( + &'tok self, + ) -> EntityIterator<'tok, 'brand, 'arena, Body<'brand, 'arena, V>> { + EntityIterator::new(self.bodies, self) + } + + // fn new_edge(&mut self, shell: ptr!(Shell)) -> (own!(Edge), [ptr!(HalfEdge); 2]) {} + + fn follow(&mut self, prev: ptr!(HalfEdge), next: ptr!(HalfEdge)) { + next.set_prev(prev, self); + prev.set_next(next, self); + } + + pub fn mevvlfs( + &mut self, + body: ptr!(Body), + data: [V; 2], + ) -> Result<Kevvlfs<'brand, 'arena, V>, OperatorErr<Mevvlfs<'brand, 'arena, V>, Infallible>> + { + Mevvlfs::new(body, data).apply(self) + } + + pub fn kevvlfs( + &mut self, + edge: own!(Edge), + vertices: [own!(Vertex); 2], + loop_: own!(Loop), + face: own!(Face), + shell: own!(Shell), + ) -> Result<Mevvlfs<'brand, 'arena, V>, OperatorErr<Kevvlfs<'brand, 'arena, V>, KevvlfsError>> + { + Kevvlfs::new(edge, vertices, loop_, face, shell).apply(self) + } + + pub fn mev( + &mut self, + loop_: ptr!(Loop), + vertex: ptr!(Vertex), + data: V, + ) -> Result<Kev<'brand, 'arena, V>, OperatorErr<Mev<'brand, 'arena, V>, MevError>> { + Mev::new(loop_, vertex, data).apply(self) + } + + 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( + &mut self, + vertices: [ptr!(Vertex); 2], + 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, + edge: ptr!(Edge), + data: V, + ) -> Result<Kve<'brand, 'arena, V>, OperatorErr<Mve<'brand, 'arena, V>, Infallible>> { + Mve::new(edge, data).apply(self) + } + + 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( + &mut self, + shell: ptr!(Shell), + into_loop: ptr!(Loop), + into_vertex: ptr!(Vertex), + hole_loop: own!(Loop), + hole_vertex: ptr!(Vertex), + ) -> Result<Kemh<'brand, 'arena, V>, OperatorErr<Mekh<'brand, 'arena, V>, MekhError>> { + Mekh::new(shell, into_loop, into_vertex, hole_loop, hole_vertex).apply(self) + } + + pub fn kemh( + &mut self, + shell: ptr!(Shell), + edge: own!(Edge), + loop_: ptr!(Loop), + hole_vertex: ptr!(Vertex), + ) -> Result<Mekh<'brand, 'arena, V>, OperatorErr<Kemh<'brand, 'arena, V>, KemhError>> { + Kemh::new(shell, edge, loop_, hole_vertex).apply(self) + } + + pub fn msev( + &mut self, + shell: ptr!(Shell), + vertex: ptr!(Vertex), + loops: [ptr!(Loop); 2], + data: V, + ) -> Result<Ksev<'brand, 'arena, V>, OperatorErr<Msev<'brand, 'arena, V>, MsevError>> { + Msev::new(shell, vertex, loops, data).apply(self) + } + + pub fn ksev( + &mut self, + shell: ptr!(Shell), + loops: [ptr!(Loop); 2], + old_vertex: ptr!(Vertex), + new_vertex: own!(Vertex), + edge: own!(Edge), + ) -> Result<Msev<'brand, 'arena, V>, OperatorErr<Ksev<'brand, 'arena, V>, KsevError>> { + Ksev::new(shell, loops, old_vertex, new_vertex, edge).apply(self) + } + + pub fn mpkh( + &mut self, + loop_: ptr!(Loop), + ) -> Result<Kpmh<'brand, 'arena, V>, OperatorErr<Mpkh<'brand, 'arena, V>, MpkhError>> { + Mpkh::new(loop_).apply(self) + } + + pub fn kpmh( + &mut self, + new_shell: Option<own!(Shell)>, + old_face: ptr!(Face), + new_face: own!(Face), + ) -> Result<Mpkh<'brand, 'arena, V>, OperatorErr<Kpmh<'brand, 'arena, V>, KpmhError>> { + Kpmh::new(new_shell, old_face, new_face).apply(self) + } +} + +use std::io::Write; + +fn _main() { + let show = |name, dcel: &Dcel<(&'static str, [i64; 2])>| { + write!( + &mut std::fs::File::create(name).unwrap(), + "{}", + DisplayFn(|f: &mut fmt::Formatter<'_>| dcel_write_dot( + dcel, + |v| v.1.map(|x| x as _), + |v, f| write!(f, "{}", v.0), + f, + DcelDotOptions { + prev: false, + next: true, + twin: true, + } + )) + ) + .unwrap(); + }; + + GhostToken::new(|token| { + let arena = DcelArena::default(); + let mut dcel = Dcel::from_token(token, &arena); + + let body = dcel.new_body(); + // Mevvlfs(a, [w, n], l, f, s) + + //let op = dcel.mevvlfs(*body, [("W", [-4, 0]), ("N", [0, 4])]); + let op = dcel + .mevvlfs(*body, [("W", [-4, 0]), ("N", [0, 4])]) + .unwrap(); + 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([*op3.vertex, *op.vertices[0]], *op.loop_) + .unwrap(); + dcel.melf([*op.vertices[0], *op2.vertex], *op.loop_) + .unwrap(); + + show("cool_stuff.dot", &dcel); + + /*println!("{:?}", op.edge.lens(&dcel)); + println!("{:?}", op.vertices[0].lens(&dcel)); + println!("{:?}", op.vertices[1].lens(&dcel)); + println!("{:?}", op.loop_.lens(&dcel)); + println!("{:?}", op.face.lens(&dcel)); + println!("{:?}", op.shell.lens(&dcel));*/ + + //dbg!(body.lens(&dcel)); + + // dcel.undo(op); + + /* + + let (a, [w, n], _) = dcel.mevvls([("W", [-4, 0]), ("N", [0, 4])]); + show("1.dot", &dcel); + + let b = dcel.mve(a, ("E", [4, 0])).unwrap().0; + show("2.dot", &dcel); + + dcel.mve(a, ("S", [0, -4])).unwrap(); + show("3.dot", &dcel); + + //dcel.mel(w, n); + show("4.dot", &dcel);*/ + + /* + eprintln!( + "{} {}", + a.borrow(&dcel.token).id.unwrap(), + b.borrow(&dcel.token).id.unwrap() + );*/ + + /* + print!( + "{}", + "{}", + layFn(|f: &mut fmt::Formatter<'_>| { + v in dcel.vertices.elements.iter() { + } + + + h in dcel.half_edges.elements.iter() { + } + + Ok(()) + }) + }) + );*/ + }); +} |