#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(any(doc, doctest), doc = include_str!("../README.md"))]
#![forbid(unsafe_code)]
#[expect(
clippy::redundant_pub_crate,
reason = "`pub(crate)` keeps internal cross-module intent visible while `core` is private"
)]
mod core {
#[cfg(test)]
pub(crate) mod test_support {
use crate::core::simplex::Simplex;
use crate::core::tds::{Tds, TdsBuilder};
use crate::core::vertex::Vertex;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct TopologySnapshot {
pub(crate) vertices: Vec<Uuid>,
pub(crate) simplex_vertices: Vec<Vec<Uuid>>,
pub(crate) simplex_neighbors: Vec<Vec<Option<Uuid>>>,
}
pub(crate) fn tds_from_specs<U: Copy, const D: usize>(
vertices: &[Vertex<U, D>],
simplices: &[Vec<usize>],
) -> Tds<U, (), D> {
TdsBuilder::new(vertices, simplices)
.build()
.expect("shared TDS fixture should be valid")
}
pub(crate) fn single_simplex_tds<U: Copy, const D: usize>(
vertices: &[Vertex<U, D>],
) -> Tds<U, (), D> {
tds_from_specs(vertices, &[(0..vertices.len()).collect()])
}
pub(crate) fn snapshot_topology<const D: usize>(tds: &Tds<(), (), D>) -> TopologySnapshot {
let mut vertices: Vec<Uuid> = tds.vertices().map(|(_, vertex)| vertex.uuid()).collect();
vertices.sort();
let mut simplex_vertices: Vec<Vec<Uuid>> = tds
.simplices()
.map(|(_, simplex)| {
let mut uuids: Vec<Uuid> = simplex
.vertices()
.iter()
.map(|&vertex_key| {
tds.vertex(vertex_key)
.expect("vertex key missing in TDS")
.uuid()
})
.collect();
uuids.sort();
uuids
})
.collect();
simplex_vertices.sort();
TopologySnapshot {
vertices,
simplex_vertices,
simplex_neighbors: snapshot_neighbors(tds),
}
}
pub(crate) fn assert_same_vertex_simplex_topology(
actual: &TopologySnapshot,
expected: &TopologySnapshot,
) {
assert_eq!(actual.vertices, expected.vertices);
assert_eq!(actual.simplex_vertices, expected.simplex_vertices);
}
fn snapshot_neighbors<const D: usize>(tds: &Tds<(), (), D>) -> Vec<Vec<Option<Uuid>>> {
let mut simplex_neighbors: Vec<Vec<Option<Uuid>>> = tds
.simplices()
.map(|(_, simplex)| {
let mut neighbors: Vec<Option<Uuid>> = simplex
.neighbors()
.map(|neighbor_keys| {
neighbor_keys
.map(|neighbor| {
neighbor.and_then(|neighbor_key| {
tds.simplex(neighbor_key).map(Simplex::uuid)
})
})
.collect()
})
.unwrap_or_default();
neighbors.sort();
neighbors
})
.collect();
simplex_neighbors.sort();
simplex_neighbors
}
}
pub mod algorithms {
pub mod flips {
use crate::core::algorithms::insertion::{
CavityFillingError, HullExtensionReason, InsertionError, InsertionErrorKind,
InsertionTopologyValidationContext, NeighborWiringError,
SpatialIndexConstructionFailure, TdsConstructionFailure, TdsValidationFailure,
external_facets_for_boundary, wire_cavity_neighbors,
};
use crate::core::algorithms::locate::{
ConflictError, LocateError, extract_cavity_boundary,
};
use crate::core::collections::{
FastHashMap, FastHashSet, FastHasher, MAX_PRACTICAL_DIMENSION_SIZE,
PeriodicOffsetBuffer, SimplexKeyBuffer, SmallBuffer,
};
use crate::core::edge::{EdgeKey, EdgeKeyError};
use crate::core::facet::{
AllFacetsIter, FacetError, FacetHandle, facet_key_from_vertices,
};
use crate::core::operations::TopologicalOperation;
use crate::core::simplex::{NeighborSlot, Simplex, SimplexValidationError};
use crate::core::tds::{
EntityKind, NeighborValidationError, SimplexKey, Tds, TdsMutationError,
TdsRollbackTransaction, TdsRollbackWindow, TopologyOwnerId, VertexKey,
};
use crate::core::traits::data_type::DataType;
use crate::core::util::stable_hash_u64_slice;
use crate::core::vertex::Vertex;
use crate::geometry::kernel::{Kernel, RobustKernel};
use crate::geometry::point::Point;
use crate::geometry::predicates::Orientation;
use crate::geometry::robust_predicates::robust_orientation;
use crate::geometry::traits::coordinate::{
CoordinateConversionError, CoordinateValidationError, CoordinateValues,
};
use crate::topology::traits::global_topology_model::{
GlobalTopologyModel, GlobalTopologyModelAdapter, GlobalTopologyModelError,
};
use crate::topology::traits::topological_space::GlobalTopology;
use crate::triangulation::realization::TriangulationRealizationValidationError;
use crate::triangulation::validation::{
TopologyGuarantee, TriangulationValidationError,
};
use crate::validation::DelaunayTriangulationValidationError;
use slotmap::Key;
use std::borrow::Cow;
use std::collections::VecDeque;
use std::env;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::iter::once;
use std::time::{Duration, Instant};
use thiserror::Error;
type VertexKeyList = SmallBuffer<VertexKey, MAX_PRACTICAL_DIMENSION_SIZE>;
type RemovedSimplexVertexSnapshot =
SmallBuffer<VertexKeyList, MAX_PRACTICAL_DIMENSION_SIZE>;
type ReplacementSimplexVertices =
SmallBuffer<VertexKeyList, MAX_PRACTICAL_DIMENSION_SIZE>;
type ExternalFacetBuffer = SmallBuffer<FacetHandle, 64>;
type ReplacementPeriodicOffsets<const D: usize> =
SmallBuffer<Option<PeriodicOffsetBuffer<D>>, MAX_PRACTICAL_DIMENSION_SIZE>;
#[cfg(test)]
mod test_support {
pub(super) fn init_tracing() {
static INIT: std::sync::Once = std::sync::Once::new();
INIT.call_once(|| {
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("warn"));
let _ = tracing_subscriber::fmt()
.with_env_filter(filter)
.with_test_writer()
.try_init();
});
}
}
mod context;
mod contexts;
mod engine;
mod errors;
mod moves;
mod orientation;
mod repair;
mod repair_queue;
mod support;
pub use self::context::*;
pub(crate) use self::contexts::*;
pub(crate) use self::engine::*;
pub use self::errors::*;
pub use self::moves::*;
use self::orientation::{
debug_postcondition_facet_context, debug_ridge_context, facet_order,
k1_inserted_vertex_periodic_offset, normalized_facet_order_with_offsets,
orient_replacement_simplices, permutation_odd,
replacement_simplex_periodic_offsets, validate_replacement_orientation,
};
pub use self::repair::*;
use self::repair_queue::{
FlipSignature, LastAppliedFlip, MAX_REPEAT_SIGNATURE, RepairAttemptConfig,
RepairDiagnostics, RepairQueues, default_max_flips, duration_nanos_saturating,
emit_repair_debug_summary, enqueue_facet, enqueue_simplex_facets, flip_signature,
non_convergent_error, pop_queue, predicate_key_from_vertices,
repair_flip_is_unavailable, repair_ridge_debug_enabled, repair_trace_enabled,
run_next_edge_repair_step, run_next_facet_repair_step, run_next_ridge_repair_step,
run_next_triangle_repair_step, seed_repair_queues,
should_emit_postcondition_facet_debug, should_emit_ridge_debug,
};
use self::support::{
EuclideanPointCache, align_periodic_offset, build_flip_topology_index,
collect_simplices_around_ridge, facet_vertices_from_simplex,
flip_would_create_nonmanifold_facets_any, flip_would_duplicate_simplex_any,
lift_vertex_point, matching_source_simplex, missing_opposite_for_simplex,
periodic_offset_lifted_into_simplex, periodic_offsets_or_zero_frame,
removed_simplex_frame, ridge_vertices_from_simplex, simplex_extras_for_ridge,
validate_periodic_offset_len, vertex_point, vertex_point_lifted_into_simplex,
vertices_to_points, vertices_to_points_with_optional_lift,
};
}
pub mod insertion;
pub mod locate;
pub(crate) mod pl_manifold_repair;
}
pub mod adjacency;
pub mod facet_incidence;
pub mod simplex;
pub mod collections {
mod aliases;
mod buffers;
mod helpers;
mod key_maps;
mod secondary_maps;
mod triangulation_maps;
pub(crate) mod spatial_hash_grid;
pub use aliases::{
Entry, FacetIndex, FastBuildHasher, FastHashMap, FastHashSet, FastHasher,
MAX_PRACTICAL_DIMENSION_SIZE, SecureHashMap, SecureHashSet, SmallBuffer, Uuid,
};
pub(crate) use aliases::{StorageKeys, StorageMap};
pub use buffers::*;
pub use helpers::*;
pub use key_maps::*;
pub use secondary_maps::*;
pub use triangulation_maps::*;
}
pub mod edge;
pub mod facet;
pub mod operations;
pub mod tds {
mod builder;
mod draft;
mod equality;
pub mod errors;
pub(crate) mod incidence;
mod keys;
mod model;
mod mutation;
pub(crate) mod rollback;
mod snapshot;
mod validation;
pub(crate) use builder::{ExplicitSimplexParseError, ParsedTdsInput};
pub use builder::{TdsBuilder, TdsBuilderError};
pub use draft::{TdsDraft, TdsDraftError, TdsDraftInsertionError};
pub use errors::*;
pub use keys::{SimplexKey, VertexKey};
pub use model::{Tds, TopologyOwner, TopologyOwnerId};
pub(crate) use rollback::{
TdsOwnerRollbackTransaction, TdsRollbackOwner, TdsRollbackSavepoint,
TdsRollbackTransaction, TdsRollbackWindow,
};
pub(crate) use snapshot::{
RawTdsSnapshot, TdsSnapshot, TdsSnapshotError, ValidatedTdsSerialization,
};
}
pub mod util {
pub(crate) mod canonical_points;
pub mod deduplication;
pub mod facet_keys;
pub mod hashing;
pub mod hilbert;
pub mod measurement;
pub mod uuid;
pub use deduplication::*;
pub use facet_keys::*;
pub use hashing::*;
pub use hilbert::*;
pub use measurement::*;
pub use uuid::*;
}
pub mod vertex;
pub mod traits {
pub mod data_type;
pub use data_type::*;
}
}
pub(crate) mod triangulation {
pub mod builder;
pub mod construction;
pub mod draft;
pub mod flips;
pub mod insertion;
pub mod jaccard;
pub mod locality;
pub mod model;
pub mod orientation;
pub mod pachner;
pub mod query;
pub mod realization;
pub mod repair;
pub mod rollback;
pub mod validation;
pub use model::Triangulation;
}
#[cfg(feature = "bench")]
#[doc(hidden)]
pub mod bench_fixtures;
pub mod geometry {
pub mod algorithms {
pub mod convex_hull;
pub use convex_hull::*;
}
pub mod coordinate_range;
pub mod realization;
#[macro_use]
pub mod matrix;
pub mod kernel;
pub mod point;
pub mod predicates;
pub mod quality;
pub mod robust_predicates;
pub mod sos;
pub mod util {
pub mod circumsphere;
pub mod conversions;
pub mod measures;
pub mod norms;
pub mod point_generation;
pub(crate) mod simplex_lp;
pub mod triangulation_generation;
pub use circumsphere::*;
pub use conversions::*;
pub use measures::*;
pub use norms::*;
pub use point_generation::*;
pub use triangulation_generation::*;
}
pub mod traits {
pub mod coordinate;
pub use coordinate::*;
}
pub use algorithms::*;
pub use coordinate_range::*;
pub use matrix::*;
pub use point::*;
pub use predicates::*;
pub use quality::*;
pub use realization::*;
pub use traits::*;
pub use util::*;
}
#[path = "delaunay/builder.rs"]
pub mod builder;
#[path = "delaunay/construction.rs"]
pub mod construction;
#[path = "delaunay/property_validation.rs"]
mod delaunay_property_validation;
#[path = "delaunay/query.rs"]
pub(crate) mod delaunay_query;
#[path = "delaunay/rollback.rs"]
pub(crate) mod delaunay_rollback;
#[path = "delaunay/delaunayize.rs"]
pub mod delaunayize;
#[path = "delaunay/deletion.rs"]
pub(crate) mod deletion;
#[path = "delaunay/diagnostics.rs"]
pub mod diagnostics;
#[path = "delaunay/draft.rs"]
mod draft;
#[path = "delaunay/incremental_builder.rs"]
pub mod incremental_builder;
pub use crate::triangulation::flips;
#[path = "delaunay/insertion.rs"]
pub(crate) mod insertion;
pub use crate::triangulation::pachner;
#[path = "delaunay/serialization.rs"]
pub mod checkpoint;
#[path = "delaunay/model.rs"]
pub(crate) mod delaunay_model;
pub mod refinement;
#[path = "delaunay/repair.rs"]
pub mod repair;
#[path = "delaunay/spherical.rs"]
pub mod spherical;
#[path = "delaunay/validation.rs"]
pub mod validation;
pub mod io {
pub mod visualization;
pub use visualization::*;
}
pub use crate::builder::DelaunayTriangulationBuilder;
pub use crate::construction::{
ConstructionOptions, ConstructionSkipSample, ConstructionSlowInsertionSample,
ConstructionStatistics, DedupPolicy, DedupTolerance, DelaunayConstructionFailure,
DelaunayConstructionRepairPhase, DelaunayConstructionRetryFailure, DelaunayError,
DelaunayResult, DelaunayTriangulationConstructionError,
DelaunayTriangulationConstructionErrorWithStatistics, InitialSimplexStrategy,
InsertionOrderStrategy, RetryPolicy,
};
pub use crate::core::algorithms::insertion::{
CavityFillingError, CavityRepairStage, DelaunayRepairErrorKind, DelaunayRepairFailureContext,
HullExtensionReason, InitialSimplexConstructionError, InitialSimplexUnexpectedInsertionStage,
InsertionError, InsertionErrorKind, InsertionErrorSourceKind,
InsertionTopologyValidationContext, NeighborRebuildError, NeighborWiringError,
SpatialIndexConstructionFailure, TdsConstructionFailure, TdsValidationFailure,
};
pub use crate::core::algorithms::pl_manifold_repair::{
PlManifoldRepairConfig, PlManifoldRepairError, PlManifoldRepairRefinementError,
PlManifoldRepairStage, PlManifoldRepairStats, PlManifoldTdsRepairResult,
repair_pl_manifold_tds,
};
pub use crate::core::operations::{
InsertionOutcome, InsertionResult, InsertionStatistics, RepairDecision, RepairSkipReason,
SuspicionFlags, TopologicalOperation,
};
pub use crate::core::util::DeduplicationError;
pub use crate::delaunay_model::DelaunayTriangulation;
#[cfg(feature = "diagnostics")]
#[cfg_attr(docsrs, doc(cfg(feature = "diagnostics")))]
pub use crate::delaunay_property_validation::debug_print_first_delaunay_violation;
pub use crate::delaunay_property_validation::{
DelaunayValidationError, DelaunayViolationDetail, DelaunayViolationReport,
delaunay_violation_report, find_delaunay_violations,
};
pub use crate::delaunay_query::SimplexDataFillError;
pub use crate::delaunayize::DelaunayRefinementBuilder;
pub use crate::deletion::DeleteVertexError;
pub use crate::incremental_builder::{DelaunayIncrementalBuilder, DelaunayIncrementalBuilderError};
pub use crate::io::visualization::{
AdjacencyRecord, SimplexRecord, VISUALIZATION_SCHEMA, VISUALIZATION_SCHEMA_VERSION,
ValidatedVisualizationData, VertexRecord, VisualizationData, VisualizationDataValidationError,
VisualizationExportError, VisualizationMetadata, VisualizationTopologyGuarantee,
VisualizationTopologyKind,
};
pub use crate::refinement::RefinementError;
pub use crate::repair::{DelaunayCheckPolicy, DelaunayRepairOperation, DelaunayRepairPolicy};
pub use crate::spherical::{
SphericalDelaunayBuilder, SphericalDelaunayConstructionError, SphericalDelaunayTriangulation,
SphericalDelaunayValidationError, SphericalSimplex, SphericalSimplexError,
SphericalValidationLayer,
};
pub use crate::tds::{
InvariantError, InvariantKind, InvariantViolation, TriangulationValidationReport,
};
pub use crate::topology::spaces::spherical::{
SphericalMetric, SphericalPoint, SphericalPointError,
};
pub use crate::triangulation::Triangulation;
pub use crate::triangulation::builder::{
TriangulationBuildFailure, TriangulationBuilder, TriangulationBuilderError,
};
pub use crate::triangulation::construction::{
FinalDelaunayValidationContext, FinalTopologyValidationContext, TriangulationConstructionError,
};
pub use crate::triangulation::insertion::DuplicateDetectionMetrics;
pub use crate::triangulation::query::SimplexBarycenterError;
pub use crate::triangulation::realization::{
PeriodicDomainPeriodError, TriangulationRealizationIntersectionDetail,
TriangulationRealizationSimplexDetail, TriangulationRealizationSimplexPairDetail,
TriangulationRealizationValidationError, TriangulationRealizationValidationErrorKind,
TriangulationRealizationValidationReport,
};
pub use crate::triangulation::repair::{LocalFacetRepairGuard, TriangulationRepairOperation};
pub use crate::triangulation::validation::{
OrientationWitness, TopologyGuarantee, TriangulationValidationError,
ValidationConfigurationError, ValidationPolicy,
};
pub use crate::validation::{
DelaunayTriangulationRefinementError, DelaunayTriangulationValidationError,
DelaunayVerificationError, DelaunayVerificationErrorKind,
};
pub fn try_vertices_from_points<const D: usize>(
points: &[geometry::Point<D>],
) -> Result<Vec<tds::Vertex<(), D>>, geometry::CoordinateConversionError> {
points
.iter()
.map(|point| tds::Vertex::try_new(*point.coords()))
.collect()
}
pub mod topology {
pub mod traits {
pub(crate) mod global_topology_model;
pub mod topological_space;
pub use global_topology_model::GlobalTopologyModelError;
pub use topological_space::*;
}
pub mod characteristics {
pub mod euler;
pub mod validation;
pub use euler::*;
pub use validation::*;
}
pub mod manifold;
pub mod ridge;
pub mod spaces {
pub mod euclidean;
pub mod spherical;
pub mod toroidal;
pub use euclidean::EuclideanSpace;
pub use spherical::{SphericalMetric, SphericalPoint, SphericalPointError};
pub use toroidal::{LiftedLinkEdge, LiftedVertexId, ToroidalSpace};
}
pub use crate::TopologyGuarantee;
pub use characteristics::*;
pub use manifold::{
BoundaryFacetClassification, ManifoldError, classify_boundary_facet,
validate_closed_boundary, validate_ridge_links, validate_vertex_links,
};
pub use ridge::{RidgeCandidate, RidgeCandidateError, RidgeLinkView, RidgeQuery, RidgeView};
pub use traits::*;
}
pub mod collections {
pub use crate::core::collections::{
Entry, FacetIndex, FacetSharingSimplicesBuffer, FastBuildHasher, FastHashMap, FastHashSet,
FastHasher, KeyBasedSimplexMap, KeyBasedVertexMap, MAX_PRACTICAL_DIMENSION_SIZE,
NeighborBuffer, PeriodicOffsetBuffer, SecureHashMap, SecureHashSet, SimplexKeyBuffer,
SimplexKeySet, SimplexNeighborsMap, SimplexSecondaryMap, SimplexVertexBuffer,
SimplexVertexKeyBuffer, SimplexVertexKeysMap, SimplexVertexUuidBuffer, SimplexVerticesMap,
SmallBuffer, Uuid, UuidToSimplexKeyMap, UuidToVertexKeyMap, VertexKeyBuffer, VertexKeySet,
VertexSecondaryMap, VertexToSimplicesMap, VertexUuidSet, fast_hash_map_with_capacity,
fast_hash_set_with_capacity,
};
pub mod algorithm_buffers {
pub use crate::core::collections::{
CLEANUP_OPERATION_BUFFER_SIZE, CavityBoundaryBuffer, GeometricPointBuffer,
SimplexRemovalBuffer, ViolationBuffer,
};
}
}
pub mod tds {
pub use crate::core::adjacency::*;
pub use crate::core::collections::{
FacetIndex, FastHashMap, FastHashSet, NeighborBuffer, PeriodicOffsetBuffer,
SimplexKeyBuffer, SmallBuffer, Uuid,
};
pub use crate::core::edge::*;
pub use crate::core::facet::*;
pub use crate::core::simplex::*;
pub use crate::core::tds::*;
pub use crate::core::util::{
UuidValidationError, checked_facet_key_from_vertex_keys, make_uuid, measure_with_result,
stable_hash_u64_slice, usize_to_u8, validate_uuid, verify_facet_index_consistency,
};
pub use crate::core::vertex::*;
pub use crate::triangulation::jaccard::{
format_jaccard_report, jaccard_distance, jaccard_index,
};
}
pub mod algorithms {
pub use crate::core::algorithms::locate::{
ConflictError, InternalInconsistencySite, LocateError, LocateFallback,
LocateFallbackReason, LocateResult, LocateStats, locate, locate_with_stats,
};
}
pub mod query {
pub use crate::assert_jaccard_gte;
pub use crate::core::traits::data_type::{
DataCopy, DataDebug, DataDeserialize, DataIdentity, DataSerde, DataSerialize, DataType,
};
pub use crate::core::util::measure_with_result;
pub use crate::flips::RidgeHandle;
pub use crate::geometry::Point;
pub use crate::geometry::algorithms::convex_hull::{
ConvexHull, ConvexHullConstructionError, ConvexHullFacetView,
ConvexHullInsufficientDataReason, ConvexHullQueryError, ConvexHullVertex,
};
pub use crate::geometry::kernel::{
AdaptiveKernel, ExactPredicates, FastKernel, Kernel, RobustKernel,
};
pub use crate::geometry::traits::coordinate::Coordinate;
pub use crate::geometry::{insphere, insphere_distance, insphere_lifted};
pub use crate::tds::{
AllFacetsIter, BoundaryFacetsIter, EdgeIndex, EdgeKey, EdgeKeyError, EdgeView, FacetHandle,
FacetIncidenceView, FacetToSimplicesIndex, FacetView, IncidenceView, OneSidedFacetsIter,
Simplex, SimplexFacetsIter, SimplexKey, SimplexNeighborIndex, TopologyIndexBuildError,
TriangulationAdjacency, Vertex, VertexKey,
};
pub use crate::topology::ridge::{
RidgeCandidate, RidgeCandidateError, RidgeLinkView, RidgeQuery, RidgeView,
};
pub use crate::triangulation::jaccard::{
JaccardComputationError, extract_edge_set, extract_facet_identifier_set,
extract_hull_facet_set, extract_vertex_coordinate_set, format_jaccard_report,
jaccard_distance, jaccard_index,
};
pub use crate::triangulation::query::{
CavityBoundary, ConflictRegion, ConflictSimplexView, QueryError,
};
pub use crate::{DelaunayTriangulation, Triangulation};
pub use crate::{SimplexBarycenterError, SimplexDataFillError};
}
pub mod prelude {
pub use crate::query::{
DataCopy, DataDebug, DataDeserialize, DataIdentity, DataSerde, DataSerialize, DataType,
QueryError, RidgeCandidate, RidgeCandidateError, RidgeHandle, RidgeLinkView, RidgeQuery,
RidgeView, SimplexBarycenterError, SimplexDataFillError,
};
pub use crate::tds::*;
pub use crate::vertex;
pub use crate::{
ConstructionOptions, ConstructionSkipSample, ConstructionSlowInsertionSample,
ConstructionStatistics, DedupPolicy, DedupTolerance, DelaunayCheckPolicy,
DelaunayConstructionFailure, DelaunayConstructionRepairPhase,
DelaunayConstructionRetryFailure, DelaunayError, DelaunayIncrementalBuilder,
DelaunayIncrementalBuilderError, DelaunayRefinementBuilder, DelaunayRepairOperation,
DelaunayRepairPolicy, DelaunayResult, DelaunayTriangulation, DelaunayTriangulationBuilder,
DelaunayTriangulationConstructionError,
DelaunayTriangulationConstructionErrorWithStatistics, DelaunayTriangulationRefinementError,
DelaunayTriangulationValidationError, DelaunayVerificationError,
DelaunayVerificationErrorKind, DuplicateDetectionMetrics, FinalDelaunayValidationContext,
FinalTopologyValidationContext, InitialSimplexStrategy, InsertionOrderStrategy,
InsertionResult, PeriodicDomainPeriodError, PlManifoldRepairError,
PlManifoldRepairRefinementError, PlManifoldRepairStage, PlManifoldRepairStats,
RefinementError, RepairDecision, RepairSkipReason, RetryPolicy, SphericalDelaunayBuilder,
SphericalDelaunayConstructionError, SphericalDelaunayTriangulation,
SphericalDelaunayValidationError, SphericalMetric, SphericalPoint, SphericalPointError,
SphericalSimplex, SphericalSimplexError, SphericalValidationLayer, TopologicalOperation,
TopologyGuarantee, Triangulation, TriangulationConstructionError,
TriangulationRealizationIntersectionDetail, TriangulationRealizationSimplexDetail,
TriangulationRealizationSimplexPairDetail, TriangulationRealizationValidationError,
TriangulationRealizationValidationErrorKind, TriangulationRealizationValidationReport,
TriangulationValidationError, TriangulationValidationReport, ValidationConfigurationError,
ValidationPolicy, try_vertices_from_points,
};
pub use self::ordering::{
HilbertBitDepth, HilbertError, HilbertQuantizedBatch, HilbertQuantizedVec,
MAX_HILBERT_BITS, hilbert_index_in_range, hilbert_indices_for_quantized_batch,
hilbert_indices_prequantized, hilbert_quantize_batch_in_range, hilbert_quantize_in_range,
hilbert_sort_by_stable_in_range, hilbert_sort_by_unstable_in_range,
hilbert_sorted_indices_in_range, try_hilbert_index, try_hilbert_quantize,
try_hilbert_sort_by_stable, try_hilbert_sort_by_unstable, try_hilbert_sorted_indices,
};
pub use crate::core::util::{
DeduplicationError, dedup_vertices_exact, filter_vertices_excluding,
try_dedup_vertices_epsilon,
};
pub use crate::delaunay_property_validation::{
DelaunayValidationError, DelaunayViolationDetail, DelaunayViolationReport,
delaunay_violation_report, find_delaunay_violations,
};
pub use crate::query::{
JaccardComputationError, extract_edge_set, extract_facet_identifier_set,
extract_hull_facet_set, extract_vertex_coordinate_set, format_jaccard_report,
jaccard_distance, jaccard_index, measure_with_result,
};
pub use crate::tds::{
UuidValidationError, checked_facet_key_from_vertex_keys, make_uuid, stable_hash_u64_slice,
usize_to_u8, validate_uuid, verify_facet_index_consistency,
};
pub use crate::topology::{
GlobalTopology, GlobalTopologyModelError, TopologyError, TopologyKind,
ToroidalConstructionMode, ToroidalDomain, ToroidalDomainError,
};
pub use crate::algorithms::{
ConflictError, InternalInconsistencySite, LocateError, LocateFallback,
LocateFallbackReason, LocateResult, LocateStats, locate, locate_with_stats,
};
pub mod checkpoint {
pub use crate::checkpoint::{
DELAUNAY_CHECKPOINT_DIGEST_ALGORITHM, DELAUNAY_CHECKPOINT_DIGEST_VERSION,
DELAUNAY_CHECKPOINT_MANIFEST_VERSION, DELAUNAY_CHECKPOINT_SCHEMA_VERSION,
DelaunayCheckpoint, DelaunayCheckpointDecodeError, DelaunayCheckpointDigest,
DelaunayCheckpointDigestAlgorithm, DelaunayCheckpointError,
DelaunayCheckpointLoadError, DelaunayCheckpointManifest,
DelaunayCheckpointTdsHydrationError, DelaunayCheckpointV1,
};
}
pub use crate::{
CavityFillingError, CavityRepairStage, DelaunayRepairErrorKind,
DelaunayRepairFailureContext, HullExtensionReason, InitialSimplexConstructionError,
InitialSimplexUnexpectedInsertionStage, InsertionError, InsertionErrorKind,
InsertionErrorSourceKind, InsertionTopologyValidationContext, NeighborRebuildError,
NeighborWiringError, SpatialIndexConstructionFailure, TdsConstructionFailure,
TdsValidationFailure,
};
pub use crate::{InsertionOutcome, InsertionStatistics, SuspicionFlags};
pub use crate::flips::{
DelaunayRepairDiagnostics, DelaunayRepairError, DelaunayRepairHeuristicRebuildFailure,
DelaunayRepairHeuristicRebuildFailureKind, DelaunayRepairHeuristicVertexContext,
DelaunayRepairOrientationCanonicalizationFailure,
DelaunayRepairOrientationCanonicalizationFailureKind, DelaunayRepairPostconditionFailure,
DelaunayRepairStats, DelaunayRepairVerificationContext, FlipContextError,
FlipEdgeAdjacencyError, FlipError, FlipFailureKind, FlipMutationError,
FlipNeighborCavityFailureKind, FlipNeighborDelaunayValidationFailureKind,
FlipNeighborHullExtensionFailureKind, FlipNeighborRepairDiagnostics,
FlipNeighborRepairFailure, FlipNeighborWiringError, FlipOrientationCheckStage,
FlipPredicateError, FlipPredicateOperation, FlipTriangleAdjacencyError,
FlipVertexAdjacencyError, RepairQueueOrder, TriangleHandleError,
};
pub use crate::collections::{
FastHashMap, FastHashSet, SecureHashMap, SecureHashSet, SimplexNeighborsMap,
SimplexSecondaryMap, SmallBuffer, VertexSecondaryMap, VertexToSimplicesMap,
fast_hash_map_with_capacity, fast_hash_set_with_capacity,
};
pub use crate::geometry::{
algorithms::*, coordinate_range::*, kernel::*, matrix::*, point::*, predicates::*,
quality::*, robust_predicates::*, traits::coordinate::*, util::*,
};
pub mod construction {
pub use crate::builder::{DelaunayTriangulationBuilder, ExplicitConstructionError};
pub use crate::construction::{
ConstructionOptions, ConstructionSkipSample, ConstructionSlowInsertionSample,
ConstructionStatistics, DedupPolicy, DedupTolerance, DelaunayConstructionFailure,
DelaunayConstructionRepairPhase, DelaunayConstructionRetryFailure, DelaunayError,
DelaunayResult, DelaunayTriangulationConstructionError,
DelaunayTriangulationConstructionErrorWithStatistics, InitialSimplexStrategy,
InsertionOrderStrategy, RetryPolicy,
};
pub use crate::core::util::DeduplicationError;
pub use crate::geometry::coordinate_range::{
CoordinateRangeBound, CoordinateRangeError, CoordinateRangeOrdering,
InvalidCoordinateValue,
};
pub use crate::geometry::traits::coordinate::CoordinateValidationError;
pub use crate::geometry::util::{InvalidPositiveScalar, RandomPointGenerationError};
pub use crate::repair::DelaunayRepairPolicy;
pub use crate::spherical::{
SphericalDelaunayBuilder, SphericalDelaunayConstructionError,
SphericalDelaunayTriangulation, SphericalDelaunayValidationError, SphericalSimplex,
SphericalSimplexError, SphericalValidationLayer,
};
pub use crate::tds::{
SimplexValidationError, SimplexValidationReport, Vertex, VertexValidationError,
VertexValidationReport,
};
pub use crate::topology::traits::{
GlobalTopology, GlobalTopologyModelError, TopologyKind, ToroidalConstructionMode,
ToroidalDomain, ToroidalDomainError,
};
pub use crate::validation::{
DelaunayTriangulationValidationError, DelaunayVerificationError,
DelaunayVerificationErrorKind,
};
pub use crate::vertex;
pub use crate::{
CavityFillingError, CavityRepairStage, DelaunayIncrementalBuilder,
DelaunayIncrementalBuilderError, DelaunayTriangulation, FinalDelaunayValidationContext,
FinalTopologyValidationContext, SpatialIndexConstructionFailure, TopologyGuarantee,
Triangulation, TriangulationConstructionError, TriangulationRealizationValidationError,
try_vertices_from_points,
};
pub use crate::{
TriangulationBuildFailure, TriangulationBuilder, TriangulationBuilderError,
};
}
pub mod triangulation {
pub use crate::collections::{SimplexKeyBuffer, SmallBuffer};
pub use crate::geometry::kernel::{
AdaptiveKernel, ExactPredicates, FastKernel, Kernel, RobustKernel,
};
pub use crate::geometry::point::Point;
pub use crate::query::{
AllFacetsIter, BoundaryFacetsIter, DataCopy, DataDebug, DataDeserialize, DataIdentity,
DataSerde, DataSerialize, DataType, EdgeIndex, EdgeKey, EdgeKeyError, EdgeView,
FacetIncidenceView, FacetToSimplicesIndex, FacetView, IncidenceView,
OneSidedFacetsIter, QueryError, RidgeCandidate, RidgeCandidateError, RidgeHandle,
RidgeLinkView, RidgeQuery, RidgeView, SimplexFacetsIter, SimplexNeighborIndex,
TopologyIndexBuildError, TriangulationAdjacency,
};
pub use crate::tds::{
FacetHandle, InvariantError, NeighborSlot, Simplex, SimplexKey, Tds,
TdsConstructionError, TdsError, TdsErrorKind, TdsMutationError,
TriangulationValidationErrorKind, Vertex, VertexKey,
};
pub use crate::topology::manifold::ManifoldError;
pub use crate::vertex;
pub use crate::{
InsertionError, LocalFacetRepairGuard, PeriodicDomainPeriodError, RefinementError,
SpatialIndexConstructionFailure, TopologyGuarantee, Triangulation,
TriangulationBuildFailure, TriangulationBuilder, TriangulationBuilderError,
TriangulationConstructionError, TriangulationRealizationIntersectionDetail,
TriangulationRealizationSimplexDetail, TriangulationRealizationSimplexPairDetail,
TriangulationRealizationValidationError, TriangulationRealizationValidationErrorKind,
TriangulationRealizationValidationReport, TriangulationValidationError,
TriangulationValidationReport, ValidationConfigurationError, ValidationPolicy,
};
}
pub mod pachner {
pub use crate::flips::{
BistellarFlipKind, BistellarFlipKindError, FlipDirection, FlipError, RidgeHandle,
TriangleHandle, TriangleHandleError,
};
pub use crate::pachner::{
PachnerMove, PachnerMoveFeasibility, PachnerMoveResult, PachnerMoves, PachnerProposal,
};
pub use crate::tds::{
EdgeKey, EdgeKeyError, FacetError, FacetHandle, SimplexKey, TopologyOwner,
TopologyOwnerId, Vertex, VertexKey,
};
pub use crate::vertex;
}
pub mod insertion {
pub use crate::{
CavityFillingError, CavityRepairStage, DelaunayRepairErrorKind,
DelaunayRepairFailureContext, HullExtensionReason, InitialSimplexConstructionError,
InitialSimplexUnexpectedInsertionStage, InsertionError, InsertionErrorKind,
InsertionErrorSourceKind, InsertionTopologyValidationContext, NeighborRebuildError,
NeighborWiringError, SpatialIndexConstructionFailure, TdsConstructionFailure,
TdsValidationFailure,
};
pub use crate::{InsertionOutcome, InsertionResult, InsertionStatistics};
}
pub mod deletion {
pub use crate::tds::VertexKey;
pub use crate::{DeleteVertexError, TriangulationRepairOperation};
}
pub mod operations {
pub use crate::{
InsertionOutcome, InsertionResult, InsertionStatistics, RepairDecision,
RepairSkipReason, SuspicionFlags, TopologicalOperation,
};
}
pub mod repair {
pub use crate::flips::{
DelaunayRepairDiagnostics, DelaunayRepairError, DelaunayRepairHeuristicRebuildFailure,
DelaunayRepairHeuristicRebuildFailureKind, DelaunayRepairHeuristicVertexContext,
DelaunayRepairOrientationCanonicalizationFailure,
DelaunayRepairOrientationCanonicalizationFailureKind,
DelaunayRepairPostconditionFailure, DelaunayRepairStats,
DelaunayRepairVerificationContext, FlipContextError, FlipEdgeAdjacencyError, FlipError,
FlipFailureKind, FlipMutationError, FlipNeighborCavityFailureKind,
FlipNeighborDelaunayValidationFailureKind, FlipNeighborHullExtensionFailureKind,
FlipNeighborRepairDiagnostics, FlipNeighborRepairFailure, FlipNeighborWiringError,
FlipOrientationCheckStage, FlipPredicateError, FlipPredicateOperation,
FlipTriangleAdjacencyError, FlipVertexAdjacencyError, RepairQueueOrder,
TriangleHandleError,
};
pub use crate::repair::{DelaunayCheckPolicy, DelaunayRepairPolicy};
pub use crate::topology::traits::GlobalTopology;
pub use crate::{
DelaunayRepairErrorKind, DelaunayRepairOperation, DelaunayTriangulation,
DelaunayTriangulationValidationError, DelaunayVerificationError,
DelaunayVerificationErrorKind, PlManifoldRepairConfig, PlManifoldRepairError,
PlManifoldRepairRefinementError, PlManifoldRepairStage, PlManifoldRepairStats,
PlManifoldTdsRepairResult, repair_pl_manifold_tds,
};
pub use crate::{
DelaunayValidationError, DelaunayViolationDetail, DelaunayViolationReport,
delaunay_violation_report, find_delaunay_violations,
};
pub use crate::{
TopologyGuarantee, Triangulation, ValidationConfigurationError, ValidationPolicy,
};
}
pub mod delaunayize {
pub use crate::delaunayize::*;
pub use crate::{DelaunayTriangulation, DelaunayTriangulationBuilder, RefinementError};
}
pub mod validation {
pub use crate::topology::manifold::ManifoldError;
pub use crate::validation::*;
pub use crate::{
DelaunayTriangulationRefinementError, DelaunayTriangulationValidationError,
DelaunayVerificationError, DelaunayVerificationErrorKind, OrientationWitness,
PeriodicDomainPeriodError, RefinementError, SphericalDelaunayValidationError,
SphericalValidationLayer, TopologyGuarantee,
TriangulationRealizationIntersectionDetail, TriangulationRealizationSimplexDetail,
TriangulationRealizationSimplexPairDetail, TriangulationRealizationValidationError,
TriangulationRealizationValidationErrorKind, TriangulationRealizationValidationReport,
TriangulationValidationError, TriangulationValidationReport,
ValidationConfigurationError, ValidationPolicy,
};
pub use crate::{
DelaunayValidationError, DelaunayViolationDetail, DelaunayViolationReport,
delaunay_violation_report, find_delaunay_violations,
};
}
pub mod collections {
pub use crate::collections::{
Entry, FacetIndex, FacetSharingSimplicesBuffer, FastBuildHasher, FastHashMap,
FastHashSet, FastHasher, KeyBasedSimplexMap, KeyBasedVertexMap,
MAX_PRACTICAL_DIMENSION_SIZE, NeighborBuffer, PeriodicOffsetBuffer, SecureHashMap,
SecureHashSet, SimplexKeyBuffer, SimplexKeySet, SimplexNeighborsMap,
SimplexSecondaryMap, SimplexVertexBuffer, SimplexVertexKeyBuffer, SimplexVertexKeysMap,
SimplexVertexUuidBuffer, SimplexVerticesMap, SmallBuffer, Uuid, UuidToSimplexKeyMap,
UuidToVertexKeyMap, VertexKeyBuffer, VertexKeySet, VertexSecondaryMap,
VertexToSimplicesMap, VertexUuidSet, fast_hash_map_with_capacity,
fast_hash_set_with_capacity,
};
pub mod algorithm_buffers {
pub use crate::collections::algorithm_buffers::{
CLEANUP_OPERATION_BUFFER_SIZE, CavityBoundaryBuffer, GeometricPointBuffer,
SimplexRemovalBuffer, ViolationBuffer,
};
}
}
pub mod tds {
pub use crate::collections::{
FacetIndex, FastHashMap, FastHashSet, NeighborBuffer, PeriodicOffsetBuffer,
SimplexKeyBuffer, SmallBuffer, Uuid,
};
pub use crate::tds::*;
}
pub mod geometry {
pub use crate::geometry::{
coordinate_range::{
CoordinateRange, CoordinateRangeBound, CoordinateRangeError,
CoordinateRangeOrdering, InvalidCoordinateValue,
},
kernel::{AdaptiveKernel, ExactPredicates, FastKernel, Kernel, RobustKernel},
matrix::{LaError, Matrix, MatrixError, determinant},
point::Point,
predicates::{
InSphere, Orientation, insphere, insphere_distance, insphere_lifted,
simplex_orientation,
},
quality::{
QualityDegeneracyMeasure, QualityError, QualityNumericOperation,
QualitySimplexVerticesError, normalized_volume, radius_ratio,
},
realization::{
LabeledSimplexRealization, LabeledSimplexRealizationError, PeriodicSimplexSpan,
PeriodicSimplexSpanError, SimplexIntersectionFailure, SimplexIntersectionWitness,
SimplexRealizationBuffer, axis_aligned_bounding_boxes_overlap,
coordinate_range_for_axis, try_periodic_simplex_span,
validate_simplex_intersection,
},
robust_predicates::{
ConsistencyResult, InsphereConsistencyError, robust_insphere, robust_orientation,
},
sos::{sos_insphere_sign, sos_orientation_sign},
traits::coordinate::{
Coordinate, CoordinateConversionError, CoordinateConversionValue,
CoordinateIdentity, CoordinateRepresentation, CoordinateValidationError,
CoordinateValues, DEFAULT_TOLERANCE_F64, DegenerateSimplexReason,
F64_MANTISSA_DIGITS, FiniteCheck, FiniteCoordinateValue, HashCoordinate,
OrderedCmp, OrderedEq,
},
util::{
ArrayConversionFailureReason, CircumcenterError, CircumcenterFailureReason,
DegenerateGeometry, DegenerateMeasure, SurfaceMeasureError, ValueConversionError,
ValueConversionFailureReason, circumcenter, circumradius, circumradius_with_center,
facet_measure, hypot, inradius, safe_coords_from_f64, safe_coords_to_f64,
safe_scalar_from_f64, safe_scalar_to_f64, safe_usize_to_scalar, simplex_volume,
squared_norm, surface_measure,
},
};
}
pub mod algorithms {
pub use crate::algorithms::{
ConflictError, InternalInconsistencySite, LocateError, LocateFallback,
LocateFallbackReason, LocateResult, LocateStats, locate, locate_with_stats,
};
}
pub mod diagnostics {
#[cfg(feature = "diagnostics")]
#[cfg_attr(docsrs, doc(cfg(feature = "diagnostics")))]
pub use crate::debug_print_first_delaunay_violation;
pub use crate::diagnostics::{
BatchLocalRepairTrigger, ConstructionTelemetry, LocalRepairSample,
};
}
pub mod export {
pub use crate::geometry::traits::coordinate::InvalidCoordinateValue;
pub use crate::io::visualization::{
AdjacencyRecord, SimplexRecord, VISUALIZATION_SCHEMA, VISUALIZATION_SCHEMA_VERSION,
ValidatedVisualizationData, VertexRecord, VisualizationData,
VisualizationDataValidationError, VisualizationExportError, VisualizationMetadata,
VisualizationTopologyGuarantee, VisualizationTopologyKind,
};
}
pub mod query {
pub use crate::tds::{
EdgeIndex, EdgeKey, EdgeKeyError, EdgeView, FacetHandle, FacetIncidenceView,
FacetToSimplicesIndex, IncidenceView, SimplexKey, SimplexNeighborIndex,
TopologyIndexBuildError, TriangulationAdjacency, VertexKey,
};
pub use crate::{DelaunayTriangulation, Triangulation};
pub use crate::geometry::Point;
pub use crate::geometry::kernel::{
AdaptiveKernel, ExactPredicates, FastKernel, Kernel, RobustKernel,
};
pub use crate::geometry::traits::coordinate::Coordinate;
pub use crate::query::{
AllFacetsIter, BoundaryFacetsIter, DataCopy, DataDebug, DataDeserialize, DataIdentity,
DataSerde, DataSerialize, DataType, FacetView, OneSidedFacetsIter, QueryError,
RidgeCandidate, RidgeCandidateError, RidgeHandle, RidgeLinkView, RidgeQuery, RidgeView,
Simplex, SimplexBarycenterError, SimplexDataFillError, SimplexFacetsIter, Vertex,
};
pub use crate::geometry::{insphere, insphere_distance, insphere_lifted};
pub use crate::assert_jaccard_gte;
pub use crate::geometry::algorithms::convex_hull::{
ConvexHull, ConvexHullConstructionError, ConvexHullFacetView,
ConvexHullInsufficientDataReason, ConvexHullQueryError, ConvexHullVertex,
};
pub use crate::query::{
JaccardComputationError, extract_edge_set, extract_facet_identifier_set,
extract_hull_facet_set, extract_vertex_coordinate_set, format_jaccard_report,
jaccard_distance, jaccard_index,
};
pub use crate::query::measure_with_result;
}
pub mod generators {
pub use crate::TopologyGuarantee;
pub use crate::construction::InsertionOrderStrategy;
pub use crate::geometry::coordinate_range::{
CoordinateRange, CoordinateRangeBound, CoordinateRangeError, CoordinateRangeOrdering,
InvalidCoordinateValue,
};
pub use crate::geometry::util::{
InvalidPositiveScalar, RandomPointCount, RandomPointCountError,
RandomPointGenerationError, RandomTriangulationBuilder,
RandomTriangulationBuilderError, generate_grid_points,
generate_poisson_points_in_range, generate_random_points_in_ball,
generate_random_points_in_ball_seeded, generate_random_points_in_range,
generate_random_points_in_range_seeded, generate_random_points_periodic,
generate_random_triangulation_in_range,
generate_random_triangulation_in_range_with_topology, scaled_bounds_by_point_count,
try_generate_poisson_points, try_generate_random_points,
try_generate_random_points_seeded, try_generate_random_triangulation,
try_generate_random_triangulation_with_topology,
};
}
pub mod ordering {
pub use crate::core::util::{
HilbertBitDepth, HilbertError, HilbertQuantizedBatch, HilbertQuantizedVec,
MAX_HILBERT_BITS, hilbert_index_in_range, hilbert_indices_for_quantized_batch,
hilbert_indices_prequantized, hilbert_quantize_batch_in_range,
hilbert_quantize_in_range, hilbert_sort_by_stable_in_range,
hilbert_sort_by_unstable_in_range, hilbert_sorted_indices_in_range, try_hilbert_index,
try_hilbert_quantize, try_hilbert_sort_by_stable, try_hilbert_sort_by_unstable,
try_hilbert_sorted_indices,
};
}
pub mod topology {
pub mod validation {
pub use crate::topology::TopologyGuarantee;
pub use crate::topology::characteristics::{euler, validation};
pub use crate::topology::characteristics::{euler::*, validation::*};
pub use crate::topology::manifold::{
BoundaryFacetClassification, ManifoldError, classify_boundary_facet,
validate_closed_boundary, validate_ridge_links, validate_ridge_links_for_simplices,
validate_vertex_links,
};
pub use crate::topology::ridge::{
RidgeCandidate, RidgeCandidateError, RidgeLinkView, RidgeQuery, RidgeView,
};
pub use crate::topology::traits::{
GlobalTopology, GlobalTopologyModelError, TopologicalSpace, TopologyError,
TopologyKind, ToroidalConstructionMode,
};
}
pub mod spaces {
pub use crate::topology::spaces::*;
pub use crate::topology::traits::{
GlobalTopology, GlobalTopologyModelError, TopologicalSpace, TopologyError,
TopologyKind, ToroidalConstructionMode, ToroidalDomain, ToroidalDomainError,
};
}
}
}
#[cfg(test)]
mod tests {
use crate::geometry::matrix::LaError;
use crate::{
DelaunayTriangulation, PlManifoldRepairConfig, PlManifoldRepairError,
PlManifoldRepairStage, PlManifoldRepairStats, PlManifoldTdsRepairResult,
TriangulationBuildFailure, TriangulationBuilder,
core::{
adjacency::TriangulationAdjacency, edge::EdgeKey, simplex::Simplex, tds::Tds,
vertex::Vertex,
},
geometry::{
Point, algorithms::convex_hull::ConvexHull, kernel::FastKernel, util::CircumcenterError,
},
prelude::delaunayize::{
DelaunayTriangulationConstructionError, DelaunayizeError, DelaunayizeOutcome,
DelaunayizeRefinementError, SimplexDataRestoreError, SimplexValidationError,
},
prelude::repair::{
DelaunayCheckPolicy, DelaunayRepairError, DelaunayRepairPolicy, DelaunayRepairStats,
DelaunayTriangulation as RepairDelaunayTriangulation, FlipContextError, FlipError,
RepairQueueOrder, TopologyGuarantee,
},
prelude::*,
triangulation::Triangulation,
vertex,
};
use std::assert_matches;
#[cfg(feature = "count-allocations")]
use allocation_counter::measure;
#[test]
fn normal_types() {
const fn assert_normal<T: Send + Sync + Unpin>() {}
assert_normal::<Point<3>>();
assert_normal::<Vertex<(), 3>>();
assert_normal::<Simplex<(), 4>>();
assert_normal::<Tds<(), (), 4>>();
assert_normal::<Triangulation<FastKernel<f64>, (), (), 3>>();
assert_normal::<DelaunayTriangulation<FastKernel<f64>, (), (), 3>>();
assert_normal::<TriangulationBuilder<FastKernel<f64>, (), (), 3>>();
assert_normal::<DelaunayRefinementBuilder<FastKernel<f64>, (), (), 3>>();
assert_normal::<ConvexHull<(), 3>>();
assert_normal::<EdgeKey>();
assert_normal::<TriangulationAdjacency<'static>>();
assert_normal::<DelaunayizeOutcome>();
assert_normal::<DelaunayizeError>();
assert_normal::<RefinementError<u8, DelaunayizeError>>();
assert_normal::<DelaunayizeRefinementError<FastKernel<f64>, (), (), 3>>();
assert_normal::<TriangulationBuildFailure<(), (), 3>>();
assert_normal::<DelaunayTriangulationRefinementError<FastKernel<f64>, (), (), 3>>();
assert_normal::<DelaunayRepairError>();
assert_normal::<DelaunayRepairStats>();
assert_normal::<PlManifoldRepairError>();
assert_normal::<PlManifoldRepairRefinementError<(), (), 3>>();
assert_normal::<PlManifoldRepairStage>();
assert_normal::<PlManifoldRepairStats<(), (), 3>>();
assert_normal::<PlManifoldRepairConfig>();
assert_normal::<PlManifoldTdsRepairResult<(), (), 3>>();
assert_normal::<SimplexDataRestoreError>();
assert_normal::<SimplexValidationError>();
assert_normal::<DelaunayError>();
assert_normal::<DelaunayTriangulationConstructionError>();
}
#[test]
fn circumcenter_error_clones_linear_algebra_source() {
let source = LaError::non_finite_input_matrix(1, 2);
let error = CircumcenterError::LinearAlgebraFailure { source };
assert_eq!(error.clone(), error);
assert!(error.to_string().contains("Linear algebra"));
}
#[test]
fn la_errors_map_to_public_circumcenter_errors() {
let unsupported = CircumcenterError::from(LaError::unsupported_dimension(9, 7));
assert_eq!(
unsupported,
CircumcenterError::UnsupportedMatrixDimension {
requested: 9,
max: 7,
}
);
let index_error = CircumcenterError::from(LaError::index_out_of_bounds(3, 4, 2));
assert_eq!(
index_error,
CircumcenterError::MatrixError {
source: MatrixError::OutOfBounds {
row: 3,
column: 4,
dimension: 2,
},
}
);
}
#[test]
fn prelude_collections_exports() {
let mut map: FastHashMap<u64, usize> = FastHashMap::default();
map.insert(123, 456);
assert_eq!(map.get(&123), Some(&456));
let mut set: FastHashSet<u64> = FastHashSet::default();
set.insert(789);
assert!(set.contains(&789));
let mut buffer: SmallBuffer<i32, 8> = SmallBuffer::new();
buffer.push(42);
assert_eq!(buffer.len(), 1);
let map_with_cap = fast_hash_map_with_capacity::<u64, usize>(100);
assert!(map_with_cap.capacity() >= 100);
let set_with_cap = fast_hash_set_with_capacity::<u64>(50);
assert!(set_with_cap.capacity() >= 50);
let _neighbors: SimplexNeighborsMap = SimplexNeighborsMap::default();
let _vertex_simplices: VertexToSimplicesMap = VertexToSimplicesMap::default();
}
#[test]
fn prelude_repair_exports() {
let vertices = vec![
vertex![0.0, 0.0].unwrap(),
vertex![1.0, 0.0].unwrap(),
vertex![0.0, 1.0].unwrap(),
];
let dt: RepairDelaunayTriangulation<_, (), (), 2> =
RepairDelaunayTriangulation::builder(&vertices)
.build()
.unwrap();
assert!(dt.verify_via_flip_predicates().is_ok());
assert!(dt.is_valid_delaunay().is_ok());
let stats = DelaunayRepairStats::default();
assert_eq!(stats.flips_performed, 0);
let order = RepairQueueOrder::Fifo;
assert_matches!(order, RepairQueueOrder::Fifo);
assert_eq!(
DelaunayRepairPolicy::default(),
DelaunayRepairPolicy::EveryInsertion
);
assert_eq!(DelaunayCheckPolicy::default(), DelaunayCheckPolicy::EndOnly);
let err = DelaunayRepairError::from(FlipError::DegenerateSimplex);
assert_matches!(err, DelaunayRepairError::Flip { .. });
let context_err = FlipContextError::ReplacementPeriodicOffsetCountMismatch {
simplex_count: 1,
offset_count: 0,
};
assert_matches!(
context_err,
FlipContextError::ReplacementPeriodicOffsetCountMismatch { .. }
);
let topo = TopologyGuarantee::PLManifold;
assert_matches!(topo, TopologyGuarantee::PLManifold);
}
#[test]
fn prelude_quality_exports() {
let vertices = vec![
vertex![0.0, 0.0].unwrap(),
vertex![1.0, 0.0].unwrap(),
vertex![0.0, 1.0].unwrap(),
];
let dt: DelaunayTriangulation<_, (), (), 2> =
DelaunayTriangulation::builder(&vertices).build().unwrap();
let (simplex_key, _) = dt.simplices().next().unwrap();
let ratio = radius_ratio(dt.as_triangulation(), simplex_key).unwrap();
assert!(ratio > 0.0);
let norm_vol = normalized_volume(dt.as_triangulation(), simplex_key).unwrap();
assert!(norm_vol > 0.0);
}
#[test]
fn test_prelude_kernel_exports() {
let fast_kernel = FastKernel::<f64>::new();
let robust_kernel = RobustKernel::<f64>::new();
let triangle = [
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([0.0, 1.0]).expect("finite point coordinates"),
];
let fast_orientation = fast_kernel.orientation(&triangle).unwrap();
assert_ne!(fast_orientation, 0, "Triangle should be non-degenerate");
let robust_orientation = robust_kernel.orientation(&triangle).unwrap();
assert_eq!(
fast_orientation, robust_orientation,
"Both kernels should agree"
);
let collinear = [
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([2.0, 0.0]).expect("finite point coordinates"),
];
assert_eq!(
fast_kernel.orientation(&collinear).unwrap(),
0,
"Collinear points should have zero orientation"
);
let inside_point = Point::try_new([0.25, 0.25]).expect("finite point coordinates");
let result = fast_kernel.in_sphere(&triangle, &inside_point).unwrap();
assert_eq!(result, 1, "Point should be inside circumcircle");
let outside_point = Point::try_new([2.0, 2.0]).expect("finite point coordinates");
let result = fast_kernel.in_sphere(&triangle, &outside_point).unwrap();
assert_eq!(result, -1, "Point should be outside circumcircle");
}
#[test]
fn test_prelude_core_types() {
let p1 = Point::try_new([0.0, 0.0, 0.0]).expect("finite point coordinates");
let p2 = Point::try_new([1.0, 0.0, 0.0]).expect("finite point coordinates");
assert_ne!(p1, p2);
let v1: Vertex<(), 3> = vertex!([0.0, 0.0, 0.0]).unwrap();
let v2: Vertex<(), 3> = vertex!([1.0, 0.0, 0.0]).unwrap();
assert_ne!(v1.point(), v2.point());
let vertices = vec![
vertex![0.0, 0.0, 0.0].unwrap(),
vertex![1.0, 0.0, 0.0].unwrap(),
vertex![0.0, 1.0, 0.0].unwrap(),
vertex![0.0, 0.0, 1.0].unwrap(),
];
let dt: DelaunayTriangulation<_, (), (), 3> =
DelaunayTriangulation::builder(&vertices).build().unwrap();
assert_eq!(dt.number_of_vertices(), 4);
assert_eq!(dt.number_of_simplices(), 1);
let tri = dt.as_triangulation();
assert_eq!(tri.number_of_vertices(), 4);
assert_eq!(tri.number_of_simplices(), 1);
for (simplex_key, _simplex) in tri.simplices() {
assert!(tri.simplex(simplex_key).is_some());
}
}
#[test]
fn test_prelude_point_location() {
let vertices = vec![
vertex![0.0, 0.0].unwrap(),
vertex![1.0, 0.0].unwrap(),
vertex![0.0, 1.0].unwrap(),
];
let dt: DelaunayTriangulation<_, (), (), 2> =
DelaunayTriangulation::builder(&vertices).build().unwrap();
let query_point = Point::try_new([0.3, 0.3]).expect("finite point coordinates");
let result = dt.locate(&query_point, None);
assert!(result.is_ok());
match result.unwrap() {
LocateResult::InsideSimplex(_)
| LocateResult::OnFacet { .. }
| LocateResult::OnEdge { .. }
| LocateResult::OnVertex(_) => { }
LocateResult::Outside => panic!("Point should be inside triangulation"),
}
let outside_point = Point::try_new([10.0, 10.0]).expect("finite point coordinates");
let result = dt.locate(&outside_point, None);
assert!(result.is_ok());
}
#[test]
fn test_prelude_geometry_types() {
let p = Point::try_new([1.0_f64, 2.0_f64, 3.0_f64]).expect("finite point coordinates");
assert!((p.coords()[0] - 1.0_f64).abs() < f64::EPSILON);
assert!((p.coords()[1] - 2.0_f64).abs() < f64::EPSILON);
assert!((p.coords()[2] - 3.0_f64).abs() < f64::EPSILON);
let triangle = [
Point::try_new([0.0, 0.0]).expect("finite point coordinates"),
Point::try_new([1.0, 0.0]).expect("finite point coordinates"),
Point::try_new([0.0, 1.0]).expect("finite point coordinates"),
];
let orientation = simplex_orientation(&triangle).unwrap();
assert_ne!(orientation, Orientation::DEGENERATE);
let test_point = Point::try_new([0.25, 0.25]).expect("finite point coordinates");
let result = insphere(&triangle, test_point).unwrap();
assert_eq!(result, InSphere::INSIDE);
}
#[test]
fn test_prelude_convex_hull() {
let vertices = vec![
vertex![0.0, 0.0, 0.0].unwrap(),
vertex![1.0, 0.0, 0.0].unwrap(),
vertex![0.0, 1.0, 0.0].unwrap(),
vertex![0.0, 0.0, 1.0].unwrap(),
];
let dt: DelaunayTriangulation<_, (), (), 3> =
DelaunayTriangulation::builder(&vertices).build().unwrap();
let hull = ConvexHull::try_from_triangulation(dt.as_triangulation()).unwrap();
assert_eq!(hull.number_of_facets(), 4);
let outside_point = Point::try_new([2.0, 2.0, 2.0]).expect("finite point coordinates");
let is_outside = hull.is_point_outside(&outside_point).unwrap();
assert!(is_outside);
let inside_point = Point::try_new([0.25, 0.25, 0.25]).expect("finite point coordinates");
let is_outside = hull.is_point_outside(&inside_point).unwrap();
assert!(!is_outside);
}
#[cfg(feature = "count-allocations")]
#[test]
fn basic_alloc_counting() {
let result = measure(|| {
let x = 1 + 1;
assert_eq!(x, 2);
});
assert_eq!(
result.count_total, 0,
"Expected zero total allocations for trivial operation, found: {}",
result.count_total
);
assert_eq!(
result.bytes_total, 0,
"Expected zero total bytes allocated for trivial operation, found: {}",
result.bytes_total
);
assert_eq!(
result.count_current, 0,
"Expected zero current allocations after trivial operation, found: {}",
result.count_current
);
assert_eq!(
result.bytes_current, 0,
"Expected zero current bytes allocated after trivial operation, found: {}",
result.bytes_current
);
}
#[cfg(feature = "count-allocations")]
#[test]
fn alloc_counting_with_vec() {
let result = measure(|| {
let _vec: Vec<i32> = vec![1, 2, 3, 4, 5];
});
assert!(
result.count_total > 0,
"Expected some allocations for Vec creation, found: {}",
result.count_total
);
assert!(
result.bytes_total > 0,
"Expected some bytes allocated for Vec creation, found: {}",
result.bytes_total
);
assert_eq!(
result.count_current, 0,
"Expected zero current allocations after Vec drop, found: {}",
result.count_current
);
assert_eq!(
result.bytes_current, 0,
"Expected zero current bytes after Vec drop, found: {}",
result.bytes_current
);
assert!(
result.count_max >= result.count_total,
"Max count should be >= total count"
);
assert!(
result.bytes_max >= result.bytes_total,
"Max bytes should be >= total bytes"
);
}
}