mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 00:21:06 -04:00
Revert "feat(engine): live sheet preview while Irregular packs"
This reverts commit 9f0e536eeed85e4417f285b94913e03f594400f7.
This commit is contained in:
1 parent
b11225135e
commit
a2fb945669
5 files changed
+5
-114
No files matched your search
@@ -1,13 +1,13 @@
|
||||
using OpenNest.Engine.NestingEngines.Irregular;
|
||||
using static OpenNest.Engine.Tests.NestingEngines.JobBuilder;
|
||||
using static OpenNest.Engine.Tests.NestingEngines.Shapes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.Engine.Jobs;
|
||||
using OpenNest.Engine.Jobs.Adapters;
|
||||
using OpenNest.Engine.NestingEngines.Irregular;
|
||||
using OpenNest.Geometry;
|
||||
using static OpenNest.Engine.Tests.NestingEngines.JobBuilder;
|
||||
using static OpenNest.Engine.Tests.NestingEngines.Shapes;
|
||||
|
||||
namespace OpenNest.Engine.Tests.NestingEngines;
|
||||
|
||||
@@ -211,42 +211,6 @@ public class IrregularNestingEngineTests
|
||||
Assert.Equal(2, Assert.Single(result.Plates).Placements.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReportsLiveSheetPreviewWithoutChangingTheLayout()
|
||||
{
|
||||
var job = Job(new[] { Part("disc", Disc(3), 10), Part("ell", LShape(12, 8, 4), 10) },
|
||||
new[] { Stock("sheet", 40, 60, spacing: 0.5) });
|
||||
var reports = new List<NestJobProgress>();
|
||||
|
||||
var withPreview = new IrregularNestingEngine().Solve(job, new SyncProgress(reports.Add));
|
||||
var without = new IrregularNestingEngine().Solve(job);
|
||||
|
||||
var previews = reports.Where(r => r.LegacyProgress?.BestParts is { Count: > 0 }).ToList();
|
||||
Assert.NotEmpty(previews);
|
||||
var work = job.Plates[0].WorkArea;
|
||||
foreach (var preview in previews.Select(r => r.LegacyProgress))
|
||||
{
|
||||
Assert.True(preview.IsOverallBest);
|
||||
Assert.Equal((work.Left, work.Bottom, work.Right, work.Top), (preview.ActiveWorkArea.Left,
|
||||
preview.ActiveWorkArea.Bottom, preview.ActiveWorkArea.Right, preview.ActiveWorkArea.Top));
|
||||
foreach (var part in preview.BestParts)
|
||||
{
|
||||
Assert.InRange(part.BoundingBox.Left, work.Left - 1e-6, work.Right);
|
||||
Assert.InRange(part.BoundingBox.Right, work.Left, work.Right + 1e-6);
|
||||
Assert.InRange(part.BoundingBox.Bottom, work.Bottom - 1e-6, work.Top);
|
||||
Assert.InRange(part.BoundingBox.Top, work.Bottom, work.Top + 1e-6);
|
||||
}
|
||||
}
|
||||
Assert.Equal(
|
||||
without.Plates.SelectMany(p => p.Placements),
|
||||
withPreview.Plates.SelectMany(p => p.Placements));
|
||||
}
|
||||
|
||||
private sealed class SyncProgress(Action<NestJobProgress> report) : IProgress<NestJobProgress>
|
||||
{
|
||||
public void Report(NestJobProgress value) => report(value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasPublicParameterlessConstructorForPluginDiscovery()
|
||||
{
|
||||
|
||||
@@ -64,9 +64,6 @@ internal sealed class FrontierPacker
|
||||
private readonly BlockCatalog? blocks;
|
||||
private readonly ClampObstacles? clamps;
|
||||
|
||||
/// <summary>Observer of the placements so far (live preview); read-only, it never steers packing.</summary>
|
||||
private readonly Action<IReadOnlyList<Placed>>? placedChanged;
|
||||
|
||||
public FrontierPacker(
|
||||
IReadOnlyList<PartType> types,
|
||||
NoFitCache nfps,
|
||||
@@ -76,11 +73,9 @@ internal sealed class FrontierPacker
|
||||
double beta,
|
||||
WorkCounter counter,
|
||||
BlockCatalog? blocks = null,
|
||||
ClampObstacles? clamps = null,
|
||||
Action<IReadOnlyList<Placed>>? placedChanged = null
|
||||
ClampObstacles? clamps = null
|
||||
)
|
||||
{
|
||||
this.placedChanged = placedChanged;
|
||||
this.blocks = blocks;
|
||||
this.clamps = stock.ClampZones.Count == 0 ? null : clamps ?? new ClampObstacles(stock);
|
||||
this.counter = counter;
|
||||
@@ -187,7 +182,6 @@ internal sealed class FrontierPacker
|
||||
partArea += types[typeIndex].Area;
|
||||
front = System.Math.Max(front, axis == PackAxis.X ? part.Right : part.Top);
|
||||
}
|
||||
placedChanged?.Invoke(placed);
|
||||
|
||||
left[typeIndex] -= choice.Count;
|
||||
blockStates.RemoveAll(b => b.Members.Count > left[b.Members[0].Orientation.TypeIndex]);
|
||||
|
||||
@@ -131,7 +131,6 @@ public sealed class IrregularNestingEngine : INestingEngine
|
||||
}
|
||||
|
||||
private const int MaxTail = 3;
|
||||
private readonly SheetPreview? preview = progress == null ? null : new SheetPreview(progress, types, drawingFor);
|
||||
private readonly Dictionary<double, NoFitCache> caches = new();
|
||||
private readonly Dictionary<NestPlateStock, ClampObstacles> clamps = new();
|
||||
private readonly Dictionary<double, IReadOnlyDictionary<int, IReadOnlyList<PairPose>>> pairs = new();
|
||||
@@ -290,10 +289,8 @@ public sealed class IrregularNestingEngine : INestingEngine
|
||||
if (stock.Quantity is int available && used[stock.Id] >= available)
|
||||
continue;
|
||||
progress?.Report(new NestJobProgress(NestJobStage.EvaluatingCandidate, stock.Id, sheets.Count, 0, 0));
|
||||
var plateIndex = sheets.Count;
|
||||
var packer = new FrontierPacker(types, CacheFor(stock), PairsFor(stock), stock, axis, beta, Work,
|
||||
BlocksFor(stock), ClampsFor(stock),
|
||||
preview == null ? null : placed => preview.Report(stock, plateIndex, placed));
|
||||
BlocksFor(stock), ClampsFor(stock));
|
||||
var fill = packer.Fill(remaining, token);
|
||||
sheetPacked?.Invoke();
|
||||
if (fill.Parts.Count > 0)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenNest.Engine.Jobs;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Engine.NestingEngines.Irregular;
|
||||
|
||||
/// <summary>
|
||||
/// Live preview of the sheet a packer is filling, sent as job progress detail
|
||||
/// (<see cref="NestJobProgress.LegacyProgress"/>) for front ends that draw it. Reports are
|
||||
/// throttled to one per <see cref="Interval"/>; the clock only gates reporting and never feeds
|
||||
/// back into packing, so the solve stays deterministic.
|
||||
/// </summary>
|
||||
internal sealed class SheetPreview(
|
||||
IProgress<NestJobProgress> progress,
|
||||
IReadOnlyList<PartType> types,
|
||||
Func<NestJobPart, Drawing> drawingFor
|
||||
)
|
||||
{
|
||||
internal static readonly TimeSpan Interval = TimeSpan.FromMilliseconds(250);
|
||||
|
||||
private readonly Stopwatch clock = Stopwatch.StartNew();
|
||||
private TimeSpan? last;
|
||||
|
||||
/// <summary>Called after each placement on a sheet trial; reports when the interval has passed.</summary>
|
||||
public void Report(NestPlateStock stock, int plateIndex, IReadOnlyList<Placed> placed)
|
||||
{
|
||||
var now = clock.Elapsed;
|
||||
if (last is TimeSpan previous && now - previous < Interval)
|
||||
return;
|
||||
last = now;
|
||||
|
||||
var parts = new List<Part>(placed.Count);
|
||||
foreach (var pose in placed)
|
||||
{
|
||||
// Same pose mapping as the materialized result: rotate about the snapshot origin, then move.
|
||||
var part = new Part(drawingFor(types[pose.Orientation.TypeIndex].Part));
|
||||
part.Rotate(pose.Orientation.Rotation);
|
||||
part.Location = new Vector(pose.X, pose.Y);
|
||||
part.UpdateBounds();
|
||||
parts.Add(part);
|
||||
}
|
||||
|
||||
progress.Report(new NestJobProgress(NestJobStage.EvaluatingCandidate, stock.Id, plateIndex, 0, 0,
|
||||
new NestProgress
|
||||
{
|
||||
Phase = NestPhase.Custom,
|
||||
PlateNumber = plateIndex + 1,
|
||||
BestParts = parts,
|
||||
ActiveWorkArea = stock.WorkArea,
|
||||
IsOverallBest = true,
|
||||
Description = $"Irregular: packing plate {plateIndex + 1} on stock {stock.Id} ({parts.Count} parts)",
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -63,13 +63,6 @@ Curved outlines retain conservative flattening-error padding. This does not rela
|
||||
footprints, no-fit polygons or layout validation tolerances; a part extending beyond the accepted
|
||||
work-area bounds remains invalid.
|
||||
|
||||
While it runs with a progress sink, Irregular previews the sheet it is packing: at most four
|
||||
times a second it reports the placements so far as `NestProgress.BestParts` with the stock's
|
||||
work area, and desktop Auto Nest draws them on the plate view. The preview follows every trial
|
||||
(each stock, sheet, strategy variant and tail re-plan), so it shows the search at work, not the
|
||||
layout that will be kept. Reporting only reads finished placements, so layouts are identical
|
||||
with or without a sink.
|
||||
|
||||
Irregular fills gaps and open notches using outer profiles; it does not yet place parts inside
|
||||
enclosed cutouts. For a part with two or more copies it also offers its best-fit pairs (two copies
|
||||
interlocked, as the Best Fit viewer shows them) alongside the single copies, and places a pair
|
||||
|
||||
Reference in new issue
Block a user