2026-01-26 14:51:28 +09:00

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);
}
}
}
}