Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement 2D map and basic operations #3

Merged
merged 47 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
04154f3
chore: create cmap module & template files
imrn99 Feb 8, 2024
7bba33b
feat: dart structure & useful trait/method impl
imrn99 Feb 8, 2024
12dba7d
doc: complete missing part for the Dart impl block
imrn99 Feb 8, 2024
067ef98
feat: basic embedding structures
imrn99 Feb 8, 2024
7ab44ea
feat: 2D map structure & basic reading interfaces
imrn99 Feb 9, 2024
04754b8
fix: missing import in doc example
imrn99 Feb 9, 2024
25b7454
feat: implement more methods
imrn99 Feb 9, 2024
630ec9a
doc: complete missing doc in impl TwoMap block
imrn99 Feb 9, 2024
dd9a75a
feat: add cell-specific identifier types
imrn99 Feb 9, 2024
971cf6a
refactor: replace usize in structs by custom ID types
imrn99 Feb 9, 2024
c749d2c
fix: update doc example to fit new ID types
imrn99 Feb 9, 2024
06a8738
doc: update method documentation to match new sig
imrn99 Feb 9, 2024
26fa286
feat: add I-cell computation in 2-map
imrn99 Feb 12, 2024
e42b95b
feat: add topological operations to i-sew implementation
imrn99 Feb 12, 2024
607a200
feat: add geometrical ops for 1-sew/unsew
imrn99 Feb 13, 2024
7630799
doc: add module level & TwoMap doc
imrn99 Feb 13, 2024
b8498ec
feat: add beta0 encoding to the TwoMap structure
imrn99 Feb 13, 2024
44123ce
doc: improve map module doc
imrn99 Feb 13, 2024
7899fc9
feat: implement new structure to handle darts & associated data
imrn99 Feb 13, 2024
111022c
refactor: introduce DartData structure to TwoMap
imrn99 Feb 14, 2024
09fffa8
feat: add face support
imrn99 Feb 14, 2024
8ebaff6
fix: correct i-cell computation with beta0 usage
imrn99 Feb 14, 2024
805b466
fix: complete 1-sew geometrical operations
imrn99 Feb 14, 2024
3159a21
fix: remove deadcode & change CellIdentifiers type
imrn99 Feb 14, 2024
1e332a4
feat: add 2-sew geometrical operations
imrn99 Feb 15, 2024
3690c27
refactor: improve various TwoMap methods/API
imrn99 Feb 15, 2024
d69c2f9
feat: add geometrical operations for 2-unsew
imrn99 Feb 15, 2024
77d7aa5
doc: update map module
imrn99 Feb 15, 2024
7ef8280
chore: update re-exports & remove dead-code ref in doc example
imrn99 Feb 15, 2024
4ef564d
doc: update dart module documentation
imrn99 Feb 15, 2024
c1a52e4
doc: update embed module documentation
imrn99 Feb 16, 2024
1b4b77f
refactor: flatten module structure
imrn99 Feb 16, 2024
d9277ea
refactor: rename TwoMap methods to fit Rust API Guidelines
imrn99 Feb 16, 2024
62bd694
feat: add face_id support directly to the build_face method
imrn99 Feb 16, 2024
e4c9b2a
refactor: make vertices attribute public & change TwoMap constructor
imrn99 Feb 16, 2024
1de4252
doc: add illustration for the main TwoMap example
imrn99 Feb 16, 2024
9e49bbc
doc: add map creation section of the TwoMap example
imrn99 Feb 16, 2024
997fd35
doc: complete TwoMap example up to step (c)
imrn99 Feb 16, 2024
93c0c5f
doc: finish TwoMap example
imrn99 Feb 16, 2024
5c131c4
refactor: change stretch macro to allow in-module definition
imrn99 Feb 18, 2024
6438356
doc: remove useless lines about removed generic argument
imrn99 Feb 18, 2024
e5a33cb
refactor: rename getter methods of vertex/face id
imrn99 Feb 18, 2024
11b3d5e
refactor: rename set_vertx/face methods for consistency
imrn99 Feb 18, 2024
ba35f3f
feat: add getter for Vertex2 & Face of the map
imrn99 Feb 18, 2024
41be619
refactor: add API for vertex manipulation
imrn99 Feb 18, 2024
e4fc325
doc: update documentation of new methods
imrn99 Feb 18, 2024
f0cd8ec
doc: update TwoMap example to use new methods
imrn99 Feb 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 194 additions & 0 deletions honeycomb-core/src/dart.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
//! Basic dart utilities
//!
//! **Useful definitions of this module being re-exported, the user should
//! most likely not interact directly with it.**
//!
//! This module contains all code used to model darts as element of the
//! combinatorial map. This includes geometric embedding as associated
//! identifiers, though spatial representation is left to another part
//! of the crate.

