#[cfg(feature = "diagnostics")]
use delaunay::prelude::construction::{
ConstructionOptions, DelaunayResult, DelaunayTriangulation, DelaunayTriangulationBuilder,
DelaunayTriangulationConstructionError, vertex,
};
#[cfg(feature = "diagnostics")]
use delaunay::prelude::geometry::AdaptiveKernel;
#[cfg(feature = "diagnostics")]
fn main() -> DelaunayResult<()> {
init_tracing();
println!("Diagnostics feature example");
println!("===========================\n");
report_valid_triangulation()?;
println!();
report_non_delaunay_triangulation()?;
println!("\nDone. Set RUST_LOG=delaunay=debug to see verbose tracing output.");
Ok(())
}
#[cfg(not(feature = "diagnostics"))]
fn main() {
println!("This example requires the diagnostics feature.");
println!("Run: cargo run --features diagnostics --example diagnostics");
}
#[cfg(feature = "diagnostics")]
fn init_tracing() {
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).try_init();
}
#[cfg(feature = "diagnostics")]
fn report_valid_triangulation() -> DelaunayResult<()> {
let vertices = vec![
vertex![0.0, 0.0, 0.0]?,
vertex![1.0, 0.0, 0.0]?,
vertex![0.0, 1.0, 0.0]?,
vertex![0.0, 0.0, 1.0]?,
];
let dt: DelaunayTriangulation<_, (), (), 3> =
DelaunayTriangulationBuilder::new(&vertices).build()?;
let report = dt.delaunay_violation_report(None)?;
println!("Valid 3D triangulation:");
println!(" vertices: {}", report.number_of_vertices);
println!(" simplices: {}", report.number_of_simplices);
println!(" checked simplices: {}", report.checked_simplices);
println!(" Delaunay valid: {}", report.is_valid());
assert!(report.is_valid());
Ok(())
}
#[cfg(feature = "diagnostics")]
fn report_non_delaunay_triangulation() -> DelaunayResult<()> {
let dt = build_non_delaunay_triangulation_2d()?;
let report = dt.delaunay_violation_report(None)?;
println!("Explicit non-Delaunay 2D triangulation:");
println!(" vertices: {}", report.number_of_vertices);
println!(" simplices: {}", report.number_of_simplices);
println!(
" violating simplices: {}",
report.violating_simplices.len()
);
assert!(!report.is_valid());
if let Some(detail) = report.first_violation() {
println!(" first violating simplex: {:?}", detail.simplex_key);
println!(" simplex vertex count: {}", detail.simplex_vertices.len());
println!(" offending external vertex: {:?}", detail.offending_vertex);
}
dt.debug_print_first_delaunay_violation(None);
Ok(())
}
#[cfg(feature = "diagnostics")]
fn build_non_delaunay_triangulation_2d()
-> DelaunayResult<DelaunayTriangulation<AdaptiveKernel<f64>, (), (), 2>> {
let vertices = vec![
vertex![0.0, 0.0]?,
vertex![4.0, 0.0]?,
vertex![4.0, 2.0]?,
vertex![1.0, 2.0]?,
];
let simplices = vec![vec![0, 1, 2], vec![0, 2, 3]];
let dt = DelaunayTriangulationBuilder::try_from_vertices_and_simplices(&vertices, &simplices)
.map_err(DelaunayTriangulationConstructionError::from)?
.construction_options(ConstructionOptions::default().without_final_delaunay_enforcement())
.build()?;
dt.as_triangulation().validate()?;
assert!(dt.is_valid_delaunay().is_err());
Ok(dt)
}