#![forbid(unsafe_code)]
use crate::core::tds::{
SimplexKey, Tds, TdsMutationError, TopologyOwner, TopologyOwnerId, VertexKey,
};
use crate::core::validation::{TopologyGuarantee, ValidationPolicy};
use crate::geometry::kernel::Kernel;
use crate::topology::traits::topological_space::GlobalTopology;
#[derive(Clone, Debug)]
pub struct Triangulation<K, U, V, const D: usize> {
pub(crate) kernel: K,
pub(crate) tds: Tds<U, V, D>,
pub(crate) global_topology: GlobalTopology<D>,
pub(crate) validation_policy: ValidationPolicy,
pub(crate) topology_guarantee: TopologyGuarantee,
}
impl<K, U, V, const D: usize> TopologyOwner for Triangulation<K, U, V, D> {
#[inline]
fn topology_owner_id(&self) -> TopologyOwnerId {
self.tds.topology_owner_id()
}
#[inline]
fn topology_generation(&self) -> u64 {
self.tds.generation()
}
}
impl<K, U, V, const D: usize> Triangulation<K, U, V, D>
where
K: Kernel<D>,
{
#[must_use]
pub fn new_empty(kernel: K) -> Self {
Self::new_empty_with_topology_context(
kernel,
TopologyGuarantee::DEFAULT,
GlobalTopology::DEFAULT,
)
}
#[inline]
pub(crate) fn new_empty_with_topology_context(
kernel: K,
topology_guarantee: TopologyGuarantee,
global_topology: GlobalTopology<D>,
) -> Self {
Self {
kernel,
tds: Tds::empty(),
global_topology,
validation_policy: topology_guarantee.default_validation_policy(),
topology_guarantee,
}
}
#[cfg(test)]
#[inline]
pub(crate) const fn new_with_tds(kernel: K, tds: Tds<U, V, D>) -> Self {
Self {
kernel,
tds,
global_topology: GlobalTopology::DEFAULT,
validation_policy: TopologyGuarantee::DEFAULT.default_validation_policy(),
topology_guarantee: TopologyGuarantee::DEFAULT,
}
}
#[inline]
pub fn set_vertex_data(
&mut self,
key: VertexKey,
data: Option<U>,
) -> Result<Option<U>, TdsMutationError> {
self.tds.set_vertex_data(key, data)
}
#[inline]
pub fn set_simplex_data(
&mut self,
key: SimplexKey,
data: Option<V>,
) -> Result<Option<V>, TdsMutationError> {
self.tds.set_simplex_data(key, data)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::tds::TdsError;
use crate::geometry::kernel::FastKernel;
use slotmap::KeyData;
use std::assert_matches;
#[test]
fn new_empty_sets_default_topology_and_validation_policy() {
let tri: Triangulation<FastKernel<f64>, (), (), 3> =
Triangulation::new_empty(FastKernel::new());
assert_eq!(tri.tds.number_of_vertices(), 0);
assert_eq!(tri.tds.number_of_simplices(), 0);
assert_eq!(tri.global_topology, GlobalTopology::DEFAULT);
assert_eq!(tri.topology_guarantee, TopologyGuarantee::DEFAULT);
assert_eq!(
tri.validation_policy,
TopologyGuarantee::DEFAULT.default_validation_policy()
);
}
#[test]
fn set_vertex_data_returns_error_for_invalid_key() {
let mut tri: Triangulation<FastKernel<f64>, i32, (), 2> =
Triangulation::new_empty(FastKernel::new());
let stale = VertexKey::from(KeyData::from_ffi(0xDEAD_BEEF));
let err = tri.set_vertex_data(stale, Some(42)).unwrap_err();
assert_matches!(err.as_tds_error(), TdsError::VertexNotFound { .. });
assert_eq!(tri.tds.number_of_vertices(), 0);
}
#[test]
fn set_simplex_data_returns_error_for_invalid_key() {
let mut tri: Triangulation<FastKernel<f64>, (), i32, 2> =
Triangulation::new_empty(FastKernel::new());
let stale = SimplexKey::from(KeyData::from_ffi(0xDEAD_BEEF));
let err = tri.set_simplex_data(stale, Some(42)).unwrap_err();
assert_matches!(err.as_tds_error(), TdsError::SimplexNotFound { .. });
assert_eq!(tri.tds.number_of_simplices(), 0);
}
}