迈智数创建筑 AI · Coding

试试搜索

↑↓ 选择Enter 打开Esc 关闭

Lesson15:综合实战:扩展一个 MiniCAD 功能

下载 .md
系列:MiniCAD第 17 / 17 篇
  1. MiniCAD 初级教程课程规划
  2. C++ 基础课:读懂 MiniCAD 所需的语言知识
  3. Lesson01:项目能跑起来
  4. Lesson02:整体架构地图
  5. Lesson03:程序入口与主循环
  6. Lesson04:输入系统与消息映射
  7. Lesson05:绘图工具如何工作
  8. Lesson06:Core 核心层:数学、几何、对象与实体
  9. Lesson07:命令模式与撤销重做
  10. Lesson08:选择、拾取与夹点编辑
  11. Lesson09:视口、相机与坐标转换
  12. Lesson10:渲染层入门
  13. Lesson11:文字与字体系统
  14. Lesson12:吸附与约束系统
  15. Lesson13:命令行系统
  16. Lesson14:多文档管理
  17. Lesson15:综合实战:扩展一个 MiniCAD 功能
目录
  1. 学习目标
  2. 相关源码
  3. 原理
  4. MiniCAD 中的应用
  5. 实战一:添加命令别名
  6. 实战二:添加一个简单绘图工具
  7. 实战三:显示选中对象信息
  8. 课堂演示
  9. 拓展练习
  10. 综合检查清单

学习目标

本课把前 11 课串起来,完成一个小型扩展。学习者应能按照 MiniCAD 的现有架构添加命令、工具或 UI 信息,而不是绕过命令栈或直接修改渲染层。

相关源码

  • src/Editor/Editor.cpp
  • src/Editor/Tools/ITool.h
  • src/Editor/Tools/RectangleTool.h
  • src/Core/Entity/RectangleEntity.hpp
  • src/Document/Command/AddEntityCommand.h
  • src/Document/CommandStack/CommandStack.cpp
  • src/UI/UIManager.cpp

原理

MiniCAD 的扩展路径应遵守已有链路:

输入事件 -> Editor -> Tool -> Command -> Scene -> Entity::Draw -> Viewport -> Renderer

新功能要放在正确层级。命令别名属于 Editor;绘图交互属于 Tool;图形数据属于 Core/Entity;场景变更必须通过 CommandStack;UI 只负责展示和触发,不应直接改写场景对象。

这样做的好处是,新功能能自然获得撤销/重做、选择、预览、跨平台渲染和 dirty 刷新能力。

MiniCAD 中的应用

实战一:添加命令别名

命令别名由 Editor::RegisterAlias() 管理,最终映射到工具 ID。用户输入字母后,Editor::HandleGlobal() 把字符加入 m_cmdBuffer,按 Enter 或 Space 后调用 ActivateToolByAlias()。

在 Editor::RegisterBuiltinTools() 中添加:

RegisterAlias("R", "Rectangle");

然后运行程序,输入 R 并回车,验证是否启动矩形工具。

实战二:添加一个简单绘图工具

一个新工具通常需要:

  1. 继承 ITool。
  2. 在 OnInput() 中维护点击状态。
  3. 用 Overlay 显示临时预览。
  4. 用实体和命令提交最终结果。
  5. 在 Editor::RegisterBuiltinTools() 中注册。

可以实现一个简化版“两点矩形工具”。项目中已有 RectangleTool.h,初学者可以先阅读它,再尝试做一个变体:第一次左键记录角点,鼠标移动显示预览矩形,第二次左键创建 RectangleEntity。

核心路线:

TwoPointRectangleTool
-> OnInput()
-> overlay.AddLine() 预览四条边
-> RectangleEntity
-> AddEntityCommand
-> CommandStack::Execute()

实战三:显示选中对象信息

选择集由 Editor::GetSelection() 提供,主选中对象可以通过 Editor::GetPrimarySelectedObject() 获取。UI 层可以读取这些信息并显示,不应直接修改场景。

在 UIManager::DrawStatusBar() 中增加选中对象数量:

auto count = dm.GetEditor().GetSelection().size();
ImGui::Text("Selected: %zu", count);

如果需要显示对象类型,可以对 GetPrimarySelectedObject() 返回值使用运行时类型系统判断。

课堂演示

推荐课堂上完成实战一,因为它改动小、反馈直接:

  1. 打开 src/Editor/Editor.cpp。
  2. 找到 Editor::RegisterBuiltinTools()。
  3. 添加 RegisterAlias("R", "Rectangle");。
  4. 构建并运行。
  5. 在命令输入中按 R,再按 Enter。
  6. 验证矩形工具是否启动。

如果时间充足,再演示在状态栏显示选择数量,帮助学习者理解 UI 读取 Editor 状态的方式。

拓展练习

  1. 为常用命令建立一组更接近 AutoCAD 习惯的别名,并同步检查工具栏 tooltip 是否一致。
  2. 给两点矩形工具加入 Shift 键约束,让矩形变成正方形。
  3. 增加一个属性面板,显示对象 ID、图层 ID、实体类型和包围盒。
  4. 为属性修改设计命令对象,确保修改颜色或图层时支持撤销/重做。

综合检查清单

  • 是否遵守现有模块边界?
  • 是否通过 CommandStack 修改场景?
  • 是否调用 Scene::MarkDirty() 或通过命令触发 dirty?
  • 是否支持撤销/重做?
  • 是否兼容 Windows 和 Web 的共享核心?
  • 是否避免直接修改 3rd/ 中的第三方代码?