From c8051d8f6f1f33bfaaec997d3021308c3e027817 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:19:50 +0200 Subject: [PATCH 1/6] Make module public --- crates/fj-kernel/src/algorithms/mod.rs | 3 +-- crates/fj-kernel/src/algorithms/triangulate/mod.rs | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/mod.rs b/crates/fj-kernel/src/algorithms/mod.rs index 9a55ef184..7e88992af 100644 --- a/crates/fj-kernel/src/algorithms/mod.rs +++ b/crates/fj-kernel/src/algorithms/mod.rs @@ -3,13 +3,12 @@ //! 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..a79478740 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; From 6f5af2c5234a938a2678046e2c87e4858b6dcd45 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:21:37 +0200 Subject: [PATCH 2/6] Add trait `Triangulate` --- crates/fj-kernel/src/algorithms/triangulate/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index a79478740..5bd43a4cc 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -12,6 +12,16 @@ use self::{delaunay::TriangulationPoint, polygon::Polygon}; use super::approx::{Approx, Tolerance}; +/// Triangulate a shape +pub trait Triangulate: Sized { + /// Triangulate the shape + fn triangulate( + self, + tolerance: impl Into, + debug_info: &mut DebugInfo, + ) -> Mesh>; +} + /// Triangulate a shape pub fn triangulate( faces: Vec, From 1c9ba78f07acbeff29af5d876f2fdec15a10d939 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:25:58 +0200 Subject: [PATCH 3/6] Implement `Triangulate` for faces --- .../src/algorithms/triangulate/mod.rs | 21 ++++++++++++++----- crates/fj-operations/src/shape_processor.rs | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 5bd43a4cc..a0e9ffb02 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -22,6 +22,19 @@ pub trait Triangulate: Sized { ) -> Mesh>; } +impl Triangulate for T +where + T: IntoIterator, +{ + fn triangulate( + self, + tolerance: impl Into, + debug_info: &mut DebugInfo, + ) -> Mesh> { + triangulate(self.into_iter().collect(), tolerance.into(), debug_info) + } +} + /// Triangulate a shape pub fn triangulate( faces: Vec, @@ -91,6 +104,8 @@ mod tests { objects::{Face, Surface}, }; + use super::Triangulate; + #[test] fn simple() -> anyhow::Result<()> { let a = [0., 0.]; @@ -202,10 +217,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, From 8b243d38a4237371b0ed7bd7e719dc57d1973354 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:28:36 +0200 Subject: [PATCH 4/6] Inline function --- crates/fj-kernel/src/algorithms/mod.rs | 2 - .../src/algorithms/triangulate/mod.rs | 104 ++++++++---------- 2 files changed, 48 insertions(+), 58 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/mod.rs b/crates/fj-kernel/src/algorithms/mod.rs index 7e88992af..ffd390285 100644 --- a/crates/fj-kernel/src/algorithms/mod.rs +++ b/crates/fj-kernel/src/algorithms/mod.rs @@ -10,5 +10,3 @@ 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 a0e9ffb02..6f389b911 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -31,67 +31,59 @@ where tolerance: impl Into, debug_info: &mut DebugInfo, ) -> Mesh> { - triangulate(self.into_iter().collect(), tolerance.into(), debug_info) - } -} + let tolerance = tolerance.into(); + let mut mesh = Mesh::new(); + + for face in self { + if let Some(triangles) = face.triangles() { + for &(triangle, color) in triangles { + mesh.push_triangle(triangle, color); + } + continue; + } -/// 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() { - for &(triangle, color) in triangles { - mesh.push_triangle(triangle, color); + let surface = face.surface(); + let approx = face.approx(tolerance); + + let points: Vec<_> = approx + .points + .into_iter() + .map(|(point_surface, point_global)| TriangulationPoint { + point_surface, + point_global, + }) + .collect(); + let face_as_polygon = Polygon::new(*surface) + .with_exterior( + approx + .exterior + .points + .into_iter() + .map(|(point_surface, _)| point_surface), + ) + .with_interiors(approx.interiors.into_iter().map(|interior| { + interior + .points + .into_iter() + .map(|(point_surface, _)| point_surface) + })); + + let mut triangles = delaunay::triangulate(points); + triangles.retain(|triangle| { + face_as_polygon.contains_triangle( + triangle.map(|point| point.point_surface), + debug_info, + ) + }); + + for triangle in triangles { + let points = triangle.map(|point| point.point_global); + mesh.push_triangle(points, face.color()); } - continue; } - let surface = face.surface(); - let approx = face.approx(tolerance); - - let points: Vec<_> = approx - .points - .into_iter() - .map(|(point_surface, point_global)| TriangulationPoint { - point_surface, - point_global, - }) - .collect(); - let face_as_polygon = Polygon::new(*surface) - .with_exterior( - approx - .exterior - .points - .into_iter() - .map(|(point_surface, _)| point_surface), - ) - .with_interiors(approx.interiors.into_iter().map(|interior| { - interior - .points - .into_iter() - .map(|(point_surface, _)| point_surface) - })); - - let mut triangles = delaunay::triangulate(points); - triangles.retain(|triangle| { - face_as_polygon.contains_triangle( - triangle.map(|point| point.point_surface), - debug_info, - ) - }); - - for triangle in triangles { - let points = triangle.map(|point| point.point_global); - mesh.push_triangle(points, face.color()); - } + mesh } - - mesh } #[cfg(test)] From 6d582542823f3a185df40e8571ea16535b185f31 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:42:17 +0200 Subject: [PATCH 5/6] Add `Triangulate::triangulate_into_mesh` --- .../src/algorithms/triangulate/mod.rs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 6f389b911..75b58f9f9 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -19,20 +19,35 @@ pub trait Triangulate: Sized { self, tolerance: impl Into, debug_info: &mut DebugInfo, - ) -> Mesh>; + ) -> 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( + fn triangulate_into_mesh( self, tolerance: impl Into, + mesh: &mut Mesh>, debug_info: &mut DebugInfo, - ) -> Mesh> { + ) { let tolerance = tolerance.into(); - let mut mesh = Mesh::new(); for face in self { if let Some(triangles) = face.triangles() { @@ -81,8 +96,6 @@ where mesh.push_triangle(points, face.color()); } } - - mesh } } From a085baf98bfb4e098d5e0858b10fdc1c3457c078 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Sep 2022 12:44:36 +0200 Subject: [PATCH 6/6] Implement `Triangulate` for `Face` --- .../src/algorithms/triangulate/mod.rs | 97 +++++++++++-------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 75b58f9f9..1d69b84ec 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -50,51 +50,62 @@ where let tolerance = tolerance.into(); for face in self { - if let Some(triangles) = face.triangles() { - for &(triangle, color) in triangles { - mesh.push_triangle(triangle, color); - } - continue; - } + face.triangulate_into_mesh(tolerance, mesh, debug_info); + } + } +} - let surface = face.surface(); - let approx = face.approx(tolerance); - - let points: Vec<_> = approx - .points - .into_iter() - .map(|(point_surface, point_global)| TriangulationPoint { - point_surface, - point_global, - }) - .collect(); - let face_as_polygon = Polygon::new(*surface) - .with_exterior( - approx - .exterior - .points - .into_iter() - .map(|(point_surface, _)| point_surface), - ) - .with_interiors(approx.interiors.into_iter().map(|interior| { - interior - .points - .into_iter() - .map(|(point_surface, _)| point_surface) - })); - - let mut triangles = delaunay::triangulate(points); - triangles.retain(|triangle| { - face_as_polygon.contains_triangle( - triangle.map(|point| point.point_surface), - debug_info, - ) - }); - - for triangle in triangles { - let points = triangle.map(|point| point.point_global); - mesh.push_triangle(points, face.color()); +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); } + return; + } + + let surface = self.surface(); + let approx = self.approx(tolerance.into()); + + let points: Vec<_> = approx + .points + .into_iter() + .map(|(point_surface, point_global)| TriangulationPoint { + point_surface, + point_global, + }) + .collect(); + let face_as_polygon = Polygon::new(*surface) + .with_exterior( + approx + .exterior + .points + .into_iter() + .map(|(point_surface, _)| point_surface), + ) + .with_interiors(approx.interiors.into_iter().map(|interior| { + interior + .points + .into_iter() + .map(|(point_surface, _)| point_surface) + })); + + let mut triangles = delaunay::triangulate(points); + triangles.retain(|triangle| { + face_as_polygon.contains_triangle( + triangle.map(|point| point.point_surface), + debug_info, + ) + }); + + for triangle in triangles { + let points = triangle.map(|point| point.point_global); + mesh.push_triangle(points, self.color()); } } }