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}