From 9481aae0f89f1dc45ca8d1b656b2f5b354f3132a Mon Sep 17 00:00:00 2001 From: sladro Date: Thu, 11 Dec 2025 10:58:38 +0800 Subject: [PATCH] Initial commit --- Readme.md | 645 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 645 insertions(+) create mode 100644 Readme.md diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..da2129f --- /dev/null +++ b/Readme.md @@ -0,0 +1,645 @@ +## 0. 目标 & 新流程说明 + +### 0.1 功能目标 + +基于 **AutoCAD 2014** 开发一个插件,实现: + +1. 在 AutoCAD 中**新建图纸后**,打开插件面板; +2. 用户在插件面板中**输入一组模板相关参数**(如图纸类别、项目类型、图幅、比例等), + 插件根据这些参数**自动匹配模板**(DWT/DWG中的某个图纸); +3. 用户再输入**出图相关的其它参数**(构件数量、尺寸、布置方式等,开发时再定); +4. 插件结合**选中的模板 + 业务参数**,自动在 CAD 中生成图形; +5. 生成后通过插件提供的“保存”功能,让用户选择保存位置和文件名。 + +### 0.2 使用体验要求(不走命令行) + +- 使用人员只通过 **侧边面板 UI** 操作,不需要输入命令; +- 插件加载后自动显示面板; +- 整个流程:填写参数 → 预览/确定模板 → 生成图纸 → 保存,全部在 UI 中完成; +- 命令行入口可以保留一个隐藏命令用于调试,但**不要求普通用户使用**。 + +--- + +## 1. 技术选型与项目结构 + +### 1.1 环境 & 依赖 + +- 操作系统:Windows 7 +- AutoCAD:AutoCAD 2014(x86 或 x64) +- .NET Framework:建议 4.5 +- IDE:Visual Studio 2012 / 2013+ + +AutoCAD 引用: + +- `AcCoreMgd.dll` +- `AcDbMgd.dll` +- `AcMgd.dll` + +(从 AutoCAD 2014 安装目录或 ARX SDK 中引用) +### 1.2 解决方案结构(建议) + +```text +Solution: AutoCADParamDrawing + ├─ AutoCADParamDrawing.Plugin // 插件宿主 + UI + CAD 操作 + ├─ AutoCADParamDrawing.Domain // 业务模型 + 参数校验 + 出图算法 + ├─ AutoCADParamDrawing.Data // 模板配置、系统配置等数据访问 + ├─ AutoCADParamDrawing.Common // 日志、配置工具、通用扩展方法 +``` + +- **Plugin**:与 AutoCAD、UI 直接打交道; +- **Domain**:只关心“参数”和“图形逻辑”,不关心 UI/配置文件细节; +- **Data**:负责加载模板配置、系统参数(从 config/JSON/数据库等); +- **Common**:基础设施。 + +--- + +## 2. 用户业务流程 & UI 设计 + +### 2.1 用户操作流程(从用户视角) + +1. 打开 AutoCAD,**新建一个空白图纸**(或默认新建图); +2. AutoCAD 启动时插件自动加载,右侧弹出**“参数化出图”面板**; +3. 用户在面板中完成三步: + + - **步骤 1:填写模板参数** + - 项目类型(结构 / 给排水 / …) + - 图纸类型(基础平面 / 楼层平面 / 剖面等) + - 图幅(A1 / A2 / A3 …) + - 比例(1:50 / 1:100…) + - 其他模板选型相关参数(开发时定) + + 点击【匹配模板】按钮,面板显示匹配到的模板名称与路径。 + + - **步骤 2:填写出图参数** + - 构件类别 / 数量 + - 尺寸参数(长宽高、标高、层数……) + - 出图规则选项(是否生成某些视图/明细等) + > 具体参数由开发阶段根据业务确定。 + + - **步骤 3:生成图纸 & 保存** + - 点击【生成图纸】按钮: + - 插件根据模板参数,找到模板文件; + - 根据出图参数计算几何布置; + - 调用 AutoCAD API 在图中生成图形(可选:自动基于模板新建一个新图窗体); + - 出图完成后弹出提示,并提供【保存为…】按钮: + - 打开文件保存对话框,让用户选择 DWG 名称和目录; + - 插件内部调用 `Database.SaveAs()` 完成保存。 + +4. 用户后续可手工调整图纸或继续用插件对同一模板重复生成。 + +### 2.2 插件主面板结构 + +**ParamDrawingPanel**(WinForms UserControl)建议布局: + +1. **区域一:模板参数(Template Parameters)** + - ComboBox:项目类型(ProjectType) + - ComboBox:图纸类型(DrawingType) + - ComboBox:图幅(SheetSize) + - ComboBox / TextBox:比例(Scale) + - 预留若干 TextBox/ComboBox 用于其它模板判断参数 + - 按钮:`匹配模板`(Match Template) + - Label:显示“已选模板:XXX.dwt”或“未找到匹配模板” + +2. **区域二:出图参数(Drawing Parameters)** + - 若干 TextBox/ComboBox,具体字段开发时确定,比如: + - 轴线数量、层数、构件高度等 + - 可以采用简单表格控件展示不同构件列表(可选) + +3. **区域三:操作按钮** + - `生成图纸`(Generate Drawing) + - `保存当前图纸…`(Save Drawing As…) + - `打开配置`(打开模板配置/系统配置窗口) + +4. **区域四:日志/提示** + - 多行 TextBox 或 ListBox 用于显示: + - 模板匹配结果; + - 参数校验信息; + - 出图进度、错误提示等。 + +--- + +## 3. 模块划分与职责 + +### 3.1 Plugin 层 + +主要命名空间(示例): + +- `AutoCADParamDrawing.Plugin.Entry` + - 插件入口,实现 `IExtensionApplication` + - 初始化 PaletteSet & Panel + +- `AutoCADParamDrawing.Plugin.UI` + - `ParamDrawingPanel`:主面板 + - 可选其它对话框,如“配置窗口” + +- `AutoCADParamDrawing.Plugin.Cad` + - `CadContext`:封装 Transaction / Document + - `CadDrawingService`:封装 AutoCAD 绘图操作(画线、插块、文字、图层、布局等) + - `TemplateDrawingService`:处理“基于模板新建图纸”的逻辑 + +**职责总结:** + +- 与 AutoCAD 交互(Document、Database、锁定、事务); +- 与用户交互(UI 事件); +- 将 UI 输入转为 Domain 模型; +- 调用 Domain 层完成校验和绘图。 + +--- + +### 3.2 Domain 层 + +建议基础模型结构如下(字段仅示意): + +```csharp +public class TemplateParams +{ + public string ProjectType { get; set; } + public string DrawingType { get; set; } + public string SheetSize { get; set; } + public string Scale { get; set; } + // 其他用于模板选择的参数,开发时补充 +} + +public class DrawingParams +{ + // 出图相关参数(构件、尺寸等),开发时定义 + // 示例: + // public int FloorCount { get; set; } + // public double ColumnWidth { get; set; } + // ... +} + +public class TemplateInfo +{ + public string Name { get; set; } + public string FilePath { get; set; } + public string Description { get; set; } +} +``` + +Domain 入口类(示例): + +```csharp +public static class DomainFacade +{ + public static TemplateInfo SelectTemplate(TemplateParams tplParams) + { + // 调用 Data 层:TemplateRepository.FindTemplate(tplParams) + // 并对结果做业务校验(是否唯一等) + } + + public static void ValidateParameters(TemplateParams tplParams, DrawingParams drawParams) + { + // 对必填项、数值范围等进行校验 + // 可抛出 BusinessException 反馈给 UI + } + + public static void DrawByParams( + TemplateInfo template, + DrawingParams drawParams, + CadDrawingService cadService) + { + // 真正的业务绘图逻辑: + // 1. 根据模板信息,配置图层/样式(如需要) + // 2. 根据 drawParams 计算几何位置 + // 3. 调用 cadService 画线、插块、标注、文字等 + // 4. 可封装不同图纸类型的策略类,如:BeamDrawingStrategy、ColumnDrawingStrategy 等 + } +} +``` + +职责: + +- 参数模型和校验; +- 模板选择规则(+ Data 层配置); +- 绘图算法与布置规则。 + +--- + +### 3.3 Data 层 + +Data 层主要处理 **模板配置 & 系统配置**,例如: + +```csharp +public class TemplateDefinition +{ + public string Id { get; set; } // 内部唯一 ID + public string ProjectType { get; set; } + public string DrawingType { get; set; } + public string SheetSize { get; set; } + public string Scale { get; set; } + public string FilePath { get; set; } // 模板文件路径 + public string Description { get; set; } +} +``` + +模板仓储接口: + +```csharp +public interface ITemplateRepository +{ + TemplateDefinition FindTemplate(TemplateParams tplParams); + IEnumerable GetAll(); +} +``` + +实现可以是: + +- 读取 app.config / JSON 文件 / XML 文件等; +- 配置格式示例(JSON 形式,具体由开发时确定): + +```json +[ + { + "ProjectType": "结构", + "DrawingType": "基础平面", + "SheetSize": "A1", + "Scale": "1:50", + "FilePath": "C:\\CadTemplates\\Stru_Base_A1_50.dwt", + "Description": "结构基础平面 A1 1:50" + } +] +``` + +> 具体字段和匹配策略可以开发时再细化,这里只定义架构和职责。 + +--- + +### 3.4 Common 层 + +- 日志工具:`Logger.Info/Error`(写文本或者 log4net 等); +- 配置读取:读取 app.config 或 JSON 路径; +- 通用异常类型:`BusinessException` 用于业务错误提示用户。 + +--- + +## 4. 核心技术实现示意 + +### 4.1 插件入口 & PaletteSet 创建 + +```csharp +using Autodesk.AutoCAD.Runtime; +using Autodesk.AutoCAD.ApplicationServices; +using Autodesk.AutoCAD.Windows; + +namespace AutoCADParamDrawing.Plugin.Entry +{ + public class PluginEntry : IExtensionApplication + { + private static PaletteSet _palette; + + public void Initialize() + { + CreateAndShowPalette(); + } + + public void Terminate() + { + // 可记录日志等 + } + + private void CreateAndShowPalette() + { + if (_palette == null) + { + _palette = new PaletteSet("参数化出图") + { + Style = PaletteSetStyles.ShowCloseButton | + PaletteSetStyles.ShowAutoHideButton | + PaletteSetStyles.Snappable + }; + + var panel = new UI.ParamDrawingPanel(); + _palette.Add("主面板", panel); + _palette.MinimumSize = new System.Drawing.Size(320, 400); + } + + _palette.Visible = true; + } + + // 可选:用于调试/恢复面板 + [CommandMethod("PARAM_PANEL")] + public void ShowPanelCommand() + { + CreateAndShowPalette(); + } + } +} +``` + +### 4.2 CadContext & CadDrawingService + +```csharp +using Autodesk.AutoCAD.ApplicationServices; +using Autodesk.AutoCAD.DatabaseServices; + +namespace AutoCADParamDrawing.Plugin.Cad +{ + public class CadContext : IDisposable + { + public Document Document { get; } + public Database Database => Document.Database; + public Transaction Transaction { get; private set; } + + public CadContext(Document doc) + { + Document = doc; + Transaction = Database.TransactionManager.StartTransaction(); + } + + public void Commit() + { + Transaction?.Commit(); + } + + public void Dispose() + { + Transaction?.Dispose(); + Transaction = null; + } + } + + public class CadDrawingService + { + private readonly CadContext _ctx; + + public CadDrawingService(CadContext ctx) + { + _ctx = ctx; + } + + // 示例:画线 + public ObjectId DrawLine(Point3d start, Point3d end) + { + var db = _ctx.Database; + var tr = _ctx.Transaction; + var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); + var btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); + + var line = new Line(start, end); + var id = btr.AppendEntity(line); + tr.AddNewlyCreatedDBObject(line, true); + return id; + } + + // TODO: 插块、文字、标注、图层等方法开发时补充 + } +} +``` + +### 4.3 基于模板新建图纸(可选方案) + +两种方式,二选一: + +1. **直接在当前新建图中绘图**: + - 只用模板来参考图层/样式规则,但不真正打开模板文件; +2. **真正基于模板新建一个图纸 Document**(推荐): + +示例(在 UI 的“生成图纸”里调用): + +```csharp +public Document CreateDocumentFromTemplate(TemplateInfo tpl) +{ + // template.FilePath 来自 Data 层配置 + var newDoc = Autodesk.AutoCAD.ApplicationServices.Application + .DocumentManager.Add(tpl.FilePath); + + // 设为当前活动文档 + Autodesk.AutoCAD.ApplicationServices.Application + .DocumentManager.MdiActiveDocument = newDoc; + + return newDoc; +} +``` + +之后: + +```csharp +var tplInfo = DomainFacade.SelectTemplate(templateParams); +DomainFacade.ValidateParameters(templateParams, drawingParams); + +var newDoc = TemplateDrawingService.CreateDocumentFromTemplate(tplInfo); + +using (newDoc.LockDocument()) +using (var ctx = new CadContext(newDoc)) +{ + var cadService = new CadDrawingService(ctx); + DomainFacade.DrawByParams(tplInfo, drawingParams, cadService); + ctx.Commit(); +} +``` + +### 4.4 UI 面板核心逻辑示意(ParamDrawingPanel) + +```csharp +public partial class ParamDrawingPanel : UserControl +{ + private TemplateInfo _selectedTemplate; + + public ParamDrawingPanel() + { + InitializeComponent(); + } + + private TemplateParams CollectTemplateParamsFromUI() + { + return new TemplateParams + { + ProjectType = cbProjectType.Text, + DrawingType = cbDrawingType.Text, + SheetSize = cbSheetSize.Text, + Scale = cbScale.Text + // 更多字段开发时补充 + }; + } + + private DrawingParams CollectDrawingParamsFromUI() + { + var p = new DrawingParams(); + // 从文本框/下拉框收集各类出图参数 + return p; + } + + private void btnMatchTemplate_Click(object sender, EventArgs e) + { + try + { + var tplParams = CollectTemplateParamsFromUI(); + _selectedTemplate = DomainFacade.SelectTemplate(tplParams); + + lblTemplateInfo.Text = $"已匹配模板: {_selectedTemplate.Name}"; + AppendLog($"模板: {_selectedTemplate.FilePath}"); + } + catch (BusinessException bex) + { + AppendLog($"模板选择错误: {bex.Message}"); + } + catch (Exception ex) + { + AppendLog($"异常: {ex.Message}"); + Logger.Error("MatchTemplate", ex); + } + } + + private void btnGenerate_Click(object sender, EventArgs e) + { + if (_selectedTemplate == null) + { + AppendLog("请先匹配模板。"); + return; + } + + try + { + var tplParams = CollectTemplateParamsFromUI(); + var drawingParams = CollectDrawingParamsFromUI(); + + DomainFacade.ValidateParameters(tplParams, drawingParams); + + // 创建基于模板的新图纸并绘图 + var newDoc = TemplateDrawingService.CreateDocumentFromTemplate(_selectedTemplate); + + using (newDoc.LockDocument()) + using (var ctx = new CadContext(newDoc)) + { + var cadService = new CadDrawingService(ctx); + DomainFacade.DrawByParams(_selectedTemplate, drawingParams, cadService); + ctx.Commit(); + } + + AppendLog("图纸生成完成。"); + } + catch (BusinessException bex) + { + AppendLog($"参数错误: {bex.Message}"); + } + catch (Exception ex) + { + AppendLog($"生成失败: {ex.Message}"); + Logger.Error("GenerateDrawing", ex); + } + } + + private void btnSaveAs_Click(object sender, EventArgs e) + { + var doc = Autodesk.AutoCAD.ApplicationServices.Application + .DocumentManager.MdiActiveDocument; + + using var dlg = new SaveFileDialog + { + Filter = "AutoCAD Drawing (*.dwg)|*.dwg", + FileName = "新图纸.dwg" + }; + if (dlg.ShowDialog() == DialogResult.OK) + { + doc.Database.SaveAs(dlg.FileName, true, DwgVersion.Current, doc.Database.SecurityParameters); + AppendLog($"图纸已保存到: {dlg.FileName}"); + } + } + + private void AppendLog(string msg) + { + txtLog.AppendText(msg + Environment.NewLine); + } +} +``` + +> 具体 UI 控件命名、字段等开发时根据实际参数调整。 + +--- + +## 5. 开发步骤(执行指引) + +### 步骤 1:创建解决方案 & 项目 + +1. 新建 VS 解决方案 `AutoCADParamDrawing`; +2. 创建四个项目:Plugin / Domain / Data / Common; +3. Plugin 项目引用 AutoCAD DLL; +4. Common 项目实现基础配置/日志工具类。 + +### 步骤 2:定义参数模型(Domain) + +1. 定义 `TemplateParams`, `DrawingParams`, `TemplateInfo` 等类; +2. 类上用注释说明这些属性将对应到 UI 控件; +3. 定义 `DomainFacade` 入口方法: + - `SelectTemplate` + - `ValidateParameters` + - `DrawByParams` + +### 步骤 3:实现模板配置(Data 层) + +1. 确定模板配置文件格式(建议 JSON / XML,方便非程序员维护); +2. 实现 `TemplateRepository`: + - 从配置文件加载所有模板定义; + - 提供按 `TemplateParams` 匹配模板的方法; +3. 在 `DomainFacade.SelectTemplate` 中调用 `TemplateRepository` 并处理找不到/多条等情况。 + +### 步骤 4:实现 Domain 的基本绘图算法 + +1. 先实现**简单版本**: + - 根据一两个简单参数(比如构件数量/长度)画出一些线条/框,验证流程; +2. 后续逐步细化: + - 按不同图纸类型拆分策略类; + - 完善图层、标注、文字等。 + +### 步骤 5:实现 Plugin 层的 CadContext & CadDrawingService + +1. 封装事务和 Document 操作; +2. 实现画线/插块/文字/标注等基础方法; +3. 后续根据业务增加更多方法。 + +### 步骤 6:实现 UI 面板(ParamDrawingPanel) + +1. 设计界面布局(模板参数区 + 出图参数区 + 操作区 + 日志区); +2. 编写事件处理逻辑: + - 参数收集 → 模板匹配 → 参数校验 → 调用生成图纸; +3. 实现 `btnSaveAs` 保存功能。 + +### 步骤 7:实现插件入口(IExtensionApplication) + +1. 在 `PluginEntry.Initialize` 中创建 PaletteSet,添加 ParamDrawingPanel; +2. 编译后在 AutoCAD 中 `NETLOAD` 测试: + - 确认启动时自动出现面板; + - 按步骤能生成一张简单测试图。 + +### 步骤 8:迭代完善业务细节 + +- 与业务方确认参数列表 & 模板规则; +- 丰富模板配置; +- 封装真实业务绘图算法; +- 扩展功能: + - 多图纸批量生成; + - 一键生成并保存到指定目录等。 + +--- + +## 6. 测试要点(开发自测参考) + +1. **模板匹配** + - 输入各种模板参数组合; + - 检查模板是否正确匹配,找不到/多条时提示是否合理。 + +2. **参数校��** + - 有必填项为空时,能在 UI 上提示具体字段; + - 数值异常(负数、格式错误)能被拦截。 + +3. **绘图结果** + - 图形是否根据参数变化; + - 图层/文字/标注是否按模板和规则创建。 + +4. **保存** + - “保存为…”是否成功输出 DWG 文件; + - 再次打开是否正常显示。 + +--- + +## 7. 部署与使用说明(给实施/最终用户) + +1. 将编译后的 `AutoCADParamDrawing.Plugin.dll` 及其它依赖拷贝至指定目录(如:`C:\CadPlugins\ParamDrawing\`)。 +2. 建议做成 AutoCAD `.bundle` 插件,实现自动加载;或者由实施人员在启动脚本中设置 `NETLOAD`。 +3. 用户启动 AutoCAD 后: + - 看到右侧“参数化出图”面板; + - 按“模板参数 → 匹配模板 → 出图参数 → 生成图纸 → 保存”流程使用即可。 + +--- +