附录 C · 术语表¶
术语按拼音排序。解释尽量贴近工业软件的实际语境,而不是给出教科书定义;同一个词在不同项目里可能略有差异,以项目文档为准。
ABI(二进制接口) 编译后的二进制兼容性。C++ 没有标准 ABI,同一个类在不同编译器、不同标准库、不同 Qt 版本下布局可能不同。插件接口一旦发布,就不能随便改虚函数表或成员布局;Qt 的插件用 IID 做版本标记,改接口就换 IID,比运行时崩溃可控。
B-Rep(边界表示) 用面、边、顶点及其拓扑关系描述实体的方法。与网格表示相对:B-Rep 精确,能表达圆柱、NURBS 曲面,也能做真正的布尔和倒角;网格是近似。OCCT 是开源世界里最重要的 B-Rep 内核。
CRS(坐标参考系) 描述地球表面位置的坐标系。经纬度是地理坐标系,Web Mercator 是投影坐标系。GIS 软件必须在图层加载、查询、计算、导出各环节保持 CRS 一致,否则结果会整体偏移。
DRC(设计规则检查) 设计规则检查。PCB 里检查线宽、间距、孔径是否满足工艺要求;CAD 里也有干涉、间隙、拔模角等类似检查。DRC 是“设计能不能被制造”的门槛。
ECS(实体组件系统) 一种把数据与行为拆开的三维场景组织方式:实体只是 ID,组件存数据,系统处理逻辑。Qt 3D 采用这种模型,优点是组合灵活,缺点是调试和学习成本高。
GIL(全局解释器锁) CPython 的全局锁,同一时刻只有一个线程执行 Python 字节码。C++ 通过 pybind11 调用 Python 时要处理 GIL,计算密集的 Python 代码也难以靠多线程加速;需要并行时通常用多进程或把计算放到 C++ 侧。
LOD(细节层次) 细节层次。数据量大时,按视距或屏幕尺寸选择不同精度的模型:远处用简化网格,近处用完整模型。大装配、点云、GIS 都依赖 LOD 控制绘制量。
MRML(医学影像场景描述)
Medical Reality Markup Language,3D Slicer 的场景描述格式。一个 vtkMRMLScene 持有所有节点,节点之间可以引用,界面是场景的观察者。理解 MRML 是理解 Slicer 插件结构的前提。
NURBS(非均匀有理 B 样条) 工业界表达自由曲面的标准数学工具,能精确表示圆、椭圆等二次曲线,也是 STEP、IGES 的底层表示之一。NURBS 的阶数、节点向量、权重决定了曲面的形状和连续性。
ODR(单一定义规则) C++ 要求同一个实体在所有翻译单元中只有一份定义。头文件里的内联函数、模板、全局变量如果违反 ODR,链接器可能不报错,运行时却出现难以定位的行为差异。
PCH(预编译头) 预编译头文件,把稳定的头文件预先编译成中间格式,减少重复解析。它能明显缩短大型项目的编译时间,但会掩盖头文件依赖,升级编译器或标准库时要重新验证。
QUndoStack(Qt 撤销栈)
Qt 提供的命令栈实现,配合 QUndoCommand 使用。关键不在数据结构,而在纪律:所有修改都必须经过命令,id() 与 mergeWith() 决定连续操作如何合并,beginMacro()/endMacro() 决定复合操作的粒度。
RHI(渲染硬件接口) Qt 6 的渲染抽象层,能在 OpenGL、Vulkan、Metal、Direct3D 之间切换。它把渲染资源、管线、命令缓冲抽象成统一接口,适合写跨平台的自绘视口;代价是要理解不同后端的限制。
SIMD(单指令多数据) 一条指令同时处理多个数据,常用于数据抽稀、向量运算、图像处理。编译器自动向量化能覆盖一部分场景,关键路径必要时用 intrinsics 或专用库,但要先测量再优化。
撤销重做(Undo/Redo) 见“QUndoStack”。工业软件里撤销不是锦上添花,而是编辑可信度的基础;撤销粒度、合并规则、脚本发起的修改是否进入撤销栈,都要在架构阶段定清楚。
半透明排序 渲染透明物体时,需要按相机距离从远到近排序,否则颜色混合会出错。大场景里的透明排序开销很高,常见做法是限制透明层数、用深度剥离或按区域排序。
参数化(Parametric) 用参数和约束描述模型,而不是直接描述几何。改参数后重新求值,得到新模型;核心是重算图和约束求解器。参数化 CAD 的难点不在界面,而在依赖追踪和失败恢复。
场景图(Scene Graph) 组织三维对象的树形结构,节点带变换矩阵,遍历时逐层累积。渲染器据此做剔除、排序、绘制。Coin3D、OSG、VTK 都有自己的场景图模型。
抽稀(Decimation) 在保留视觉特征的前提下减少数据点。图表里常用 min/max 抽稀:每个像素列只保留最小值和最大值;点云和网格里则是顶点合并或边折叠。
单元(Cell) 网格中的基本离散单位,二维是三角形或四边形,三维是四面体或六面体。有限元求解在单元上做积分,单元质量直接影响求解精度和稳定性。
导出(Export) 把内部数据写成外部格式。工业软件里导出不是“另存为”这么简单:单位、坐标系、颜色、图层、精度、版本都要明确,导出的文件要能被目标工具重新打开。
二进制兼容(Binary Compatibility) 见“ABI”。插件、动态库、脚本绑定都受它约束;C++ 里保持二进制兼容通常意味着不能加虚函数、不能改成员布局、不能换标准库。
反模式(Anti-pattern) 看起来能解决问题、实际上会制造更多问题的做法。工业软件里常见的有上帝类、循环依赖、在界面里写业务、隐式全局状态、把配置写死在代码里。
派生数据(Derived Data) 由原始数据计算出来的数据,如网格、索引、缩略图、缓存。派生数据要能失效、重建,否则会变成不一致的缓存;版本一致性问题的根源多半在这里。
管线(Pipeline) 数据从源经过一串过滤器到渲染器的处理链。VTK 的核心抽象,也是 ParaView 的界面模型;每一步只关心输入和输出,组合方式决定了系统的扩展性。
光栅化(Rasterization) 把几何图元转换成像素的过程。工业软件里的线宽、抗锯齿、拾取精度都和光栅化规则有关;高 DPI 下要处理设备像素比,否则线会糊。
规约(Reduction) 把一组数据合并成更小的结果,例如求和、最大值、直方图。大规模数据统计常用并行规约,GPU 上的规约要注意线程同步和数值精度。
哈希(Hash) 把任意长度的数据映射成固定长度的值。工程文件校验、内容寻址、缓存键都用它;哈希冲突和稳定性(同一内容是否总是同一哈希)要按场景选择算法。
缓存友好(Cache-friendly) 让数据布局和访问顺序符合 CPU 缓存行与预取策略。连续内存、顺序访问、减少指针跳转通常比“算法复杂度”更能决定实际性能。
几何一致性(Geometric Consistency) 同一个零件在建模、网格、结果、图纸里能对应回同一个实体。改一个倒角就要重新对结果,说明几何一致性没有建模好。
插件(Plugin)
在运行时加载的扩展模块。Qt 用 QPluginLoader 加接口实现,难点在二进制兼容、版本化、生命周期和权限边界,而不是加载本身。
事务(Transaction) 把一组修改打包,要么全部生效,要么全部回滚。数据库、撤销栈、工程文件保存都用事务思想;区别在于失败后的恢复粒度和持久化时机。
视图(View) 数据和界面的中间层。Qt 的 Model/View 把数据、选择、委托拆开,工业软件里的模型树、属性面板、结果表格都受益于这套抽象。
拾取(Picking) 把鼠标位置映射回场景中的对象或几何元素。拾取要考虑遮挡、容差、透明、实例化、GPU 回读;大场景里拾取性能往往比渲染更容易成为瓶颈。
世界坐标 / 局部坐标 世界坐标是场景的统一参考系,局部坐标是对象自身的参考系。变换矩阵把局部坐标映射到世界坐标;装配、嵌套、父子关系都靠这套变换链。
序列化(Serialization) 把对象状态写成字节流或文本,以便保存和传输。工业软件的序列化要考虑版本、向后兼容、字段默认值、引用关系和损坏恢复。
依赖注入(Dependency Injection) 不在模块内部 new 依赖,而是由外部传入。CTK 的服务注册表是运行时版本;在 Qt 项目里,构造函数注入和上下文对象比全局单例更容易测试。
隐式共享(Implicit Sharing) Qt 容器和字符串的写时复制机制。复制很便宜,但一次非 const 访问就可能 detach 并深拷贝;热路径上要清楚哪些操作会触发 detach。
中间层(Intermediate Layer)
位于内核与界面之间的适配层,负责把内核的数据结构翻译成界面能用的模型。Mayo 的 io、occ 层就是这种角色;没有中间层,界面和内核会直接长在一起。
重算图(Recompute Graph) 参数化模型内部的有向无环图。节点是特征,边是依赖;修改一个参数,只有下游节点失效并重新计算。重算图的设计决定参数化 CAD 的可维护性。
坐标系变换(Transform) 平移、旋转、缩放的组合。工业软件里大量错误来自变换顺序、单位混用、父子变换叠加;把变换链显式化,比在代码里到处乘矩阵可靠。GIS、测量、机器人、仿真都有自己的坐标系,跨系统交换数据时,坐标系必须作为元数据一起传递。
最小可复现(Minimal Reproducible) 用最少的代码、数据和步骤复现一个问题。缺陷报告、性能回归、崩溃分析都适用;Agent 辅助开发时,先让它构造最小复现,往往比直接修代码更有效。