fidget_mesh/lib.rs
1//! Octree construction and meshing
2//!
3//! This module implements
4//! [Manifold Dual Contouring](https://people.engr.tamu.edu/schaefer/research/dualsimp_tvcg.pdf),
5//! to generate a triangle mesh from an implicit surface (or anything
6//! implementing [`Shape`](fidget_core::shape::Shape)).
7//!
8//! The resulting meshes should be
9//! - Manifold
10//! - Watertight
11//! - Preserving sharp features (corners / edges)
12//!
13//! However, they may contain self-intersections, and are not guaranteed to
14//! catch thin features (below the sampling grid resolution).
15//!
16//! The resulting [`Mesh`] objects can be written out as STL files.
17//!
18//! Here's a full example, meshing a sphere:
19//!
20//! ```
21//! use fidget_core::{
22//! context::Tree,
23//! vm::VmShape
24//! };
25//! use fidget_mesh::{Octree, Settings};
26//!
27//! let radius_squared = Tree::x().square()
28//! + Tree::y().square()
29//! + Tree::z().square();
30//! let tree: Tree = radius_squared.sqrt() - 0.6;
31//! let shape = VmShape::from(tree);
32//! let settings = Settings {
33//! depth: 4,
34//! ..Default::default()
35//! };
36//! let o = Octree::build(&shape, &settings).unwrap();
37//! let mesh = o.walk_dual();
38//!
39//! // Open a file to write, e.g.
40//! // let mut f = std::fs::File::create("out.stl")?;
41//! # let mut f = vec![];
42//! mesh.write_stl(&mut f)?;
43//! # Ok::<(), std::io::Error>(())
44//! ```
45#![warn(missing_docs)]
46
47mod builder;
48mod cell;
49mod codegen;
50mod dc;
51mod frame;
52mod octree;
53mod output;
54mod qef;
55
56use fidget_core::render::{CancelToken, ThreadPool};
57
58#[doc(hidden)]
59pub mod types;
60
61// Re-export the main Octree type as public
62pub use octree::Octree;
63
64////////////////////////////////////////////////////////////////////////////////
65
66/// An indexed 3D mesh
67#[derive(Default, Debug)]
68pub struct Mesh {
69 /// Triangles, as indexes into [`self.vertices`](Self::vertices)
70 pub triangles: Vec<nalgebra::Vector3<usize>>,
71 /// Vertex positions
72 pub vertices: Vec<nalgebra::Vector3<f32>>,
73}
74
75impl Mesh {
76 /// Builds a new mesh
77 pub fn new() -> Self {
78 Self::default()
79 }
80}
81
82/// Settings when building an octree and mesh
83pub struct Settings<'a> {
84 /// Depth to recurse in the octree
85 pub depth: u8,
86
87 /// Viewport to provide a world-to-model transform
88 pub world_to_model: nalgebra::Matrix4<f32>,
89
90 /// Thread pool to use for rendering
91 ///
92 /// If this is `None`, then rendering is done in a single thread; otherwise,
93 /// the provided pool is used.
94 pub threads: Option<&'a ThreadPool>,
95
96 /// Token to cancel rendering
97 pub cancel: CancelToken,
98}
99
100impl Default for Settings<'_> {
101 fn default() -> Self {
102 Self {
103 depth: 3,
104 world_to_model: nalgebra::Matrix4::identity(),
105 threads: Some(&ThreadPool::Global),
106 cancel: CancelToken::new(),
107 }
108 }
109}