# 夜间任务进度日志(NIGHT_LOG) > 会话中断后接续本任务时:先读本文件 + `Docs/ARCHITECTURE.md`,从「待续」小节继续。 > **最终状态:✅ 全解决方案编译通过(MSBuild CLI,BUILD_OK)。三平台子流程容器(Halcon/VPP/VM)+ 闪退修复全部落地;功能运行时验证待人工进行。** ## 第二晚追加轮(09-06 早晨) 1. **Halcon 流程编辑器闪退修复(根因:本机缺 HALCON 原生运行库)** - 现象:打开 Halcon流程 → `DllNotFoundException: 无法加载 DLL"halcon"`(HSmartWindowControlWPF.OnRender 首帧触发 HHandleBase 静态构造;首次异常被吞、二次渲染异常直接致命闪退)。桌面副本同样有 Runtime\dll\x64\halcon.dll 但 HALCON 原生运行时是 DLL 家族,孤立拷贝无效。 - 修复:HalconWindow.xaml 移除 XAML 声明式 `HSmartWindowControlWPF`,改为 code-behind **防御式创建**:先 `HOperatorSet.GetSystem("version")` 原生探测,可用才创建控件并挂事件/右键菜单;不可用显示"HALCON 原生运行库不可用"占位提示(画布/属性编辑不受影响,进程不闪退)。右键菜单 MyMenu 一并改为代码构建。 2. **VPP流程 / VM流程 容器节点(与 Halcon流程 完全同构)** - `Plugins.Vpp\VppFlowNodes.cs`:VppFlowPlugin + VppFlowModel/VppFlowInput/VppFlowOutput + **VppEditorPreview**(BeginRunCycle 换 RunStamp+ClearAll;Show 发布图层)。 - `Plugins.Vm\VmFlowNodes.cs`:VmFlowPlugin + VmFlowModel/VmFlowInput/VmFlowOutput(镜像;VM 图层发布留待 VmWindow.RefreshImage 平台对象对接)。 - 编辑器视图 `Plugins.Vpp\Views\VppFlowEditorView.*`(大显示窗=VppWindow(1)+RefreshImageDisplay(ICogImage))、`Plugins.Vm\Views\VmFlowEditorView.*`(大显示窗=VmWindow);左侧画布工具箱分别用 `FlowToolboxScope.VisionVpp/VisionVm`;均实现 IPluginViewSave/IPluginRunFeedback/IPluginViewTip + ParentGroupModel 注入(子节点公式树可见 &{输入.*})。 3. **工具箱平台隔离**:`FlowToolboxScope` 增加 `VisionVpp=2/VisionVm=3`;`FlowEditorViewModel.InitCommands` 子流程工具箱按 `IsSubFlowNode && Group=={Halocn模块|Vpp模块|Vm模块}` 过滤后按 VisionPlugin 分组——**各平台算子互不串台**;`OpenNodeEditor` 的 keepParent(保留容器输入变量)推广到全部平台子流程。 4. **算子迁移子流程**:VpBlob分析/Vp模板匹配/Vp卡尺测量/Vp找圆/Vp找直线 与 VM模块 全部 `IsSubFlowNode=true`(不再出现在主流程工具箱,只在各自平台子流程内;旧流程已放置的节点不受影响)。Vp 算子运行后经 `VppEditorPreview.Show(Model, cogImage)` 发布输入图像图层(GenImage→CogImage 只转一次,喂图/发布共用)。 5. **可诊断性**:`AssemblyScanner.CreateInstances` 实例化失败从静默改为 AppLogger.Warning("模块 xxx 实例化失败,已跳过")——直接暴露"引擎没起来/主页画面空白"这类静默降级的原因。 6. **编译方式升级**:Git Bash 仍损坏;改用 node_repl→cmd 批处理直接调 `C:\Program Files\Microsoft Visual Studio\18\Insiders\MSBuild\Current\Bin\MSBuild.exe TeamAAS.sln /p:Configuration=Debug /p:Platform=x64`(BUILD_OK),不再依赖 VS GUI。首轮 4 处 CS0246 FormulaBound(缺 `using PropertyGridLib.Controls;`)已修复。 7. **部署清理**:删除过期重复副本 `Runtime\Plugins\Plugins.Halcon.dll`(09-04 旧版,会因同名去重抢先加载、使闪退修复失效);保留 `HalconPlugins\` 内最新版。删除杂物 `EXE\win-x64\AwakenGPUToolLog.txt`、`EXE\win-x64\images_v2.db`(仓库根目录已干净;`ExE.zip`(167MB, 当日) 疑似用户打包桌面副本用,未动)。 ## 第二晚追加轮②(09-06 上午):视觉显示框位置调整 - **三个平台子流程编辑器(Halcon/VPP/VM)统一布局调整**:视觉显示框从"编辑器外挂的独立 420px 列"移入 FlowEditorView **右侧面板内**——整区替换「节点信息」(名称/类型/状态/耗时),「执行历史」「执行结果」保留在下方;画布因此占满剩余宽度。 - 实现:FlowEditorView.xaml 的「节点信息」Border 包进 `ContentControl x:Name=NodeInfoSlot` 插槽 + 新 API `ReplaceNodeInfoPanel(UIElement)`(null=恢复默认,仅影响本实例);三个编辑器 XAML 把视觉面板(视觉显示标题+图层 ComboBox+大显示窗+运行状态行)定义为折叠的 `VisionPanel`,**构造函数里** `EditorRoot.Children.Remove(VisionPanel)` 后注入(渲染前完成,无闪烁),面板 MinHeight=320、宽度随右侧面板列(320 起,画布分隔条可拖宽)。 - 编译 BUILD_OK(MSBuild CLI),产物符号已核实(ReplaceNodeInfoPanel/VisionPanel 进入 TeamAAS.FlowEngine.dll 与三平台插件 DLL)。 ## 故障记录(09-06):本机所有 WPF 程序打开空白 —— 已定位并修复 - **现象**:向日葵远程操作本机时,所有 C#/WPF 程序打开后窗口空白(非 WPF 程序正常)。 - **根因**:WPF 硬件加速(DirectX)在该环境渲染失败——本机为 Legion 双显卡(AMD 780M 空载 + RTX 4060 出图)+ 向日葵虚拟显示驱动 OrayIddDriver 的组合;与删除的工程文件无关(未动过任何系统环境)。 - **修复**:注册表 `HKCU\Software\Microsoft\Avalon.Graphics` 新建 DWORD `DisableHWAcceleration=1`(仅 WPF 改用软件渲染,即时生效、无需重启)。已启动 TeamAAS 截屏验证渲染正常。 - **还原方式**:`reg delete "HKCU\Software\Microsoft\Avalon.Graphics" /v DisableHWAcceleration /f` - **彻底解决(可选)**:升级 NVIDIA 显卡驱动(当前 566.26/2024-11)与向日葵客户端;本地(非远程)使用时理论上可还原此开关对比验证。 ## 追加轮③(09-06 上午):图层筛选实时切换 + 图层级选项设计 - **修复"切换不实时"根因**:每次图层发布都会重建下拉项,旧实现用**索引**恢复选中——ItemsSource 一换 SelectedIndex 变 -1,选中被静默重置回「最新运行」,点选的节点显示立刻被冲掉。现改为按 **(节点名, 图层名) 值** 保留选中(三平台编辑器统一)。 - **图层级选项设计(SDK 新增 LayerComboHelper/LayerComboEntry,三平台共用)**:下拉三级结构——「最新运行」(最后一次发布整体)/「节点名」(该节点底图+全部叠加)/「 └ 图层名」(图层级)。**图层级显示语义**:图像层单独显示;区域/轮廓等叠加层**自动附带该节点的原图底图**(ResolveLayers:底图=该节点首个图像层)——用户看到的是"原图上的高亮区域",直观可理解。状态行显示 `节点 · 图层 · #批次`。 - 图层发布名改短:`节点名.图像/.区域` → `图像`/`区域`(节点归属由条目结构表达,不再冗余前缀)。 - 画布点选 → 定位该节点条目(无图层回落「最新运行」)→ 同步下拉+实时刷新;正在看某节点时该节点重新发布会原地刷新。 ## 追加轮④(09-06 上午):四项反馈修复 1. **VPP 窗体白屏根因定位与修复**:最小对照程序实测——WinForms 原生控件正常、WPF 正常、**仅 Cognex 显示控件白屏**;`CogRecordDisplay.RenderEngine` 默认硬件加速渲染在本机(向日葵远程+显卡环境)不 painting,切 **GDI 渲染引擎**(`CogRenderEngineConstants.CogGDIRenderEngine=1`)立即恢复。注意该属性**只能在句柄创建后读写**(否则抛 InvalidOperationException)。落地 `Plugins.Vpp\Views\CogGdiRender.cs`(递归扫描容器内所有 Cog 显示控件、HandleCreated 时机切换):VppWindow(主页+VPP流程编辑器显示)直接 Apply;ToolBlockEdit(工具块编辑器,内部面板动态创建)用 600ms×40 次定时器重扫兜底。 2. **Halcon 筛选不生效根因修复**:编辑器曾把预览窗挂到 `HalconEditorPreview.Current` 经典通路,每个算子跑完直接推图**覆盖**图层筛选结果 → 已移除该挂接(图层总线为唯一显示驱动);区域类算子(形状筛选/连通域/形态学)发布时无底图 → `LayerComboHelper` 增加底图回退:节点没发过图像层时取**全流程最近发布的图像层**垫底("区域附带原图",不再黑底孤立区域)。 3. **Halcon 高级编辑体系(普通编辑/高级编辑两级)**:新增 `HalconOperatorModelBase`([Button 高级编辑])+ `HalconToolAdvancedEditor` 专用窗体(左 PropertyGrid 参数 + 右 HalconWindow 大显示窗 + 加载测试图像注册「图像」输入变量 + 后台单步执行,执行挂当前流程注册表);8 个现有算子模型全部翻转到新基类;新增算子 **H边缘提取**(Sobel+阈值,检测识别分类)。后续新算子继承基类即自动获得高级编辑入口。 4. **VM工具块拓展**:输出图层发布到 VisionLayerStore(VM流程编辑器视觉显示/筛选可直接查看);方案路径/流程名变化**自动重载**句柄(调试期改方案无需重启);「打开 VM 工具编辑」按钮未注入 Launcher 时兜底用系统关联调起 VisionMaster 打开方案。 ## 追加轮⑤(09-06 上午):VP 算子报错"未找到工具类型 CogBlobTool" - **根因(两层)**:① `Runtime\Vpp9.0\` 运行时目录当初只拷了 ToolBlock 需要的 DLL,**缺经典工具程序集**(Cognex.VisionPro.Blob/PMAlign/Caliper 及其 .Controls —— 它们在 VisionPro 安装的 ReferencedAssemblies 里,bin 目录没有);② VisionPro 程序集是**懒加载**的,应用没显式用到之前不在 AppDomain,反射按名扫描永远找不到。 - **修复**:① 从 `C:\Program Files\Cognex\VisionPro\ReferencedAssemblies` 补齐 6 个 DLL 到 Vpp9.0(Blob/PMAlign/Caliper ×2 含编辑控件);② `VpToolSupport` 增加 `EnsureCognexAssembliesLoaded`(Assembly.Load 触发 AssemblyResolve → Runtime 递归解析),FindToolType/FindControlType 找不到时先预载再重扫。OpenNativeEditor 同时修复了:编辑控件与工具跨程序集查找、[NonSerialized] 委托反序列化后为 null 的兜底、内部显示控件 GDI 渲染修复。 - **提示**:后续部署到其它机器时,Vpp9.0 目录必须包含 Blob/PMAlign/Caliper 工具程序集(或整目录从 ReferencedAssemblies 补齐),否则 Vp 算子创建工具时会报同类错误。 ## 追加轮⑥(09-06 晚):VP 算子联调三连修(日志实证) 1. **工具加载已通**:18:23 起 VpBlob 正常执行("Blob 完成:数量=0")——预载+补 DLL 生效。 2. **高级编辑仍"进不去"**:日志连发「未找到 CogBlobTool 的原生编辑控件」。两处遗漏:① 编辑控件程序集(Blob.Controls/PMAlign.Controls/Caliper.Controls)不在预载清单;② **VisionPro 编辑控件命名去掉了 "Tool"**(实际是 CogBlobEditV2 而非 CogBlobToolEditV2)——FindControlType 增加去 "Tool" 候选名。 3. **偶发"System.Object 无法转换为 ICogImage"**:SetInputImage 重写——支持 ICogRecord 自动递归抽取其中的 ICogImage(绑定"输出图层N"类记录时可用);类型不符时抛出**带实际类型名**的明确异常,替代反射笼统报错。 (验证提示:数量=0 属工具参数/图像内容问题,打开高级编辑调 Blob 参数即可。) ## 追加轮⑦(09-06 晚):图像转换悬空指针根因 + VP 运行记录图层(VisionPro 下拉体验) 1. **黑图/数量恒 0 的真根因**:`GenImageConverter.Grey8ToCogImage` 用 `CogImage8Root.Initialize` 包裹 GenImage.Data 托管数组后**立即解除固定**——GC 挪动/回收数组后 CogImage 读到悬空指针 → 显示黑图(有暗噪点)、Blob 数量恒 0。修复:改走 `ToBitmap() → new CogImage8Grey(bmp)` 拷贝路径(SetRootCopier/Freeze 在该版 VisionPro 中不存在,编译器证实)。 2. **VP 运行记录图层(对齐 VisionPro 原生下拉)**:Vp 算子运行后 `CogToolBase.CreateLastRunRecord()` 把整棵记录树发布为图层(`VppEditorPreview.ShowRecord`:RecordKey 命名、ContentType 判定图像层、根记录=默认合成视图、深度限 3 层防环);编辑器图层级选中直接 `VppWindow.RefreshRecordDisplay(record)` 用 **Cognex 原生渲染**(图像+图形叠加原样呈现,如 BlobImageUnfiltered 的绿色轮廓)。ICogRecord 成员名是 RecordKey/Content/ContentType/SubRecords(无 Name)。 3. `VppWindow.RefreshRecordDisplay` 去除每帧 GC.Collect(连续运行卡顿)。 ## 追加轮⑧(09-06 晚):输出图层落到节点输出 + 全记录数据可传递 - 「输出图层」之前只影响显示、不在结果里 → 下游无法绑定。现改为:**学习到的全部记录图层都声明为节点输出**(VpToolPluginBase.DeclareOutputs 按 LastRecordKeys 逐项 OutputField;首次运行学习、随流程持久化),PluginRun 把每层记录对象写入 results(如 InputImage/BlobImage/Histogram...)——下游公式直接绑定。 - 属性「输出图层」选定项额外以固定名**「输出图像」**暴露(绑定稳定,不随改名漂移);留空=根记录合成视图。 - VppEditorPreview.ShowRecord 返回改为 `Dictionary<图层名, 记录对象>`(树序)。 - 转换器「输出图层」下拉此前取不到模型:加 SelectFlow 节点兜底(PropertyGridLib 的 context.Instance 可能传包装项)。 ## 追加轮⑨(09-06 晚):删显示图层属性 + 结果筛选(多选) - **删除「输出图层(显示)」属性**(OutputLayerKey + 其 TypeConverter)——显示默认=根记录合成视图,图层传递全靠「输出图层列表」多选。 - **新增「2.结果筛选」多选**([MultiSelect] + VpResultKeyMultiProvider,可选项=运行学习到的 LastResultKeys):Vp 工具的类型化结果(数量/分数/位置/角度...)勾哪些才往下游传;**留空=全部输出**。学习时机:每次运行后把非 图层/结果/输出图像 的键存入 LastResultKeys(随流程持久化);配置了筛选时 PluginRun 会剪裁 res,DeclareOutputs 按勾选声明(未配置=按 DeclareResultFields 全声明)。 ## 追加轮⑩(09-06 晚):输出终端(迁移 VisionPro「添加终端」) - 输出区最终形态:1.输出图层列表(多选) / 2.结果筛选(多选) / **3.输出终端(多选)**。 - **输出终端**:勾选工具属性/结果树里的**任意项**(`Results.Count`、`Results.GetBlobs[0].CenterOfMassX`、`SearchRegion`...)作为输出终端,输出名=路径末段(重名自动 _2/_3)。可选项运行后由 `VpToolSupport.LearnTerminalPaths` 自动学习(递归公共属性、深度≤3、集合展开首元素标 [0]、封顶 80 条、跳过 Name/RunStatus/System 命名空间),随流程持久化;取值走既有 `GetPath` 反射路径解析(支持索引与 0 参方法)。OutputField 名字属性为 Key(非 Name)。 ## 追加轮⑪(09-06 晚):输出终端改为按钮 + 属性树弹窗(VisionPro 体验) - 「输出终端」由 MultiSelect 改为 **[Button「编辑输出终端」] → `VpTerminalEditorWindow` 专用弹窗**:工具对象树(属性/结果,带实时值,如 `CenterOfMassX = 123.4`;集合展开首元素标 [0];复杂对象可勾选整对象且可继续展开;深度≤4/节点≤400),勾选任意节点 → 确定 → 写回 `OutputTerminals`(作为输出终端,输出名=路径末段)。弹窗实时读工具对象(EnsureTool 兜底创建),勾选状态按已存路径回显。 - 模型上 OutputTerminals 转 [Browsable(false)](弹窗托管),属性面板保留:1.输出图层列表(多选)/ 2.结果筛选(多选)/ 3.编辑输出终端(按钮)。 ## 追加轮⑫(09-06 晚):删结果筛选 + 预设输出终端(下沉基类) - **删除「结果筛选」**(ResultFilter/LastResultKeys/VpResultKeyMultiProvider)——有终端编辑器后冗余。 - **预设输出终端下沉基类**:`VpToolPluginBase.PresetTerminals`(virtual,返回 VpPresetTerminal[名称,路径])——DeclareOutputs 自动声明 + PluginRun 自动赋值(GetPath 容错取 null)。全部 Vp 算子共用此封装。 - **各工具预设**(基于 Cognex 官方文档核对):VpBlob=前 3 个 Blob 的 面积1..3/重心X2 Y2/X3 Y3(注意 Area 等测量需在原生编辑器 Measurements 页启用);VpPMAlign=第 2/3 目标的 分数/位置X/Y/角度(第 1 目标已由类型化结果覆盖);VpCaliper=分数。FindCircle/FindLine 暂无额外预设。来源:docs.cognex.com(CogPMAlignResult.GetPose/Score、CogBlobResult/Blob Measurements Tab)。 ## 追加轮⑬(09-06 晚):结果筛选回归(候选=类型化结果+预设终端,无需运行) - 「结果筛选」多选恢复,但候选升级为 **类型化结果 + 预设终端**(随所选工具变化,**无需先运行**——来自输出声明而非运行学习)。 - 机制:`VpToolPluginBase` 实现 `IVpResultSource`(GetResultKeys=DeclareResultFields 名单 + PresetTerminals);`VpResultKeyMultiProvider` 候选=两者合集;**留空=全部输出**,勾选后 DeclareOutputs 按勾选声明、PluginRun 剪裁 res(图层/输出图像/输出终端不受筛选影响)。预设终端输出名可能与类型化结果重名(如 分数),重名项以筛选勾选为准。 ## 追加轮⑭(09-07):预设=预勾选终端(统一到终端树,删结果筛选) - **概念统一**:预设结果本来就是终端树里的节点 → 预设=**首次自动预勾选的终端**。「结果筛选」属性彻底删除(勾选管理只在终端弹窗树里)。 - 行为:OutputTerminals 为空时(首次使用)**自动种入该工具的预设终端路径**(PluginRun 与弹窗打开两处兜底);树中预设项呈勾选态,用户可取消/增选;一旦有勾选记录就不再覆盖。输出 = 已勾选终端(输出名=路径末段)+ 类型化结果 + 图层 + 输出图像。 - 结构:`IVpPresetSource.GetPresetPaths()`(模型实现,经 PluginLoader 按工具名反射取插件 PresetTerminals);VpToolPluginBase.PresetTerminals 改 public(接口对齐)。 ## 追加轮⑮(09-07):终端树完整性增强 + 预设路径实测验证 - **"预设结果在终端树里找不到"的根因**:① Blob 的 Area/Compactness 等测量项必须在原生编辑器 Measurements 页启用,结果对象上才有这些属性(未启用=属性不存在或 null);② 旧树扫描只扫属性不扫字段、深度 3、null 直接跳过。 - **树扫描增强**:属性+公共字段、深度 3→5、总量封顶 300、集合展开前 3 个元素(原 1 个)、标量 null 登记为有效路径。 - **预设路径实测验证**:新增 `GetPathStrict`(区分"路径不存在"与"值为 null/空集合");首次预勾选时逐条验证,**只保留工具结果对象上真实存在的路径**——Blob 未启用测量时 Area 类预设不会出现在勾选里(启用后下次运行自动可勾)。 - **弹窗树标量 null 可勾选**:路径有效、此刻无值的项(如未启用测量)显示 `= null` 且可勾选(输出 null),不再直接隐藏。 ## 追加轮⑯(09-07):Blob 测量终端(GetMeasure 机制,官方 40 项全量) - **反射实证**:`CogBlobResult` 上**没有 Area/CenterMassX 属性**——官方机制是 `GetMeasure(CogBlobMeasureConstants)`(40 项枚举:Label/Area/Perimeter/CenterMassX/Y/Inertia*/Elongation/Angle/Acircularity*/BoundingBox*×3族/NotClipped),未启用的测量抛 `CogBlobMeasureNotComputedException`。反射扫属性永远扫不到 → 这就是"树里找不到 Area"的真正原因。 - **终端树注入**:弹窗树对带 `GetMeasure(枚举)` 方法的对象自动注入「测量项 (GetMeasure)」分支——40 项全量列出(未启用的标"(未启用)"但仍可勾选,勾选输出 null),路径格式 `Results.GetBlobs[0]@Measure:Area`。 - **取值**:`VpToolSupport.GetMeasureValue`(TryParseMeasurePath 解析 @Measure: 标记 → GetPath 定位对象 → GetMeasure(枚举));PluginRun 输出环节对测量路径走专用取值。MeasureMarker 常量在 public `VpPresetTerminal` 上(分类工程可访问)。 - **Blob 预设改测量路径**:面积1..2/重心X1 Y1/X2 Y2(GetBlobs[0..1])/周长1/圆度偏差1——注意测量需在原生编辑器 Measurements 页启用后才有数值。 ## 追加轮⑰(09-07):Results 节点断层修复(方法节点展开) - **"Results (CogBlobResults) 下面没了"的根因**:CogBlobResults 的数据全在**无参方法**里(GetBlobs()/GetBlobMeasure()/CreateBlobImage()...,属性一个都没有)——属性扫描到它必然断掉。 - **树扫描新增方法节点**:无参 Get*/Create* 方法(排除 ToString/GetHashCode/GetType/Dispose)自动展开为子节点,显示名带 `()`(如 `GetBlobs() (CogBlobResultCollection) [3 项]`),路径按方法名(GetPath 支持无参方法调用,下游绑定同样有效);值渲染复用 WalkValue 统一管线(标量/集合/复杂对象)。树可以一路钻到与官方终端树同样的深度。 ## 追加轮⑱(09-07):预勾选回显修复(路径体系统一) - **"预选了但弹窗里没勾上"的根因**:预设种入的是旧属性式路径(`Results.GetBlobs[0]@Measure:Area`),新树生成方法式路径(`Results.GetBlobs()[0]...`)——字符串对不上,勾选框全空。 - **修复(路径体系统一为树格式)**:新增 `VpToolSupport.NormalizePath`(索引段方法化:`GetBlobs[0] → GetBlobs()[0]`);① GetPresetPaths 返回前规范化;② PluginRun 对已存 OutputTerminals 做一次性规范化迁移(旧流程数据兼容);③ LearnTerminalPaths 输出统一规范化(学习清单与树一致)。树 Tag=规范化路径 → 勾选回显精确对应。 ## 追加轮⑳(09-07):方法段取值修复(终端输出 null 根因) - **"GetBlobs()[0]@Measure:Area 输出 null"根因**:GetPath 按段查成员时拿的是带 `()` 的名字(`"GetBlobs()"`)——属性/字段/方法全都查不到,中途断链返回 null。 - **修复**:GetPath 解析段名时剥离 `()`(成员查找用裸名);GetMember 增加"属性不存在时尝试同名 GetXxx() 方法"兜底(GetBlobs/GetBlobMeasure 等);MemberExists 同步剥 `()`(严格验证不再误判)。另注意:测量值为 null 的另一情形是测量未在 Blob 原生编辑器 Measurements 页启用(GetMeasure 抛"未计算"被容错为 null)。 ## 追加轮㉑(09-07):树方法节点路径带括号(勾选回显最终对齐) - **"预设在结果里有值、弹窗里却不打勾"的根因(与⑱方向相反)**:方法节点的子路径拼接用的是不带括号的前缀(`Results.GetBlobs[0]...`),而 NormalizePath/预设存储是带括号的(`Results.GetBlobs()[0]...`)——树 Tag 与存储字符串又不一致。 - **修复**:AddChildren 方法循环的 path 统一带 `()`(`prefix + "." + name + "()"`),其下所有子节点路径自动继承;GetPath 运行时剥 `()` 兼容两种。至此树 Tag=存储格式=取值格式,三方一致。 ## 追加轮㉒(09-07):VPP 编辑器显示简化(去图层筛选下拉) - 用户确认:输出内容已在「编辑输出终端」里配置 → 编辑器显示端不再需要图层筛选树。 - **VppFlowEditorView 简化**:删除 视觉显示 的图层筛选下拉与全部筛选逻辑;显示端**永远跟随最新发布的图像**(任意节点发布即刷新其默认视图),画布点选节点也可直接看该节点最新图。状态行显示 `节点 · #批次`。 - Halcon/VM 编辑器保留原图层筛选(Halcon 的 图像/区域 对照对调试有价值),如需同步简化说一声即可。 ## 追加轮㉓(09-08):C#脚本节点首建卡顿优化(后台编译) - **根因**:拖入节点 → InitRun → InitPlugin 在 **UI 线程同步**做了整条重活:CodeForge 引擎首建(Roslyn 启动)+ 添加全部 TeamAAS 程序集引用 + 完整编译脚本——首次数秒冻结。 - **修复**:① `InitPlugin` 立即返回 true,编译转 `Task.Run` 后台(引擎预热/引用/编译全在后台,_engineGate 串行化与 PluginRun 的竞争);② 新增 `ScriptCompiler.TryGetEntry/TryCreateCached`(纯缓存查询,绝不触发编译);③ `DeclareOutputs` 只用缓存命中结果(该方法在 UI 线程被调用),未命中回空——后台编译完成后,下次打开属性/保存/运行即按脚本声明输出;④ `PluginRun` 保持同步编译(在 FlowExecutor 工作线程,不卡 UI)。WarmupEngine 公开供预热调用。 ## 待续(按优先级) ## 环境说明 - Git Bash 整夜损坏(cygwin fork 报错)→ 命令行 git/dotnet 不可用,**改动尚未提交**。 - 编译验证:02:30 左右通过资源管理器打开了 TeamAAS.sln(VS 18 Insiders,管理员实例),用 Ctrl+Shift+B 驱动构建。 - Git 策略执行:改动全部落在工作区、未提交(master 未被改动);shell 可用后 `git checkout -b feature/modularization` 即可把全部改动带进分支(无需合并操作)。 ## 编译验证结果(✅ 已确认通过) - 修复历程:①CS0314(SDK 泛型约束→反射闭合 IDeviceProvider<>+非泛型 GetService(Type))→ ②分类工程 halcondotnet 引用(改为显式 HintPath 引用主工程 HalconSdk\halcondotnet.dll,Private=False)→ ③HalconWindow 拖放 GetDataPresent 笔误 + HalconEditorPreview 缺 using Plugins.Halcon.Views → ④CommBatchNodes 缺 using System.ComponentModel / Plugins.Standard.Models。 - **最终状态:VS 状态栏「生成成功」(3:04),错误 0。全部产物已核实在正确位置**: - `TeamAAS.Core\TeamAAS.SDK\bin\x64\Debug\TeamAAS.SDK.dll` ✓ - `TeamAAS.Core\TeamAAS.Motion\bin\x64\Debug\TeamAAS.Motion.dll` ✓ - `EXE\win-x64\Plugins\HalconPlugins\`:Plugins.Halcon.dll、Plugins.Halcon.ImageProcessing.dll、Plugins.Halcon.Detection.dll、Plugins.Halcon.Measurement.dll、Plugins.Halcon.Logic.dll ✓(+halcondotnet.dll 随主插件复制) - Plugins.Standard.dll(含新增 批量读取/批量写入 节点)✓ ## 已完成(全部内容) 1. Docs/ARCHITECTURE.md —— 五层架构蓝图、视觉拆分规范(`Plugins.<平台>.<功能>.dll` + `Plugins\{HalconPlugins,VmPlugins,VppPlugins}\` 部署目录)、图层管线、迁移规则。 2. TeamAAS.SDK 新工程:IPluginContext/ServiceRegistry(服务上下文,替代单例直连的正规渠道)、设备契约(INamedDevice/IConnectableDevice/IDeviceProvider/IDeviceDebugPageFactory)、运动契约(IMotionCard/IIOCard/AxisStatus)、视觉图层契约+总线(LayerItem/LayerPublishArgs/VisionLayerStore:RunStamp 整体替换、owned 对象释放、ClearAll)。 3. PluginLoader 递归扫描 `Plugins\**\Plugins.*.dll`(同名 DLL 去重)。 4. FlowSerializationBinder + FlowFileStore 挂接:旧 .aas 流程在算子跨程序集迁移后零改动可加载(全域按类型全名兜底解析)。 5. Halcon 算子拆分为 4 个分类 DLL(类型全名/显示名不变)+ 主工程瘦身为引擎/容器/显示/运行时。 6. Halcon 图层显示链路:算子 → HalconEditorPreview.Show(Model,…) → VisionLayerStore → HalconFlowEditorView 右侧大显示窗(VisionMaster 风格、可拖宽、随窗自适应)+ 图层筛选 ComboBox(最新运行/按节点)+ 状态行;画布点选节点联动(依赖 FlowEditorViewModel.SelectedNode 的 INPC,若未通知则 ComboBox 手动切换兜底);HalconWindow 新增图层渲染模式(多彩叠加、缩放/ROI/保存兼容、GenImage 副本自动释放);每轮容器运行 BeginRunCycle 换批次防叠加。 7. Vm/Vpp 属性面板"高级编辑"按钮([Button] + AdvancedEditorLauncher 注入点)。 8. TeamAAS.Motion:MotionManager(MotionDevices.json)、仿真运动卡/IO卡、通用调试页 MotionDebugView + MotionDebugPageFactory、品牌适配位(雷赛/固高/IMC60G/GR20T);已挂 Core 聚合 + App 启动 LoadConfig/退出 CloseAll + CoreManager.Motion。 9. 通讯标准节点:Plugins.Standard 新增 **批量读取/批量写入**(CollectionEditor 点位列表、公式绑定来源、逐项错误报告、自动重连、失败策略可选);已随解决方案编译通过。 ## 待续(按优先级) 0. **✅ 追加轮(凌晨):Vpp/Vm 算子级节点已落地并编译通过(生成成功 3:47)**: - `Plugins.Vpp.Vision\Plugins.Vpp.Detection`:**VpBlob分析 / Vp模板匹配**;`Plugins.Vpp.Measurement`:**Vp卡尺测量 / Vp找圆 / Vp找直线**。基建=主工程新增 VpToolSupport.cs(反射创建/运行 Cog 工具、结果路径取值 Results[0].Score 等、原生编辑器 EditV2 控件 WinForms 弹出);基类 VpToolModelBase(Tool 随流程序列化不丢配置 + 输入图像绑定 + [Button]高级编辑)+ VpToolPluginBase(取图→喂图→运行→提取)。部署到 `Plugins\VppPlugins\`。✓ 产物已核实 - `Plugins.Vm.Vision\Plugins.Vm.Module`:**VM模块** 节点(方案/流程/结果键声明 → 运行读取模块结果 GetOutputImageV2 等;高级编辑调起 VisionMaster 客户端打开方案);VmRuntime 增加 GetModuleOutput。部署到 `Plugins\VmPlugins\`。✓ 产物已核实 - 注意:Vp 算子的结果字段取值路径(如 CogBlobResult.CenterOfMassX / PMAlign GetPose 等)基于 VisionPro 标准 API 反射容错取值,个别字段名如有出入只会该项输出 null,不影响节点运行——首次联调时核对日志微调即可。 1. **运行验证**(需人工/白天):工具箱应出现 Halcon 8 算子 + Vp 5 算子 + VM模块 + 批量读/写 → 各节点建流程跑通 → 旧产品加载验证 Binder。 2. **git 提交**:`git checkout -b feature/modularization` 分 7 段提交;删 `_explore.ps1`。 3. **Vpp 更多算子**:按 VpToolPluginBase 模式 5 分钟一个(FindLineSwap/Clamp/Edge 等);**Vm 模块参数直读**:确认 VmSdk 模块 SetParamValue/ModuResult 键名后把常用参数提到属性面板。 4. **VppWindow/VmWindow 显示升级** + 高级编辑按钮接线(VpToolModelBase 已自带按钮无需接线)。 ## 早间人工验证清单 - [ ] 启动程序:主页"相机画面显示区"是否恢复(若仍空白 → Logs 中搜「模块扫描」:VisionPro 引擎实例化失败原因会首次被记录;桌面副本还需确认 Runtime\Vpp9.0 与 Runtime\dll 是否拷全) - [ ] 打开 Halcon流程 **不再闪退**(无原生库时显示区出现占位提示、画布可用) - [ ] 主流程工具箱出现「VPP流程」「VM流程」容器(Halcon流程 已有);双击各自进入子流程编辑器,工具箱只显示本平台算子(VPP流程内:Vp×5 按检测识别/几何测量分组;VM流程内:VM模块) - [ ] Halcon 子流程工具箱不再出现 Vp/VM 算子(平台隔离) - [ ] VPP流程 内拖 VpBlob分析 → 绑定 &{输入.图像} → 运行:右侧大显示窗出图、点节点跟随、图层 ComboBox 按节点筛选 - [ ] 加载旧产品 流程1.aas 成功(Binder 兼容) - [ ] 不配置 MotionDevices.json 时启动无异常 - [ ] git shell 可用后:`git checkout -b feature/modularization` 分段提交(全部改动仍在工作区)