mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 09:21:05 -04:00
Plan Cutting is now the only automatic lead-in assignment, and parts the support grid cannot hold level are reported wherever they lack a steadying tab. - Remove Assign Lead-ins (plate and nest), LeadInAssigner, the lead-in tool's Auto-Assign button and the Auto Tab size range; old settings with autoTab sizes still load - Manual Place Lead-in tabs the clicked entry when support tabs are on and the grid cannot hold the part (SupportTabSettings) - New PartSupport finding: Plan Cutting replay and best-effort plans warn when a drawing pin, a lead-in that does not fit or no single tab leaves a part unsteady; the pre-post review checks each placed program's outside tab gap. These warnings replace the advisory weak-tab notes; only the inside-corner tab note stays advisory, and never for a pin - Pinned perimeters keep their pin but carry the support analysis - Draw grid points as pixel-snapped squares without anti-aliasing - Post fixtures build lead-ins through a test-only TestLeadIns helper - Docs: support tabs, pre-post verification and planner notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
2.0 KiB
C#
58 lines
2.0 KiB
C#
using OpenNest.CNC;
|
|
using OpenNest.Engine.Sequencing;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.Tests;
|
|
|
|
/// <summary>
|
|
/// Gives every unlocked part on a plate its lead-ins from the plate's cutting parameters, left
|
|
/// to right, the way the retired Assign Lead-ins command did. Post fixtures use it to build
|
|
/// programs with lead-ins without running Plan Cutting, so their expected output is unchanged.
|
|
/// </summary>
|
|
internal static class TestLeadIns
|
|
{
|
|
public static void Apply(Plate plate)
|
|
{
|
|
var parameters = plate.CuttingParameters;
|
|
if (parameters == null)
|
|
return;
|
|
|
|
var sequenced = new LeftSideSequencer().Sequence(plate.Parts.ToList(), plate);
|
|
var exitPoint = PlateHelper.GetExitPoint(plate);
|
|
// The first pass fixes each part's pierce; the second faces each part toward the next pierce.
|
|
var piercePoints = Pass(null);
|
|
Pass(piercePoints);
|
|
|
|
Vector[] Pass(Vector[] nextPiercePoints)
|
|
{
|
|
var pierces = new Vector[sequenced.Count];
|
|
var current = exitPoint;
|
|
for (var i = 0; i < sequenced.Count; i++)
|
|
{
|
|
var part = sequenced[i].Part;
|
|
if (!part.LeadInsLocked)
|
|
{
|
|
if (part.HasManualLeadIns)
|
|
part.RemoveLeadIns();
|
|
var approach = current - part.Location;
|
|
if (nextPiercePoints != null && i + 1 < sequenced.Count)
|
|
part.ApplyLeadIns(parameters, approach, nextPiercePoints[i + 1] - part.Location);
|
|
else
|
|
part.ApplyLeadIns(parameters, approach);
|
|
}
|
|
pierces[i] = Pierce(part);
|
|
current = part.Location;
|
|
}
|
|
return pierces;
|
|
}
|
|
}
|
|
|
|
private static Vector Pierce(Part part)
|
|
{
|
|
foreach (var code in part.Program.Codes)
|
|
if (code is Motion motion)
|
|
return motion.EndPoint + part.Location;
|
|
return part.Location;
|
|
}
|
|
}
|