fix(engine): route restricted-rotation requirements to OrderedPlateNester
The legacy engine reads RotationStart == RotationEnd == 0 as unconstrained and its Pairs/RectBestFit strategies rotate freely, so it returned poses a Fixed/BoundedSweep RotationPolicy forbids and the job validator threw. DefaultPlateNester now delegates such requests to the policy-aware OrderedPlateNester. Fixes RunAsync_FiniteStockExhaustion_PreservesUnplacedRequirementAndLockedRotation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace OpenNest;
|
namespace OpenNest;
|
||||||
@@ -20,6 +21,7 @@ namespace OpenNest;
|
|||||||
public sealed class DefaultPlateNester : IPlateNester
|
public sealed class DefaultPlateNester : IPlateNester
|
||||||
{
|
{
|
||||||
private readonly Func<Plate, DefaultNestEngine> engineFactory;
|
private readonly Func<Plate, DefaultNestEngine> engineFactory;
|
||||||
|
private readonly OrderedPlateNester restrictedRotationNester = new();
|
||||||
private readonly Dictionary<string, Drawing> drawingsById = new(StringComparer.Ordinal);
|
private readonly Dictionary<string, Drawing> drawingsById = new(StringComparer.Ordinal);
|
||||||
private readonly Dictionary<Drawing, string> idByDrawing = new(
|
private readonly Dictionary<Drawing, string> idByDrawing = new(
|
||||||
ReferenceEqualityComparer.Instance
|
ReferenceEqualityComparer.Instance
|
||||||
@@ -44,6 +46,13 @@ public sealed class DefaultPlateNester : IPlateNester
|
|||||||
ArgumentNullException.ThrowIfNull(request);
|
ArgumentNullException.ThrowIfNull(request);
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
// The legacy engine cannot express a locked or bounded rotation (start == end == 0 reads
|
||||||
|
// as "unconstrained") and its Pairs/RectBestFit strategies rotate freely, so it can return
|
||||||
|
// poses the requirement's RotationPolicy forbids. Restricted requirements go to the
|
||||||
|
// policy-aware ordered nester, which only proposes allowed angles and validates each pose.
|
||||||
|
if (request.Parts.Any(part => part.Rotation.Kind != RotationPolicyKind.Automatic))
|
||||||
|
return restrictedRotationNester.Place(request, progress, token);
|
||||||
|
|
||||||
var plate = DrawingJobMapper.CreatePlate(request.Stock);
|
var plate = DrawingJobMapper.CreatePlate(request.Stock);
|
||||||
var items = new List<NestItem>(request.Parts.Count);
|
var items = new List<NestItem>(request.Parts.Count);
|
||||||
foreach (var requirement in request.Parts)
|
foreach (var requirement in request.Parts)
|
||||||
|
|||||||
Reference in New Issue
Block a user