mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-14 02:15:07 -05:00
Each machine thickness already has a Name / Gauge field the shop fills in, so the report now shows that name instead of guessing one from the standard gauge table. It is matched the way the machine cutting defaults match the nest's material, grade and thickness; a thickness without a name shows just the decimal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
3.7 KiB
C#
83 lines
3.7 KiB
C#
using System.Collections.Immutable;
|
|
|
|
namespace OpenNest.Reporting;
|
|
|
|
public sealed record ReportPoint(double X, double Y);
|
|
|
|
public sealed record ReportBounds(double Left, double Bottom, double Right, double Top)
|
|
{
|
|
public double Length => Right - Left;
|
|
public double Width => Top - Bottom;
|
|
}
|
|
|
|
/// <summary>Native line or arc; angles are radians and a null center denotes a line.</summary>
|
|
public sealed record ReportSegment(ReportPoint Start, ReportPoint End, ReportPoint? Center,
|
|
double Radius, double StartAngle, double SweepAngle);
|
|
|
|
public sealed record ReportContour(ImmutableArray<ReportSegment> Segments, bool Closed);
|
|
|
|
public sealed record ReportGeometry(ImmutableArray<ReportContour> Contours, ReportBounds Bounds)
|
|
{
|
|
public bool StrokeOnly => Contours.Any(contour => !contour.Closed);
|
|
}
|
|
|
|
public sealed record ReportDrawing(string Id, string Name, long Required, long Nested,
|
|
long Shortage, long Extra, ImmutableArray<int> Plates, ReportGeometry Geometry)
|
|
{
|
|
/// <summary>
|
|
/// Net weight of one part in <see cref="NestReportSnapshot.WeightUnits"/>; null when the nest
|
|
/// has no thickness or the material has no density.
|
|
/// </summary>
|
|
public double? Weight { get; init; }
|
|
}
|
|
|
|
public sealed record ReportPlacement(string ReportId, ReportGeometry Geometry);
|
|
|
|
/// <summary>
|
|
/// A machine clamp footprint in the parts' placement frame. <paramref name="Removed"/> marks a
|
|
/// rail clamp taken off this sheet (by Auto Nest or by hand), which the operator pulls before cutting.
|
|
/// </summary>
|
|
public sealed record ReportClamp(string Id, ReportBounds Bounds, bool Removed);
|
|
|
|
public sealed record ReportPlate(int Number, ReportBounds Bounds, int Copies, double PartSpacing,
|
|
double Utilization, ImmutableArray<ReportPlacement> Parts, ImmutableArray<ReportGeometry> Cutoffs)
|
|
{
|
|
/// <summary>Estimated time to cut one copy of this plate; null when no estimate was requested.</summary>
|
|
public TimeSpan? CutTime { get; init; }
|
|
|
|
/// <summary>
|
|
/// Weight of one full sheet (outline area x nest thickness x the nest material's density) in
|
|
/// <see cref="NestReportSnapshot.WeightUnits"/>; null when the thickness or density is unknown.
|
|
/// </summary>
|
|
public double? Weight { get; init; }
|
|
|
|
/// <summary>Clamps on this sheet, active and removed; display only, never material.</summary>
|
|
public ImmutableArray<ReportClamp> Clamps { get; init; } = ImmutableArray<ReportClamp>.Empty;
|
|
}
|
|
|
|
/// <summary>A detached value snapshot. No domain objects or mutable geometry are retained.</summary>
|
|
public sealed record NestReportSnapshot(string Name, string Customer, string Notes, string Material,
|
|
string Grade, double Thickness, string Units, DateTimeOffset GeneratedAt,
|
|
ImmutableArray<ReportDrawing> Drawings, ImmutableArray<ReportPlate> Plates)
|
|
{
|
|
public long TotalSheets => Plates.Aggregate(0L, (total, plate) => checked(total + plate.Copies));
|
|
|
|
/// <summary>
|
|
/// The name the nest machine's config gives this thickness ("16 ga"), shown before the
|
|
/// decimal; empty when it has none. Reporting does not read machine configs, so the caller
|
|
/// supplies it.
|
|
/// </summary>
|
|
public string ThicknessName { get; init; } = "";
|
|
|
|
/// <summary>"lb" for inch jobs, "kg" for millimeter jobs.</summary>
|
|
public string WeightUnits => Units == "mm" ? "kg" : "lb";
|
|
|
|
/// <summary>True when the report carries estimated cut times.</summary>
|
|
public bool HasCutTimes { get; init; }
|
|
|
|
/// <summary>Every plate's estimate times its copies; null when the report has no estimates.</summary>
|
|
public TimeSpan? TotalCutTime => !HasCutTimes
|
|
? null
|
|
: Plates.Aggregate(TimeSpan.Zero, (total, plate) => total + (plate.CutTime ?? TimeSpan.Zero) * plate.Copies);
|
|
}
|