From 7ed40d4bb8575c2153035ff4a752a5c0ff903048 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Tue, 13 Oct 2026 17:09:17 -0400 Subject: [PATCH] fix(core): charge removal time only for removed clamps on the sheet Plate.ClampRemovalMinutes multiplied every listed removed id by the removal time, including ids the rail places beyond the sheet after a resize or does not know at all. Only removed clamps the rail resolves on this sheet are pulled, so only those add time; the ids themselves stay listed (C13). PM 6ded8ac4-84fd-4e8b-9a3b-6f41e494542c item (a) --- OpenNest.Core/Plate.cs | 11 ++++++++--- OpenNest.Tests/ClampRailTests.cs | 12 ++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/OpenNest.Core/Plate.cs b/OpenNest.Core/Plate.cs index e024bbb3..2c96dbbf 100644 --- a/OpenNest.Core/Plate.cs +++ b/OpenNest.Core/Plate.cs @@ -155,11 +155,16 @@ namespace OpenNest /// /// Minutes this sheet's cut-time estimate gains from (D9): - /// each listed clamp adds once. Zero - /// when there is no rail (removal is meaningless without one to remove clamps from). + /// each listed clamp the rail places on this sheet adds + /// once; a listed clamp that is beyond + /// the sheet (or unknown to the rail) is not pulled and costs nothing. Zero when there + /// is no rail (removal is meaningless without one to remove clamps from). /// public double ClampRemovalMinutes => - ClampRail == null ? 0 : RemovedClamps.Count * ClampRail.RemovalMinutes; + ClampRail == null || RemovedClamps.Count == 0 + ? 0 + : ClampRail.ResolveFor(Size, Quadrant).Count(zone => RemovedClamps.Contains(zone.Id)) + * ClampRail.RemovalMinutes; /// /// Follows and replaces the zones with its resolution for diff --git a/OpenNest.Tests/ClampRailTests.cs b/OpenNest.Tests/ClampRailTests.cs index 2ff4b218..bf04204b 100644 --- a/OpenNest.Tests/ClampRailTests.cs +++ b/OpenNest.Tests/ClampRailTests.cs @@ -370,4 +370,16 @@ public class ClampRailTests Assert.False(Machine().Matches(plate, Array.Empty())); Assert.False(Machine().Matches(plate, new[] { "clamp-4" })); } + // PM 6ded8ac4 (a): only removed clamps that are actually on this sheet cost time. + [Fact] + public void RemovalTimeCountsOnlyRemovedClampsOnTheSheet() + { + var plate = Sheet(48, 120); + plate.SetClampRail(Machine(), new[] { "clamp-3", "clamp-8", "clamp-99" }); + Assert.Equal(2 * ClampRail.DefaultRemovalMinutes, plate.ClampRemovalMinutes); // 3 and 8 + + plate.Size = new Size(48, 60); // clamp-8 is now beyond the sheet + Assert.Equal(ClampRail.DefaultRemovalMinutes, plate.ClampRemovalMinutes); + Assert.Contains("clamp-8", plate.RemovedClamps); // still listed (C13) + } }