using System;
using System.Collections.Generic;
using System.Linq;
namespace TeamAAS.Vision
{
/// 图层筛选下拉条目:NodeName=null 表示「最新运行」;LayerName=null 表示该节点全部图层。
public sealed class LayerComboEntry
{
/// 节点名;null=「最新运行」条目。
public string NodeName { get; set; }
/// 图层名;null=节点级条目(底图+全部叠加)。
public string LayerName { get; set; }
/// 下拉显示文本。
public string Display { get; set; }
public override string ToString() => Display;
}
///
/// 图层筛选条目构建与显示解析(Halcon/Vpp/Vm 三平台编辑器共用)。
/// 显示语义:
/// - 「最新运行」= 最后一次发布的完整图层集(底图+全部叠加);
/// - 节点级条目 = 该节点底图 + 全部叠加;
/// - 图层级条目 = 图像层单独显示;区域/轮廓等叠加层 **自动附带该节点底图**(原图信息),
/// 用户看到的不是一块孤立的区域,而是"原图上的高亮区域",直观可理解。
///
public static class LayerComboHelper
{
/// 按图层发布记录构建下拉条目:[最新运行] + 每节点(全部图层)+ 每图层。
/// source 为空时按 flowId 从图层库取;显式传入可做跨流程兜底展示。
public static List BuildEntries(string flowId, List source = null)
{
var entries = new List
{
new LayerComboEntry { Display = "最新运行" }
};
foreach (var args in source ?? VisionLayerStore.Instance.GetFlowLayers(flowId ?? ""))
{
if (string.IsNullOrEmpty(args?.NodeName)) continue;
entries.Add(new LayerComboEntry { NodeName = args.NodeName, Display = args.NodeName });
foreach (var layer in args.Layers)
{
if (layer == null || string.IsNullOrEmpty(layer.Name)) continue;
entries.Add(new LayerComboEntry
{
NodeName = args.NodeName,
LayerName = layer.Name,
Display = " └ " + layer.Name,
});
}
}
return entries;
}
///
/// 解析要显示的图层集:layerName 为空=全部;图像层=仅该图;
/// 非图像层=该节点底图(首个图像层)+ 该层叠加;节点没发过底图时回退到
/// 全流程最近发布的图像层(区域类节点"附带原图"显示,不再黑底孤立区域)。
///
/// 流程 Id(用于底图回退;传 null 关闭回退)。
public static List ResolveLayers(LayerPublishArgs args, string layerName, string flowId = null)
{
var result = new List();
if (args?.Layers == null || args.Layers.Count == 0) return result;
if (string.IsNullOrEmpty(layerName))
{
var all = args.Layers.Where(l => l != null).ToList();
if (!all.Any(l => l.Kind == LayerKind.Image && l.Content != null) && flowId != null)
{
var fallback = FindLatestImageLayer(flowId, args.NodeName);
if (fallback != null) all.Insert(0, fallback);
}
return all;
}
var layer = args.Layers.FirstOrDefault(l =>
l != null && string.Equals(l.Name, layerName, StringComparison.OrdinalIgnoreCase));
if (layer == null) return result;
if (layer.Kind == LayerKind.Image)
{
result.Add(layer);
return result;
}
var baseImage = args.Layers.FirstOrDefault(l =>
l != null && l.Kind == LayerKind.Image && l.Content != null);
if (baseImage == null && flowId != null)
baseImage = FindLatestImageLayer(flowId, args.NodeName);
if (baseImage != null) result.Add(baseImage);
result.Add(layer);
return result;
}
/// 在全流程的发布记录里找最近一次的图像层(从后往前;排除指定节点)。
public static LayerItem FindLatestImageLayer(string flowId, string excludeNode = null)
{
var all = VisionLayerStore.Instance.GetFlowLayers(flowId ?? "");
for (int i = all.Count - 1; i >= 0; i--)
{
if (string.Equals(all[i]?.NodeName, excludeNode, StringComparison.OrdinalIgnoreCase)) continue;
var img = all[i]?.Layers?.FirstOrDefault(l => l != null && l.Kind == LayerKind.Image && l.Content != null);
if (img != null) return img;
}
return null;
}
}
}