From 5506ed986102fc0bdaa4f3a59da2b3ff9f30d1d9 Mon Sep 17 00:00:00 2001 From: sladro Date: Wed, 31 Dec 2025 15:37:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=82=E6=95=B0=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cad/DictionaryHelper.cs | 132 ++++++++++++++++++++++++++++++++++++++++ CadParamPluging.csproj | 1 + Readme.md | 9 ++- UI/ParamDrawingPanel.cs | 18 ++++++ 4 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 Cad/DictionaryHelper.cs diff --git a/Cad/DictionaryHelper.cs b/Cad/DictionaryHelper.cs new file mode 100644 index 0000000..fc29ed1 --- /dev/null +++ b/Cad/DictionaryHelper.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using Autodesk.AutoCAD.DatabaseServices; +using CadParamPluging.Common; + +namespace CadParamPluging.Cad +{ + /// + /// 辅助类:用于操作 AutoCAD 的扩展字典 (Extension Dictionary / NOD) + /// + public static class DictionaryHelper + { + // 我们在 NOD (Named Objects Dictionary) 中使用的根字典名称 + private const string AppDictionaryName = "CadParamPluging_Data"; + // 存储参数的 XRecord 名称 + private const string ParamsRecordName = "DrawingParams"; + + /// + /// 将参数包保存到当前文档的 Extension Dictionary (NOD) 中 + /// + public static void SaveParams(Database db, ParamBag bag) + { + if (db == null || bag == null || bag.Items == null || bag.Items.Count == 0) + { + return; + } + + using (var tr = db.TransactionManager.StartTransaction()) + { + var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite); + + // 1. 获取或创建我们的应用专属字典 + DBDictionary appDict; + if (nod.Contains(AppDictionaryName)) + { + appDict = (DBDictionary)tr.GetObject(nod.GetAt(AppDictionaryName), OpenMode.ForWrite); + } + else + { + appDict = new DBDictionary(); + nod.SetAt(AppDictionaryName, appDict); + tr.AddNewlyCreatedDBObject(appDict, true); + } + + // 2. 准备数据 (XRecord) + // XRecord 本质上是一个 ResultBuffer 链表 + // 我们使用 DxfCode.Text (1000) 来存储 key=value 字符串 + var rb = new ResultBuffer(); + foreach (var item in bag.Items) + { + if (!string.IsNullOrWhiteSpace(item.Key)) + { + // 格式: Key=Value + // 也可以分开存储,但简单的 Key=Value 字符串更紧凑 + string entry = $"{item.Key}={item.Value ?? string.Empty}"; + rb.Add(new TypedValue((int)DxfCode.Text, entry)); + } + } + + var xrec = new Xrecord(); + xrec.Data = rb; + + // 如果已存在则覆盖,否则添加 + if (appDict.Contains(ParamsRecordName)) + { + // 为了简单起见,这里选择直接删除旧的再添加新的,或者覆盖 + // 如果用 GetObject 获取旧的 xrec,可以直接 xrec.Data = rb + var oldId = appDict.GetAt(ParamsRecordName); + var oldXrec = (Xrecord)tr.GetObject(oldId, OpenMode.ForWrite); + oldXrec.Data = rb; + } + else + { + appDict.SetAt(ParamsRecordName, xrec); + tr.AddNewlyCreatedDBObject(xrec, true); + } + + tr.Commit(); + } + } + + /// + /// (可选) 从当前文档读取参数 + /// + public static ParamBag ReadParams(Database db) + { + var bag = new ParamBag(); + using (var tr = db.TransactionManager.StartTransaction()) + { + var nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead); + if (!nod.Contains(AppDictionaryName)) + { + return bag; + } + + var appDict = (DBDictionary)tr.GetObject(nod.GetAt(AppDictionaryName), OpenMode.ForRead); + if (!appDict.Contains(ParamsRecordName)) + { + return bag; + } + + var xrec = (Xrecord)tr.GetObject(appDict.GetAt(ParamsRecordName), OpenMode.ForRead); + var rb = xrec.Data; + if (rb == null) + { + return bag; + } + + foreach (var tv in rb) + { + if (tv.TypeCode == (int)DxfCode.Text) + { + var line = tv.Value as string; + if (!string.IsNullOrWhiteSpace(line)) + { + var parts = line.Split(new[] { '=' }, 2); + if (parts.Length == 2) + { + bag.Set(parts[0], parts[1]); + } + else if (parts.Length == 1) + { + bag.Set(parts[0], ""); + } + } + } + } + } + return bag; + } + } +} diff --git a/CadParamPluging.csproj b/CadParamPluging.csproj index 778600f..b70ec37 100644 --- a/CadParamPluging.csproj +++ b/CadParamPluging.csproj @@ -78,6 +78,7 @@ + diff --git a/Readme.md b/Readme.md index da2129f..3db8b95 100644 --- a/Readme.md +++ b/Readme.md @@ -81,9 +81,10 @@ Solution: AutoCADParamDrawing - 插件根据模板参数,找到模板文件; - 根据出图参数计算几何布置; - 调用 AutoCAD API 在图中生成图形(可选:自动基于模板新建一个新图窗体); - - 出图完成后弹出提示,并提供【保存为…】按钮: - - 打开文件保存对话框,让用户选择 DWG 名称和目录; - - 插件内部调用 `Database.SaveAs()` 完成保存。 + - **(新特性) 参数保存**:生成图纸的同时,系统会将当前界面的所有参数自动保存到 DWG 的内部扩展字典中。 + - 出图完成后弹出提示,并提供【保存为…】按钮: + - 打开文件保存对话框,让用户选择 DWG 名称和目录; + - 插件内部调用 `Database.SaveAs()` 完成保存,**参数数据会随文件一起保存**。 4. 用户后续可手工调整图纸或继续用插件对同一模板重复生成。 @@ -135,7 +136,9 @@ Solution: AutoCADParamDrawing - `AutoCADParamDrawing.Plugin.Cad` - `CadContext`:封装 Transaction / Document - `CadDrawingService`:封装 AutoCAD 绘图操作(画线、插块、文字、图层、布局等) + - `CadDrawingService`:封装 AutoCAD 绘图操作(画线、插块、文字、图层、布局等) - `TemplateDrawingService`:处理“基于模板新建图纸”的逻辑 + - `DictionaryHelper`:封装 Extension Dictionary (NOD) 的读写操作,用于保存参数 **职责总结:** diff --git a/UI/ParamDrawingPanel.cs b/UI/ParamDrawingPanel.cs index 3d889ba..a6466bf 100644 --- a/UI/ParamDrawingPanel.cs +++ b/UI/ParamDrawingPanel.cs @@ -34,6 +34,7 @@ namespace CadParamPluging.UI private Extents3d? _selectedModelWindow; private string _selectedSheetName; + public ParamDrawingPanel() { Dock = DockStyle.Fill; @@ -780,6 +781,23 @@ namespace CadParamPluging.UI ctx.Commit(); try { doc.Editor.Regen(); } catch { } + + // 保存参数到图纸内部 (Extension Dictionary / NOD) + try + { + var bagToSave = bag; + // 注意:bag 已经在上面被使用了,直接传递即可。 + // 如果需要保存更完整的信息(比如模板路径),也可以添加到 bag 中 + // bagToSave.Set("_TemplatePath", _selectedTemplate.FilePath); + + DictionaryHelper.SaveParams(doc.Database, bagToSave); + AppendLog("参数已保存到图纸内部数据中。"); + } + catch (Exception ex) + { + AppendLog($"保存内部参数失败: {ex.Message}"); + Logger.Error("SaveParamsInternal", ex); + } } AppendLog("图纸生成完成。");