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