spade/delaunay_core/handles/
handle_defs.rs

1use core::convert::TryInto;
2
3use super::super::Dcel;
4use super::public_handles::{InnerOuterMarker, PossiblyOuterTag};
5use super::FixedVertexHandle;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10pub trait DelaunayElementType: Sized + Default {
11    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize;
12}
13/// Internal type definition that is only exposed for documentation purposes.
14///
15/// Rust will currently not generate documentation for type definitions depending on
16/// `pub(crate)` types, see [#32077](https://github.com/rust-lang/rust/issues/32077).
17///
18/// Do not use these types. Their removal will not be considered a breaking change.
19#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[cfg_attr(
21    feature = "serde",
22    derive(Serialize, Deserialize),
23    serde(crate = "serde")
24)]
25pub struct FixedHandleImpl<Type, InnerOuter: InnerOuterMarker> {
26    index: u32,
27    ty: Type,
28    inner_outer: InnerOuter,
29}
30
31impl<Type, InnerOuter: InnerOuterMarker> core::fmt::Debug for FixedHandleImpl<Type, InnerOuter> {
32    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33        f.debug_struct("FixedHandle")
34            .field("index", &self.index)
35            .finish()
36    }
37}
38
39pub const fn new_fixed_face_handle(index: usize) -> FixedHandleImpl<FaceTag, PossiblyOuterTag> {
40    FixedHandleImpl {
41        index: index as u32,
42        ty: FaceTag,
43        inner_outer: PossiblyOuterTag,
44    }
45}
46
47impl FixedVertexHandle {
48    /// Creates a new vertex handle from a `usize`.
49    ///
50    /// Ideally, this method should only be used in advanced scenarios as it allows to create
51    /// invalid vertex handles. When possible, attempt to retrieve handles by other means
52    /// instead (see [crate::handles]).
53    ///
54    /// # Panics
55    ///
56    /// Panics if `index >= 2^32`
57    pub fn from_index(index: usize) -> Self {
58        // Preferably, `new` would simply be public. However, that would allow to create a handle
59        // to the outer face marked with `InnerTag` which is bad. Let's only allow vertices for now.
60        Self::new(index)
61    }
62}
63
64impl<Type: Default, InnerOuter: InnerOuterMarker> FixedHandleImpl<Type, InnerOuter> {
65    pub(crate) fn new(index: usize) -> Self {
66        Self::new_internal(
67            index
68                .try_into()
69                .expect("Index too big - at most 2^32 elements supported"),
70        )
71    }
72
73    pub(crate) fn max() -> Self {
74        Self::new_internal(u32::MAX)
75    }
76
77    /// Returns the internal index of this element.
78    ///
79    /// Indices of the same handle type are guaranteed to be unique (e.g. different vertices will
80    /// have different indices from each other).
81    ///
82    /// Indices will always be in the interval `0` .. `number_of_elements` (e.g. the number of
83    /// directed edges).
84    ///
85    /// Adding vertices will not change any indices. Vertex removal does affect indices -
86    /// the index of elements may change to swap-fill any gaps that were created.
87    pub fn index(&self) -> usize {
88        self.index as usize
89    }
90
91    pub(crate) fn adjust_inner_outer<TargetInnerOuter: InnerOuterMarker>(
92        &self,
93    ) -> FixedHandleImpl<Type, TargetInnerOuter> {
94        FixedHandleImpl::<_, _>::new_internal(self.index)
95    }
96
97    fn new_internal(index: u32) -> Self {
98        Self {
99            index,
100            ty: Type::default(),
101            inner_outer: InnerOuter::default(),
102        }
103    }
104}
105
106/// Internal type definition that is only exposed for documentation purposes.
107///
108/// Rust will currently not generate documentation for type definitions depending on
109/// `pub(crate)` types, see [#32077](https://github.com/rust-lang/rust/issues/32077).
110///
111/// Do not use these types. Their removal from the public API will not be considered a
112/// breaking change.
113///
114/// Refer to the [handles](crate::handles) module for the handle types that should be used
115/// instead.
116pub struct DynamicHandleImpl<'a, V, DE, UE, F, Type, InnerOuter: InnerOuterMarker> {
117    pub(super) dcel: &'a Dcel<V, DE, UE, F>,
118    pub(super) handle: FixedHandleImpl<Type, InnerOuter>,
119}
120
121impl<'a, V, DE, UE, F, Type: Default, InnerOuter: InnerOuterMarker>
122    DynamicHandleImpl<'a, V, DE, UE, F, Type, InnerOuter>
123{
124    #[inline]
125    pub(crate) fn new(
126        dcel: &'a Dcel<V, DE, UE, F>,
127        handle: FixedHandleImpl<Type, InnerOuter>,
128    ) -> Self {
129        Self { dcel, handle }
130    }
131
132    pub(in super::super) fn adjust_inner_outer<TargetInnerOuter: InnerOuterMarker>(
133        &self,
134    ) -> DynamicHandleImpl<'a, V, DE, UE, F, Type, TargetInnerOuter> {
135        DynamicHandleImpl::new(self.dcel, self.handle.adjust_inner_outer())
136    }
137}
138
139#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
140#[cfg_attr(
141    feature = "serde",
142    derive(Serialize, Deserialize),
143    serde(crate = "serde")
144)]
145pub struct VertexTag;
146#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
147#[cfg_attr(
148    feature = "serde",
149    derive(Serialize, Deserialize),
150    serde(crate = "serde")
151)]
152pub struct DirectedEdgeTag;
153#[cfg_attr(
154    feature = "serde",
155    derive(Serialize, Deserialize),
156    serde(crate = "serde")
157)]
158#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
159pub struct UndirectedEdgeTag;
160#[cfg_attr(
161    feature = "serde",
162    derive(Serialize, Deserialize),
163    serde(crate = "serde")
164)]
165#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
166pub struct FaceTag;
167#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
168pub struct DirectedVoronoiEdgeTag;
169#[cfg_attr(
170    feature = "serde",
171    derive(Serialize, Deserialize),
172    serde(crate = "serde")
173)]
174#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
175pub struct UndirectedVoronoiEdgeTag;
176
177#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
178pub struct VoronoiFaceTag;
179
180impl DelaunayElementType for VertexTag {
181    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
182        dcel.num_vertices()
183    }
184}
185
186impl DelaunayElementType for DirectedEdgeTag {
187    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
188        dcel.num_directed_edges()
189    }
190}
191
192impl DelaunayElementType for UndirectedEdgeTag {
193    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
194        dcel.num_undirected_edges()
195    }
196}
197
198impl DelaunayElementType for FaceTag {
199    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
200        dcel.num_faces()
201    }
202}
203
204impl DelaunayElementType for VoronoiFaceTag {
205    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
206        dcel.num_vertices()
207    }
208}
209
210impl DelaunayElementType for DirectedVoronoiEdgeTag {
211    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
212        dcel.num_directed_edges()
213    }
214}
215
216impl DelaunayElementType for UndirectedVoronoiEdgeTag {
217    fn num_elements<V, DE, UE, F>(dcel: &Dcel<V, DE, UE, F>) -> usize {
218        dcel.num_undirected_edges()
219    }
220}