// ------ IMPORTS

// ------ CONTENT

use std::sync::atomic::AtomicBool;

use crate::{FaceIdentifier, VertexIdentifier};

/// Type definition for dart identifiers
///
/// This is used for better control over memory usage and ID encoding.
pub type DartIdentifier = u32;

pub const NULL_DART_ID: DartIdentifier = 0;

#[derive(Clone, Copy, Debug, Default)]
/// Dart-cell associative structure
///
/// Structure used to store the associated vertex and face
/// identifiers to a dart. The structure technically contains only
/// cell identifiers, the association with a dart ID is done implicitly
/// through storage indexing.
///
/// Each field is kept public as editing operations can happen during
/// execution (e.g. a sewing operation will "fuse" some geometric
/// objects).
///
/// # Example
///
/// No example is provided as the structure should not be used directly.
/// The documentation is generated mostly for developing purposes.
///
pub struct CellIdentifiers {
/// Vertex unique identifier.
pub vertex_id: VertexIdentifier,
/// Face unique identifier.
pub face_id: FaceIdentifier,
}

/// Dart-associated data
///
/// **This should not be used directly by the user.**
///
/// Structure used to store dart-related data. The association of data with
/// a given dart is done implictly through indexing.
///
/// # Generics
///
/// - `const N_MARKS: usize` -- Number of marks used for search algorithms.
/// This corresponds to the number of search that can be done concurrently.
///
/// # Example
///
/// No example is provided as the structure should not be used directly.
/// The documentation is generated mostly for developing purposes.
///
pub struct DartData<const N_MARKS: usize> {
/// Array of boolean used for algorithmic search.
///
/// Atomics allow for non-mutable interfaces, i.e. parallel friendly
/// methods. Storage is done line-wise as it would be very rare to
/// access multiple marks of the same dart successively.
pub marks: [Vec<AtomicBool>; N_MARKS],
/// List of associated cell identifiers.
pub associated_cells: Vec<CellIdentifiers>,
}

impl<const N_MARKS: usize> DartData<N_MARKS> {
/// Create a [DartData] object.
///
/// **This should not be used directly by the user.**
///
/// # Arguments
///
/// - `n_darts: usize` -- Number of darts in the new structure.
///
/// # Return / Panic
///
/// Returns a [DartData] structure with default values.
///
pub fn new(n_darts: usize) -> Self {
let marks: [Vec<AtomicBool>; N_MARKS] = (0..N_MARKS)
.map(|_| {
(0..n_darts + 1)
.map(|_| AtomicBool::new(false))
.collect::<Vec<AtomicBool>>()
})
.collect::<Vec<Vec<AtomicBool>>>()
.try_into()
.unwrap();
Self {
marks,
associated_cells: vec![
CellIdentifiers {
vertex_id: 0,
face_id: 0,
// volume_id: 0
};
n_darts + 1
],
}
}

/// Free all darts of a given mark.
///
/// **This should not be used directly by the user.**
///
/// # Arguments
///
/// - `mark_id: usize` -- Identifier of the mark that must be reset.
///
pub fn free_mark(&self, mark_id: usize) {
self.marks[mark_id]
.iter()
.filter(|e| e.load(std::sync::atomic::Ordering::Relaxed)) // useful?
.for_each(|mark| mark.store(false, std::sync::atomic::Ordering::Relaxed));
}

/// Check and update if a given dart was marked.
///
/// # Arguments
///
/// - `mark_id: usize` -- Identifier of the mark that must be checked.
/// - `dart_id: DartIdentifier` -- Identifier of the dart that must be checked.
///
/// # Return / Panic
///
/// Returns a boolean to indicate whether the dart was marked or not. In
/// both case, the dart is marked after the operation.
///
/// The method will panic if the provided mark ID is invalid.
///
pub fn was_marked(&self, mark_id: usize, dart_id: DartIdentifier) -> bool {
assert!(mark_id < N_MARKS);
match self.marks[mark_id][dart_id as usize].compare_exchange(
false,
true,
std::sync::atomic::Ordering::Release,
std::sync::atomic::Ordering::Relaxed,
) {
Ok(_) => {
// comparison was successful => was false
false
}
Err(_) => {
// comparison failed => was true
true
}
}
}

/// Add a new entry to the structure.
///
/// **This should not be used directly by the user.**
///
pub fn add_entry(&mut self) {
self.marks
.iter_mut()
.for_each(|mark| mark.push(AtomicBool::new(false)));
self.associated_cells.push(CellIdentifiers::default());
}

/// Reset a given entry of the structure.
///
/// **This should not be used directly by the user.**
///
/// # Arguments
///
/// - `dart_id: DartIdentifier` -- Identifier of the dart which entry should be reset.
///
pub fn reset_entry(&mut self, dart_id: DartIdentifier) {
self.marks.iter().for_each(|mark| {
mark[dart_id as usize].store(false, std::sync::atomic::Ordering::Relaxed)
});
self.associated_cells[dart_id as usize] = CellIdentifiers::default();
}
}

