mesh_gpu/lib.rs
1//! GPU-accelerated mesh processing using WGPU compute shaders.
2//!
3//! This crate provides GPU-accelerated implementations of computationally
4//! intensive mesh processing operations:
5//!
6//! - **SDF Computation**: Parallel signed distance field calculation
7//! - **Surface Nets**: GPU-accelerated isosurface extraction
8//! - **Collision Detection**: Parallel self-intersection detection
9//!
10//! # Performance Summary
11//!
12//! Based on benchmarks (see `BENCHMARKS.md` for full details):
13//!
14//! | Operation | GPU vs CPU | Recommendation |
15//! |-----------|------------|----------------|
16//! | SDF Computation | **3-68x faster** for meshes <5k tri | Use GPU for shell generation |
17//! | Surface Nets | 0.03-0.37x (slower) | Always use CPU |
18//! | Collision Detection | 0.03-1.0x (slower) | Always use CPU with BVH |
19//!
20//! ## When to Use GPU
21//!
22//! **SDF Computation** is the primary use case for GPU acceleration:
23//! - Small meshes (<100 tri) with 128³ grid: **48-68x speedup**
24//! - Medium meshes (320 tri) with 128³ grid: **14x speedup**
25//! - Large meshes (>5k tri): GPU overhead dominates, CPU is faster
26//!
27//! **Best use case**: Shell generation for 3D printing, where typical scan
28//! meshes (1k-10k triangles) are processed with high-resolution grids (128³+).
29//!
30//! ## When to Use CPU
31//!
32//! - **Surface Nets**: The `fast-surface-nets` crate is highly optimized
33//! - **Collision Detection**: BVH-accelerated CPU is O(n log n) vs GPU's O(n²)
34//! - **Large meshes**: GPU transfer overhead exceeds computation savings
35//!
36//! # Feature Flags
37//!
38//! This crate is designed to be an optional dependency. Enable it via
39//! the `gpu` feature flag in dependent crates:
40//!
41//! ```toml
42//! [dependencies]
43//! mesh-shell = { version = "0.1", features = ["gpu"] }
44//! ```
45//!
46//! # GPU Availability
47//!
48//! GPU support is automatically detected at runtime. Use [`context::GpuContext::is_available()`]
49//! to check if a GPU is available, or use the `try_*` variants of computation
50//! functions which return `None` instead of erroring when GPU is unavailable.
51//!
52//! # Example
53//!
54//! ```no_run
55//! use mesh_gpu::context::GpuContext;
56//! use mesh_gpu::sdf::{compute_sdf_gpu, GpuSdfParams};
57//! use mesh_repair::Mesh;
58//!
59//! // Check GPU availability
60//! if GpuContext::is_available() {
61//! println!("GPU available: {}", GpuContext::get().unwrap().adapter_info.name);
62//! }
63//!
64//! // Compute SDF (will error if no GPU)
65//! let mesh = Mesh::new();
66//! let params = GpuSdfParams {
67//! dims: [100, 100, 100],
68//! origin: [0.0, 0.0, 0.0],
69//! voxel_size: 0.1,
70//! };
71//!
72//! match compute_sdf_gpu(&mesh, ¶ms) {
73//! Ok(result) => println!("Computed {} voxels in {:.2}ms",
74//! result.values.len(), result.compute_time_ms),
75//! Err(e) => eprintln!("GPU computation failed: {}", e),
76//! }
77//! ```
78//!
79//! # Automatic Fallback
80//!
81//! For production use, consider implementing automatic CPU fallback:
82//!
83//! ```no_run
84//! use mesh_gpu::sdf::{try_compute_sdf_gpu, GpuSdfParams};
85//! use mesh_repair::Mesh;
86//!
87//! fn compute_sdf_with_fallback(mesh: &Mesh, params: &GpuSdfParams) -> Vec<f32> {
88//! // Try GPU first
89//! if let Some(result) = try_compute_sdf_gpu(mesh, params) {
90//! return result.values;
91//! }
92//!
93//! // Fall back to CPU implementation
94//! // ... CPU implementation here ...
95//! vec![]
96//! }
97//! ```
98//!
99//! # Running Benchmarks
100//!
101//! ```bash
102//! # Run all GPU benchmarks
103//! cargo bench -p mesh-gpu
104//!
105//! # Run specific benchmark group
106//! cargo bench -p mesh-gpu -- "SDF Computation"
107//!
108//! # View HTML reports
109//! open target/criterion/report/index.html
110//! ```
111
112pub mod buffers;
113pub mod collision;
114pub mod context;
115pub mod error;
116pub mod sdf;
117pub mod surface_nets;
118
119// Re-export commonly used types
120pub use collision::{
121 GpuCollisionParams, GpuCollisionResult, detect_self_intersections_gpu,
122 try_detect_self_intersections_gpu,
123};
124pub use context::{GpuContext, GpuDevicePreference};
125pub use error::{GpuError, GpuResult};
126pub use sdf::{GpuSdfParams, GpuSdfResult, compute_sdf_gpu, try_compute_sdf_gpu};
127pub use surface_nets::{
128 GpuSurfaceNetsParams, GpuSurfaceNetsResult, extract_isosurface_gpu, try_extract_isosurface_gpu,
129};