From fe7083f4c4ca1433bf622743abb0ee0e29ddd4f0 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 12 Oct 2026 19:00:50 -0400 Subject: [PATCH] fix(cutting): keep clamp zones on cutting-plan previews Plan Cutting previews were built without the plate's clamp zones, so machine clamps disappeared from the canvas while inspecting a proposal. Copy the plate's immutable zones onto the detached preview; it does not follow the rail, so it never re-resolves. Review finding 8, Project Memory 4e5f566d. --- .../CuttingPlanning/CuttingPlanBatch.cs | 3 +++ .../CuttingPlanning/ClampZonePreviewTests.cs | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 OpenNest.Tests/CuttingPlanning/ClampZonePreviewTests.cs diff --git a/OpenNest.Engine/CuttingPlanning/CuttingPlanBatch.cs b/OpenNest.Engine/CuttingPlanning/CuttingPlanBatch.cs index d26a529..06474fa 100644 --- a/OpenNest.Engine/CuttingPlanning/CuttingPlanBatch.cs +++ b/OpenNest.Engine/CuttingPlanning/CuttingPlanBatch.cs @@ -336,6 +336,9 @@ public sealed class CuttingPlanProposal PartSpacing = source.PartSpacing, EdgeSpacing = source.EdgeSpacing, }; + // Machine clamps stay visible while inspecting the proposal; zones are immutable. + foreach (var zone in source.ClampZones) + preview.ClampZones.Add(zone); foreach (var proposal in planned.Result.ProposedOrder) { var part = (Part)proposal.SourcePart.Clone(); diff --git a/OpenNest.Tests/CuttingPlanning/ClampZonePreviewTests.cs b/OpenNest.Tests/CuttingPlanning/ClampZonePreviewTests.cs new file mode 100644 index 0000000..26c1de6 --- /dev/null +++ b/OpenNest.Tests/CuttingPlanning/ClampZonePreviewTests.cs @@ -0,0 +1,22 @@ +using OpenNest.Engine.CuttingPlanning; + +namespace OpenNest.Tests.CuttingPlanning; + +/// Machine clamps stay visible on a cutting-plan preview of a clamped plate. +public class ClampZonePreviewTests +{ + [Fact] + public void PreviewCarriesThePlatesClampZones() + { + var plate = BestEffortCuttingPlanTests.Plate(BestEffortCuttingPlanTests.TouchingContours()); + plate.SetClampRail(new ClampRail(1.5, 0.625, new[] { 6.0, 21 })); + + var proposal = CuttingPlanBatch.Capture([plate], ExplicitContourTests.Parameters(), false).Plan(); + var preview = proposal.BuildPreview(0); + + Assert.NotNull(preview); + Assert.Equal(plate.ClampZones, preview.ClampZones); // same immutable zones, same order + Assert.Equal(2, preview.ClampZones.Count); + Assert.Null(preview.ClampRail); // a detached display copy never re-resolves + } +}