// ------ TESTS

#[cfg(test)]
mod tests {
//use super::*;
}
164 changes: 164 additions & 0 deletions honeycomb-core/src/embed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//! Geometric data embedding
//!
//! Note:
//! - The initialization of geometric data should eventually be done by
//! the combinatorial map constructor. Until then, the user has to
//! manually initialize it through this module's tools.
//! - A custom vector type is needed
//!
//! This module contains all code used to handle geometric data
//! embedding. This includes ID types, spatial representation,
//! (un)sewing policies.

// ------ MODULE DECLARATIONS

// ------ IMPORTS

#[cfg(doc)]
use crate::TwoMap;

// ------ CONTENT

/// Type definition for vertex identifiers
///
/// This is used for better control over memory usage and ID encoding.
pub type VertexIdentifier = u32;

/// Type definition for face identifiers
///
/// This is used for better control over memory usage and ID encoding.
pub type FaceIdentifier = u32;

/// Type definition for volume identifiers
///
/// This is used for better control over memory usage and ID encoding.
pub type VolumeIdentifier = u32;

/// Geometrical policy of the sewing operation.
///
/// All sewing operation include two darts, which we refer to as
/// *lhs_dart* and *rhs_dart*, hence the naming conventions.
///
/// For more information on why a strict policy definition is needed,
/// refer to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/
///
/// # Example
///
/// Refer to the user guide and [TwoMap] examples.
///
#[derive(Debug, Default)]
pub enum SewPolicy {
/// Default policy.
///
/// *lhs_dart* embedded data is used to overwrite *rhs_dart*
/// embedded data, effectively stretching *rhs_dart* to
/// *lhs_dart*'s position.
#[default]
StretchLeft,
/// *rhs_dart* embedded data is used to overwrite *lhs_dart*
/// embedded data, effectively stretching *lhs_dart* to
/// *rhs_dart*'s position.
StretchRight,
/// *lhs_dart* & *rhs_dart* embedded data are both used to
/// compute a "middle ground" used to overwrite both initial
/// positions.
StretchAverage,
}

/// Geometrical policy of the sewing operation.
///
/// All unsewing operation include two darts, which we refer to as
/// *lhs_dart* and *rhs_dart*, hence the naming conventions. Note that
/// the second dart is not necessarily specified as it can be computed
/// the index of the beta function affected by the operation.
///
/// For more information on why a strict policy definition is needed,
/// refer to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/
///
/// # Example
///
/// Refer to the user guide and [TwoMap] examples.
///
#[derive(Debug, Default)]
pub enum UnsewPolicy {
/// Default policy.
///
/// Vertices associated with the unsewed darts are duplicated in order
/// to allow for a shift in coordinates without mutual stretching.
#[default]
Duplicate,
}

/// Type definition for 2D vertices representation.
pub type Vertex2 = [f64; 2];

/// Type definition for 3D vertices representation.
pub type Vertex3 = [f64; 3];

/// Face object
///
/// A face is made up of a varying number of corners (e.g. 3 for a triangle).
/// The corners are stored in specific order to model the connections forming
/// the face; Additionally, a boolean indicates whether there is a connection
/// between the last corner and the first, effectively closing the face.
///
/// NOTE: It may be possible to replace the Vec with an upper-bound structure
/// to limit heap allocation during execution. We could also add references to
/// the vertices and edge list inside the structure?
///
/// # Example
///
/// This code corresponds to the initialization of 4 vertices used to build
/// 2 faces: a square and a triangle.
///
/// ```
/// use honeycomb_core::{Vertex2, embed::Face};
///
/// let vertices = [
/// [0.0, 0.0],
/// [1.0, 0.0],
/// [1.0, 1.0],
/// [0.0, 1.0],
/// [2.0, 0.0],
/// ];
///
/// let square_face = Face { corners: vec![0, 1, 2, 3], closed: true };
/// let triangle_face = Face { corners: vec![1, 4, 2], closed: true };
///
/// ```
///
/// This corresponds to the following figure:
///
/// ```text
///
/// 1.0 +------+\_
/// | | \_
/// | | \_
/// | | \
/// 0.0 +------+------+
/// 0.0 1.0 2.0
///
/// ```
pub struct Face {
/// Ordered list of all corners composing the face.
pub corners: Vec<VertexIdentifier>,
/// Boolean indicating whether there is a connection between
/// `self.corners.last()` and `self.corners.first`.
pub closed: bool,
}

// ------ TESTS

#[cfg(test)]
mod tests {
//use super::*;

#[test]
fn some_test() {
assert_eq!(1, 1);
}
}
Loading