| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.Collections.Generic;
- using VM.Core;
- namespace Plugins.Vm
- {
- /// <summary>
- /// 海康 VisionMaster SDK 适配层(唯一允许出现 VM SDK 调用的地方)。
- /// 插件/模型/视图只依赖本类的 SDK 无关签名(object / Dictionary),更换/升级 VM 版本时只改这里。
- ///
- /// 已接入 VM 4.4 的基础能力:加载方案、按名取流程、运行流程、关闭方案。
- /// 仍为 TODO 的部分:VM 的输入/输出是“模块级”(各模块 ModuResult / 模块参数),
- /// 不像 Cognex ToolBlock 有统一的输入/输出终端,需按方案里实际用到的模块逐个对接。
- /// </summary>
- public static class VmRuntime
- {
- /// <summary>VM SDK 是否可用(已引用 VM.Core)。</summary>
- public static bool IsSdkAvailable => true;
- /// <summary>当前已加载方案的路径。VmSolution 是进程级单例,用它做“同方案不重载”的守护。</summary>
- private static string _loadedSolutionPath;
- /// <summary>
- /// 加载 VM 方案(.sol)。返回 <see cref="VmSolution"/> 单例(用 object 承载,避免上层依赖 SDK 类型)。
- /// 加载后关闭各模块结果回调以提升运行效率(与 VM 官方示例一致)。
- /// </summary>
- public static object LoadSolution(string solutionPath)
- {
- if (string.IsNullOrWhiteSpace(solutionPath))
- throw new ArgumentException("VM 方案路径为空", nameof(solutionPath));
- // 单例守护:同一 .sol 已加载则直接复用,避免多个 VM 节点/多次运行反复重载(VmSolution 为进程级单例)
- if (_loadedSolutionPath == solutionPath && VmSolution.Instance != null)
- return VmSolution.Instance;
- VmSolution.Load(solutionPath, "");
- _loadedSolutionPath = solutionPath;
- var inst = VmSolution.Instance;
- try { inst?.DisableModulesCallback(); } catch { /* 某些方案无回调可关,忽略 */ }
- return inst;
- }
- /// <summary>从已加载方案中按名取流程(<see cref="VmProcedure"/>);不存在返回 null。</summary>
- public static object GetProcedure(object solution, string procedureName)
- {
- if (string.IsNullOrWhiteSpace(procedureName)) return null;
- var inst = VmSolution.Instance;
- if (inst == null) return null;
- return inst[procedureName] as VmProcedure;
- }
- /// <summary>
- /// 设置流程输入。TODO:VM 输入为模块级——需按方案中具体模块(如图像源 ImageSource)
- /// 通过 <c>VmSolution.Instance["流程名.模块名"] as XxxModuleTool</c> 设参数/图像;
- /// 待明确各节点要喂的模块后补全(当前签名保留,先不抛异常以便流程能跑通)。
- /// </summary>
- public static void SetInputs(object procedure, Dictionary<string, object> inputs)
- {
- // TODO: 按模块写入 VM 输入
- }
- /// <summary>运行流程。返回是否成功执行(未抛异常即视为已运行)。</summary>
- public static bool Run(object procedure)
- {
- var p = procedure as VmProcedure;
- if (p == null) return false;
- p.Run();
- // TODO:VM 的“通过/不通过”按模块结果或 OK/NG 判定,非单一 RunStatus;接入后按方案约定返回。
- return true;
- }
- /// <summary>
- /// 收集流程输出。TODO:VM 输出为模块级结果(如 <c>pro.ModuResult.GetOutputImageV2("ImageData")</c>、
- /// 各模块 <c>ModuResult</c> 的字段)。需按方案里配置的“输出模块/结果名”逐个读取,接入后补全。
- /// </summary>
- public static Dictionary<string, object> GetOutputs(object procedure)
- {
- return new Dictionary<string, object>();
- }
- /// <summary>
- /// 收集运行图层/渲染源(配合 VmRenderControl.ModuleSource 显示)。TODO:接入后返回 VM 模块/图像数据集。
- /// </summary>
- public static List<object> GetLayers(object procedure)
- {
- return new List<object>();
- }
- /// <summary>关闭并释放当前方案。</summary>
- public static void Close()
- {
- try { VmSolution.Instance?.CloseSolution(); } catch { }
- _loadedSolutionPath = null;
- }
- // ─────────────────────────────────────────────────────────────────
- // 模块级结果读取(供"VM模块"算子节点使用;全部反射容错,缺能力时返回 null)
- // ─────────────────────────────────────────────────────────────────
- /// <summary>
- /// 读取流程运行后的模块结果:优先 GetOutputImageV2(图像类结果键),其次 GetOutputValue/GetResultValue。
- /// key 为模块结果终端名(如 "ImageData"、"Score")。不可用时返回 null。
- /// </summary>
- public static object GetModuleOutput(object procedure, string key)
- {
- if (procedure == null || string.IsNullOrWhiteSpace(key)) return null;
- try
- {
- var moduResult = procedure.GetType().GetProperty("ModuResult")?.GetValue(procedure)
- ?? procedure.GetType().GetField("ModuResult")?.GetValue(procedure);
- if (moduResult == null) return null;
- var type = moduResult.GetType();
- foreach (var method in new[] { "GetOutputImageV2", "GetOutputValue", "GetResultValue" })
- {
- var m = type.GetMethod(method, new[] { typeof(string) });
- if (m == null) continue;
- try
- {
- var v = m.Invoke(moduResult, new[] { key });
- if (v != null) return v;
- }
- catch { }
- }
- }
- catch { }
- return null;
- }
- }
- }
|