diff --git a/crates/fj-core/src/validation/config.rs b/crates/fj-core/src/validation/config.rs index cf295ec4d..dc763c24d 100644 --- a/crates/fj-core/src/validation/config.rs +++ b/crates/fj-core/src/validation/config.rs @@ -24,12 +24,6 @@ pub struct ValidationConfig { /// The tolerance value used for intermediate geometry representation pub tolerance: Tolerance, - /// The minimum distance between distinct objects - /// - /// Objects whose distance is less than the value defined in this field, are - /// considered identical. - pub distinct_min_distance: Scalar, - /// The maximum distance between identical objects /// /// Objects that are considered identical might still have a distance @@ -37,21 +31,41 @@ pub struct ValidationConfig { /// that distance is less than the one defined in this field, can not be /// considered identical. pub identical_max_distance: Scalar, + + /// The minimum distance between distinct objects + /// + /// Objects whose distance is less than the value defined in this field, are + /// considered identical. + pub distinct_min_distance: Scalar, } -impl Default for ValidationConfig { - fn default() -> Self { +impl ValidationConfig { + /// Compute validation config from a tolerance value + pub fn from_tolerance(tolerance: impl Into) -> Self { + let tolerance = tolerance.into(); + + // This value can't be smaller than the tolerance. If it is, we'll get + // validation errors everywhere, just from numerical noise. + let identical_max_distance = tolerance.inner() * 10.; + + // This value can't be smaller than `identical_max_distance`. Otherwise + // we can have distinct points that satisfy this constraint, but must be + // considered identical according to the other. + // + // This factor was chosen pretty arbitrarily and might need to be tuned. + let distinct_min_distance = identical_max_distance * 2.; + Self { panic_on_error: false, - distinct_min_distance: Scalar::from_f64(5e-7), // 0.5 µm, - tolerance: Tolerance::from_scalar(0.001) - .expect("Tolerance provided is larger than zero"), - - // This value was chosen pretty arbitrarily. Seems small enough to - // catch errors. If it turns out it's too small (because it produces - // false positives due to floating-point accuracy issues), we can - // adjust it. - identical_max_distance: Scalar::from_f64(5e-14), + tolerance, + identical_max_distance, + distinct_min_distance, } } } + +impl Default for ValidationConfig { + fn default() -> Self { + Self::from_tolerance(0.001) + } +}