Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### ⚠️ Breaking Changes

- Support periodic flip parity for external cells [#391](https://github.com/acgetchell/delaunay/pull/391)

### Merged Pull Requests

- Support periodic flip parity for external cells [#391](https://github.com/acgetchell/delaunay/pull/391)
- Refactor/387 tds mutation boundaries [#390](https://github.com/acgetchell/delaunay/pull/390)
- Refresh release docs and benchmark guidance [#389](https://github.com/acgetchell/delaunay/pull/389)

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Added

- [**breaking**] Support periodic flip parity for external cells [#391](https://github.com/acgetchell/delaunay/pull/391)
[`5fb2d4a`](https://github.com/acgetchell/delaunay/commit/5fb2d4a22927231ba3396950cf2bbbc481f69285)

- Preserve periodic vertex offsets when bistellar flips build replacement cells.
- Align external-facet parity checks across periodic cell frames instead of rejecting periodic external cells.
- Surface replacement periodic-offset shape and frame conflicts with typed flip-context errors.

### Changed

- Refactor/387 tds mutation boundaries [#390](https://github.com/acgetchell/delaunay/pull/390)
[`da30293`](https://github.com/acgetchell/delaunay/commit/da3029302e8484d26d2a88d1291050c332e6b822)

### Documentation

- Refresh release docs and benchmark guidance [#389](https://github.com/acgetchell/delaunay/pull/389)
[`526583c`](https://github.com/acgetchell/delaunay/commit/526583c627d32d9336910bce1913b7f458ca413c)

- Update the README pitch, feature list, references, and docs.rs-facing guidance
around exact predicates, SoS, PL-manifold validation, and bistellar repair.

- Refresh roadmap, release, limitation, robustness, orientation, invariant,
diagnostics, property-testing, workflow, and validation docs for the v0.7.8
cleanup path and v0.8.0 paper-facing work.

- Align contributor and script docs around non-mutating `just` checks before
mutating fixes.

- Update generated benchmark-summary guidance to surface `just bench-perf-summary`,
current Criterion metadata, and large-scale characterization defaults.

## [0.7.7] - 2026-05-15

### ⚠️ Breaking Changes
Expand Down Expand Up @@ -3376,6 +3420,7 @@ Older releases are archived by minor series:
- [0.3.x](docs/archive/changelog/0.3.md)
- [0.2.x](docs/archive/changelog/0.2.md)

[Unreleased]: https://github.com/acgetchell/delaunay/compare/v0.7.7...HEAD
[0.7.7]: https://github.com/acgetchell/delaunay/compare/v0.7.6...v0.7.7
[0.7.6]: https://github.com/acgetchell/delaunay/compare/v0.7.5...v0.7.6
[0.7.5]: https://github.com/acgetchell/delaunay/compare/v0.7.4...v0.7.5
Expand Down
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,33 @@ Follow the patterns documented in [code organization documentation][code-organiz
7. Trait implementations
8. Tests (comprehensive with subsections)

### Public Namespace Policy

`src/core/` is the internal implementation namespace for the low-level TDS and
algorithm layer. Do not make `crate::core` public or add a broad
`delaunay::core` facade. The public low-level surface should stay explicit and
workflow-oriented:

- `delaunay::tds` for cells, facets, vertex keys, TDS validation, and generic
triangulation data structures
- `delaunay::collections` for collection aliases, small buffers, and secondary
maps
- `delaunay::algorithms` for low-level algorithms such as point location and
Hilbert ordering
- `delaunay::query` for read-only traversal, convex hull extraction, boundary
analysis, and diagnostics helpers

Expose new low-level APIs through those curated modules and their focused
preludes when the item is useful to downstream callers. Keep high-level
Delaunay construction, repair, validation policy, and workflow APIs separate
from this layer so imports describe the level of abstraction being used.

During pre-1.0 development, breaking import changes are acceptable when they
improve correctness, orthogonality, or performance. When changing the public
surface, update the facade modules in `src/lib.rs`, the focused preludes,
README import guidance, code-organization docs, doctests, and any
downstream-style integration tests that demonstrate supported imports.

## Testing

### Test Categories
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ intent. The broad `delaunay::prelude::triangulation::*` import is retained for
compatibility, but new docs and tests should prefer the narrow workflow preludes
above.

### Low-level imports

`delaunay::core` is an internal implementation namespace. Public low-level APIs
are exposed through `delaunay::tds`, `delaunay::collections`,
`delaunay::algorithms`, and `delaunay::query`, plus the matching focused
preludes. Contributors should follow the namespace policy in
[CONTRIBUTING.md](CONTRIBUTING.md) and [docs/code_organization.md](docs/code_organization.md).

```rust
use delaunay::prelude::triangulation::construction::{
DelaunayTriangulationBuilder, DelaunayTriangulationConstructionError, vertex,
Expand Down
7 changes: 7 additions & 0 deletions docs/code_organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ The `benchmark-utils` CLI provides integrated benchmark workflow functionality,
- `canonical_points.rs` - Canonical vertex-ordering helpers for geometric predicate call sites (SoS consistency)
- `operations.rs` - Semantic classification and telemetry for topological operations

Public namespace policy: `crate::core` is the internal implementation namespace
for the low-level TDS and algorithm layer. The public low-level surface is
exposed through curated modules and focused preludes (`delaunay::tds`,
`delaunay::collections`, `delaunay::algorithms`, `delaunay::query`, and their
`delaunay::prelude::*` counterparts) rather than a broad public
`delaunay::core` module.

**`src/geometry/`** - Geometric algorithms and predicates:

- `kernel.rs` - Kernel abstraction (`AdaptiveKernel` default, `RobustKernel`, `FastKernel`) and `ExactPredicates` marker trait
Expand Down
7 changes: 4 additions & 3 deletions docs/production_review_remediation_checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ Treat partial items as still open until their acceptance notes are satisfied.
- [ ] **25. Protect `Vertex::incident_cell` mutation.**
Introduce a checked setter or newtype so invalid incident-cell links are
harder to construct. Tracked for v0.7.8 in #387.
- [ ] **26. Revisit public `core` module naming.**
Decide whether to keep the shadowing surface, rename it, or hide it behind
curated exports. Tracked for v0.7.8 in #388.
- [x] **26. Revisit public `core` module naming.**
Keep `crate::core` as the internal implementation namespace, and expose the
public low-level surface through curated modules and focused preludes such as
`tds`, `collections`, `algorithms`, and `query`. Tracked for v0.7.8 in #388.
- [ ] **27. Normalize boxing policy in Delaunay repair error variants.**
Pick a consistent enum-size and payload strategy. Tracked for v0.7.8 in #384.

Expand Down
2 changes: 0 additions & 2 deletions src/core/algorithms/incremental_insertion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ use crate::triangulation::delaunay::DelaunayTriangulationValidationError;
use std::fmt;
use std::hash::{Hash, Hasher};

pub use crate::core::operations::{InsertionOutcome, InsertionResult, InsertionStatistics};

/// Reason for hull extension failure.
///
/// # Examples
Expand Down
2 changes: 1 addition & 1 deletion src/core/algorithms/locate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@ where
/// assert_eq!(missed, 0);
/// # }
/// ```
#[cfg(any(test, feature = "diagnostics"))]
#[cfg(any(feature = "diagnostics", all(test, debug_assertions)))]
#[cfg_attr(docsrs, doc(cfg(feature = "diagnostics")))]
pub fn verify_conflict_region_completeness<K, U, V, const D: usize>(
tds: &Tds<K::Scalar, U, V, D>,
Expand Down
6 changes: 3 additions & 3 deletions src/core/boundary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl<T, U, V, const D: usize> BoundaryAnalysis<T, U, V, D> for Tds<T, U, V, D> {
/// Any facet shared by 0, 3, or more cells indicates a topological error in the triangulation.
///
/// For a comprehensive discussion of all topological invariants in Delaunay triangulations,
/// see the [Topological Invariants](crate::core::tds#topological-invariants)
/// see the [Topological Invariants](crate::tds::Tds#topological-invariants)
/// section in the triangulation data structure documentation.
///
/// # Returns
Expand Down Expand Up @@ -66,7 +66,7 @@ impl<T, U, V, const D: usize> BoundaryAnalysis<T, U, V, D> for Tds<T, U, V, D> {
/// // TDS-level API (fallible): returns `TdsError` on corruption.
/// let count = dt.tds().boundary_facets()?.count();
/// assert_eq!(count, 4);
/// # Ok::<(), delaunay::core::tds::TdsError>(())
/// # Ok::<(), delaunay::tds::TdsError>(())
/// ```
fn boundary_facets(&self) -> Result<BoundaryFacetsIter<'_, T, U, V, D>, TdsError> {
// Build a map from facet keys to the cells that contain them
Expand Down Expand Up @@ -202,7 +202,7 @@ impl<T, U, V, const D: usize> BoundaryAnalysis<T, U, V, D> for Tds<T, U, V, D> {
///
/// // A single tetrahedron has 4 boundary facets
/// assert_eq!(dt.tds().number_of_boundary_facets()?, 4);
/// # Ok::<(), delaunay::core::tds::TdsError>(())
/// # Ok::<(), delaunay::tds::TdsError>(())
/// ```
fn number_of_boundary_facets(&self) -> Result<usize, TdsError> {
self.build_facet_to_cells_map()
Expand Down
7 changes: 4 additions & 3 deletions src/core/traits/facet_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use std::sync::{
/// ```
/// use delaunay::prelude::tds::FacetCacheProvider;
/// use delaunay::prelude::tds::Tds;
/// use delaunay::prelude::collections::FacetToCellsMap;
/// use delaunay::prelude::geometry::CoordinateScalar;
/// use delaunay::prelude::triangulation::DataType;
/// use std::sync::Arc;
Expand All @@ -43,7 +44,7 @@ use std::sync::{
/// use arc_swap::ArcSwapOption;
///
/// struct MyAlgorithm {
/// facet_to_cells_cache: ArcSwapOption<delaunay::core::collections::FacetToCellsMap>,
/// facet_to_cells_cache: ArcSwapOption<FacetToCellsMap>,
/// cached_generation: AtomicU64,
/// }
///
Expand All @@ -62,7 +63,7 @@ use std::sync::{
/// U: DataType,
/// V: DataType,
/// {
/// fn facet_cache(&self) -> &ArcSwapOption<delaunay::core::collections::FacetToCellsMap> {
/// fn facet_cache(&self) -> &ArcSwapOption<FacetToCellsMap> {
/// &self.facet_to_cells_cache
/// }
///
Expand Down Expand Up @@ -333,9 +334,9 @@ where
mod tests {
use super::*;
use crate::core::tds::Tds;
use crate::core::vertex;
use crate::geometry::kernel::AdaptiveKernel;
use crate::triangulation::delaunay::DelaunayTriangulation;
use crate::vertex;
use std::sync::Arc;
use std::sync::Barrier;
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
Expand Down
4 changes: 2 additions & 2 deletions src/core/util/jaccard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,11 @@ macro_rules! assert_jaccard_gte {
let threshold = $threshold;

// Use jaccard_index function for safety and consistency
let jaccard_index = $crate::core::util::jaccard_index(a_ref, b_ref)
let jaccard_index = $crate::query::jaccard_index(a_ref, b_ref)
.expect("Jaccard computation should not overflow for reasonable test sets");

if jaccard_index < threshold {
let report = $crate::core::util::format_jaccard_report(
let report = $crate::query::format_jaccard_report(
a_ref,
b_ref,
"Set A",
Expand Down
4 changes: 2 additions & 2 deletions src/core/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl<T, U, const D: usize> VertexBuilder<T, U, D> {
macro_rules! vertex {
// Pattern 1: Just coordinates - no data (defaults to ())
($coords:expr) => {
$crate::core::vertex::VertexBuilder::<_, (), _>::default()
$crate::prelude::triangulation::construction::VertexBuilder::<_, (), _>::default()
.point($crate::geometry::point::Point::try_from($coords)
.expect("Failed to convert coordinates to Point: invalid or out-of-range values"))
.build()
Expand All @@ -247,7 +247,7 @@ macro_rules! vertex {

// Pattern 2: Coordinates with data
($coords:expr, $data:expr) => {
$crate::core::vertex::VertexBuilder::default()
$crate::prelude::triangulation::construction::VertexBuilder::default()
.point($crate::geometry::point::Point::try_from($coords)
.expect("Failed to convert coordinates to Point: invalid or out-of-range values"))
.data($data)
Expand Down
Loading
Loading