using System; using OpenNest.Geometry; namespace OpenNest.Engine.Jobs; /// Shared numerical contract for layout validation. /// Only material contours (SpecialLayers.IsMaterial) count for bounds, clearance and scoring. /// Scribe/etch marks never affect these checks or salvage envelopes, even outside the sheet. public static class NestTolerances { /// Arc chord tolerance used by both validators. The layout check circumscribes /// perimeter arcs and inscribes cutouts; the placement validator uses inscribed arcs. public const double ValidationOutline = 0.001; /// How far under the part spacing a gap may fall and still pass both validators. /// Layouts placed exactly at the spacing land up to ~1e-4 short once rotated, rounded /// coordinates (e.g. PEP's 4-decimal exports) meet the Clipper grid; 0.0005 covers that /// with margin and is far below anything a cutting machine can resolve. public const double SpacingSlack = 0.0005; /// Clipper decimal precision (a 1e-4 coordinate grid). public const int ClipperPrecision = ClipperBridge.Precision; /// Extra pair clearance for an engine whose outline error is bounded by t. /// Each of two boundaries contributes ValidationOutline from validator flattening, /// one Clipper grid unit from rounding, and t from engine flattening: therefore /// 2 * ValidationOutline + 2 * 10^(-ClipperPrecision) + 2 * t. /// This budget assumes valid material geometry and bounded chord error on both sides. /// Tolerance is negative or non-finite. public static double SafeClearanceMargin(double engineChordTolerance) { if (!double.IsFinite(engineChordTolerance) || engineChordTolerance < 0) throw new ArgumentOutOfRangeException(nameof(engineChordTolerance)); return 2 * ValidationOutline + 2 * System.Math.Pow(10, -ClipperPrecision) + 2 * engineChordTolerance; } }