2026-01-26 18:56:53 +09:00

441 lines
17 KiB
C#

using Aurora.Api;
using VisionCommon;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Controls.Primitives;
using VisionCommonUI.Resources;
using System.Windows.Media;
using DevExpress.Xpf.Core;
using AuroraUIComponent.UserControls;
using Aurora;
using Hermes;
using System.IO;
using System.Threading;
using System.Drawing;
namespace VisionCommonUI {
public partial class ChildImageSettingView : UserControl {
private Logger _Logger = new Logger(typeof(ChildImageSettingView).Name);
private FovInfo _FovInfo;
private eCamId _CamId;
private CameraAgentBase _CameraAgent;
private CamConfig _CamConfig;
private ICameraDisplay _CameraDisplay;
private object _GrabImage;
private const int ROW_COL_MAX_CNT = 10;
public ChildImageSettingView(FovInfo fovInfo, ICameraDisplay cameraDisplay) {
_FovInfo = fovInfo;
_CamId = VisionRecipeManager.GetCamRecipe(_FovInfo).CamId;
_CameraAgent = CameraAgentManager.GetCameraAgent(_FovInfo);
_CameraDisplay = cameraDisplay;
UpdateCamConfig();
InitializeComponent();
}
private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
bool isVisible = (bool)e.NewValue;
if (isVisible == true) {
UpdateView();
}
}
public void UpdateView() {
try {
ClearView();
AddRowColumnDefinitions();
for (int rowIdx = 0; rowIdx < _CamConfig.ChildImage.RowCnt; rowIdx++) {
for (int colIdx = 0; colIdx < _CamConfig.ChildImage.ColCnt; colIdx++) {
var toggleBtn = new ToggleButton() {
//Style = FindResource("defaultToggleButton") as Style,
Content = GetToggleButtonContent(rowIdx, colIdx),
IsChecked = IsChecked(rowIdx, colIdx),
Tag = GetRowColIdxString(rowIdx, colIdx)
};
Grid.SetRow(toggleBtn, rowIdx);
Grid.SetColumn(toggleBtn, colIdx);
gridRowCols.Children.Add(toggleBtn);
}
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
}
private Viewbox GetToggleButtonContent(int rowIdx, int colIdx) {
var viewBox = new Viewbox();
viewBox.Stretch = Stretch.Uniform;
try {
var grid = new Grid();
var rowDef1 = new RowDefinition();
var rowDef2 = new RowDefinition();
var rowDef3 = new RowDefinition();
var rowDef4 = new RowDefinition();
grid.RowDefinitions.Add(rowDef1);
grid.RowDefinitions.Add(rowDef2);
grid.RowDefinitions.Add(rowDef3);
grid.RowDefinitions.Add(rowDef4);
ChildBufRowCol childBufRowCol = GetChildBufRowCol(rowIdx, colIdx);
// Row, Col 인덱스
var tbRowCols = new TextBlock() {
Text = GetRowColIdxString(rowIdx, colIdx), // 3x3 예시 : 00, 01, 02, ... 22
FontSize = 20,
FontWeight = FontWeights.SemiBold,
Margin = new Thickness(5)
};
// 플라잉 순서 인덱스
var tbIdx = new TextBox() {
FontSize = 20,
FontWeight = FontWeights.SemiBold,
Width = 55,
Text = (childBufRowCol != null) ? childBufRowCol.PosIdx.ToString() : GetDefaultIndexFromRowCols(rowIdx, colIdx).ToString(), // 3x3 예시 : 0, 1, 2, ... 8
Foreground = new SolidColorBrush(Colors.Orange),
Background = new SolidColorBrush(Colors.Gray),
Margin = new Thickness(5)
};
// 플라잉 모터 위치
var spMotorPos = new StackPanel() {
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right
};
var motorPosX = new UCKeyValue() {
KeyText = "M.X",
FontWeight = FontWeights.Light,
ValueTextSize = 13,
ValueTextWidth = "100",
DecimalPlaces = 4,
Value = (childBufRowCol != null) ? (decimal)childBufRowCol.MotorPos.X : 0,
ValueTextFgColor = new SolidColorBrush(Colors.Orange)
};
var motorPosY = new UCKeyValue() {
KeyText = "M.Y",
FontWeight = FontWeights.Light,
ValueTextSize = 13,
ValueTextWidth = "100",
DecimalPlaces = 4,
Value = (childBufRowCol != null) ? (decimal)childBufRowCol.MotorPos.Y : 0,
ValueTextFgColor = new SolidColorBrush(Colors.Orange)
};
spMotorPos.Children.Add(motorPosX);
spMotorPos.Children.Add(motorPosY);
// 플라잉 모터 위치 오프셋
var spMotorPosOffset = new StackPanel() {
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right
};
var motorPosOffsetX = new UCKeyValue() {
KeyText = "O.X",
FontWeight = FontWeights.Light,
ValueTextSize = 13,
ValueTextWidth = "100",
DecimalPlaces = 4,
Value = (childBufRowCol != null) ? (decimal)childBufRowCol.MotorPosOffset.X : 0,
ValueTextFgColor = new SolidColorBrush(Colors.Orange)
};
var motorPosOffsetY = new UCKeyValue() {
KeyText = "O.Y",
FontWeight = FontWeights.Light,
ValueTextSize = 13,
ValueTextWidth = "100",
DecimalPlaces = 4,
Value = (childBufRowCol != null) ? (decimal)childBufRowCol.MotorPosOffset.Y : 0,
ValueTextFgColor = new SolidColorBrush(Colors.Orange)
};
spMotorPosOffset.Children.Add(motorPosOffsetX);
spMotorPosOffset.Children.Add(motorPosOffsetY);
Grid.SetRow(tbRowCols, 0);
Grid.SetRow(tbIdx, 1);
Grid.SetRow(spMotorPos, 2);
Grid.SetRow(spMotorPosOffset, 3);
grid.Children.Add(tbRowCols);
grid.Children.Add(tbIdx);
grid.Children.Add(spMotorPos);
grid.Children.Add(spMotorPosOffset);
viewBox.Child = grid;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return viewBox;
}
private bool IsChecked(int rowIdx, int colIdx) {
foreach (ChildBufRowCol bufRowCol in _CamConfig.ChildImage.ChildBufRowCols) {
if (bufRowCol.RowIdx == rowIdx && bufRowCol.ColIdx == colIdx) {
if (bufRowCol.Enabled) {
return true;
}
}
}
return false;
}
private ChildBufRowCol GetChildBufRowCol(int rowIdx, int colIdx) {
foreach (ChildBufRowCol childBufRowCol in _CamConfig.ChildImage.ChildBufRowCols) {
if (childBufRowCol.RowIdx == rowIdx && childBufRowCol.ColIdx == colIdx) {
return childBufRowCol;
}
}
return null;
}
private int GetDefaultIndexFromRowCols(int rowIdx, int colIdx) {
var rowCols = _CamConfig.ChildImage.ChildBufRowCols;
for (int i = 0; i < rowCols.Count; i++) {
if (rowCols[i].RowIdx == rowIdx && rowCols[i].ColIdx == colIdx) {
return i;
}
}
return _CamConfig.ChildImage.ColCnt * rowIdx + colIdx;
}
private string GetRowColIdxString(int rowIdx, int colIdx) {
return string.Format($"{rowIdx}{colIdx}");
}
private (int, int) GetRowColIdxFromTag(object tag) {
var tagStr = (string)tag;
int rowIdx = Convert.ToInt16(tagStr[0] - '0');
int colIdx = Convert.ToInt16(tagStr[1] - '0');
return (rowIdx, colIdx);
}
private void ClearView() {
gridRowCols.Children.Clear();
gridRowCols.RowDefinitions.Clear();
gridRowCols.ColumnDefinitions.Clear();
}
private void AddRowColumnDefinitions() {
var rows = GetUiPosRows();
var cols = GetUiPosCols();
foreach (var row in rows) {
gridRowCols.RowDefinitions.Add(new RowDefinition());
}
foreach (var col in cols) {
gridRowCols.ColumnDefinitions.Add(new ColumnDefinition());
}
}
private List<int> GetUiPosRows() {
var rows = new SortedSet<int>();
for (int rowIdx = 0; rowIdx < _CamConfig.ChildImage.RowCnt; rowIdx++) {
rows.Add(rowIdx);
}
return new List<int>(rows);
}
private List<int> GetUiPosCols() {
var cols = new SortedSet<int>();
for (int colIdx = 0; colIdx < _CamConfig.ChildImage.ColCnt; colIdx++) {
cols.Add(colIdx);
}
return new List<int>(cols);
}
private void UpdateCamConfig() {
var camConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(_CamId.ToString()) as CamConfig;
_CamConfig = camConfig.Clone();
}
private void Click_RemoveRow(object sender, RoutedEventArgs e) {
if (_CamConfig.ChildImage.RowCnt == 1) {
return;
}
_CamConfig.ChildImage.RowCnt--;
UpdateView();
}
private void Click_AddRow(object sender, RoutedEventArgs e) {
if (_CamConfig.ChildImage.RowCnt == ROW_COL_MAX_CNT) {
_Logger.FuncE($"Row count exceeds the maximum number {ROW_COL_MAX_CNT}");
return;
}
_CamConfig.ChildImage.RowCnt++;
UpdateView();
}
private void Click_RemoveCol(object sender, RoutedEventArgs e) {
if (_CamConfig.ChildImage.ColCnt == 1) {
return;
}
_CamConfig.ChildImage.ColCnt--;
UpdateView();
}
private void Click_AddCol(object sender, RoutedEventArgs e) {
if (_CamConfig.ChildImage.ColCnt == ROW_COL_MAX_CNT) {
_Logger.FuncE($"Column count exceeds the maximum number {ROW_COL_MAX_CNT}.");
return;
}
_CamConfig.ChildImage.ColCnt++;
UpdateView();
}
private void Click_Reload(object sender, RoutedEventArgs e) {
UpdateCamConfig();
UpdateView();
}
private void Click_FlyingGrab(object sender, RoutedEventArgs e) {
if (_CameraAgent.IsLiveRunning()) {
_CameraAgent.StopLive();
}
_CameraAgent.StartFlying(_FovInfo);
EquipAdapter.Instance.EquipTrigger.SetTrigger();
EquipAdapter.Instance.EquipTrigger.TriggerOn();
Thread.Sleep(_CamConfig.HwTrigConfig.OffDelay_Ms);
EquipAdapter.Instance.EquipTrigger.TriggerOff();
if (_GrabImage == null) {
_GrabImage = _CameraAgent.CloneImageBuffer();
}
int res = _CameraAgent.GetGrabImageFromBuffer(_CameraDisplay, ref _GrabImage);
if (res == E1.OK) {
_Logger.FuncI("[HwTrigger] Grab Success.");
}
else {
_Logger.FuncE("[HwTrigger] Grab Failed.");
}
_CameraAgent.StopFlying();
}
private void Click_Verify(object sender, RoutedEventArgs e) {
object parentImage = null;
if (_CameraAgent.VerifyChildImage(_CameraDisplay, ref parentImage) == E1.OK) {
var filePath = Path.Combine(ApplicationExt.DataPath, "1_VerifyParentImage.png");
IpAdapter.Instance.IpEnvironment.SaveImage(filePath, parentImage);
VerifyParentImageWindow.Instance.Show(filePath);
VerifyParentImageWindow.Instance.Activate();
}
else {
_Logger.FuncE("Failed to create the verify parent image.");
}
}
private void Click_Save(object sender, RoutedEventArgs e) {
try {
var camConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(_CamId.ToString()) as CamConfig;
camConfig.ChildImage.RowCnt = _CamConfig.ChildImage.RowCnt;
camConfig.ChildImage.ColCnt = _CamConfig.ChildImage.ColCnt;
camConfig.ChildImage.ChildBufRowCols.Clear();
var imageSizeWidthChild = (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX);
var mageSizeHeightChild = (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY);
foreach (ToggleButton toggleBtn in gridRowCols.Children) {
// Enabled 추출
var childBufRowCol = new ChildBufRowCol();
childBufRowCol.Enabled = ((bool)toggleBtn.IsChecked) ? true : false;
// Row & Col Idx 추출
(int rowIdx, int colIdx) = GetRowColIdxFromTag(toggleBtn.Tag);
childBufRowCol.RowIdx = rowIdx;
childBufRowCol.ColIdx = colIdx;
Viewbox content = (Viewbox)toggleBtn.Content;
Grid child = (Grid)content.Child;
// PosIdx 추출 (Flying 순서)
TextBox tb = (TextBox)child.Children[1];
int posIdx = Convert.ToInt16(tb.Text);
if (IsValidPosIdx(posIdx)) {
childBufRowCol.PosIdx = posIdx;
}
else {
int minPosIdx = 0;
_Logger.FuncE($"The range of pos idx must be between 0 and {camConfig.ChildImage.ChildBufRowCols.Count - 1}.");
tb.Text = minPosIdx.ToString();
childBufRowCol.PosIdx = minPosIdx; // Min 값으로 대체
}
// MotorPos 추출
StackPanel spMotorPos = (StackPanel)child.Children[2];
childBufRowCol.MotorPos.X = (double)(spMotorPos.Children[0] as UCKeyValue).Value;
childBufRowCol.MotorPos.Y = (double)(spMotorPos.Children[1] as UCKeyValue).Value;
// MotorPosOffset 추출
StackPanel spMotorPosOffset = (StackPanel)child.Children[3];
childBufRowCol.MotorPosOffset.X = (double)(spMotorPosOffset.Children[0] as UCKeyValue).Value;
childBufRowCol.MotorPosOffset.Y = (double)(spMotorPosOffset.Children[1] as UCKeyValue).Value;
// Rect 복원
childBufRowCol.Rect = new Rectangle(
imageSizeWidthChild * childBufRowCol.ColIdx,
mageSizeHeightChild * childBufRowCol.RowIdx,
imageSizeWidthChild,
mageSizeHeightChild);
camConfig.ChildImage.ChildBufRowCols.Add(childBufRowCol);
}
_CamConfig = camConfig.Clone(); // 저장된 camConfig와 Sync를 맞춰주기 위함
VisionEnv.AuroraEnv.DeviceManager.SaveDeviceConfig(_CamId.ToString());
MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted);
_CameraAgent.Deactivate();
_CameraAgent.Activate();
VisionEnv.AuroraEnv.EventPublisher.Publish(new EventMessage(_CamId.ToString(), VisionEventId.SAVE_CHILD_IMAGE_SETTING));
var rootParent = this.GetRootParent();
if (rootParent != null) {
var window = rootParent as Window;
window?.Close();
}
}
catch (Exception ex) {
_Logger.FuncE(ex.Message);
}
}
private bool IsValidPosIdx(int posIdx) {
if (posIdx >= 0 && posIdx < _CamConfig.ChildImage.ChildBufRowCols.Count) {
return true;
}
else {
return false;
}
}
private IEnumerable<T> ToEnumerable<T>(Func<IEnumerator<T>> getEnumerator) {
var enumerator = getEnumerator();
while (enumerator.MoveNext()) {
yield return enumerator.Current;
}
}
private void Click_Close(object sender, RoutedEventArgs e) {
var rootParent = this.GetRootParent();
if (rootParent != null) {
var window = rootParent as Window;
window?.Close();
}
}
}
}