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
use fj_interop::{debug::DebugInfo, processed_shape::ProcessedShape};
use fj_kernel::{
algorithms::{
approx::{InvalidTolerance, Tolerance},
triangulate::Triangulate,
validate::{ValidationConfig, ValidationError},
},
objects::Objects,
};
use fj_math::Scalar;
use crate::Shape as _;
pub struct ShapeProcessor {
pub tolerance: Option<Tolerance>,
}
impl ShapeProcessor {
pub fn process(&self, shape: &fj::Shape) -> Result<ProcessedShape, Error> {
let aabb = shape.bounding_volume();
let tolerance = match self.tolerance {
None => {
let mut min_extent = Scalar::MAX;
for extent in aabb.size().components {
if extent > Scalar::ZERO && extent < min_extent {
min_extent = extent;
}
}
let tolerance = min_extent / Scalar::from_f64(1000.);
Tolerance::from_scalar(tolerance)?
}
Some(user_defined_tolerance) => user_defined_tolerance,
};
let config = ValidationConfig::default();
let objects = Objects::new();
let mut debug_info = DebugInfo::new();
let shape = shape.compute_brep(&config, &objects, &mut debug_info)?;
let mesh = (&shape.into_inner(), tolerance).triangulate();
Ok(ProcessedShape {
aabb,
mesh,
debug_info,
})
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Error converting to shape")]
ToShape(#[from] ValidationError),
#[error("Model has zero size")]
Extent(#[from] InvalidTolerance),
}