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 { }
}
}
}