Skip to main content

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 bound_shape = shape.try_into().expect("no extra vars");
33//! let settings = Settings {
34//!     depth: 4,
35//!     ..Default::default()
36//! };
37//! let o = Octree::build(&bound_shape, &settings).unwrap();
38//! let mesh = o.walk_dual();
39//!
40//! // Open a file to write, e.g.
41//! // let mut f = std::fs::File::create("out.stl")?;
42//! # let mut f = vec![];
43//! mesh.write_stl(&mut f)?;
44//! # Ok::<(), Box<dyn std::error::Error>>(())
45//! ```
46#![warn(missing_docs)]
47
48mod builder;
49mod cell;
50mod codegen;
51mod dc;
52mod frame;
53mod octree;
54mod output;
55mod qef;
56
57use fidget_core::render::{CancelToken, ThreadPool};
58
59#[doc(hidden)]
60pub mod types;
61
62// Re-export the main Octree type as public
63pub use octree::Octree;
64
65////////////////////////////////////////////////////////////////////////////////
66
67/// An indexed 3D mesh
68#[derive(Default, Debug)]
69pub struct Mesh {
70    /// Triangles, as indexes into [`self.vertices`](Self::vertices)
71    pub triangles: Vec<nalgebra::Vector3<usize>>,
72    /// Vertex positions
73    pub vertices: Vec<nalgebra::Vector3<f32>>,
74}
75
76impl Mesh {
77    /// Builds a new mesh
78    pub fn new() -> Self {
79        Self::default()
80    }
81}
82
83/// Settings when building an octree and mesh
84pub struct Settings<'a> {
85    /// Depth to recurse in the octree
86    pub depth: u8,
87
88    /// Viewport to provide a world-to-model transform
89    pub world_to_model: nalgebra::Matrix4<f32>,
90
91    /// Thread pool to use for rendering
92    ///
93    /// If this is `None`, then rendering is done in a single thread; otherwise,
94    /// the provided pool is used.
95    pub threads: Option<&'a ThreadPool>,
96
97    /// Token to cancel rendering
98    pub cancel: CancelToken,
99}
100
101impl Default for Settings<'_> {
102    fn default() -> Self {
103        Self {
104            depth: 3,
105            world_to_model: nalgebra::Matrix4::identity(),
106            threads: Some(&ThreadPool::Global),
107            cancel: CancelToken::new(),
108        }
109    }
110}