honeycomb_core/cmap/dim3/
structure.rs

1//! Main definitions
2//!
3//! This module contains the main structure definition ([`CMap3`]) as well as its constructor
4//! implementation.
5
6use crate::{
7    attributes::{AttrSparseVec, AttrStorageManager, UnknownAttributeStorage},
8    cmap::components::{betas::BetaFunctions, unused::UnusedDarts},
9    geometry::{CoordsFloat, Vertex3},
10};
11
12use super::CMAP3_BETA;
13
14/// Main map object.
15pub struct CMap3<T: CoordsFloat> {
16    /// List of vertices making up the represented mesh
17    pub(super) attributes: AttrStorageManager,
18    /// List of vertices making up the represented mesh
19    pub(super) vertices: AttrSparseVec<Vertex3<T>>,
20    /// List of free darts identifiers, i.e. empty spots
21    /// in the current dart list
22    pub(super) unused_darts: UnusedDarts,
23    /// Array representation of the beta functions
24    pub(super) betas: BetaFunctions<CMAP3_BETA>,
25}
26
27unsafe impl<T: CoordsFloat> Send for CMap3<T> {}
28unsafe impl<T: CoordsFloat> Sync for CMap3<T> {}
29
30#[doc(hidden)]
31/// # 3D combinatorial map implementation
32///
33/// Information regarding maps can be found in the [user guide][UG].
34/// This documentation focuses on the implementation and its API.
35///
36/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/cmaps
37///
38/// Notes on implementation:
39/// - We encode *β<sub>0</sub>* as the inverse function of *β<sub>1</sub>*. This is extremely
40///   useful (read *required*) to implement correct and efficient i-cell computation. Additionally,
41///   while *β<sub>0</sub>* can be accessed using the [`beta`][Self::beta] method, we do not define
42///   the 0-sew / 0-unsew operations.
43/// - We chose a boundary-less representation of meshes (i.e. darts on the boundary are 3-free).
44/// - The null dart will always be encoded as `0`.
45///
46/// ## Generics
47///
48/// - `T: CoordsFloat` -- Generic FP type for coordinates representation
49///
50/// ## Example
51///
52/// The following example corresponds to this flow of operations:
53///
54/// - Building a tetrahedron (A)
55/// - Building another tetrahedron (B)
56/// - Sewing both tetrahedrons along a face (C)
57/// - Adjusting shared vertices (D)
58/// - Separating and removing the shared face (E)
59///
60/// ```rust
61/// # fn main() {
62/// // TODO: complete with test example once the structure is integrated to the builder
63/// # }
64/// ```
65///
66/// Note that:
67/// - We use the builder structure: [`CMapBuilder`][crate::prelude::CMapBuilder]
68/// - We insert a few assertions to demonstrate the progressive changes applied to the structure
69/// - Even though volumes are represented in the figure, they are not stored in the structure
70/// - We use a lot of methods with the `force_` prefix; these are convenience methods when
71///   synchronization isn't needed
72impl<T: CoordsFloat> CMap3<T> {
73    /// Creates a new 3D combinatorial map.
74    #[allow(unused)]
75    #[must_use = "unused return value"]
76    pub(crate) fn new(n_darts: usize) -> Self {
77        Self {
78            attributes: AttrStorageManager::default(),
79            vertices: AttrSparseVec::new(n_darts + 1),
80            unused_darts: UnusedDarts::new(n_darts + 1),
81            betas: BetaFunctions::new(n_darts + 1),
82        }
83    }
84
85    /// Creates a new 3D combinatorial map with user-defined attributes
86    ///
87    /// We expect the passed storages to be defined but empty, i.e. attributes are known,
88    /// but no space has been used/ allocated yet.
89    #[allow(unused)] // FIXME: remove once the structure is integrated to the builder
90    #[must_use = "unused return value"]
91    pub(crate) fn new_with_undefined_attributes(
92        n_darts: usize,
93        mut attr_storage_manager: AttrStorageManager,
94    ) -> Self {
95        // extend all storages to the expected length: n_darts + 1 (for the null dart)
96        attr_storage_manager.extend_storages(n_darts + 1);
97        Self {
98            attributes: attr_storage_manager,
99            vertices: AttrSparseVec::new(n_darts + 1),
100            unused_darts: UnusedDarts::new(n_darts + 1),
101            betas: BetaFunctions::new(n_darts + 1),
102        }
103    }
104}