namespace OpenNest.Data;
///
/// A machine's fixed edge-clamp rail, stored on its in the machine's
/// units. New nests assigned the machine copy it as their own rail; editing it never changes an
/// existing nest. validates the stored values field by field.
///
public sealed class MachineClamps
{
/// Whether new nests assigned this machine receive the rail. Default off.
public bool Enabled { get; set; }
/// Clamp extent along its edge.
public double Width { get; set; } = ClampSettings.DefaultWidth;
/// Clamp intrusion into the sheet from its edge.
public double Depth { get; set; } = ClampSettings.DefaultDepth;
/// Minutes to remove one clamp and put it back after cutting; never scaled.
public double RemovalMinutes { get; set; } = ClampRail.DefaultRemovalMinutes;
/// Origin-side clamp centers along X, measured from the plate origin.
public List Centers { get; set; } = new();
/// Far-side clamp centers along X, measured from the plate origin.
public List FarSideCenters { get; set; } = new();
/// Origin-end clamp centers along Y, measured from the plate origin.
public List OriginEndCenters { get; set; } = new();
/// Far-end clamp centers along Y, measured from the plate origin.
public List FarEndCenters { get; set; } = new();
/// The matching a machine's .
public static Units UnitsOf(UnitSystem units) =>
units == UnitSystem.Millimeters ? Units.Millimeters : Units.Inches;
///
/// converted to a machine in , e.g. for
/// "Save as Machine Defaults" from a nest in other units or the clamps.json migration.
///
public static MachineClamps FromSettings(ClampSettings settings, UnitSystem units)
{
ArgumentNullException.ThrowIfNull(settings);
var converted = settings.ConvertedTo(UnitsOf(units));
return new MachineClamps
{
Enabled = converted.Enabled,
Width = converted.Width,
Depth = converted.Depth,
RemovalMinutes = converted.RemovalMinutes,
Centers = converted.Centers.ToList(),
FarSideCenters = converted.FarSideCenters.ToList(),
OriginEndCenters = converted.OriginEndCenters.ToList(),
FarEndCenters = converted.FarEndCenters.ToList(),
};
}
///
/// The rail as clamp settings in the machine's . An invalid size or
/// removal time falls back to the default, and an invalid center is dropped, as when
/// reads a file.
///
public ClampSettings ToSettings(UnitSystem units)
{
var defaults = ClampSettings.FromRail(null, UnitsOf(units), Enabled);
if (IsLength(Width) && Width > 0)
defaults.Width = Width;
if (IsLength(Depth) && Depth > 0)
defaults.Depth = Depth;
if (IsLength(RemovalMinutes) && RemovalMinutes >= 0)
defaults.RemovalMinutes = RemovalMinutes;
defaults.Centers = Valid(Centers);
defaults.FarSideCenters = Valid(FarSideCenters);
defaults.OriginEndCenters = Valid(OriginEndCenters);
defaults.FarEndCenters = Valid(FarEndCenters);
return defaults;
}
private static double[] Valid(IEnumerable? centers) =>
(centers ?? Enumerable.Empty()).Where(c => IsLength(c) && c >= 0).Distinct().Order().ToArray();
// Finite in either unit, so converting to an inch or millimeter nest cannot overflow.
private static bool IsLength(double value) => double.IsFinite(value) && double.IsFinite(value * 25.4);
}