mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 08:21:05 -04:00
Drawing cut pins and the per-placement pins-off flag now survive save/reload and travel in drawing packages. - `DrawingDto.cutPins` reuses the plate cutting-parameter lead and tab DTOs. Pins are read strictly per entry: an unknown lead or tab type is never replaced by a default, because a pin that cut differently from what was saved is worse than no pin. A bad entry is skipped with a reader warning naming the drawing and pin, and the rest load; a value that is not a list loads no pins, with a warning. A nest never fails to open over pins. - `PartDto.drawingPinsOff` is written only when true. Anything other than a boolean loads as pins on (the drawing wins, D1) with a warning naming the plate and part, so an operator's override is never lost silently. - Packages carry pins as drawing content, so pinning a drawing changes its package hash and the newer-revision notice can tell geometry/pins changes from detail-only ones. - `Part.DrawingPinsOff` holds the flag; nothing plans with it yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
72 lines
2.9 KiB
C#
72 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using OpenNest.CNC.CuttingStrategy;
|
|
using OpenNest.Geometry;
|
|
using static OpenNest.IO.CuttingParametersDto;
|
|
using static OpenNest.IO.NestFormat;
|
|
|
|
namespace OpenNest.IO;
|
|
|
|
/// <summary>
|
|
/// Maps drawing cut pins to and from the nest file. Reading is strict per pin: unlike desktop
|
|
/// settings, an unknown lead or tab type is not replaced by a default, because a pin that cut
|
|
/// differently from what was saved would be worse than no pin.
|
|
/// </summary>
|
|
internal static class CutPinFormat
|
|
{
|
|
private static readonly HashSet<string> LeadInTypes = new(StringComparer.Ordinal)
|
|
{ "None", "Line", "Arc", "LineArc", "CleanHole", "LineLine" };
|
|
|
|
private static readonly HashSet<string> LeadOutTypes = new(StringComparer.Ordinal) { "None", "Line", "Arc" };
|
|
|
|
private static readonly HashSet<string> TabTypes = new(StringComparer.Ordinal) { "Normal", "Machine", "Breaker" };
|
|
|
|
internal static CutPinDto ToDto(ContourCutPin pin) => new()
|
|
{
|
|
X = pin.Point.X,
|
|
Y = pin.Point.Y,
|
|
LeadIn = CuttingParametersSerializer.ToLeadInDto(pin.LeadIn),
|
|
LeadOut = CuttingParametersSerializer.ToLeadOutDto(pin.LeadOut),
|
|
Tab = pin.HasTab ? CuttingParametersSerializer.ToTabDto(pin.Tab) : null,
|
|
};
|
|
|
|
/// <summary>Builds the pin, or returns null with the reason it cannot be trusted.</summary>
|
|
internal static ContourCutPin Read(CutPinDto dto, out string problem)
|
|
{
|
|
problem = null;
|
|
if (dto == null || dto.Malformed)
|
|
return Fail("it is not a readable pin", out problem);
|
|
if (!IsLeadIn(dto.LeadIn))
|
|
return Fail("its lead-in is missing or of an unknown type", out problem);
|
|
if (!IsLeadOut(dto.LeadOut))
|
|
return Fail("its lead-out is missing or of an unknown type", out problem);
|
|
if (dto.Tab != null && (!TabTypes.Contains(dto.Tab.Type ?? "")
|
|
|| dto.Tab.TabLeadIn != null && !IsLeadIn(dto.Tab.TabLeadIn)
|
|
|| dto.Tab.TabLeadOut != null && !IsLeadOut(dto.Tab.TabLeadOut)))
|
|
return Fail("its tab is of an unknown type", out problem);
|
|
|
|
try
|
|
{
|
|
return new ContourCutPin(
|
|
new Vector(dto.X, dto.Y),
|
|
CuttingParametersSerializer.FromLeadInDto(dto.LeadIn),
|
|
CuttingParametersSerializer.FromLeadOutDto(dto.LeadOut),
|
|
dto.Tab == null ? null : CuttingParametersSerializer.FromTabDto(dto.Tab));
|
|
}
|
|
catch (Exception ex) when (ex is ArgumentException || ex is NotSupportedException)
|
|
{
|
|
return Fail(ex.Message, out problem);
|
|
}
|
|
}
|
|
|
|
private static bool IsLeadIn(LeadInDto dto) => dto != null && LeadInTypes.Contains(dto.Type ?? "");
|
|
|
|
private static bool IsLeadOut(LeadOutDto dto) => dto != null && LeadOutTypes.Contains(dto.Type ?? "");
|
|
|
|
private static ContourCutPin Fail(string reason, out string problem)
|
|
{
|
|
problem = reason;
|
|
return null;
|
|
}
|
|
}
|