mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-04 08:01:35 -05:00
Irregular's block catalog fills a private plate per part type, and that fill searched best-fit pairs through the overload that ignores the token. On one CPU the search can take minutes, so a time limit waited for it: the converted Nestbolt m-public-gear-1 job under a 60 s limit ran past 180 s. PrivatePlateFill now passes its token, as PairCatalog does since 9431006e; the search still finishes in the background and fills the shared cache. gear-1, Irregular, one CPU, 60 s limit: killed after 180 s -> stops at 60.0 s (no layout yet; its no-fit polygons are the next bottleneck).
48 lines
2.2 KiB
C#
48 lines
2.2 KiB
C#
#nullable enable
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using OpenNest.Engine.BestFit;
|
|
using OpenNest.Engine.Jobs.Adapters;
|
|
using OpenNest.Engine.Jobs.Placement.Fillers;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.Engine.Jobs.Placement;
|
|
|
|
/// <summary>
|
|
/// Runs the Fill strategy for one private drawing on a private plate, for callers that turn the
|
|
/// result into job poses. The caller owns the drawing and must call
|
|
/// <see cref="BestFitCache.Invalidate"/> for it when finished.
|
|
/// </summary>
|
|
internal static class PrivatePlateFill
|
|
{
|
|
/// <param name="length">X extent of the plate and work area.</param>
|
|
/// <param name="width">Y extent of the plate and work area.</param>
|
|
/// <param name="quantity">Copies wanted; zero fills the whole area.</param>
|
|
internal static List<Part> Run(Drawing drawing, RotationPolicy rotation, double spacing,
|
|
double length, double width, int quantity, CancellationToken token)
|
|
{
|
|
var plate = new Plate(new Size(width, length)) { PartSpacing = spacing };
|
|
// The drawing is private: stabilize this cache entry before Fill's candidate pruning.
|
|
// Cancelling stops the wait; the search finishes in the background and fills the cache.
|
|
var fits = BestFitCache.GetOrCompute(drawing, plate.Size.Length, plate.Size.Width, spacing,
|
|
token);
|
|
var sorted = fits.OrderBy(f => f.RotatedArea).ThenBy(f => f.Candidate.StrategyIndex)
|
|
.ThenBy(f => f.Candidate.Part2Rotation).ThenBy(f => f.Candidate.Part2Offset.X)
|
|
.ThenBy(f => f.Candidate.Part2Offset.Y).ThenBy(f => f.OptimalRotation).ToArray();
|
|
fits.Clear();
|
|
fits.AddRange(sorted);
|
|
// A positive quantity lets supporting strategies avoid surplus rows. Zero still
|
|
// fills the whole area (the cutout lattice caller requires an uncapped lattice).
|
|
var filler = new PlateFiller(plate) { StopAtQuantity = true };
|
|
return filler.Fill(new NestItem
|
|
{
|
|
Drawing = drawing,
|
|
Quantity = quantity,
|
|
RotationStart = rotation.Start,
|
|
RotationEnd = rotation.End,
|
|
StepAngle = DrawingJobMapper.LegacyStep(rotation),
|
|
}, new Box(0, 0, length, width), null!, token);
|
|
}
|
|
}
|