400 lines
18 KiB
C#
400 lines
18 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api;
|
|
using VisionCommon;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using VisionCommonUI;
|
|
using VisionCommonUI.Resources;
|
|
using Aurora.View;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace VisionUI.Pattern {
|
|
/// <summary>
|
|
/// 패턴 콤보박스 정보 키
|
|
/// </summary>
|
|
public class PatternCbInfoKey {
|
|
/// <summary>Fov Id</summary>
|
|
public eFovId FovId { get; set; }
|
|
/// <summary>Proc 패턴 Id</summary>
|
|
public eProcPatternId ProcPatternId { get; set; }
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="fovId">Fov Id</param>
|
|
/// <param name="procPatternId">Proc 패턴 Id</param>
|
|
public PatternCbInfoKey(eFovId fovId, eProcPatternId procPatternId) {
|
|
this.FovId = fovId;
|
|
this.ProcPatternId = procPatternId;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 패턴 콤보박스 정보 값
|
|
/// </summary>
|
|
public class PatternCbInfoValue {
|
|
/// <summary> 패턴 이름</summary>
|
|
public string PatternName { get; set; }
|
|
/// <summary>패턴 콤보박스</summary>
|
|
public ComboBox PatternComboBox { get; set; }
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="patternName">패턴이름</param>
|
|
/// <param name="patternComboBox">패턴 콤보박스</param>
|
|
public PatternCbInfoValue(string patternName, ComboBox patternComboBox) {
|
|
this.PatternName = patternName;
|
|
this.PatternComboBox = patternComboBox;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 패턴 리스트에 등록된 패턴을 공정 패턴으로 지정
|
|
/// </summary>
|
|
public partial class ProcPatternSettingView : UserControl {
|
|
private const string PATTERN_UNDEFINED = "Undefined";
|
|
|
|
private Logger _Logger;
|
|
private SubSysInfo _SubSysInfo;
|
|
private SubSysRecipe _SubSysRecipe;
|
|
|
|
private Dictionary<PatternCbInfoKey, PatternCbInfoValue> _PatternCbInfos = new Dictionary<PatternCbInfoKey, PatternCbInfoValue>();
|
|
private Dictionary<PatternCbInfoKey, List<PatternIndex>> _PatternIndexesAll = new Dictionary<PatternCbInfoKey, List<PatternIndex>>();
|
|
|
|
private string _ProcId;
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="subSysInfo">서브시스템 정보</param>
|
|
/// <param name="procId">Proc Id</param>
|
|
public ProcPatternSettingView(SubSysInfo subSysInfo, string procId) {
|
|
_Logger = new Logger(typeof(ProcPatternSettingView).Name);
|
|
_SubSysInfo = subSysInfo;
|
|
_SubSysRecipe = VisionRecipeManager.GetSubSysRecipe(_SubSysInfo);
|
|
_ProcId = procId;
|
|
InitializeComponent();
|
|
CreateViews();
|
|
}
|
|
|
|
//public ProcPatternSettingView() {
|
|
// _Logger = new Logger(typeof(ProcPatternSettingView).Name);
|
|
// InitializeComponent();
|
|
//}
|
|
|
|
///// <summary>
|
|
///// 초기 생성 후 한번만 설정 해 줄 것
|
|
///// </summary>
|
|
///// <param name="subSysInfo"></param>
|
|
///// <param name="procId"></param>
|
|
//public void InitView(SubSysInfo subSysInfo, string procId) {
|
|
// _SubSysInfo = subSysInfo;
|
|
// _SubSysRecipe = VisionRecipeManager.GetSubSysRecipe(_SubSysInfo);
|
|
// _FovPatternAgent = FovPatternAgentManager.GetAgent(_SubSysInfo);
|
|
// _ProcId = procId;
|
|
// CreateViews();
|
|
//}
|
|
|
|
private void CreateViews() {
|
|
gridProcPatterns.Children.Add(CreateProcPatternScrollView());
|
|
}
|
|
|
|
/// <summary>
|
|
/// ProcPatternSettingView를 새로고침
|
|
/// </summary>
|
|
/// <param name="subSysInfo">서브시스템 정보</param>
|
|
/// <param name="procId">Proc Id</param>
|
|
public void RefreshViews(SubSysInfo subSysInfo, string procId) {
|
|
// Align View에서 저장 시 PrcPatternSettingView를 새로고침한다.
|
|
_SubSysInfo = subSysInfo;
|
|
_SubSysRecipe = VisionRecipeManager.GetSubSysRecipe(_SubSysInfo);
|
|
_ProcId = procId;
|
|
|
|
gridProcPatterns.Children.Clear();
|
|
_PatternCbInfos.Clear();
|
|
CreateViews();
|
|
InitPatternItemsList();
|
|
}
|
|
|
|
private ProcPatternInfo CreateNewProcPatternInfo(eFovId fovId, int cnt) {
|
|
var procPatternInfo = new ProcPatternInfo();
|
|
procPatternInfo.ProcId = _ProcId;
|
|
if (cnt == 1) {
|
|
procPatternInfo.ProcPatternId = eProcPatternId.ProcPattern1;
|
|
procPatternInfo.PatternName = fovId.ToString() + "_" + _ProcId.ToString() + "_" + "Proc1";
|
|
}
|
|
else if (cnt == 2) {
|
|
procPatternInfo.ProcPatternId = eProcPatternId.ProcPattern2;
|
|
procPatternInfo.PatternName = fovId.ToString() + "_" + _ProcId.ToString() + "_" + "Proc2";
|
|
}
|
|
return procPatternInfo;
|
|
}
|
|
|
|
private ScrollViewer CreateProcPatternScrollView() {
|
|
var scrollViewer = new ScrollViewer();
|
|
scrollViewer.Visibility = Visibility.Visible;
|
|
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
|
|
scrollViewer.CanContentScroll = true;
|
|
scrollViewer.Margin = new Thickness(5);
|
|
|
|
StackPanel spOtherFov = new StackPanel();
|
|
spOtherFov.Orientation = Orientation.Vertical;
|
|
|
|
try {
|
|
// Align Subsystem의 경우 ProcId를 통해 어떤 Align의 ProcPattern을 가져와야 하는지 파악한다.
|
|
var alignRecipe = new AlignRecipe();
|
|
foreach (var recipe in _SubSysRecipe.AlignRecipes) {
|
|
// Inspect Subsystem의 경우에는 Align1의 ProcFovType을 가져오도록 한다.
|
|
if (_ProcId == "Inspect") {
|
|
if (recipe.AlignId == eAlignId.Align1) {
|
|
alignRecipe = recipe;
|
|
}
|
|
}
|
|
else if (recipe.AlignId.ToString().Equals(_ProcId)) {
|
|
alignRecipe = recipe;
|
|
}
|
|
}
|
|
foreach (FovRecipe fovRecipe in _SubSysRecipe.FovRecipes) {
|
|
eFovId fovId = fovRecipe.FovId;
|
|
//ProcFovType을 보고 필요한 Fov만 보이도록 한다.
|
|
if (ProcParams.GetFovNum(alignRecipe.ProcParams.ProcFovType) <= (int)fovId) {
|
|
continue;
|
|
}
|
|
|
|
StackPanel spSameFov = new StackPanel();
|
|
spSameFov.Orientation = Orientation.Vertical;
|
|
|
|
if (fovRecipe.PatternRecipe.ProcPatternInfos.Count > 0) {
|
|
bool checkProcPattern1 = false;
|
|
foreach (var procPatternInfo in fovRecipe.PatternRecipe.ProcPatternInfos) {
|
|
if (procPatternInfo.ProcPatternId == eProcPatternId.ProcPattern1 &&
|
|
procPatternInfo.ProcId.Equals(_ProcId)) {
|
|
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
checkProcPattern1 = true;
|
|
}
|
|
}
|
|
// ProcPatternInfos에 해당 ProcPatternInfo가 없으면 만들어준다.
|
|
if (!checkProcPattern1) {
|
|
var procPatternInfo = CreateNewProcPatternInfo(fovId, 1);
|
|
fovRecipe.PatternRecipe.ProcPatternInfos.Add(procPatternInfo);
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
}
|
|
// Align의 종류가 하나의 Fov에서 여러개의 패턴을 가져와야 하는 경우 ProcPattern을 더 가져온다.
|
|
if (alignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_M2R ||
|
|
alignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_AP2_A2 ||
|
|
_SubSysRecipe.SubSysType == eSubSysType.Inspect) {
|
|
bool checkProcPattern2 = false;
|
|
foreach (var procPatternInfo in fovRecipe.PatternRecipe.ProcPatternInfos) {
|
|
if (procPatternInfo.ProcPatternId == eProcPatternId.ProcPattern2 &&
|
|
procPatternInfo.ProcId.Equals(_ProcId)) {
|
|
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
checkProcPattern2 = true;
|
|
}
|
|
}
|
|
// ProcPatternInfos에 해당 ProcPatternInfo가 없으면 만들어준다.
|
|
if (!checkProcPattern2) {
|
|
var procPatternInfo = CreateNewProcPatternInfo(fovId, 2);
|
|
fovRecipe.PatternRecipe.ProcPatternInfos.Add(procPatternInfo);
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
}
|
|
}
|
|
}
|
|
// PatternRecipe에 ProcPatternInfos가 비어있는 경우에는 바로 ProcPatternInfo를 만들어준다
|
|
else {
|
|
var procPatternInfo = CreateNewProcPatternInfo(fovId, 1);
|
|
fovRecipe.PatternRecipe.ProcPatternInfos.Add(procPatternInfo);
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
if (alignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_M2R ||
|
|
alignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_AP2_A2 ||
|
|
_SubSysRecipe.SubSysType == eSubSysType.Inspect) {
|
|
procPatternInfo = CreateNewProcPatternInfo(fovId, 2);
|
|
fovRecipe.PatternRecipe.ProcPatternInfos.Add(procPatternInfo);
|
|
AddNewCb(procPatternInfo, fovId, spSameFov);
|
|
}
|
|
}
|
|
|
|
spOtherFov.Children.Add(spSameFov);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
|
|
scrollViewer.Content = spOtherFov;
|
|
return scrollViewer;
|
|
}
|
|
|
|
private void AddNewCb(ProcPatternInfo procPatternInfo, eFovId fovId, StackPanel spSameFov) {
|
|
var spSameFovInside = new StackPanel();
|
|
spSameFovInside.Orientation = Orientation.Horizontal;
|
|
spSameFovInside.Margin = new Thickness(5, 3, 5, 3);
|
|
|
|
TextBlock tbPatternName = GetPatternName(procPatternInfo.PatternName);
|
|
tbPatternName.TextAlignment = TextAlignment.Left;
|
|
//tbPatternName.Width = 130;
|
|
//tbPatternName.Width = 155;
|
|
spSameFovInside.Children.Add(tbPatternName);
|
|
|
|
ComboBox cbPattern = new ComboBox();
|
|
spSameFovInside.Children.Add(cbPattern);
|
|
|
|
SetPatternCbInfos(fovId, procPatternInfo, cbPattern);
|
|
|
|
spSameFov.Children.Add(spSameFovInside);
|
|
}
|
|
|
|
private TextBlock GetPatternName(string patternName) {
|
|
var tbPatternName = new TextBlock();
|
|
tbPatternName.FontSize = 13;
|
|
tbPatternName.Style = FindResource("styleTextBlockSubTitleSmall") as Style;
|
|
tbPatternName.Margin = new Thickness(5, 5, 15, 5);
|
|
tbPatternName.HorizontalAlignment = HorizontalAlignment.Left;
|
|
tbPatternName.Text = patternName;
|
|
|
|
return tbPatternName;
|
|
}
|
|
|
|
private void SetPatternCbInfos(eFovId fovId, ProcPatternInfo procPatternInfo, ComboBox patternComboBox) {
|
|
var infoKey = new PatternCbInfoKey(fovId, procPatternInfo.ProcPatternId);
|
|
if (!_PatternCbInfos.ContainsKey(infoKey)) {
|
|
_PatternCbInfos.Add(infoKey, new PatternCbInfoValue(procPatternInfo.PatternName, patternComboBox));
|
|
}
|
|
}
|
|
|
|
private void InitPatternItemsList() {
|
|
try {
|
|
foreach (var key in _PatternCbInfos.Keys.Select((value, index) => (value, index))) {
|
|
PatternCbInfoKey infoKey = key.value;
|
|
var index = key.index;
|
|
AddComboBoxItems(infoKey);
|
|
SelectComboBoxItem(infoKey, index);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
}
|
|
|
|
// 콤보박스 항목 추가
|
|
private void AddComboBoxItems(PatternCbInfoKey infoKey) {
|
|
try {
|
|
ComboBox cb = _PatternCbInfos[infoKey].PatternComboBox;
|
|
cb.Items.Clear();
|
|
|
|
var fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo.UnitId, _SubSysInfo.SubSysId, infoKey.FovId);
|
|
var fovRecipe = VisionRecipeManager.GetFovRecipe(_SubSysInfo.UnitId, _SubSysInfo.SubSysId, infoKey.FovId);
|
|
var patternAgent = PatternAgentManager.GetAgent(fovInfo);
|
|
|
|
if (VisionSettingManager.VisionSetting.UseCamPattern) {
|
|
// CamPattern을 사용하는 경우에는 Pattern Agent들마다 동기화를 해줘야 하므로 패턴을 다시 불러온다.
|
|
patternAgent.LoadPatterns();
|
|
}
|
|
|
|
var fovPatternInfos = patternAgent.GetMainPatterns(_SubSysInfo, infoKey.FovId);
|
|
List<PatternIndex> patternIndexes = new List<PatternIndex>();
|
|
|
|
for (int i = 0; i < fovPatternInfos.Count; i++) {
|
|
patternIndexes.Add(new PatternIndex(_SubSysInfo, fovRecipe.FovId, fovPatternInfos[i].GetPatternId()));
|
|
cb.Items.Add(PatternUtil.GetPatternDescription(fovPatternInfos[i]));
|
|
}
|
|
|
|
if (!_PatternIndexesAll.ContainsKey(infoKey)) {
|
|
_PatternIndexesAll.Add(infoKey, patternIndexes);
|
|
}
|
|
else {
|
|
_PatternIndexesAll[infoKey] = patternIndexes;
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
}
|
|
|
|
// 콤보박스 항목 선택
|
|
private void SelectComboBoxItem(PatternCbInfoKey infoKey, int index) {
|
|
try {
|
|
var procPatternInfos = _SubSysRecipe.FovRecipes[(int)infoKey.FovId].PatternRecipe.ProcPatternInfos;
|
|
var procPatternInfo = procPatternInfos.Where(p => p.ProcPatternId.Equals(infoKey.ProcPatternId) && p.ProcId.Equals(_ProcId)).FirstOrDefault().Clone();
|
|
|
|
for (int i = 0; i < _PatternIndexesAll[infoKey].Count(); i++) {
|
|
if (_PatternIndexesAll[infoKey][i].PatternId == procPatternInfo.PatternId) {
|
|
_PatternCbInfos[infoKey].PatternComboBox.SelectedIndex = i;
|
|
}
|
|
}
|
|
}
|
|
catch (NullReferenceException e) {
|
|
MessageUtil.ShowErrorToast($"[{_SubSysInfo.SubSysId}][{infoKey.FovId}][{infoKey.ProcPatternId}] Not Found in ProcPatternInfos.");
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
}
|
|
|
|
private void PrintRecipeError(FovRecipe fovRecipe, StackPanel spSameFov) {
|
|
var errMsg = string.Format(StrTokens.RecipeErrorMessage, $"PatternRecipe.ProcPatternInfos of {fovRecipe.FovId}");
|
|
spSameFov.Children.Add(new UCRecipeErrorTextBlock(errMsg) {
|
|
Margin = new Thickness(5),
|
|
HorizontalContentAlignment = HorizontalAlignment.Left
|
|
}); ;
|
|
}
|
|
|
|
private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
|
|
bool isVisible = (bool)e.NewValue;
|
|
if (isVisible == true) {
|
|
RefreshVisionRecipes();
|
|
InitPatternItemsList();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 비전 레시피 Refresh
|
|
/// </summary>
|
|
public void RefreshVisionRecipes() {
|
|
_SubSysRecipe = VisionRecipeManager.GetSubSysRecipe(_SubSysInfo);
|
|
}
|
|
/// <summary>
|
|
/// UI로 부터 레시피 업데이트
|
|
/// </summary>
|
|
public void UpdateRecipeFromUI() {
|
|
try {
|
|
foreach (var key in _PatternCbInfos.Keys.Select((value, index) => (value, index))) {
|
|
PatternCbInfoKey infoKey = key.value;
|
|
var patternRecipe = VisionRecipeManager.GetPatternRecipe(_SubSysInfo, infoKey.FovId);
|
|
var procPatternInfos = patternRecipe.ProcPatternInfos;
|
|
var procPatternInfo = procPatternInfos.Where(p => p.ProcPatternId.Equals(infoKey.ProcPatternId) && p.ProcId.Equals(_ProcId)).FirstOrDefault();
|
|
|
|
if (_PatternCbInfos[infoKey].PatternName == procPatternInfo.PatternName) {
|
|
int cbSelectedIdx = _PatternCbInfos[infoKey].PatternComboBox.SelectedIndex;
|
|
|
|
if (!_PatternIndexesAll.ContainsKey(infoKey) || _PatternIndexesAll[infoKey].Count <= cbSelectedIdx) {
|
|
AddComboBoxItems(infoKey);
|
|
}
|
|
|
|
List<PatternIndex> patternIndexes = _PatternIndexesAll[infoKey];
|
|
PatternIndex patternIndex = patternIndexes[cbSelectedIdx];
|
|
|
|
procPatternInfo.PatternId = patternIndex.PatternId;
|
|
if (VisionSettingManager.VisionSetting.UseCamPattern) {
|
|
procPatternInfo.IsFovPattern = false;
|
|
}
|
|
else {
|
|
procPatternInfo.IsFovPattern = true;
|
|
}
|
|
}
|
|
}
|
|
InitPatternItemsList();
|
|
}
|
|
catch (Exception e) {
|
|
_Logger.FuncE(e.Message);
|
|
}
|
|
}
|
|
}
|
|
} |