Technical note
区域化修复事务
记录区域化 CAD/CAE 模型修复的一条工程主线:如何从问题聚类、区域分析、真实预览走到可验证、可回滚的局部提交事务。
背景:修复的基本单位不应该永远是一条 Issue
前两篇分别讨论了特征边提取和特征边约束构面。
这些能力可以生成独立 Edge,也可以生成一张新的候选 Face。
但在真实模型修复里,新的几何对象最终还要回答一个更难的问题:
它应该替换原模型中的哪一片区域?
传统检测结果通常是一组平铺的 Issue。
例如:
FaceGap;
FreeEdge;
SmallEdge;
SlenderFace;
SelfIntersection;
MissingPCurve;
MeshConformityRisk。
但一处真实缺陷往往会同时产生多条 Issue。
例如一个局部开口,可能同时表现为:
两条 FreeEdge;
一个 FaceGap;
若干边表示风险;
一张狭长面;
一次表面网格失败。
如果界面和修复策略仍然逐条处理,用户需要自己判断这些问题是否属于同一原因,系统也可能对同一区域重复生成多个互相冲突的候选。
所以区域化修复的基本思路是:
Issue 是检测证据;
Region 才是分析、预览和修复的工作单元。
这不是简单把邻近问题合并成一行,而是建立一条从问题聚类、范围约束、专项分析、真实预览到原子提交的完整链路。
区域化修复要解决什么
区域化修复的价值,不是让所有问题都自动修。
它真正想回答的是:
哪里可以改;
哪里只能参与计算;
哪里必须保持;
当前证据是否足够;
哪种策略适合这个区域;
生成的候选是否真的改善了目标问题;
什么条件下必须拒绝提交。
这几个问题比“调用哪个修复函数”更重要。
因为 CAD/CAE 模型修复的风险,往往不是算法没有输出,而是输出结果的影响范围和语义不清楚。
一个局部修复如果改动了区域外 face,或者让原本保留的边界条件失去映射,即使几何上看起来有效,也不能直接认为成功。
所以区域化修复需要把构区、分析、执行、预览、验证和提交拆成不同阶段。
任何一个阶段成功,都不能默认放开后一个阶段。
从 Issue 到 Region
区域构建的输入是当前 baseline root shape 和正式检测得到的问题列表。
它的输出应该是稳定到当前 baseline 的区域证据。
这里有一个重要边界:构区阶段不应该修改 shape。
如果一边分析问题一边修改模型,后面的 face index、edge index、邻接关系和问题引用会立即失效,区域证据也无法复现。
因此 RegionBuilder 更适合作为只读过程:
读取问题;
建立问题之间的拓扑或几何关系;
把相关问题聚成区域;
输出区域证据;
不生成修复几何;
不提交模型变更。
区域也不能只靠空间距离聚类。
同一张面上可能同时存在自由边和小边,但它们的修复目标不同:
FreeEdge 关注开口和边界闭合;
SmallEdge 关注局部小特征和网格尺度。
如果把它们强行合成一个 Region,后续 Analyzer 很难判断应该优先 Sewing、补面、去特征还是只做诊断。
所以更稳妥的做法是按问题族分组,再在同族内部根据拓扑关系和保守几何关系聚类。
区域化不是简单的“空间聚类”,而是带问题语义的聚类。
一个 Region 不只是 face 列表
区域构建完成以后,最重要的不是得到一组 face,而是区分几种角色。
Core:问题直接发生的位置
Core 由问题直接引用的面、边、点,以及必要的 owner faces 构成。
它回答:
这次修复真正针对哪里?
例如:
FreeEdge 对应的缺陷边和 owner face;
SelfIntersection 的两张关联面;
DuplicateFace 的整组重复面;
NonManifoldEdge 及其全部 owner faces;
MeshConformityRisk 的问题面和障碍面。
Influence:允许算法调整的缓冲邻域
局部算法通常不能只看 Core。
修复一条边需要知道周围面;替换一张面需要知道与外部相接的边界;重裁剪需要相邻边和支撑面信息。
因此系统需要从 Core 向外扩展有限邻域,形成 Influence。
Influence 回答:
算法为了完成局部重建,可以在哪些邻域内调整?
Anchor:局部结果与保留模型的接口
选中邻域和区域外拓扑之间的交界 Edge 可以作为 Anchor。
Anchor 回答:
局部候选重新装回 root shape 时,哪些接口必须保持?
Anchor 不只是视觉边界,还应该参与执行门禁。
如果修复候选切断 Anchor,或者无法唯一保留包含 Anchor 的面片,执行器就不应该自动提交。
Preserve:区域外必须保持的模型
Preserve 是 Core 和 Influence 以外的 baseline face。
它回答:
哪些面不应该因为这次局部修复而改变身份?
这几个角色的意义在于把“参与分析、允许修改、必须保持、完全不参与修改”的对象分开。
如果这些角色混在一起,局部修复就很容易越界。
特征边也可以是区域边界
区域从 Core 向外扩展时,不能无限沿面邻接传播。
当前停止条件可以包括:
达到 Influence ring 上限;
达到区域最大 face 数;
遇到 root 边界;
遇到特征边;
遇到无法可靠判断的连续性。
这里的特征边和前两篇文章正好呼应。
在特征提取里,特征边可以作为构面的 Boundary、Guide 或 Crease。
在区域构建里,特征边也可以作为 Influence 扩张的阻断边界,避免修复范围跨过明显设计分区。
例如一条锐边两侧可能属于不同功能面。局部修复不应该因为拓扑邻接就自动跨过去。
当然,局部二面角只能提供几何证据。
它不能自动推断材料分区、用户命名、边界条件或工程语义。这些更高层的保护关系仍然需要产品宿主提供。
区域可定位,不等于可自动修复
区域构建完成,只说明系统知道问题大致在哪里。
它不代表这个区域一定可以自动修。
所以 Analyzer 和 Executor 必须分开。
Analyzer 回答:
从当前证据看,这个区域可能适合哪些策略?
证据是否完整?
风险在哪里?
为什么某些策略被拒绝?
Executor 回答:
当前是否已经具备真实几何预览;
是否有完整验收;
是否有可回滚事务;
是否可以提交。
一个策略在几何上“可能适用”,不代表执行器已经完成。
例如某个一般曲面缝隙可能适合重新求交和 trim,但如果当前只实现了更保守的平面场景,就必须保持只分析或只建议,不能因为 Analyzer 给出了方向就开放 Apply。
这是区域化框架里很关键的一条安全边界:
适用性判断,不等于执行能力。
真实预览必须是不可变候选
很多交互式几何命令的预览只是高亮影响范围,用户确认后再重新执行一次算法。
对高风险区域修复来说,这种做法不够可靠。
几何算法可能受输入顺序、容差、底层求交状态、当前 baseline 或缓存影响。如果预览和 Apply 分别计算,用户确认的结果不一定是最终提交的结果。
因此更稳妥的做法是 Prepared Transaction:
Executor 生成真实 candidate shape;
完整验证 candidate;
保存 baseline shape 和 signature;
保存 preview result shape 和 signature;
保存 topology history;
保存 validation report;
状态标记为 Prepared。
Apply 时不重新运行几何修复,而是直接提交预览中的 result shape。
这样用户确认的,就是最终提交的那一份几何。
这不是形式问题,而是交互可信度问题。
如果预览和提交不是同一份结果,用户看到的“影响范围”和最终真正改动的模型就可能不一致。
陈旧结果必须拒绝
Prepared Transaction 绑定当前 baseline。
如果用户预览后又修改了模型,旧预览不能继续 Apply。
提交前系统至少应该重新确认:
当前 baseline 是否仍然匹配;
Region 证据是否仍然有效;
分析选项是否变化;
预览结果是否仍然可提交。
如果基线变化,事务应该被标记为陈旧并拒绝提交。
这不是为了追求绝对哈希安全,而是建立一个明确门禁:
预览对应的模型已经变了,
就必须重新构区、分析和预览。
否则旧候选可能被提交到一个新的 root shape 上,导致拓扑引用、属性迁移、显示映射全部失效。
区域修复怎样做验收
一个区域候选要被接受,至少需要通过几层门禁。
基础 B-Rep 门禁
结果 shape 非空;
BRep 检查有效;
root 容器类型保持;
没有异常丢失 solid / shell。
目标问题门禁
选定区域的目标缺陷减少;
自相交数量下降;
目标缺陷边成为预期共享边;
不能只看算法是否返回 true。
自由边总数不是所有策略的唯一指标。
例如桥接重建可能用新的外侧连接边替换原缺陷边,所以还需要判断选定 defect edges 是否完成预期拓扑变化。
新增问题门禁
全局不新增自由边;
不新增非流形边;
不新增新的主阻断问题。
Anchor / Preserve 门禁
Core / Influence 外 face 身份保持;
Anchor 没有被意外切断;
局部结果与保留区接口一致。
几何变化门禁
表面积变化在可解释范围内;
体积变化在可解释范围内;
最大边界位移不超过允许范围。
表面网格门禁
局部候选通过 B-Rep 检查以后,还应该重新执行表面剖分,确认结果至少能生成有效显示或前处理表面网格。
这还不能等同于生产体网格验收,但比只看 B-Rep 有效更接近下游使用条件。
这些门禁共同回答一个问题:
这次局部修改是不是用一个问题换来了另一个问题?
如果不能证明结果更好,就不应该提交。
拓扑 History 为什么不能省
区域执行器可能产生很多拓扑变化:
Modified;
Split;
Merged;
Deleted;
Generated。
这些变化不能只用一个新 root shape 表达。
事务需要记录旧拓扑到新拓扑的映射,包括:
原始 shape;
一个或多个来源 shape;
一个或多个结果 shape;
变化类型;
是否删除。
这份 History 是上层迁移数据的基础。
例如:
材料属性;
边界条件;
端口和激励;
网格控制;
命名选择;
模型树节点;
显示与拾取引用。
如果只替换 root shape 而没有 History,上层无法判断原来的某张 face 对应新模型中的哪张或哪几张 face。
这也是局部修复和普通生成新 shape 的区别。
生成几何只是第一步。真正进入工程模型,还需要知道旧语义怎样迁移到新拓扑上。
属性迁移应该由宿主完成
修复库通常不拥有材料、边界条件和网格控制数据库。
因此它不能在内部自行决定:
Split 后属性复制给哪一张新面;
Merged 时多个来源属性冲突怎么处理;
Deleted face 上的端口是否允许消失;
Generated patch 应该继承哪个区域的属性。
这些属于产品宿主的业务语义。
修复库更适合输出 topology history 和事务回调契约,让宿主决定如何迁移。
如果属性迁移被要求但失败,几何提交也应该拒绝或回滚。
否则会出现一种很危险的中间状态:
几何已经替换成功;
但边界条件、材料或网格控制只迁移了一半。
在 CAE 软件里,这种结果比直接修复失败更难发现。
多对象事务必须原子提交
投影、压印、共形和多对象干涉,可能同时修改 tool 和 target。
这类操作不能依次提交每个对象:
Object A 提交成功;
Object B 验收失败;
系统留下半个结果。
更合理的是 prepared batch commit。
在真正提交之前,系统应该先检查:
所有 baseline 都没有变化;
所有 preview result 都仍然有效;
所有 prepared item 都处于可提交状态;
所有事务约束一致。
任何一个对象失败,整个 batch 都不应该返回部分结果。
这为未来的 tool-target 类区域执行提供必要基础。
但这类能力也要逐步开放,不能因为事务层具备批量概念,就直接把所有多对象修复都接入自动执行。
用户界面应该从 Issue 列表走向 Region 列表
区域化以后,用户看到的基本单位不应该永远是一条错误。
更合理的是一个危险区域。
每一行可以显示:
Region ID 和问题族;
风险等级;
是否阻断网格;
Core 面/边数量;
内部 Issue 数量;
证据是否完整;
推荐策略;
当前是仅分析、可预览还是可应用。
用户仍然可以展开区域查看原始 Issue,但不需要逐条选择同一缺陷产生的多条自由边或小边。
三维 Overlay 也应该表达区域结构:
Core:问题核心;
Influence:允许影响的邻域;
Anchor:局部结果接口;
Preserve:保持原模型颜色。
用户点击区域时,先看到“系统认为会影响哪一片”,再决定是否生成真实候选。
这比只高亮一条红边更符合区域修复的实际影响范围。
当前能力边界要说清楚
区域框架可以为多种问题族构区和显示 Overlay,但执行能力必须逐类开放。
有底层修复函数,不等于已经具备可商业提交的区域修复闭环。
两者之间还隔着:
专项分析;
真实预览;
Anchor / Preserve 门禁;
Topology History;
属性迁移回调;
局部和全局验收;
Prepared Transaction;
陈旧结果拒绝;
失败回滚。
因此文章和产品文案都应该区分:
有底层修复能力;
有区域化诊断能力;
有真实预览能力;
有可提交事务能力。
这几个成熟度不同,不能混在一起宣传。
当前更适合保守表达为:
部分开放边界类问题已经适合形成真实候选;
部分严格场景的自相交可以尝试保守闭环;
更多小特征、非流形、通用共形、复杂曲面 gap 和多对象干涉,仍应以区域化诊断和人工确认优先。
这种表述比列出内部执行器清单更适合公开发布。
测试更应该覆盖拒绝路径
区域化修复的测试,不应该只验证“能生成 shape”。
更重要的是验证拒绝路径和事务语义。
例如:
相邻问题能稳定聚类;
远距离问题不会误合并;
不同问题族不会因为共享拓扑被误合并;
特征边能阻止 Influence 扩张;
无法定位的问题不会被静默丢弃;
边匹配歧义时拒绝自动执行;
Anchor 被切断时拒绝提交;
预览后 baseline 改变时拒绝 Apply;
属性迁移失败时拒绝几何提交;
多对象 batch 不产生部分结果。
这些测试建立的是保守边界。
区域化修复最怕的不是“拒绝太多”,而是证据不足时仍然提交了一个不可解释的结果。
当前还缺什么
区域化闭环已经有了基础方向,但仍有几项关键工作需要继续推进。
第一,生产属性迁移。
修复库可以输出 topology history 和 callback 契约,但材料、边界条件、网格控制和命名选择迁移,仍需要产品宿主真正接入。
第二,生产体网格验收。
表面剖分门禁只能说明候选几何至少能被显示或表面离散。真正进入 CAE 流程,还需要接入生产网格器,验证体网格成功率、质量和单元规模。
第三,一般曲面区域重建。
严格平面场景不能直接泛化到平面—圆柱、圆柱—圆柱、自由曲面—自由曲面。不同支撑面组合需要分别解决交线唯一性、trim domain、PCurve 和连续性问题。
第四,更复杂的自相交。
开放交线、多段闭合交线、多孔面片、两面以上联动和近相切区域,仍需要新的保留侧规则与局部曲面重建策略。
第五,小特征和非流形专项执行器。
这些问题可以形成 Region 和 Overlay,但真正可提交,还需要各自的 Analyzer、Preview、Validation 和 Commit 闭环。
第六,跨版本持久命名。
当前 face/edge index 和 Region ID 更适合稳定于当前 baseline。复杂拓扑更新后的长期引用恢复,仍需要更强的持久命名和 history 机制。
这些未完成项不应该被隐藏。
把边界说清楚,反而更有利于后续持续迭代。
一个完整的用户流程
从用户角度,区域化修复最终应该表现为四步。
第一步,检测问题区域。
系统显示 Region,而不是铺满逐条 Issue。用户可以查看 Core、Influence、Anchor 和内部证据。
第二步,选择区域策略。
系统先排除证据不完整、边匹配歧义、Curve/PCurve 缺失或超出安全范围的策略,再显示推荐项和拒绝原因。
第三步,真实预览与应用。
Executor 生成并验收真实候选。只有 Prepared Transaction 通过全部门禁,Apply 才可用。
用户应用时提交的就是预览中的同一份结果。
第四步,区域修复复盘。
系统重新检测并显示:
目标问题前后数量;
剩余问题;
新增问题;
Anchor 和 Preserve 状态;
面积 / 体积变化;
表面或生产网格结果;
属性迁移结果;
下一步建议。
这个流程让用户看到的不再只是“修复成功”,而是这次修复为什么可以被接受。
和前两篇的关系
特征边提取、约束构面和区域化修复并不是三个孤立功能。
它们可以形成一条连续链路:
问题检测或用户选面
↓
提取 Boundary / Guide / Crease 特征曲线
↓
构造一个或多个候选 Face
↓
确定 Core / Influence / Anchor / Preserve
↓
专项执行器把候选 Face 或重裁剪结果装回 root
↓
验证目标问题、区域边界和全局模型
↓
Prepared Transaction
↓
属性迁移和原子提交
特征边在其中有两种作用:
作为几何约束,帮助重建曲面;
作为区域屏障,阻止修复范围跨过设计锐边。
构面工具负责生成候选几何。
区域事务负责证明候选可以安全进入原模型。
这两层不能混在一起。
小结
区域化修复不是把全局修复函数的输入从一个 root shape 换成几张 face。
它真正建立的是一套范围和责任边界:
Issue 提供原始检测证据;
Region 把同族问题组织成稳定区域;
Core 表达目标问题;
Influence 提供有限调整空间;
Anchor 定义局部结果的接口;
Preserve 保护区域外模型;
Analyzer 判断策略是否适用;
Executor 只开放已经完成真实几何闭环的策略;
Validation 证明结果没有用一个问题换来另一个问题;
Prepared Transaction 保证 Preview 和 Apply 是同一份结果;
Topology History 和属性回调保证上层语义可以原子迁移。
从用户角度看,它把“模型有很多条错误”变成“模型有几个危险区域,每个区域为什么危险、哪些策略可用、哪些策略被拒绝”。
从工程角度看,它把不可解释的 root shape 替换,收敛成可预览、可验证、可回滚的局部事务。
这也是区域化模型修复真正的价值:不仅减少修改范围,更重要的是让每一次修改都有明确边界,并且只有在证据、几何和事务都通过门禁以后才允许提交。