1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::marker::PhantomData;
use nalgebra::{RealField, U4};
use crate::tessellation::DefaultDivider;
/// Options for adaptive tessellation of a surface
#[derive(Clone, Debug, PartialEq)]
pub struct AdaptiveTessellationOptions<T = f64, D = U4, F = DefaultDivider<T, D>> {
/// Tolerance for the normal vector: if the L2 norm of the normal vectors is below this value, the edge is considered flat
pub norm_tolerance: T,
/// Maximum allowed 3D edge length. Subdivides when any edge exceeds this length.
pub max_edge_length: Option<T>,
/// Minimum allowed 3D edge length. Stops subdivision when edges are shorter than this.
pub min_edge_length: Option<T>,
/// Minimum number of divisions in u direction
pub min_divs_u: usize,
/// Minimum number of divisions in v direction
pub min_divs_v: usize,
/// Minimum depth for division
pub min_depth: usize,
/// Maximum depth for division
pub max_depth: usize,
/// Divider function
pub divider: Option<F>,
_marker: PhantomData<D>,
}
impl<T: RealField, D, F> Default for AdaptiveTessellationOptions<T, D, F> {
fn default() -> Self {
Self {
// Compared as tolerance² against norm_squared in should_divide();
// 0.025 corresponds to ~1.4° normal-deviation per quad and gives
// reasonable mesh density for typical CAD usage.
norm_tolerance: T::from_f64(2.5e-2).unwrap(),
max_edge_length: None,
min_edge_length: None,
min_divs_u: 1,
min_divs_v: 1,
min_depth: 0,
max_depth: 8,
divider: None,
_marker: PhantomData,
}
}
}
impl<T: RealField, D, F> AdaptiveTessellationOptions<T, D, F> {
/// Set the tolerance for the normal vector
pub fn with_norm_tolerance(mut self, norm_tolerance: T) -> Self {
self.norm_tolerance = norm_tolerance;
self
}
/// Set the maximum allowed 3D edge length
pub fn with_max_edge_length(mut self, max_edge_length: T) -> Self {
self.max_edge_length = Some(max_edge_length);
self
}
/// Set the minimum allowed 3D edge length
pub fn with_min_edge_length(mut self, min_edge_length: T) -> Self {
self.min_edge_length = Some(min_edge_length);
self
}
/// Set the minimum number of divisions in u direction
pub fn with_min_divs_u(mut self, min_divs_u: usize) -> Self {
self.min_divs_u = min_divs_u;
self
}
/// Set the minimum number of divisions in v direction
pub fn with_min_divs_v(mut self, min_divs_v: usize) -> Self {
self.min_divs_v = min_divs_v;
self
}
/// Set the minimum depth for division
pub fn with_min_depth(mut self, min_depth: usize) -> Self {
self.min_depth = min_depth;
self
}
/// Set the maximum depth for division
pub fn with_max_depth(mut self, max_depth: usize) -> Self {
self.max_depth = max_depth;
self
}
/// Set the divider function
pub fn with_divider(mut self, divider: Option<F>) -> Self {
self.divider = divider;
self
}
}