Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Process/DieTransfer/Planning/DieTransferPlanningContext.cs
Shi.Ji e31d3560bb 添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
2026-05-18 11:43:09 +08:00

259 lines
10 KiB
C#

using MainShell.Common;
using MainShell.Models;
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MainShell.Process
{
public class DieTransferPlanningContext
{
public DieTransferPlanningContext()
{
PadRows = new List<PadTransferRow>();
DieRows = new List<DieTransferRow>();
TransPathType = TransPathType.Sequence;
PadRowDirectionStrategy = DieTransferRowTraversalStrategy.AllPositive;
DieRowDirectionStrategy = DieTransferRowTraversalStrategy.Serpentine;
SkipNgDie = true;
}
public DieTransferRegion DieRegion { get; set; }
public DieTransferRegion SubstrateRegion { get; set; }
public TransPathType TransPathType { get; set; }
public DieTransferRowTraversalStrategy PadRowDirectionStrategy { get; set; }
public DieTransferRowTraversalStrategy DieRowDirectionStrategy { get; set; }
public bool SkipNgDie { get; set; }
public List<PadTransferRow> PadRows { get; set; }
public List<DieTransferRow> DieRows { get; set; }
public int AvailablePadCount
{
get
{
return PadRows == null ? 0 : PadRows.Sum(row => row.AvailableCount);
}
}
public int AvailableDieCount
{
get
{
return DieRows == null ? 0 : DieRows.Sum(row => row.AvailableCount);
}
}
public List<Pad> GetOrderedPads()
{
List<Pad> pads = new List<Pad>();
if (PadRows == null)
{
return pads;
}
foreach (PadTransferRow row in PadRows.OrderBy(item => item.RowIndex))
{
pads.AddRange(row.GetAvailablePads());
}
return pads;
}
public List<Die> GetOrderedDies()
{
List<Die> dies = new List<Die>();
if (DieRows == null)
{
return dies;
}
foreach (DieTransferRow row in DieRows.OrderBy(item => item.RowIndex))
{
dies.AddRange(row.GetAvailableDies());
}
return dies;
}
public static DieTransferPlanningContext Create(DieTransferPathRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
DieTransferPlanningContext context = new DieTransferPlanningContext();
context.DieRegion = DieTransferRegion.FromRegionModel(request.DieRegion);
context.SubstrateRegion = DieTransferRegion.FromRegionModel(request.SubstrateRegion);
context.TransPathType = request.TransPathType;
context.PadRowDirectionStrategy = request.PadRowDirectionStrategy;
context.DieRowDirectionStrategy = request.DieRowDirectionStrategy;
context.SkipNgDie = request.SkipNgDie;
context.PadRows = CreatePadRows(request.PadCandidates, context.SubstrateRegion, context.PadRowDirectionStrategy);
context.DieRows = CreateDieRows(request.DieCandidates, context.DieRegion, request.SkipNgDie, context.DieRowDirectionStrategy);
return context;
}
public static List<PadTransferRow> CreatePadRows(IReadOnlyCollection<Pad> padCandidates, DieTransferRegion region, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
IEnumerable<Pad> filteredPads = (padCandidates ?? Array.Empty<Pad>())
.Where(pad => pad != null && IsInRegion(pad.Row, pad.Column, region));
List<PadTransferRow> rows = new List<PadTransferRow>();
foreach (IGrouping<int, Pad> rowGroup in filteredPads.GroupBy(pad => pad.Row).OrderBy(group => group.Key))
{
PadTransferRow row = new PadTransferRow();
row.RowIndex = rowGroup.Key;
row.Direction = ResolveRowDirection(rowGroup.Key, rowTraversalStrategy);
row.Pads = rowGroup.OrderBy(pad => pad.Column).ToList();
rows.Add(row);
}
return rows;
}
public static List<DieTransferRow> CreateDieRows(IReadOnlyCollection<Die> dieCandidates, DieTransferRegion region, bool skipNgDie, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
IEnumerable<Die> filteredDies = (dieCandidates ?? Array.Empty<Die>())
.Where(die => die != null && IsInRegion(die.Row, die.Column, region));
List<DieTransferRow> rows = new List<DieTransferRow>();
foreach (IGrouping<int, Die> rowGroup in filteredDies.GroupBy(die => die.Row).OrderBy(group => group.Key))
{
DieTransferRow row = new DieTransferRow();
row.RowIndex = rowGroup.Key;
row.Direction = ResolveRowDirection(rowGroup.Key, rowTraversalStrategy);
row.SkipNgDie = skipNgDie;
row.Dies = rowGroup.OrderBy(die => die.Column).ToList();
rows.Add(row);
}
return rows;
}
public static List<PadTransferRow> TrimPadRows(IReadOnlyCollection<PadTransferRow> sourceRows, int targetCount, out List<PadTransferRow> remainingRows)
{
List<PadTransferRow> activeRows = new List<PadTransferRow>();
remainingRows = new List<PadTransferRow>();
int remainingCount = Math.Max(0, targetCount);
foreach (PadTransferRow sourceRow in (sourceRows ?? Array.Empty<PadTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Pad> availablePads = sourceRow.GetAvailablePads().ToList();
if (availablePads.Count == 0)
{
continue;
}
if (remainingCount <= 0)
{
remainingRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads));
continue;
}
if (availablePads.Count <= remainingCount)
{
activeRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads));
remainingCount -= availablePads.Count;
continue;
}
activeRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads.Take(remainingCount)));
remainingRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads.Skip(remainingCount)));
remainingCount = 0;
}
return activeRows;
}
public static List<DieTransferRow> TrimDieRows(IReadOnlyCollection<DieTransferRow> sourceRows, int targetCount, out List<DieTransferRow> remainingRows)
{
List<DieTransferRow> activeRows = new List<DieTransferRow>();
remainingRows = new List<DieTransferRow>();
int remainingCount = Math.Max(0, targetCount);
foreach (DieTransferRow sourceRow in (sourceRows ?? Array.Empty<DieTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Die> availableDies = sourceRow.GetAvailableDies().ToList();
if (availableDies.Count == 0)
{
continue;
}
if (remainingCount <= 0)
{
remainingRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies));
continue;
}
if (availableDies.Count <= remainingCount)
{
activeRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies));
remainingCount -= availableDies.Count;
continue;
}
activeRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies.Take(remainingCount)));
remainingRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies.Skip(remainingCount)));
remainingCount = 0;
}
return activeRows;
}
private static bool IsInRegion(int row, int column, DieTransferRegion region)
{
if (region == null)
{
return true;
}
return region.Contains(row, column);
}
private static DieTransferRowDirection ResolveRowDirection(int rowIndex, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
switch (rowTraversalStrategy)
{
case DieTransferRowTraversalStrategy.AllNegative:
return DieTransferRowDirection.Negative;
case DieTransferRowTraversalStrategy.Serpentine:
return rowIndex % 2 == 0 ? DieTransferRowDirection.Negative : DieTransferRowDirection.Positive;
case DieTransferRowTraversalStrategy.AllPositive:
default:
return DieTransferRowDirection.Positive;
}
}
private static PadTransferRow CreatePadRow(int rowIndex, DieTransferRowDirection direction, IEnumerable<Pad> pads)
{
PadTransferRow row = new PadTransferRow();
row.RowIndex = rowIndex;
row.Direction = direction;
row.Pads = (pads ?? Array.Empty<Pad>()).Where(pad => pad != null).ToList();
return row;
}
private static DieTransferRow CreateDieRow(int rowIndex, DieTransferRowDirection direction, bool skipNgDie, IEnumerable<Die> dies)
{
DieTransferRow row = new DieTransferRow();
row.RowIndex = rowIndex;
row.Direction = direction;
row.SkipNgDie = skipNgDie;
row.Dies = (dies ?? Array.Empty<Die>()).Where(die => die != null).ToList();
return row;
}
}
}