
1. 前言拓扑追踪机制一般会有两个层次的概念一种是某个操作前后新旧拓扑的映射另一种是标志的持久化一般会称之为“拓扑命名机制”这种要求模型存盘后还能恢复。occt没有持久化的id或者Handle的概念一般要想存盘后还能重新定位一般是要通过TNaming来自行给拓扑对象命名。实际上本专栏另一篇文件介绍基于XCAF文档实现属性读写的介绍中使用的就是此机制。本文关注的主要第一种概念一种瞬时、过程性的追踪当用户执行一个操作如布尔运算、倒角、拉伸切除时需要能力建立输入拓扑与输出拓扑之间的映射关系这是后续属性继承的基础。Parasolid接口中有tracking的概念ACIS中也有历史公告板的工具在occt中主要是BRepTools_History工具。下面会分别介绍三种内核获取拓扑映射的方法。2. Parasolid中的拓扑追踪映射Parasolid有一个全局变更记录机制一般称之为“BULLETIN”每当接口被调用内核会自动将这次修改拆解为一系列原子操作并记录到当前会话的 BULLETIN 日志中。TODO3. ACIS中的拓扑追踪映射acis的api接口可选一个DELTA_STATE参数内核会将模型从操作前状态变换到操作后状态所需的所有原子变更信息存入其中。TODO4. occt中的History机制occt中每个算法对象可以记录它的入参Shape和结果Shape之间的映射关系。在这套体系中它关注的是入参Shape在结果Shape中是否还存在、哪些与之关联有三个概念Modified、Generated 和 IsDeleted。4.1 映射状态分类Modified、Generated 、IsDeletedModified修改表示输入形状被替换或分割。它的几何或拓扑在操作中发生了变化但是维度一般不会改变。一个面被切割成多个子面那么子面与原面是Modified关系几何没变但是拓扑边界变了一个面被平移新面和原面也是Modified关系几何发生改变Generated生成表示从输入形状新生出拓扑元素。它的维度一般会发生改变。一个边在拉伸后生成一个面两个边相交生成一个顶点IsDeleted已删除表示输入形状在操作后被彻底移除没有直接对应的新形状留下。两个体重合的内部面在合并时被完全移除一个注意事项入参Shape可以既是Deleted又存在Generated映射对象。例如在一个复杂操作中一个边先拉伸了一个Face但是最后自身又被倒角删除了。此外任意的ShapeModified和Generated的结果不能相交。4.2 Reused状态occt的Shape/TShape是一个可高度复用的对象导致一个入参Shape可能完完整整的存在于结果Shape中。例如拉伸一个面所得棱柱的底面对象可能与入参Face完全相同两个TopoDS_Face对象满足IsEqual或者IsSame。我将这种称之为“Reused”。4.3 BRepTools_History工具很多occt的算法对象可以直接提供Modified/Generated/IsDeleted接口但为了统一简便用法提供了一个统一的BRepTools_History工具并且基于此提供了统一的Merge功能。4.3.1 构建提供模板构造函数要求算法对象存在Modified/Generated/IsDeleted接口。会从算法对象内部的History数据中读取入参theArguments其下所有Shape对象的映射信息。templateclassTheAlgoBRepTools_History(constNCollection_ListTopoDS_ShapetheArguments,TheAlgotheAlgo)可以主动往History中添加映射信息voidAddGenerated(constTopoDS_ShapetheInitial,constTopoDS_ShapetheGenerated)voidAddModified(constTopoDS_ShapetheInitial,constTopoDS_ShapetheModified)voidRemove(constTopoDS_ShapetheRemoved)voidReplaceGenerated(constTopoDS_ShapetheInitial,constTopoDS_ShapetheGenerated)voidReplaceModified(constTopoDS_ShapetheInitial,constTopoDS_ShapetheModified)4.2 合并将两段映射链 S→T 和 T→Q 合并为一段 S→Q。两个History的Merge操作就是将能去除的中间环节去除。一旦合并两个算法中间的Shape就不存在于History中了voidMerge(constocc::handleBRepTools_HistorytheHistory23)4.3.2 查询constNCollection_ListTopoDS_ShapeGenerated(constTopoDS_ShapetheInitial)constconstNCollection_ListTopoDS_ShapeModified(constTopoDS_ShapetheInitial)constboolIsRemoved(constTopoDS_ShapetheInitial)const