using System; using System.Collections.Generic; using System.Threading; using OpenNest.Engine; using OpenNest.Engine.Fill; using OpenNest.Engine.Strategies; using OpenNest.Geometry; namespace OpenNest.Engine.Jobs.Placement.Fillers; internal abstract class PlateFillerBase { private IFillComparer comparer; protected PlateFillerBase(Plate plate) { Plate = plate; } public Plate Plate { get; } public int PlateNumber { get; set; } public NestDirection NestDirection { get; set; } public NestPhase WinnerPhase { get; protected set; } public List PhaseResults { get; } = new(); public List AngleResults { get; } = new(); protected IFillComparer Comparer => comparer ??= CreateComparer(); protected virtual IFillComparer CreateComparer() => new DefaultFillComparer(); public virtual NestDirection? PreferredDirection => null; public virtual ShrinkAxis TrimAxis => ShrinkAxis.Width; public virtual List BuildAngles( NestItem item, ClassificationResult classification, Box workArea ) { return new List { classification.PrimaryAngle, classification.PrimaryAngle + OpenNest.Math.Angle.HalfPI, }; } protected virtual void RecordProductiveAngles(List angleResults) { } protected FillPolicy BuildPolicy() => new(Comparer, PreferredDirection); public virtual List Fill( NestItem item, Box workArea, IProgress progress, CancellationToken token ) { return new List(); } public virtual List Fill( List groupParts, Box workArea, IProgress progress, CancellationToken token ) { return new List(); } public virtual List PackArea( Box box, List items, IProgress progress, CancellationToken token ) { return new List(); } public List Nest( List items, IProgress progress, CancellationToken token ) { return PlateFillOrchestrator.Nest( Plate, items, Comparer, (item, workArea, sink, cancellation) => Fill(item, workArea, sink, cancellation), (workArea, packItems, sink, cancellation) => PackArea(workArea, packItems, sink, cancellation), progress, token ); } }