using HalconDotNet;
|
using LB_VisionControls;
|
using LB_VisionControls.Forms;
|
using LB_VisionProcesses;
|
using LB_VisionProcesses.Cameras;
|
using LB_VisionProcesses.Communicators;
|
using LB_VisionProcesses.Processes;
|
using OpenCvSharp;
|
using System.Diagnostics;
|
using System.Runtime.CompilerServices;
|
using System.Collections.Concurrent;
|
using LB_SmartVision.Tool;
|
using LB_SmartVision.ProcessRun;
|
|
namespace LB_SmartVision.Forms.Pages.ProcessPage
|
{
|
public partial class ProcessPage : UserControl
|
{
|
/// <summary>
|
/// 运行步骤(object为IProces或者object为ICamera)
|
/// </summary>
|
public ProcessRunBll ProcessRunBll { get; set; }
|
|
public Action<string, LogInfoType> LogInfo;
|
|
private UserHSmartWindowControl UserHSmartWindowControl = new UserHSmartWindowControl();
|
|
public ProcessPage()
|
{
|
InitializeComponent();
|
}
|
|
public ProcessPage(string Name, ProcessRunBll ProcessRunBll)
|
{
|
InitializeComponent();
|
this.Text = "ProcessPage";
|
this.Name = Name;
|
|
this.ProcessRunBll = ProcessRunBll;
|
|
Name = ProcessRunBll.Name;
|
Text = ProcessRunBll.Name;
|
|
this.splitContainer1.Panel1.Controls.Add(UserHSmartWindowControl);
|
UserHSmartWindowControl.Dock = DockStyle.Fill;
|
|
this.panel1.Controls.Add(ProcessRunBll.nodesControl);
|
|
ProcessRunBll.nodesControl.Location = new System.Drawing.Point(0, 0);
|
ProcessRunBll.nodesControl.Size = new System.Drawing.Size(5000, 5000);
|
|
RemoveAllHandler();
|
|
ProcessRunBll.nodesControl.AddNodeAction += AddProcess;
|
ProcessRunBll.nodesControl.CopyNodeAction += CopyProcess;
|
ProcessRunBll.nodesControl.RenameNodeAction += RenameProcess;
|
ProcessRunBll.nodesControl.InAndOutNodeAction += InAndOutProcess;
|
ProcessRunBll.nodesControl.DeleteNodeAction += DeleteProcess;
|
ProcessRunBll.nodesControl.EditNodeAction += EditProcess;
|
ProcessRunBll.nodesControl.AddBranchAction += AddBranch;
|
ProcessRunBll.nodesControl.DeleteBranchAction += DeleteBranch;
|
}
|
|
private void ProcessPage_Paint(object sender, PaintEventArgs e)
|
{
|
if (ProcessRunBll.Result)
|
uiButtonRun.ButtonType = ReaLTaiizor.Util.HopeButtonType.Success;
|
else
|
uiButtonRun.ButtonType = ReaLTaiizor.Util.HopeButtonType.Danger;
|
|
if (ProcessRunBll.GetImage(out _, out HObject RecordImage))
|
UserHSmartWindowControl.ShowHoImage(RecordImage);
|
}
|
|
public void RemoveAllHandler()
|
{
|
ProcessRunBll.nodesControl.AddNodeAction -= AddProcess;
|
ProcessRunBll.nodesControl.RenameNodeAction -= RenameProcess;
|
ProcessRunBll.nodesControl.InAndOutNodeAction -= InAndOutProcess;
|
ProcessRunBll.nodesControl.DeleteNodeAction -= DeleteProcess;
|
ProcessRunBll.nodesControl.EditNodeAction -= EditProcess;
|
ProcessRunBll.nodesControl.AddBranchAction -= AddBranch;
|
ProcessRunBll.nodesControl.DeleteBranchAction -= DeleteBranch;
|
}
|
|
private void uiButtonRun_Click(object sender, EventArgs e)
|
{
|
this.BeginInvoke(new Action(() =>
|
{
|
UserHSmartWindowControl.ClearObj();
|
|
LogInfo?.Invoke(string.Format("流程[{0}]开始运行", this.ProcessRunBll.Name), LogInfoType.INFO);
|
|
bool result = this.ProcessRunBll.Run();
|
string msg = ProcessRunBll.Msg;
|
|
LogInfo?.Invoke(string.Format("流程[{0}]运行完成,结果:{1}", this.ProcessRunBll.Name, msg)
|
, result ? LogInfoType.PASS : LogInfoType.ERROR);
|
|
if (ProcessRunBll.GetImage(out _, out HObject RecordImage))
|
UserHSmartWindowControl.ShowHoImage(RecordImage);
|
|
if (result)
|
uiButtonRun.ButtonType = ReaLTaiizor.Util.HopeButtonType.Success;
|
else
|
uiButtonRun.ButtonType = ReaLTaiizor.Util.HopeButtonType.Danger;
|
}));
|
}
|
|
public void AddProcess(string ProcessName, string Descript)
|
{
|
string ClassName = ProcessRunBll.Node2ToolClassName(Descript);
|
string ProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + ProcessName + ".json";
|
if (ProcessRunBll.AddStep(ProcessRunBll.Name, ProcessName, ClassName, ProcessPath))
|
{
|
ProcessRunBll.SaveInputs();
|
ProcessRunBll.SaveOutputs();
|
ProcessRunBll.CompileMappings();
|
}
|
else
|
LogInfo?.Invoke(string.Format("流程[{0}]添加步骤\"{1}\"失败", this.Text, ProcessName), LogInfoType.ERROR);
|
}
|
|
public void CopyProcess(string oriProcessName, string newProcessName, string Descript)
|
{
|
var dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(oriProcessName))
|
return;
|
string ClassName = ProcessRunBll.Node2ToolClassName(Descript);
|
string oriProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + oriProcessName + ".json";
|
string newProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + newProcessName + ".json";
|
|
// 把新的步骤文件复制一份
|
if (File.Exists(oriProcessPath))
|
File.Copy(oriProcessPath, newProcessPath, true);
|
else
|
{
|
string oriProcessDirectory = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + oriProcessName;
|
string newProcessDirectory = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + newProcessName;
|
if (Directory.Exists(oriProcessDirectory))
|
{
|
if (Directory.Exists(newProcessDirectory))
|
Directory.Delete(newProcessDirectory, true);
|
|
LB_SmartVision.Tool.Tool.CopyDirectory(oriProcessDirectory, newProcessDirectory);
|
|
string[] Files = Directory.GetFiles(newProcessDirectory);
|
|
foreach (var file in Files)
|
{
|
string fileName = Path.GetFileName(file);
|
if (fileName.StartsWith(oriProcessName))
|
{
|
string newFileName = fileName.Replace(oriProcessName, newProcessName);
|
string newFilePath = Path.Combine(newProcessDirectory, newFileName);
|
File.Move(file, newFilePath);
|
}
|
}
|
}
|
}
|
|
if (ProcessRunBll.AddStep(ProcessRunBll.Name, newProcessName, ClassName, newProcessPath))
|
{
|
ProcessRunBll.SaveInputs();
|
ProcessRunBll.SaveOutputs();
|
ProcessRunBll.CompileMappings();
|
}
|
else
|
LogInfo?.Invoke(string.Format("流程[{0}]复制步骤\"{1}\"为\"{2}\"失败", this.Text, oriProcessName, newProcessName), LogInfoType.ERROR);
|
}
|
|
private void InAndOutProcess(string ProcessName)
|
{
|
var dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
ProcessInputsSelectForm inputsSelectForm = new ProcessInputsSelectForm(ProcessName, ProcessRunBll);
|
inputsSelectForm.Text = ProcessName;
|
inputsSelectForm.ShowDialog();
|
|
ProcessRunBll.SaveInputs();
|
ProcessRunBll.SaveOutputs();
|
ProcessRunBll.CompileMappings();
|
//string ProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + ProcessName + ".json";
|
//((IProcess)dicSteps[ProcessName]).Load(ProcessPath);
|
}
|
|
public void DeleteProcess(string ProcessName)
|
{
|
try
|
{
|
var dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
string ProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + ProcessName + ".json";
|
|
if (string.IsNullOrEmpty(ProcessName) || string.IsNullOrEmpty(ProcessPath))
|
return;
|
|
// 获取所有文件(不管后缀名是什么)并进行遍历
|
string directoryPath = Path.GetDirectoryName(ProcessPath);
|
|
string[] files = Directory.GetFiles(directoryPath, ProcessName + ".*"); // 匹配所有名称为aa的文件,后缀不限
|
|
foreach (var file in files)
|
{
|
try
|
{
|
if (File.Exists(file))
|
File.Delete(file);
|
}
|
catch (Exception ex)
|
{
|
Debug.WriteLine($"删除文件 {file} 时出错: {ex.Message}");
|
LogInfo?.Invoke(string.Format("流程[{0}]移除步骤\"{1}\"失败,原因是{2}", this.Text, ProcessName, ex.Message), LogInfoType.ERROR);
|
return;
|
}
|
}
|
|
if (Directory.Exists(directoryPath + "\\" + ProcessName))
|
Directory.Delete(directoryPath + "\\" + ProcessName, true);
|
|
if (!ProcessRunBll.Remove(ProcessName))
|
LogInfo?.Invoke(string.Format("流程[{0}]移除步骤\"{1}\"失败", this.Text, ProcessName), LogInfoType.ERROR);
|
}
|
catch (Exception ex) { Debug.WriteLine(ex.Message); }
|
}
|
|
private void RenameProcess(string ProcessName, string newProcessName)
|
{
|
ConcurrentDictionary<string, IProcess> dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
ProcessRenameEvent(ProcessName, newProcessName);
|
}
|
|
private void ProcessRenameEvent(string oriName, string newName)
|
{
|
ConcurrentDictionary<string, IProcess> dicSteps = ProcessRunBll.GetSteps();
|
|
//更新后的步骤名仍然需要是唯一
|
if (dicSteps.ContainsKey(newName))
|
{
|
MessageBox.Show(string.Format("重命名失败,步骤名称[{0}]已存在!", newName), "异常");
|
return;
|
}
|
|
if (dicSteps.ContainsKey(oriName))
|
{
|
string oriPath = GlobalVar.allProcessPath + this.Text + "\\" + oriName + ".json";
|
string newPath = GlobalVar.allProcessPath + this.Text + "\\" + newName + ".json";
|
|
string directoryPath = Path.GetDirectoryName(oriPath);
|
string[] files = new string[] { };
|
|
// 重命名当前文件夹
|
files = Directory.GetFiles(directoryPath, oriName + ".*"); // 匹配所有名称为oriName的文件,后缀不限
|
foreach (var file in files)
|
{
|
try
|
{
|
// 获取文件的扩展名
|
string extension = Path.GetExtension(file);
|
|
// 构造新文件名
|
string newFileName = Path.Combine(directoryPath, newName + extension);
|
|
if (!File.Exists(newFileName))
|
{
|
// 重命名文件
|
File.Move(file, newFileName);
|
Debug.WriteLine($"文件已重命名: {file} -> {newFileName}");
|
}
|
else
|
{
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤\"{1}\"为\"{2}\"失败,原因是{3}", this.Text, oriName, newName, "命名重复"), LogInfoType.ERROR);
|
return;
|
}
|
|
}
|
catch (Exception ex)
|
{
|
Debug.WriteLine($"重命名文件 {file} 时出错: {ex.Message}");
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤\"{1}\"为\"{2}\"失败,原因是{3}", this.Text, oriName, newName, ex.Message), LogInfoType.ERROR);
|
return;
|
}
|
}
|
|
|
// 重命名当前文件夹
|
if (Directory.Exists(directoryPath + "\\" + oriName))
|
{
|
Directory.Move(directoryPath + "\\" + oriName, directoryPath + "\\" + newName);
|
// 重命名子文件夹
|
string newParentDirectory = Path.GetDirectoryName(GlobalVar.allProcessPath + this.Text + "\\" + newName + "\\" + oriName + ".json");
|
files = Directory.GetFiles(newParentDirectory, oriName + ".*"); // 匹配子文件夹内所有名称为oriName的文件,后缀不限(一般只有一个)
|
foreach (var file in files)
|
{
|
try
|
{
|
// 获取文件的扩展名
|
string extension = Path.GetExtension(file);
|
// 构造新文件名
|
string newFileName = Path.Combine(newParentDirectory, newName + extension);
|
|
if (!File.Exists(newFileName))
|
{
|
if (!Directory.Exists(newParentDirectory))
|
Directory.CreateDirectory(newParentDirectory);
|
|
// 重命名文件
|
File.Move(file, newFileName);
|
Debug.WriteLine($"文件已重命名: {file} -> {newFileName}");
|
}
|
else
|
{
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤\"{1}\"为\"{2}\"失败,原因是{3}", this.Text, oriName, newName, "命名重复"), LogInfoType.ERROR);
|
return;
|
}
|
|
}
|
catch (Exception ex)
|
{
|
Debug.WriteLine($"重命名文件 {file} 时出错: {ex.Message}");
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤\"{1}\"为\"{2}\"失败,原因是{3}", this.Text, oriName, newName, ex.Message), LogInfoType.ERROR);
|
return;
|
}
|
}
|
}
|
|
ProcessRunBll.Rename(oriName, newName);
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤\"{1}\"为\"{2}\"成功", this.Text, oriName, newName), LogInfoType.PASS);
|
|
//if (dicSteps[newName] is VisionProTool && Tool.ContainsChinese(newName))
|
// MessageBox.Show($"VisionPro工具不支持命名为中文:{newName}", "异常");
|
}
|
}
|
|
private void EditProcess(string ProcessName)
|
{
|
try
|
{
|
ConcurrentDictionary<string, IProcess> dicSteps = ProcessRunBll.GetSteps();
|
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
string ClassName = dicSteps[ProcessName].GetType().ToString();
|
string ProcessPath = GlobalVar.allProcessPath + ProcessRunBll.Name + "\\" + ProcessName + ".json";
|
|
if (string.IsNullOrEmpty(ProcessName) || string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(ProcessPath))
|
return;
|
|
//利用反射创建实例
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName);
|
if (type == null)
|
{
|
LogInfo?.Invoke(string.Format("流程[{0}]步骤\"{1}\"打开失败了,类[{2}]不存在", this.Text, ProcessName, ClassName), LogInfoType.ERROR);
|
return;
|
}
|
|
((IProcess)dicSteps[ProcessName]).Save(Path.GetDirectoryName(ProcessPath));
|
IProcess process = ((IProcess)dicSteps[ProcessName]).Clone() as IProcess;
|
|
Object InputImage = new Object();
|
if (process.InputImage != null)
|
{
|
if (process.InputImage is HObject ho_image && ho_image.IsInitialized())
|
InputImage = ho_image.CopyObj(1, -1);
|
else if (process.InputImage is Mat mat && !mat.Empty())
|
InputImage = mat.Clone();
|
else if (process.InputImage is Bitmap bitmap)
|
InputImage = bitmap.Clone();
|
}
|
|
if (ClassName.Contains("CameraConfig") && process is CameraConfig)
|
{
|
LB_VisionProcesses.Cameras.CameraForm cameraForm
|
= new LB_VisionProcesses.Cameras.CameraForm(GlobalVar.dicCameras.Items, (CameraConfig)process, ProcessPath);
|
cameraForm.ShowDialog();
|
|
if (!(process.Load(ProcessPath)))
|
LogInfo?.Invoke(string.Format("流程[{0}]步骤\"{1}\"加载失败了", this.Text, ProcessName), LogInfoType.ERROR);
|
process.strProcessName = ProcessName;
|
}
|
else if (ClassName.Contains("Communicators") && process is CommunicatorConfig)
|
{
|
LB_VisionProcesses.Communicators.CommunicatorForm communicatorForm
|
= new LB_VisionProcesses.Communicators.CommunicatorForm(GlobalVar.dicCommunicators.Items, (CommunicatorConfig)process, ProcessPath);
|
communicatorForm.ShowDialog();
|
|
if (!(process.Load(ProcessPath)))
|
LogInfo?.Invoke(string.Format("流程[{0}]步骤\"{1}\"加载失败了", this.Text, ProcessName), LogInfoType.ERROR);
|
process.strProcessName = ProcessName;
|
}
|
else
|
{
|
ProcessEditForm processEditForm = new ProcessEditForm(process, ProcessPath);
|
processEditForm.ShowDialog();
|
|
//重新加载更新后的步骤
|
if (processEditForm.hasChanged)
|
LogInfo?.Invoke(string.Format("流程[{0}]步骤\"{1}\"更新了", this.Text, ProcessName), LogInfoType.WARN);
|
|
if (!(process.Load(ProcessPath)))
|
LogInfo?.Invoke(string.Format("流程[{0}]步骤\"{1}\"加载失败了", this.Text, ProcessName), LogInfoType.ERROR);
|
process.strProcessName = ProcessName;
|
}
|
|
if (InputImage != null)
|
{
|
if (InputImage is HObject ho_image && ho_image.IsInitialized())
|
process.InputImage = ho_image.CopyObj(1, -1);
|
else if (InputImage is Mat mat && !mat.Empty())
|
process.InputImage = mat.Clone();
|
else if (InputImage is Bitmap bitmap)
|
process.InputImage = bitmap.Clone();
|
}
|
dicSteps[ProcessName] = process;
|
|
ProcessRunBll.UpdataInputsAndOutputs(ProcessName, process);
|
}
|
catch (Exception ex) { Debug.WriteLine(ex.Message); }
|
}
|
|
private void AddBranch(string ProcessName)
|
{
|
var dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
// 多分支的本质为脚本工具,根据branchIndex来走对应的分支
|
if (dicSteps[ProcessName] is ScriptTool ScriptTool)
|
{
|
ScriptTool.Params.Outputs.Add($"Branch{ScriptTool.Params.Outputs.Count}", false);
|
Debug.WriteLine($"脚本工具[{ProcessName}]增加了Branch{ScriptTool.Params.Outputs.Count - 1}");
|
}
|
}
|
|
private void DeleteBranch(string ProcessName)
|
{
|
var dicSteps = ProcessRunBll.GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return;
|
|
// 多分支的本质为脚本工具,根据branchIndex来走对应的分支
|
if (dicSteps[ProcessName] is ScriptTool ScriptTool
|
&& ScriptTool.Params.Outputs.Remove($"Branch{ScriptTool.Params.Outputs.Count}"))
|
{
|
Debug.WriteLine($"脚本工具[{ProcessName}]移除了Branch{ScriptTool.Params.Outputs.Count + 1}");
|
}
|
}
|
}
|
}
|