diff --git a/crates/fj-kernel/src/algorithms/mod.rs b/crates/fj-kernel/src/algorithms/mod.rs index 9a55ef184..ffd390285 100644 --- a/crates/fj-kernel/src/algorithms/mod.rs +++ b/crates/fj-kernel/src/algorithms/mod.rs @@ -3,13 +3,10 @@ //! Algorithmic code is collected in this module, to keep other modules focused //! on their respective purpose. -mod triangulate; - pub mod approx; pub mod intersect; pub mod reverse; pub mod sweep; pub mod transform; +pub mod triangulate; pub mod validate; - -pub use self::triangulate::triangulate; diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 98621ab02..1d69b84ec 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -1,3 +1,5 @@ +//! Shape triangulation + mod delaunay; mod polygon; @@ -11,23 +13,64 @@ use self::{delaunay::TriangulationPoint, polygon::Polygon}; use super::approx::{Approx, Tolerance}; /// Triangulate a shape -pub fn triangulate( - faces: Vec, - tolerance: Tolerance, - debug_info: &mut DebugInfo, -) -> Mesh> { - let mut mesh = Mesh::new(); - - for face in faces { - if let Some(triangles) = face.triangles() { +pub trait Triangulate: Sized { + /// Triangulate the shape + fn triangulate( + self, + tolerance: impl Into, + debug_info: &mut DebugInfo, + ) -> Mesh> { + let mut mesh = Mesh::new(); + self.triangulate_into_mesh(tolerance, &mut mesh, debug_info); + mesh + } + + /// Triangulate a partial shape into the provided mesh + /// + /// This is a low-level method, intended for implementation of + /// `Triangulate`. Most callers should prefer [`Triangulate::triangulate`]. + fn triangulate_into_mesh( + self, + tolerance: impl Into, + mesh: &mut Mesh>, + debug_info: &mut DebugInfo, + ); +} + +impl Triangulate for T +where + T: IntoIterator, +{ + fn triangulate_into_mesh( + self, + tolerance: impl Into, + mesh: &mut Mesh>, + debug_info: &mut DebugInfo, + ) { + let tolerance = tolerance.into(); + + for face in self { + face.triangulate_into_mesh(tolerance, mesh, debug_info); + } + } +} + +impl Triangulate for Face { + fn triangulate_into_mesh( + self, + tolerance: impl Into, + mesh: &mut Mesh>, + debug_info: &mut DebugInfo, + ) { + if let Some(triangles) = self.triangles() { for &(triangle, color) in triangles { mesh.push_triangle(triangle, color); } - continue; + return; } - let surface = face.surface(); - let approx = face.approx(tolerance); + let surface = self.surface(); + let approx = self.approx(tolerance.into()); let points: Vec<_> = approx .points @@ -62,11 +105,9 @@ pub fn triangulate( for triangle in triangles { let points = triangle.map(|point| point.point_global); - mesh.push_triangle(points, face.color()); + mesh.push_triangle(points, self.color()); } } - - mesh } #[cfg(test)] @@ -79,6 +120,8 @@ mod tests { objects::{Face, Surface}, }; + use super::Triangulate; + #[test] fn simple() -> anyhow::Result<()> { let a = [0., 0.]; @@ -190,10 +233,6 @@ mod tests { let tolerance = Tolerance::from_scalar(Scalar::ONE)?; let mut debug_info = DebugInfo::new(); - Ok(super::triangulate( - vec![face.into()], - tolerance, - &mut debug_info, - )) + Ok(vec![face.into()].triangulate(tolerance, &mut debug_info)) } } diff --git a/crates/fj-operations/src/shape_processor.rs b/crates/fj-operations/src/shape_processor.rs index e104a6d87..77b1b7b97 100644 --- a/crates/fj-operations/src/shape_processor.rs +++ b/crates/fj-operations/src/shape_processor.rs @@ -3,7 +3,7 @@ use fj_interop::{debug::DebugInfo, processed_shape::ProcessedShape}; use fj_kernel::algorithms::{ approx::{InvalidTolerance, Tolerance}, - triangulate, + triangulate::Triangulate, validate::{ValidationConfig, ValidationError}, }; use fj_math::Scalar; @@ -42,7 +42,7 @@ impl ShapeProcessor { let config = ValidationConfig::default(); let mut debug_info = DebugInfo::new(); let shape = shape.compute_brep(&config, tolerance, &mut debug_info)?; - let mesh = triangulate(shape.into_inner(), tolerance, &mut debug_info); + let mesh = shape.into_inner().triangulate(tolerance, &mut debug_info); Ok(ProcessedShape { aabb,