From 30f08d9f5bc691543caa9ba5fe4c08e9940af3d1 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 7 Aug 2024 20:31:34 +0200 Subject: [PATCH] Prepare for follow-on change --- crates/fj-core/src/algorithms/approx/curve.rs | 10 ++++--- .../fj-core/src/algorithms/approx/vertex.rs | 4 +-- .../src/algorithms/bounding_volume/face.rs | 29 +++++++++++++++---- .../fj-core/src/algorithms/triangulate/mod.rs | 22 +++++++------- crates/fj-core/src/geometry/surface.rs | 11 +++++-- crates/fj-core/src/operations/holes.rs | 5 +++- crates/fj-core/src/operations/sweep/path.rs | 8 +++-- crates/fj-core/src/validate/solid.rs | 1 + .../coincident_half_edges_are_not_siblings.rs | 4 +-- .../checks/curve_geometry_mismatch.rs | 14 ++++++--- 10 files changed, 75 insertions(+), 33 deletions(-) diff --git a/crates/fj-core/src/algorithms/approx/curve.rs b/crates/fj-core/src/algorithms/approx/curve.rs index d772512e5..a9ccfa50f 100644 --- a/crates/fj-core/src/algorithms/approx/curve.rs +++ b/crates/fj-core/src/algorithms/approx/curve.rs @@ -95,7 +95,8 @@ fn approx_circle_on_straight_surface( // point available, so it needs to be computed later anyway, in // the general case. - let point_global = surface.point_from_surface_coords(point_surface); + let point_global = + surface.point_from_surface_coords(point_surface, tolerance); ApproxPoint::new(point_curve, point_global) }) .collect() @@ -125,7 +126,8 @@ fn approx_line_on_any_surface( for (u, _) in approx_u { let t = (u.t - line.origin().u) / line.direction().u; let point_surface = line.point_from_line_coords([t]); - let point_global = surface.point_from_surface_coords(point_surface); + let point_global = + surface.point_from_surface_coords(point_surface, tolerance); points.push(ApproxPoint::new(u, point_global)); } @@ -262,7 +264,7 @@ mod tests { .layers .geometry .of_surface(&surface) - .point_from_surface_coords(point_surface); + .point_from_surface_coords(point_surface, tolerance); ApproxPoint::new(point_local, point_global) }) .collect::>(); @@ -290,7 +292,7 @@ mod tests { .layers .geometry .of_surface(&surface) - .point_from_surface_coords(point_surface); + .point_from_surface_coords(point_surface, tolerance); ApproxPoint::new(point_local, point_global) }) .collect::>(); diff --git a/crates/fj-core/src/algorithms/approx/vertex.rs b/crates/fj-core/src/algorithms/approx/vertex.rs index 60dcfcb8f..813cef9fd 100644 --- a/crates/fj-core/src/algorithms/approx/vertex.rs +++ b/crates/fj-core/src/algorithms/approx/vertex.rs @@ -16,7 +16,7 @@ pub fn approx_vertex( curve: &Handle, surface: &Handle, position_curve: Point<1>, - _: impl Into, + tolerance: impl Into, cache: &mut VertexApproxCache, geometry: &Geometry, ) -> ApproxPoint<1> { @@ -33,7 +33,7 @@ pub fn approx_vertex( None => { let position_global = geometry .of_surface(surface) - .point_from_surface_coords(position_surface); + .point_from_surface_coords(position_surface, tolerance); cache.insert(vertex, position_global) } }; diff --git a/crates/fj-core/src/algorithms/bounding_volume/face.rs b/crates/fj-core/src/algorithms/bounding_volume/face.rs index 2de9af4d0..8520a87ba 100644 --- a/crates/fj-core/src/algorithms/bounding_volume/face.rs +++ b/crates/fj-core/src/algorithms/bounding_volume/face.rs @@ -1,8 +1,9 @@ use std::ops::Deref; -use fj_math::Aabb; +use fj_math::{Aabb, Vector}; use crate::{ + algorithms::approx::Tolerance, geometry::{Geometry, GlobalPath, SurfaceGeom}, topology::Face, }; @@ -29,10 +30,28 @@ impl super::BoundingVolume<3> for &Face { aabb_bottom.merged(&aabb_top) } - GlobalPath::Line(_) => Aabb { - min: surface.point_from_surface_coords(aabb2.min), - max: surface.point_from_surface_coords(aabb2.max), - }, + GlobalPath::Line(_) => { + // A bounding volume must include the body it bounds, + // but does not need to match it precisely. So it's + // okay, if it's a bit larger. + // + // Let's just choose a reasonable tolerance value here, + // then make sure we enlarge the AABB accordingly, to + // make sure it fits. + let tolerance_f64 = 0.001; + let tolerance = Tolerance::from_scalar(tolerance_f64) + .expect("Tolerance provided is larger than zero"); + let offset = Vector::from([tolerance_f64; 3]); + + Aabb { + min: surface.point_from_surface_coords( + aabb2.min, tolerance, + ) - offset, + max: surface.point_from_surface_coords( + aabb2.max, tolerance, + ) + offset, + } + } } }) } diff --git a/crates/fj-core/src/algorithms/triangulate/mod.rs b/crates/fj-core/src/algorithms/triangulate/mod.rs index 7ef1c391c..ad6d3606d 100644 --- a/crates/fj-core/src/algorithms/triangulate/mod.rs +++ b/crates/fj-core/src/algorithms/triangulate/mod.rs @@ -180,32 +180,32 @@ mod tests { .layers .geometry .of_surface(&surface) - .point_from_surface_coords(a); + .point_from_surface_coords(a, core.tolerance()); let b = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(b); + .point_from_surface_coords(b, core.tolerance()); let e = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(e); + .point_from_surface_coords(e, core.tolerance()); let f = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(f); + .point_from_surface_coords(f, core.tolerance()); let g = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(g); + .point_from_surface_coords(g, core.tolerance()); let h = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(h); + .point_from_surface_coords(h, core.tolerance()); // Let's test that some correct triangles are present. We don't need to // test them all. @@ -275,27 +275,27 @@ mod tests { .layers .geometry .of_surface(&surface) - .point_from_surface_coords(a); + .point_from_surface_coords(a, core.tolerance()); let b = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(b); + .point_from_surface_coords(b, core.tolerance()); let c = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(c); + .point_from_surface_coords(c, core.tolerance()); let d = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(d); + .point_from_surface_coords(d, core.tolerance()); let e = core .layers .geometry .of_surface(&surface) - .point_from_surface_coords(e); + .point_from_surface_coords(e, core.tolerance()); assert!(triangles.contains_triangle([a, b, d])); assert!(triangles.contains_triangle([a, d, e])); diff --git a/crates/fj-core/src/geometry/surface.rs b/crates/fj-core/src/geometry/surface.rs index 9d049efe8..81f91974b 100644 --- a/crates/fj-core/src/geometry/surface.rs +++ b/crates/fj-core/src/geometry/surface.rs @@ -118,6 +118,7 @@ impl SurfaceGeom { pub fn point_from_surface_coords( &self, point: impl Into>, + _: impl Into, ) -> Point<3> { let point = point.into(); let Self::Basic { u, .. } = self; @@ -157,7 +158,10 @@ mod tests { use fj_math::{Line, Point, Vector}; use pretty_assertions::assert_eq; - use crate::geometry::{GlobalPath, SurfaceGeom}; + use crate::{ + algorithms::approx::Tolerance, + geometry::{GlobalPath, SurfaceGeom}, + }; #[test] fn point_from_surface_coords() { @@ -169,8 +173,11 @@ mod tests { v: Vector::from([0., 0., 2.]), }; + // Value doesn't matter; we're dealing with a plane. + let tolerance = Tolerance::from_scalar(1.).unwrap(); + assert_eq!( - surface.point_from_surface_coords([2., 4.]), + surface.point_from_surface_coords([2., 4.], tolerance), Point::from([1., 5., 9.]), ); } diff --git a/crates/fj-core/src/operations/holes.rs b/crates/fj-core/src/operations/holes.rs index 706ceac4e..834720277 100644 --- a/crates/fj-core/src/operations/holes.rs +++ b/crates/fj-core/src/operations/holes.rs @@ -93,7 +93,10 @@ impl AddHole for Shell { core.layers .geometry .of_surface(location.face.surface()) - .point_from_surface_coords(location.position) + .point_from_surface_coords( + location.position, + core.tolerance(), + ) }; let entry_point = point(&entry_location); diff --git a/crates/fj-core/src/operations/sweep/path.rs b/crates/fj-core/src/operations/sweep/path.rs index 63d00dc8f..b5e51f37e 100644 --- a/crates/fj-core/src/operations/sweep/path.rs +++ b/crates/fj-core/src/operations/sweep/path.rs @@ -66,7 +66,10 @@ impl SweepSurfacePath for SurfacePath { let u = match self { SurfacePath::Circle(circle) => { - let center = surface.point_from_surface_coords(circle.center()); + let center = surface.point_from_surface_coords( + circle.center(), + core.tolerance(), + ); let a = surface.vector_from_surface_coords(circle.a()); let b = surface.vector_from_surface_coords(circle.b()); @@ -75,7 +78,8 @@ impl SweepSurfacePath for SurfacePath { GlobalPath::Circle(circle) } SurfacePath::Line(line) => { - let origin = surface.point_from_surface_coords(line.origin()); + let origin = surface + .point_from_surface_coords(line.origin(), core.tolerance()); let direction = surface.vector_from_surface_coords(line.direction()); diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index 64d0ebae9..4f400596f 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -125,6 +125,7 @@ impl SolidValidationError { .unwrap() .position, ), + config.tolerance, ), h.start_vertex().clone(), )) diff --git a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs index 25b6a289e..404602260 100644 --- a/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs +++ b/crates/fj-core/src/validation/checks/coincident_half_edges_are_not_siblings.rs @@ -203,7 +203,7 @@ fn distances( half_edge: &Handle, end_vertex: &Handle, surface: &Handle, - _: Tolerance, + tolerance: Tolerance, geometry: &Geometry, ) -> Option> { let [start, end] = [ @@ -229,7 +229,7 @@ fn distances( Some( geometry .of_surface(surface) - .point_from_surface_coords(surface_coords), + .point_from_surface_coords(surface_coords, tolerance), ) } diff --git a/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs b/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs index f8f16ec8d..06b81322f 100644 --- a/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs +++ b/crates/fj-core/src/validation/checks/curve_geometry_mismatch.rs @@ -162,10 +162,16 @@ impl ValidationCheck for CurveGeometryMismatch { .path .point_from_path_coords(point_curve); - let a_global = - surface_geom_a.point_from_surface_coords(a_surface); - let b_global = - surface_geom_b.point_from_surface_coords(b_surface); + let a_global = surface_geom_a + .point_from_surface_coords( + a_surface, + config.tolerance, + ); + let b_global = surface_geom_b + .point_from_surface_coords( + b_surface, + config.tolerance, + ); let distance = (a_global - b_global).magnitude();