using System; using System.Collections.Generic; using TeamAAS.Vision; using TeamAAS.FlowEditor.Plugins; using Plugins.Halcon.Views; namespace Plugins.Halcon { /// /// 编辑器内嵌预览的挂接点 + 视觉图层发布桥。 /// /// 两条显示通路(互不干扰): /// 1) 图层通路(新): /// 把节点运行结果按「节点 → 图层集」发布到 , /// HalconFlowEditorView 的大显示窗按选中节点/图层筛选渲染 —— 类 VisionMaster 的图层体验; /// 2) 经典通路(兼容保留): 静态窗体直接推图(主页引擎画面、旧调用方不受影响)。 /// /// 内存策略:每轮运行开始()换新 RunStamp;同名节点再次发布=整体替换, /// 跨批次发布时由 VisionLayerStore 释放上一批次自有对象(GenImage 副本等),图层永不无限叠加。 /// public static class HalconEditorPreview { static HalconEditorPreview() { // 图层库释放自有对象时走 HALCON 安全释放(吞异常) VisionLayerStore.Disposer = obj => { var h = obj as HalconDotNet.HObject; if (h != null) { HalconRuntime.Dispose(h); return; } var d = obj as IDisposable; if (d != null) { try { d.Dispose(); } catch { } } }; } /// 当前 HALCON 流程编辑器内嵌的预览窗体(无编辑器打开时为 null)——经典通路。 public static HalconWindow Current { get; set; } private static string _runStamp = "0"; /// 当前运行批次号(每轮容器运行开始时更新)。 public static string RunStamp => _runStamp; private static long _runSeq = 0; /// /// 一轮运行开始:更新 RunStamp 并清掉上一轮遗留图层(防跨轮叠加)。 /// 由 HalconFlowPlugin.PluginRun 在执行子流程前调用。 /// public static void BeginRunCycle() { _runSeq++; _runStamp = _runSeq.ToString(); VisionLayerStore.Instance.ClearAll(); } /// /// 【图层通路】节点运行结果发布:写 VisionLayerStore(驱动编辑器大显示窗/图层筛选), /// 同时保持经典通路(Current 窗体直接推图)行为不变。 /// 后台线程调用安全(内部切 UI 线程);无消费方时零开销。 /// /// 节点模型(取 FlowId/NodeName/NodeName 定位图层归属) /// 底图(HObject/GenImage),null=只叠加 /// 叠加对象(区域/XLD),null=无 /// 叠加颜色(如 "green"),null 用默认 public static void Show(BasePluginModel model, object image, object overlay = null, string color = null) { string flowId = model?.FlowId; string nodeName = model?.NodeName; bool hasContext = !string.IsNullOrEmpty(flowId) && !string.IsNullOrEmpty(nodeName); // 1) 图层发布(有节点上下文才发布) if (hasContext) { var args = new LayerPublishArgs { FlowId = flowId, NodeName = nodeName, RunStamp = _runStamp, }; if (image != null) args.Layers.Add(new LayerItem("图像", LayerKind.Image, image, owned: !(image is HalconDotNet.HObject))); if (overlay != null) args.Layers.Add(new LayerItem("区域", LayerKind.Region, overlay, owned: !(overlay is HalconDotNet.HObject), color: color ?? "red")); if (args.Layers.Count > 0) VisionLayerStore.Instance.Publish(args); } // 2) 经典通路:编辑器内嵌窗体直接推图(行为不变) Show(image, overlay); } /// /// 【经典通路】把结果推到编辑器内嵌预览窗体(若已打开)。 /// image 可为 null(只更新叠加区域、保留底图,供只产出区域的节点用)。 /// 在后台线程调用也安全(内部切 UI 线程);无预览窗体时静默跳过(生产运行零开销)。 /// public static void Show(object image, object overlay = null) { var w = Current; if (w == null) return; try { System.Windows.Application.Current?.Dispatcher.Invoke(() => w.RefreshImage(image, overlay)); } catch { } } } }