Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 34 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ workflow. Agents must load every file in `docs/dev/` before making changes.
focused surfaces changed.
- **Do not edit generated changelogs manually.** Changelog and documentation
maintenance rules live in `docs/dev/docs.md`.
- **Keep README and citation prose mirrored.** The first paragraph under
`README.md`'s Introduction is mirrored by the `abstract` field in
`CITATION.cff`; update both together. The invariant is checked by
`scripts/tests/test_readme_citation_mirror.py`.

## Project Context

Expand Down Expand Up @@ -99,10 +103,13 @@ When in doubt, favor the invariant over the convenient edit.

### Topological Correctness

- Every mutating operation preserves the invariants checked by `Tds::is_valid`
(Levels 1-3) and `DelaunayTriangulation::is_valid` (Level 4). An operation
that cannot preserve them must fail explicitly rather than leave inconsistent
state behind.
- Every mutating operation preserves the invariants checked by
`Tds::is_valid` / `validate` (Levels 1-2),
`Triangulation::is_valid_topology` / `validate` (Level 3),
`Triangulation::is_valid_embedding` / `validate_embedding` (Level 4), and
`DelaunayTriangulation::is_valid_delaunay` / `validate` (Level 5). An
operation that cannot preserve them must fail explicitly rather than leave
inconsistent state behind.
- PL-manifold invariants: facets have multiplicity 1 (boundary) or 2
(interior), ridges are linked consistently, and Euler characteristic matches
the triangulation's `TopologyGuarantee`.
Expand All @@ -112,18 +119,31 @@ When in doubt, favor the invariant over the convenient edit.

### Validation Layers

The library exposes four validation levels, each a superset of the last:
The library exposes five validation levels, each a superset of the last:

1. **Level 1 - elements**: individual simplices, vertices, and facets are
internally consistent.
2. **Level 2 - structure**: adjacency pointers and neighbor links form a valid
incidence graph.
3. **Level 3 - topology**: PL-manifold-with-boundary, Euler characteristic, and
ridge-link consistency.
4. **Level 4 - Delaunay property**: every facet is locally Delaunay.

Only Level 4 requires predicate evaluation. Levels 1-3 are pure graph checks.
Validation code belongs at the lowest layer that owns the invariant.
4. **Level 4 - embedding**: maximal simplices are nondegenerate and intersect
only in shared faces in the active affine chart.
5. **Level 5 - Delaunay property**: every facet is locally Delaunay.

Level 4 uses orientation and exact barycentric geometry. Level 5 uses
Delaunay predicates. Levels 1-3 are pure graph/topology checks. Validation code
belongs at the lowest layer that owns the invariant.
Each layer should expose the standard validation surface. Use plain
`is_valid()` when the owner already names the invariant scope (`Vertex`,
`Simplex`, and `Tds`); use `is_valid_*` when higher-level owners expose
multiple validation layers. Use `*_diagnostic` for the first actionable
repair/retry diagnostic, `*_report` for layer-local aggregate diagnostics, and
`validate()` / `validation_report()` for cumulative roll-up through the owning
layer. Report names should identify the layer being checked, e.g.
`structure_report`, `topology_report`, `embedding_report`, and
`delaunay_report`. Higher layers should roll lower diagnostics up without
stringifying them.

### Symbolic Perturbation

