using System; using System.Threading.Tasks; using System.Windows; using HalconDotNet; using TeamAAS.FlowEditor.Models; using TeamAAS.FlowEditor.Plugins; using TeamAAS.FlowEngine; using TeamAAS.Vision; namespace Plugins.Halcon.Views { /// /// HALCON 算子专用高级编辑窗体(普通编辑=属性面板常用参数;高级编辑=本窗体): /// - 左侧参数面板:同一套模型属性(PropertyGridLib),改完即生效; /// - 右侧大显示窗:HalconWindow(缩放/平移/ROI 绘制/保存),运行结果经图层总线渲染; /// - 加载图像:从文件载入测试图并注册为流程「图像」输入变量(算子绑定 &{输入.图像} 时直接生效); /// - 执行:用当前流程注册表跑一遍该算子(与画布运行同一执行路径),状态栏回报结果与耗时。 /// 窗体非模态(可边看流程边调参)。 /// public partial class HalconToolAdvancedEditor : Window { private readonly BasePluginModel _model; private readonly HalconWindow _display; private IFlowNodePlugin _plugin; private bool _running; /// 打开算子高级编辑窗体(非模态)。 public static void Show(BasePluginModel model) { if (model == null) return; var win = new HalconToolAdvancedEditor(model); win.Show(); win.Activate(); } public HalconToolAdvancedEditor(BasePluginModel model) { InitializeComponent(); _model = model; TxtTitle.Text = $"{model.ToolName ?? "Halcon 算子"} · {model.NodeName}"; Title = $"高级编辑 - {model.ToolName ?? model.GetType().Name}"; // 普通参数面板(与属性面板同一套模型,双向实时同步) PropertyHost.Content = new PropertyGridLib.PropertyGrid { SelectedObject = model }; // 大显示窗 _display = new HalconWindow(1); _display.SetCaption(model.ToolName ?? "预览"); DisplayHost.Content = _display; // 图层总线:该算子发布图层 → 渲染(整组:底图+叠加,区域自动附带原图) VisionLayerStore.Instance.LayerPublished += OnLayerPublished; Closed += (s, e) => VisionLayerStore.Instance.LayerPublished -= OnLayerPublished; } /// 算子插件实例(懒创建;挂当前流程注册表,公式/输入变量按流程上下文解析)。 private IFlowNodePlugin Plugin { get { if (_plugin == null) { _plugin = PluginLoader.Instance.CreateInstance(_model.ToolName); if (_plugin != null) { _plugin.GetModel = _model; _plugin.Registry = PluginLoader.Instance.SelectFlow?.Registry; } } return _plugin; } } /// 该算子发布图层 → 整组渲染(含区域附带原图回退)。 private void OnLayerPublished(LayerPublishArgs args) { if (args == null || _model == null) return; if (!string.Equals(args.FlowId, _model.FlowId, StringComparison.OrdinalIgnoreCase)) return; if (!string.Equals(args.NodeName, _model.NodeName, StringComparison.OrdinalIgnoreCase)) return; try { Dispatcher.Invoke(() => { var layers = LayerComboHelper.ResolveLayers(args, null, args.FlowId); if (layers.Count > 0) _display.ShowLayers(layers); }); } catch { } } /// 执行:后台线程跑一遍该算子(不卡 UI),完成回报状态与耗时。 private void BtnRun_Click(object sender, RoutedEventArgs e) { if (_running) return; var plugin = Plugin; if (plugin == null) { TxtStatus.Text = "创建插件实例失败(检查插件是否加载)"; return; } _running = true; BtnRun.IsEnabled = false; TxtStatus.Text = "执行中…"; Task.Run(() => { try { var status = plugin.Run(System.Threading.CancellationToken.None); SetStatus($"执行完成: {status},耗时 {plugin.CostTime}ms"); } catch (Exception ex) { SetStatus("执行失败: " + ex.Message); } finally { try { Dispatcher.Invoke(() => { _running = false; BtnRun.IsEnabled = true; }); } catch { } } }); } /// 加载测试图像:注册为流程「图像」输入变量并立即预览。 private void BtnLoadImage_Click(object sender, RoutedEventArgs e) { var dlg = new Microsoft.Win32.OpenFileDialog { Filter = "图像文件|*.png;*.jpg;*.jpeg;*.bmp;*.tif;*.tiff|所有文件|*.*", Title = "加载测试图像" }; if (dlg.ShowDialog(this) != true) return; try { HOperatorSet.ReadImage(out HObject img, dlg.FileName); var registry = PluginLoader.Instance.SelectFlow?.Registry; if (!string.IsNullOrEmpty(_model.FlowId)) registry?.SetInputVariable(_model.FlowId, "图像", img); _display.RefreshImage(img); TxtStatus.Text = registry != null ? "已加载图像并注册为输入变量「图像」" : "已加载图像(未找到流程注册表,仅预览)"; } catch (Exception ex) { TxtStatus.Text = "加载失败: " + ex.Message; } } private void SetStatus(string message) { try { Dispatcher.Invoke(() => TxtStatus.Text = message); } catch { } } } }