| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Linq;
- using System.Threading;
- using PropertyGridLib.Attributes;
- using TeamAAS.FlowEditor.Execution;
- using TeamAAS.FlowEditor.Models;
- using TeamAAS.FlowEditor.Plugins;
- using Plugins.Vm.Models;
- namespace Plugins.Vm
- {
- // ─────────────────────────────────────────────────────────────────────
- // VM 模块算子(算子级节点,操作习惯对齐 Halcon/Vp 算子):
- // - 属性面板开放简单配置:方案路径 / 流程名 / 结果键声明 / 失败策略;
- // - "高级编辑"按钮调起 VisionMaster 客户端打开该方案 —— 模块增删、参数调整、
- // 调试全部在 VM 原生界面完成(与 VP 每个工具单独编辑的体验对齐);
- // - 运行时加载方案 → 运行指定流程 → 按声明的结果键读取模块结果(图像键走
- // GetOutputImageV2,其余键走 GetOutputValue/GetResultValue,均经 VmRuntime 容错)。
- // ─────────────────────────────────────────────────────────────────────
- [Serializable]
- [Plugin("VM模块", PluginCategory.Vm模块, typeof(VmModuleModel), "Hexagon",
- NodeShape = NodeCategory.Normal, IsSubFlowNode = true, VisionCategory = VisionPlugin.其他,
- Description = "VisionMaster 模块算子:绑定方案与流程,属性面板声明结果键;高级编辑调起 VM 客户端改方案")]
- public class VmModulePlugin : BasePlugin<VmModuleModel>
- {
- public override List<OutputField> DeclareOutputs()
- {
- var list = new List<OutputField>
- {
- new OutputField("结果", typeof(bool)),
- };
- var keys = Model?.ResultKeys ?? new List<string>();
- foreach (var key in keys)
- {
- if (string.IsNullOrWhiteSpace(key)) continue;
- list.Add(new OutputField(key, typeof(object)));
- }
- return list;
- }
- public override NodeRunStatus PluginRun(CancellationToken token, out Dictionary<string, object> results)
- {
- var res = new Dictionary<string, object>();
- results = res;
- NodeRunStatus Fail(string m) { res["Error"] = m; res["结果"] = false; Log(1, $"VM模块失败: {m}", TeamAAS.LogLevel.Error); return NodeRunStatus.Failed; }
- try
- {
- if (string.IsNullOrWhiteSpace(Model.SolutionPath))
- return Fail("未配置 VM 方案路径");
- if (string.IsNullOrWhiteSpace(Model.ProcedureName))
- return Fail("未配置流程名");
- Log(3, $"VM模块:加载方案 {Model.SolutionPath},流程 [{Model.ProcedureName}]");
- var solution = VmRuntime.LoadSolution(Model.SolutionPath);
- var procedure = VmRuntime.GetProcedure(solution, Model.ProcedureName);
- if (procedure == null) return Fail($"方案中不存在流程 [{Model.ProcedureName}]");
- if (!VmRuntime.Run(procedure))
- return Fail("VM 流程运行失败");
- // 按声明的结果键读取模块结果(图像/数值通用,经 VmRuntime 容错)
- int got = 0;
- foreach (var key in Model.ResultKeys ?? new List<string>())
- {
- if (string.IsNullOrWhiteSpace(key)) continue;
- var value = VmRuntime.GetModuleOutput(procedure, key);
- res[key] = value;
- if (value != null) got++;
- Log(4, $"结果键[{key}] = {(value?.GetType().Name ?? "null")}");
- }
- res["结果"] = true;
- Log(2, $"VM模块完成:取到 {got}/{(Model.ResultKeys?.Count ?? 0)} 个结果键");
- return NodeRunStatus.Success;
- }
- catch (Exception ex)
- {
- return Fail(ex.Message);
- }
- }
- }
- }
- namespace Plugins.Vm.Models
- {
- using TeamAAS.FlowEditor.Plugins;
- /// <summary>VM 模块算子模型。</summary>
- [Serializable]
- public class VmModuleModel : BasePluginModel
- {
- [Category("I.方案")]
- [DisplayName("1.VM方案路径")]
- [Description("海康 VisionMaster 方案(.sol)文件路径;运行前由适配层加载")]
- public string SolutionPath { get; set; } = "";
- [Category("I.方案")]
- [DisplayName("2.流程名")]
- [Description("方案内要执行的流程名称")]
- public string ProcedureName { get; set; } = "";
- [Category("II.结果")]
- [DisplayName("1.结果键列表")]
- [Description("要读取的模块结果终端名(每行一个,如 ImageData/Score);运行后每个键成为本节点输出")]
- public List<string> ResultKeys { get; set; } = new List<string>();
- [Category("III.选项")]
- [DisplayName("1.VM客户端路径")]
- [Description("VisionMaster 客户端可执行文件路径(高级编辑用);留空则用系统文件关联打开方案")]
- public string VmClientPath { get; set; } = "";
- // ── 高级编辑:调起 VisionMaster 客户端打开方案 ──
- [Category("IV.高级编辑")]
- [DisplayName("1.打开 VM 编辑")]
- [Description("调起 VisionMaster 客户端打开该方案(模块增删/参数调整/调试在 VM 原生界面完成)")]
- [Button("高级编辑", nameof(OpenAdvancedEditor))]
- public object AdvancedEditButton { get; set; }
- public void OpenAdvancedEditor()
- {
- // 经安全封装调起 VisionMaster:扩展名白名单(仅 .sol)+ 参数列表启动,防命令注入
- VmSolutionLauncher.OpenSolution(SolutionPath, VmClientPath);
- }
- }
- }
|