Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/PageCalib/AlgorithmCalib/ViewModel/FusionMenuCalibViewModel.cs

399 lines
15 KiB
C#
Raw Normal View History

using JM1.VisionModule;
using MainShell.AlgorithmCalib.Model;
using MainShell.AlgorithmCalib.Service;
using MainShell.AlgorithmCalib.View;
using MainShell.Common;
using MainShell.Common.Display.ViewModel;
using MainShell.Filewritable;
using MainShell.Hardware;
using MaxwellFramework.Core.Interfaces;
using MwFramework.Controls.SystemCalib;
using MwFramework.ManagerService;
using Stylet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;
using Point = SemiconductorVisionAlgorithm.SemiParams.Point;
namespace MainShell.AlgorithmCalib.ViewModel
{
public class FusionMenuCalibViewModel : Screen, IPage
{
private readonly Dictionary<string, Window> _calibWindows = new Dictionary<string, Window>();
private List<Point> _calibResultRealPoint = new List<Point>();
private List<Point> _calibResultAxisPoint = new List<Point>();
private MotionFusion _motionFusion = new MotionFusion();
private FusionCalibMotionService _fusionCalibMotionService;
public string Name { get; set; } = "FusionMenuCalib";
public string CalibName { get; set; }
public string FileSaveDir { get; set; }
private bool _isDataLoaded = false;
private CameraAxisViewModel _cameraAxisViewModelSevice = new CameraAxisViewModel();
public CameraAxisViewModel CameraAxisViewModelSevice
{
get { return _cameraAxisViewModelSevice; }
set
{
_cameraAxisViewModelSevice = value;
OnPropertyChanged(nameof(CameraAxisViewModelSevice));
}
}
private ObservableCollection<FusionCalibParItem> _fusionCalibParItem = new ObservableCollection<FusionCalibParItem>();
public ObservableCollection<FusionCalibParItem> FusionCalibParItem
{
get { return _fusionCalibParItem; }
set
{
_fusionCalibParItem = value;
OnPropertyChanged(nameof(FusionCalibParItem));
}
}
private FusionCalibParItem _selectedCalibPar;
public FusionCalibParItem SelectedCalibPar
{
get { return _selectedCalibPar; }
set
{
_selectedCalibPar = value;
OnPropertyChanged(nameof(SelectedCalibPar));
}
}
private FusionCalibParItem _inputParam;
public FusionCalibParItem InputParam
{
get { return _inputParam; }
set { SetAndNotify(ref _inputParam, value); }
}
private FusionCalibParItem _resultParam;
public FusionCalibParItem ResultParam
{
get { return _resultParam; }
set { SetAndNotify(ref _resultParam, value); }
}
private List<HardwareDevice> _hardwareDevice;
public List<HardwareDevice> HardwareDevice
{
get { return _hardwareDevice; }
set
{
_hardwareDevice = value;
NotifyOfPropertyChange();
}
}
private HardwareManager _hardware;
public HardwareManager Hardware
{
get { return _hardware; }
set
{
_hardware = value;
NotifyOfPropertyChange();
}
}
private bool _isCalibFinished;
public bool IsCalibFinished
{
get { return _isCalibFinished; }
set { SetAndNotify(ref _isCalibFinished, value); }
}
/// <summary>
/// 无参构造函数
/// </summary>
public FusionMenuCalibViewModel()
{
}
/// <summary>
/// 手动创建时使用的静态工厂方法
/// </summary>
/// <param name="cameraName">相机名称,如 "BottomCamera"</param>
/// <param name="device">对应的硬件设备</param>
public static FusionMenuCalibViewModel Create(string calibName, string fileSaveName, List<HardwareDevice> device, HardwareManager hardware, FusionCalibMotionService motion)
{
var vm = new FusionMenuCalibViewModel();
vm.Initialize(calibName, fileSaveName, device, hardware, motion);
return vm;
}
protected override void OnViewLoaded()
{
base.OnViewLoaded();
if (_hardware != null)
{
_cameraAxisViewModelSevice = new CameraAxisViewModel();
_cameraAxisViewModelSevice.CameraAxisDevices.HardwareDeviceList = HardwareDevice;
NotifyOfPropertyChange(nameof(CameraAxisViewModel));
}
if (!_isDataLoaded)
{
ReadCalibData();
_isDataLoaded = true;
}
}
private void Initialize(string calibName, string fileSaveName, List<HardwareDevice> device, HardwareManager hardware, FusionCalibMotionService motion)
{
CalibName = calibName;
Hardware = hardware;
HardwareDevice = device;
_fusionCalibMotionService = motion;
FileSaveDir = Path.Combine(Paths.CalibSettingPath, "fusionCalib");
var paramList = IoC.Get<IParameterManager>() as IParamList;
}
public void btnOpenCalibWindow()
{
if (SelectedCalibPar == null)
{
MwMessageBox.Show("请先选择一组标定数据。", "提示",
MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
string cameraId = SelectedCalibPar.Camera_ID;
// ── 如果已有缓存窗口,直接激活显示 ──
if (_calibWindows.TryGetValue(cameraId, out var existingWindow))
{
if (existingWindow.WindowState == WindowState.Minimized)
existingWindow.WindowState = WindowState.Normal;
existingWindow.Show();
existingWindow.Activate();
return;
}
var calibVM = CameraFusionPadCalibViewModel.Create("", CalibName, HardwareDevice, SelectedCalibPar, Hardware, _fusionCalibMotionService);
calibVM.FileSaveDir = this.FileSaveDir;
// ② 创建视图
var calibView = new CameraFusionPadCalibView
{
DataContext = calibVM,
};
// 4. 创建 Window 包裹这个 UserControl
var window = new Window
{
Title = $"融合标定-{cameraId}",
Width = 1100,
Height = 750,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Owner = Application.Current.MainWindow,
ResizeMode = ResizeMode.CanResize,
Content = calibView
};
// ── 拦截关闭:改为隐藏,保留内存状态 ──
window.Closing += (s, args) =>
{
args.Cancel = true; // 取消真正的关闭
window.Hide(); // 仅隐藏VM 和 View 状态全部保留
};
// ── 用 Unloaded 代替 Closed 做数据同步 ──
// 每次隐藏时都把 Service 最新数据写回选中行
window.IsVisibleChanged += (s, args) =>
{
if (!(bool)args.NewValue) // 变为不可见Hide
{
SyncCalibResultBack(calibVM);
}
};
// 缓存
_calibWindows[cameraId] = window;
window.Show();
window.Closed += (s, args) =>
{
var innerData = calibVM.FusionCalibParItem;
if (innerData != null)
{
SelectedCalibPar.Index = innerData.Index;
SelectedCalibPar.MoveAxisPos = innerData.MoveAxisPos;
SelectedCalibPar.ApproachXPos = innerData.ApproachXPos;
SelectedCalibPar.ApproachYPos = innerData.ApproachYPos;
SelectedCalibPar.StartX = innerData.StartX;
SelectedCalibPar.StartY = innerData.StartY;
SelectedCalibPar.Step = innerData.Step;
SelectedCalibPar.Count = innerData.Count;
SelectedCalibPar.RulerPoints = innerData.RulerPoints;
SelectedCalibPar.RealPoints = innerData.RealPoints;
// 刷新 DataGrid
OnPropertyChanged(nameof(FusionCalibParItem));
}
};
}
/// <summary>
/// 将内部标定窗口的最新数据同步回外部 DataGrid 选中行
/// </summary>
private void SyncCalibResultBack(CameraFusionPadCalibViewModel calibVM)
{
var innerData = calibVM.ResultParam;
if (innerData != null) return;
var target = FusionCalibParItem.FirstOrDefault(p => p.Camera_ID == calibVM.CameraName);
if(target == null) return;
target.Index = innerData.Index;
target.MoveAxisPos = innerData.MoveAxisPos;
target.ApproachXPos = innerData.ApproachXPos;
target.ApproachYPos = innerData.ApproachYPos;
target.StartX = innerData.StartX;
target.StartY = innerData.StartY;
target.Step = innerData.Step;
target.Count = innerData.Count;
target.RulerPoints = innerData.RulerPoints;
target.RealPoints = innerData.RealPoints;
// 刷新 DataGrid
OnPropertyChanged(nameof(FusionCalibParItem));
}
public void btnReadCalibData()
{
var result = MwMessageBox.Show($"确认读取本地标定数据?", "确认读取", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
if (!ReadCalibData())
{
MwMessageBox.Show("读取本地标定数据失败!", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
public bool ReadCalibData()
{
try
{
var paramList = IoC.Get<IParameterManager>() as IParamList;
//FusionCalibParItem.CalibParList = new ObservableCollection<FusionSysDataItem>();
for (int i = 0; i < 4; i++)
{
var filePath = Path.Combine(FileSaveDir, $"Fusion_Time{i + 1}.xml");
var pointsFilePath = Path.Combine(FileSaveDir, $"Fusion_Time{i + 1}.txt");
bool hasXml = File.Exists(filePath);
bool hasTxt = File.Exists(pointsFilePath);
double moveAxisPos = 0;
double approachXPos = 0;
double approachYPos = 0;
double startX = 0;
double startY = 0;
double step = 0;
int count = 0;
List<Point> rulerPoints = new List<Point>();
List<Point> realPoints = new List<Point>();
// ① 有 XML → 读取参数
if (hasXml)
{
//var uiData = UIDataManager.Instance.GetUIData<FusionCalibParItem>(paramList);
//uiData.Read(filePath);
//var xmlData=XmlReader(filePath);
//if (xmlData.Datas != null && xmlData.Datas.Count > 0)
//{
// var item = xmlData.Datas[0]; // 每个文件只有一组数据
// index=item.Index;
// moveAxisPos = item.MoveAxisPos;
// approachXPos = item.ApproachXPos;
// approachYPos = item.ApproachYPos;
// startX = item.StartX;
// startY = item.StartY;
// step = item.Step;
// count = item.Count;
//}
}
// ② 有 TXT → 读取标定点位
if (hasTxt)
{
MotionCalibFileService.ReadCalibPointsFile(
pointsFilePath, out realPoints, out rulerPoints);
rulerPoints = rulerPoints ?? new List<Point>();
realPoints = realPoints ?? new List<Point>();
}
// ③ 无论什么情况,都加到列表(保证 5 组都在)
var par = new FusionCalibParItem
{
Index = i + 1,
Camera_ID = "Fusion_Time" + (i + 1),
MoveAxisPos = moveAxisPos,
ApproachXPos = approachXPos,
ApproachYPos = approachYPos,
StartX = startX,
StartY = startY,
Step = step,
Count = count,
RulerPoints = rulerPoints,
RealPoints = realPoints,
};
FusionCalibParItem.Add(par);
}
return true;
}
catch
{
return false;
}
}
public void btnApplyCalibData()
{
//if (FusionCalibParItem.CalibParList.Count != 5)
//{
// MwMessageBox.Show("标定数据不足,请完成全部标定!", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
// return;
//}
//var result = MwMessageBox.Show($"确认应用标定数据?", "确认应用", MessageBoxButton.YesNo, MessageBoxImage.Warning);
//if (result == MessageBoxResult.Yes)
//{
// if (true) //
// {
// MwMessageBox.Show("应用标定数据成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
// }
//}
}
public void ApplayCalibData()
{
//List<string> cameraIdList = new List<string>();
//for (int i = 0; i < 5; i++)
//{
// var resultPointsList = FusionCalibParItem.CalibParList[i];
// _motionFusion.Set(i, resultPointsList.ResultRealPoints, resultPointsList.ResultAxisPoints);
// cameraIdList.Add(resultPointsList.CameraId);
//}
//_motionFusion.AutoSelectPt(cameraIdList[0], cameraIdList[1], cameraIdList[2], cameraIdList[3], out _calibResultRealPoint, out _calibResultAxisPoint);
//MwAlgorithmHelper.Instance.RulerToRealMaritex("topCameraPad", _calibResultAxisPoint, _calibResultRealPoint, 1, 1, 1, 1, UIDataManager.CalibDataDir);
}
public void XmlReader(string xmlFilePath)
{
}
}
}