diff --git a/experiments/2024-12-09/src/extra/triangulate.rs b/experiments/2024-12-09/src/extra/triangulate.rs index b9196caf0..7e7185a90 100644 --- a/experiments/2024-12-09/src/extra/triangulate.rs +++ b/experiments/2024-12-09/src/extra/triangulate.rs @@ -10,7 +10,8 @@ use crate::{ pub fn triangulate(vertices: &[Handle], surface: &Plane) -> TriMesh { // This is a placeholder implementation that only supports convex faces. - let triangles = triangles(vertices, surface); + let points = points(vertices, surface); + let triangles = triangles(&points); let mut mesh = TriMesh::new(); mesh.triangles.extend(triangles); @@ -18,38 +19,45 @@ pub fn triangulate(vertices: &[Handle], surface: &Plane) -> TriMesh { mesh } -fn triangles(vertices: &[Handle], surface: &Plane) -> Vec { +fn points( + vertices: &[Handle], + surface: &Plane, +) -> Vec { + vertices + .iter() + .map(|vertex| { + // Here, we project a 3D point (from the vertex) into the face's + // surface, creating a 2D point. Through the surface, this 2D + // point has a position in 3D space. + // + // But this position isn't necessarily going to be the same as + // the position of the original 3D point, due to numerical + // inaccuracy. + // + // This doesn't matter. Neither does the fact, that other faces + // might share the same vertices and project them into their own + // surfaces, creating more redundancy. + // + // The reason that it doesn't, is that we're using the projected + // 2D points _only_ for this local triangulation. Once that + // tells us how the different 3D points must connect, we use the + // original 3D points to build those triangles. We never convert + // the 2D points back into 3D. + let point_surface = surface.project_point(vertex.point); + + TriangulationPoint { + point_surface, + point_vertex: vertex.point, + } + }) + .collect() +} + +fn triangles(points: &[TriangulationPoint]) -> Vec { let mut triangulation = spade::ConstrainedDelaunayTriangulation::<_>::new(); triangulation - .add_constraint_edges( - vertices.iter().map(|vertex| { - // Here, we project a 3D point (from the vertex) into the face's - // surface, creating a 2D point. Through the surface, this 2D - // point has a position in 3D space. - // - // But this position isn't necessarily going to be the same as - // the position of the original 3D point, due to numerical - // inaccuracy. - // - // This doesn't matter. Neither does the fact, that other faces - // might share the same vertices and project them into their own - // surfaces, creating more redundancy. - // - // The reason that it doesn't, is that we're using the projected - // 2D points _only_ for this local triangulation. Once that - // tells us how the different 3D points must connect, we use the - // original 3D points to build those triangles. We never convert - // the 2D points back into 3D. - let point_surface = surface.project_point(vertex.point); - - TriangulationPoint { - point_surface, - point_vertex: vertex.point, - } - }), - true, - ) + .add_constraint_edges(points.iter().copied(), true) .unwrap(); triangulation