Expand Down Expand Up @@ -175,6 +195,11 @@ enforce that contract.
- Prefer small, focused patches.
- Search `docs/`, `docs/dev/README.md`, and `docs/architecture/README.md`
before inventing new conventions.
- Opportunistically fix nearby issues discovered while working in a touched
area, even when they predate the current patch, when the fix is small,
clearly related, and improves correctness, clarity, tests, or
maintainability. Avoid broad mechanical churn; split repo-wide cleanup into
separate work.
- Keep code simple and maintainable when multiple correct solutions exist.
- Preserve numerical and topological invariants first; optimize only inside
that envelope.
5 changes: 3 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ abstract: >-
global topologies. Uses exact predicates and Simulation of Simplicity for
robustness and degeneracy handling, and Hilbert curves for deterministic
insertion ordering and efficient spatial indexing. Provides an explicit
4-level validation hierarchy on individual elements, triangulation data
structure validity, manifold topology, and Delaunay property adherence.
5-level validation hierarchy on individual elements, triangulation data
structure validity, manifold topology, faithful embedding in the active
affine chart, and Delaunay property adherence.
Allows for the complete set of Pachner moves up to D=5 using bistellar flips,
vertex insertion and deletion, and the conversion of non-Delaunay
triangulations into Delaunay triangulations via bounded flip/rebuilds.
Expand Down
37 changes: 23 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,24 @@ Rust crate providing D-dimensional [Delaunay triangulations] and [convex hulls][
[pseudomanifold][Pseudomanifold] guarantee on finite point sets with Euclidean and toroidal global
topologies. Uses [exact predicates] and [Simulation of Simplicity] for robustness and degeneracy
handling, and [Hilbert curve]s for deterministic insertion ordering and efficient spatial indexing.
Provides an explicit [4-level validation hierarchy][Validation Guide] on individual elements,
triangulation data structure validity, manifold topology, and Delaunay property adherence. Allows for
the complete set of [Pachner moves] up to D=5 using bistellar flips, vertex insertion and deletion,
and the conversion of non-Delaunay triangulations into Delaunay triangulations via bounded
flip/rebuilds. Auxiliary data may be stored directly in vertices and simplices with external
[secondary maps][Secondary maps] provided for vertex- and simplex-keyed algorithm use, and the entire
data structure is serializable/deserializable. Written in safe Rust with no unsafe code.
Provides an explicit [5-level validation hierarchy][Validation Guide] on individual elements,
triangulation data structure validity, manifold topology, faithful embedding in the active affine
chart, and Delaunay property adherence. Allows for the complete set of [Pachner moves] up to D=5
using bistellar flips, vertex insertion and deletion, and the conversion of non-Delaunay
triangulations into Delaunay triangulations via bounded flip/rebuilds. Auxiliary data may be stored
directly in vertices and simplices with external [secondary maps][Secondary maps] provided for
vertex- and simplex-keyed algorithm use, and the entire data structure is
serializable/deserializable. Written in safe Rust with no unsafe code.

Use this crate when you want:

- Delaunay triangulations or convex hulls in 2D through 5D.
- Exact predicates and deterministic SoS handling for degenerate inputs.
- Faithful Euclidean and toroidal affine embedding validation independent of Delaunay predicates.
- PL-manifold checks and explicit topology guarantees.
- PL-manifold-aware editing via bistellar flips and bounded Delaunay repair.
- Typed construction, insertion, validation, topology, and repair diagnostics.
- Validation reports that separate element, structure, topology, and Delaunay failures.
- Validation reports that separate element, structure, topology, embedding, and Delaunay failures.

This is not a replacement for full meshing packages such as [CGAL], TetGen, or Gmsh when you need
constrained Delaunay triangulations, direct Voronoi extraction, out-of-core meshing, GPU/parallel
Expand Down Expand Up @@ -147,14 +149,21 @@ and [`docs/numerical_robustness_guide.md`](docs/numerical_robustness_guide.md).
| Level | Validates | Primary API |
|---|---|---|
| 1 | Vertex, simplex, and facet element invariants | `vertex.is_valid()` / `simplex.is_valid()` |
| 2 | TDS keys, incidences, and neighbor links | `dt.tds().is_valid()` |
| 3 | Manifold topology, ridge links, and Euler consistency | `dt.as_triangulation().is_valid()` |
| 4 | Delaunay property via local predicates | `dt.is_valid()` |
| 1-4 | Cumulative diagnostics | `dt.validate()` / `dt.validation_report()` |
| 2 | TDS keys, incidences, and neighbor links | `dt.tds().is_valid()` / `dt.tds().structure_report()` |
| 3 | Manifold topology, ridge links, and Euler consistency | `dt.as_triangulation().is_valid_topology()` / `dt.as_triangulation().topology_report()` |
| 4 | Faithful embedding | `dt.as_triangulation().is_valid_embedding()` / `dt.as_triangulation().embedding_report()` |
| 5 | Delaunay property via local predicates | `dt.is_valid_delaunay()` / `dt.delaunay_report()` |
| 1-5 | Cumulative diagnostics | `dt.validate()` / `dt.validation_report()` |

`TopologyGuarantee` controls which Level 3 topology invariants are enforced. `ValidationPolicy`
controls when Level 3 checks run during incremental insertion. The default is PL-manifold topology with
explicit full-validation checkpoints.
controls when Level 3 checks run during incremental insertion. Level 4 embedding validation is
topology-aware for Euclidean and toroidal affine charts and runs before Level 5 Delaunay predicate
validation. Use `dt.as_triangulation().validate_embedding()` when you want cumulative Levels 1-4
validation. `dt.as_triangulation().embedding_report()` returns simplex keys, simplex UUIDs, and
offending vertex keys/UUIDs for Level 4 repair planning. The default is PL-manifold topology with explicit full-validation
checkpoints. Layer-local APIs use `is_valid()` for unambiguous element/TDS owners, `is_valid_*`
for higher-level fast-fail checks, and `*_diagnostic` / `*_report` for diagnostics; cumulative
APIs use `validate()` / `validation_report()`.

## 🗺️ Documentation Map

Expand Down
26 changes: 23 additions & 3 deletions REFERENCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ These references support specialized features and high-dimensional computations

### High-Dimensional Computational Geometry

- Avis, D., and Bremner, D. "How Good Are Convex Hull Algorithms?" *Computational Geometry* 7,
- Avis, D., Bremner, D., and Seidel, R. "How Good Are Convex Hull Algorithms?" *Computational Geometry* 7,
no. 5-6 (1997): 265-301. DOI: [10.1016/S0925-7721(96)00023-5](https://doi.org/10.1016/S0925-7721(96)00023-5)
- Chazelle, B. "An Optimal Convex Hull Algorithm in Any Fixed Dimension."
*Discrete & Computational Geometry* 10, no. 4 (1993): 377-409. DOI: [10.1007/BF02573985](https://doi.org/10.1007/BF02573985)
Expand Down Expand Up @@ -241,7 +241,7 @@ These references ensure the library's geometric computations are mathematically

### Geometric Tie-Breaking and Deterministic Perturbations

- Burnikel, C., Funke, S., and Mehlhorn, K. "Exact Geometric Computation Made Easy."
- Burnikel, C., Fleischer, R., Mehlhorn, K., and Schirra, S. "Efficient Exact Geometric Computation Made Easy."
*Proceedings of the Fifteenth Annual Symposium on Computational Geometry* (1999): 341-350.
DOI: [10.1145/304893.304988](https://doi.org/10.1145/304893.304988)
- Yap, C. K. "Towards Exact Geometric Computation."
Expand Down Expand Up @@ -306,7 +306,7 @@ These references inform the library's performance optimization strategies and me

### Memory-Efficient Data Structures

- Blandford, D.K., Blelloch, G.E., Dahle, C., and Karp, R. "Compact Representations of Simplicial Meshes in Two and Three Dimensions."
- Blandford, D.K., Blelloch, G.E., Cardoze, D.E., and Kadow, C. "Compact Representations of Simplicial Meshes in Two and Three Dimensions."
*International Journal of Computational Geometry & Applications* 15, no. 1 (2005): 3-24.
DOI: [10.1142/S0218195905001580](https://doi.org/10.1142/S0218195905001580)
- Geuzaine, C., and Remacle, J.-F. "Gmsh: A 3-D Finite Element Mesh Generator
Expand Down Expand Up @@ -360,3 +360,23 @@ library (facet degree, closed-boundary checks, and links of simplices).
- Rourke, C. P., and Sanderson, B. J. *Introduction to Piecewise-Linear Topology*. Springer, 1972.
- Stillwell, J. *Euler's Gem: The Polyhedron Formula and the Birth of Topology*. Princeton University Press, 2010.
- Zomorodian, A. *Topology for Computing*. Cambridge University Press, 2005.

## Embedded-Geometry Overlap Detection (Level 4 Validation)

These references support the embedded-geometry (Level 4) validator, which certifies that maximal
simplices are nondegenerate and intersect only in their shared faces. Candidate overlapping pairs
are found with a sweep-and-prune broad phase over axis-aligned bounding boxes before exact rational
barycentric intersection tests are applied. Two axis-aligned boxes intersect if and only if their
projections overlap on every coordinate axis (the separating-axis test), and sorting boxes by their
lower endpoint on one axis while retiring boxes whose upper endpoint precedes the current lower
endpoint examines a superset of all axis-overlapping pairs, so no intersecting pair is skipped.

- Baraff, D. "Dynamic Simulation of Non-Penetrating Rigid Bodies." PhD thesis, Cornell University, 1992.
Introduces coordinate sorting ("sort and sweep") for axis-aligned bounding-box overlap detection.
Available at: <https://www.cs.cmu.edu/~baraff/papers/index.html>
- Cohen, J. D., Lin, M. C., Manocha, D., and Ponamgi, M. "I-COLLIDE: An Interactive and Exact Collision
Detection System for Large-Scale Environments." *Proceedings of the 1995 Symposium on Interactive 3D
Graphics* (1995): 189-196. DOI: [10.1145/199404.199437](https://doi.org/10.1145/199404.199437)
- Ericson, C. *Real-Time Collision Detection*. Morgan Kaufmann, 2005. ISBN: 978-1-55860-732-3.
(Chapter 7: sweep-and-prune broad phase; Chapters 4-5: axis-aligned bounding boxes and the
separating-axis test for box intersection.)
2 changes: 1 addition & 1 deletion benches/ci_performance_suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! 2. Convex hull extraction from completed triangulations
//! 3. Convex hull visibility/containment queries
//! 4. Boundary facet traversal
//! 5. Full validation (Levels 1-4)
//! 5. Full validation (Levels 1-5)
//! 6. Incremental vertex insertion
//! 7. Explicit bistellar flip workflows on stable and adversarial 2D-5D
//! PL-manifold cases
Expand Down
51 changes: 48 additions & 3 deletions benches/common/flip_fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ pub const STABLE_POINTS_3D: &[[f64; 3]] = &[
///
/// The unit 4-simplex hull plus clustered but non-degenerate interior vertices
/// is the control case for 4D k=1/k=2/k=3 roundtrip benchmarks.
#[cfg_attr(
not(feature = "slow-tests"),
allow(
dead_code,
reason = "4D fixture certification is gated behind slow-tests in the integration suite"
)
)]
pub const STABLE_POINTS_4D: &[[f64; 4]] = &[
[0.0, 0.0, 0.0, 0.0],
[1.0, 0.0, 0.0, 0.0],
Expand All @@ -64,6 +71,13 @@ pub const STABLE_POINTS_4D: &[[f64; 4]] = &[
///
/// The unit 5-simplex hull plus clustered but non-degenerate interior vertices
/// is the control case for 5D k=1/k=2/k=3 roundtrip benchmarks.
#[cfg_attr(
not(feature = "slow-tests"),
allow(
dead_code,
reason = "5D fixture certification is gated behind slow-tests in the integration suite"
)
)]
pub const STABLE_POINTS_5D: &[[f64; 5]] = &[
[0.0, 0.0, 0.0, 0.0, 0.0],
[1.0, 0.0, 0.0, 0.0, 0.0],
Expand Down Expand Up @@ -108,7 +122,7 @@ pub const ADVERSARIAL_POINTS_3D: &[[f64; 3]] = &[
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 1.0, 0.0],
[1.0, 1.0, 1.0],
[1.0e-9, 0.25, 0.25],
[0.25, 1.0e-9, 0.25],
[0.25, 0.25, 1.0e-9],
Expand All @@ -121,13 +135,20 @@ pub const ADVERSARIAL_POINTS_3D: &[[f64; 3]] = &[
/// Combines a D+2 cospherical set from the simplex vertices plus one extra
/// hypercube corner, near-boundary interior points, nearly degenerate interior
/// clustering, and a large-coordinate hull point.
#[cfg_attr(
not(feature = "slow-tests"),
allow(
dead_code,
reason = "4D fixture certification is gated behind slow-tests in the integration suite"
)
)]
pub const ADVERSARIAL_POINTS_4D: &[[f64; 4]] = &[
[0.0, 0.0, 0.0, 0.0],
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 0.0],
[1.0, 1.0, 1.0, 1.0],
[1.0e-9, 0.20, 0.20, 0.20],
[0.20, 1.0e-9, 0.20, 0.20],
[0.20, 0.20, 1.0e-9, 0.20],
Expand All @@ -142,14 +163,21 @@ pub const ADVERSARIAL_POINTS_4D: &[[f64; 4]] = &[
/// Combines a D+2 cospherical set from the simplex vertices plus one extra
/// hypercube corner, near-boundary interior points, nearly degenerate interior
/// clustering, and a large-coordinate hull point.
#[cfg_attr(
not(feature = "slow-tests"),
allow(
dead_code,
reason = "5D fixture certification is gated behind slow-tests in the integration suite"
)
)]
pub const ADVERSARIAL_POINTS_5D: &[[f64; 5]] = &[
[0.0, 0.0, 0.0, 0.0, 0.0],
[1.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 0.0, 0.0],
[1.0, 1.0, 1.0, 1.0, 1.0],
[1.0e-9, 0.16, 0.16, 0.16, 0.16],
[0.16, 1.0e-9, 0.16, 0.16, 0.16],
[0.16, 0.16, 1.0e-9, 0.16, 0.16],
Expand All @@ -159,3 +187,20 @@ pub const ADVERSARIAL_POINTS_5D: &[[f64; 5]] = &[
[0.160_000_001, 0.16, 0.16, 0.16, 0.16],
[1.0e6, -1.0e6, 1.0e6, -1.0e6, 1.0e6],
];

/// Intentionally invalid 3D fixture used to prove benchmark setup rejects
/// degenerate inputs instead of silently sanitizing them.
///
/// All points are coplanar (`z = 0`), so no faithful 3D simplex embedding can
/// be formed.
#[allow(
dead_code,
reason = "negative fixture is imported by integration tests, not every benchmark target"
)]
pub const DEGENERATE_POINTS_3D: &[[f64; 3]] = &[
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[1.0, 1.0, 0.0],
[0.5, 0.25, 0.0],
];
Loading
Loading