外观
04a 圆角(Fillet)Harness 技术侦察
目标:构建一个"生成 CAD 几何代码 → 沙箱执行 → 基于几何/拓扑反馈自我纠错"的 Agent,单点突破口 = FILLET。技术栈:FreeCAD + OpenCASCADE(OCCT) + Python Agent 层(LangChain/LlamaIndex) + pybind11/gRPC 桥接。
一句话结论
反馈信号源(圆角的 faulty-contour/vertex + ChFiDS_ErrorStatus)、scorers(BRepCheck_Analyzer/GProp/曲率)、桥接(pythonocc 或 pybind11+gRPC)、框架范式(CADSmith 双循环、build123d#1224 坏边探测)全部有现成件可复用;真正需要自研、也最有价值的是把 OCCT 底层圆角错误码翻译成可解释、可定向纠错的结构化反馈,外加稳健子进程沙箱和fillet 专项 benchmark——这三点目前业界空白,正契合你的 C++/几何强项。
1. OCCT 圆角内部机制与错误处理(核心:被测对象 + 反馈源)
官方 API 参考
BRepFilletAPI_MakeFillet(refman)——圆角主入口。关键错误/拓扑探测方法都在这里:IsDone()(整体成功)、HasResult()(是否有部分结果)、BadShape()(取带洞的部分结果)NbFaultyContours()/FaultyContour(I)(哪个轮廓失败)、NbFaultyVertices()/FaultyVertex(IV)(哪个顶点失败)StripeStatus(IC)(每轮廓详细错误码)、NbComputedSurfaces(IC)(成功算出的面数)- 继承自
BRepBuilderAPI_MakeShape的Generated()/Modified()/IsDeleted()(输入边/面→输出映射,做拓扑追踪)
StripeStatus返回的ChFiDS_ErrorStatus枚举(你纠错反馈的核心翻译表):ChFiDS_OkChFiDS_StartsolFailure(半径与几何不兼容,最常见"半径过大")ChFiDS_TwistedSurface(生成面自相交/扭曲)ChFiDS_WalkingFailure(行进算法失败)ChFiDS_Error(其他)- → 可映射成"半径太大请缩小 / 该边拓扑无法生成圆角 / 换边"等可读纠错提示。
ChFi3d_ChBuilder(refman)——圆角/倒角底层引擎。BRepFilletAPI_MakeFillet只是薄封装,真正的 walking / surface intersection / corner filling 在 ChFi3d 包。理解这层有助于判断"为何小半径成功、大半径失败"。- Modeling Algorithms 用户指南(含失败条件原文 "the algorithm may fail if the radius is not compatible with the geometry")
论坛故障案例(dev.opencascade.org)
- error control for BRepFilletAPI_MakeFillet——OCCT 开发者官方建议:
Add()不做即时校验,失败发生在Build();要么用 ShapeAnalysis 预筛掉 seam edge 等不可圆角边,要么 try/catch 捕获 "There are no suitable edges for chamfer or fillet" 的Standard_Failure。 - crash: StdFail_NotDone "BRep_API: command not done"——典型"调了
Shape()但IsDone()==false"崩溃,提醒必须先查IsDone()再取结果。 - MakeChamfer errors cannot be trapped with try/catch——关键陷阱:OCCT 内部 SIGSEGV/SIGFPE 不会自动变成 C++ 异常,普通 try/catch 抓不住,必须配
OCC_CATCH_SIGNALS。
FreeCAD 侧圆角故障实战帖(现成"负样本"灵感)
- OpenCascade Fillet Fiasco|bug 4543 crash on fillet/chamfer——FreeCAD 社区长期记录了哪些"几何 + 半径"组合会让 OCCT 圆角崩溃。
异常处理机制(务必读)
- Foundation Classes 用户指南|
Standard_Failure(refman)|Standard_ErrorHandler.hxx(refman) - 要点:① 每个 try 块第一行放
OCC_CATCH_SIGNALS宏;② 启动时调OSD::SetSignal()把 SIGSEGV/SIGFPE/SIGILL 转成Standard_Failure异常;③ Linux/MinGW 需用OCC_CONVERT_SIGNALS编译。这是让圆角崩溃"不杀沙箱进程、而变成可捕获反馈"的前提。强烈建议沙箱仍用子进程隔离兜底。
2. 几何有效性 / 评估工具(harness 的 "Scorers")
BRepCheck_Analyzer(refman)——IsValid()是 pass/fail 总闸;对每个 subshape 取BRepCheck_Result拿具体BRepCheck_Status(如BRepCheck_SelfIntersectingWire),精确定位坏边/坏面 → 结构化反馈。GProp_GProps+BRepGProp——BRepGProp::VolumeProperties()→Mass()(体积)/CentreOfMass()/PrincipalProperties()。做数值 scorer:比对圆角前后体积变化、重心漂移。- ShapeHealing(
ShapeFix/ShapeAnalysis/ShapeUpgrade)(wiki)——双重作用:(a) 圆角前用 ShapeAnalysis 识别 seam/退化边并过滤;(b) 圆角产生微小缝隙时用 ShapeFix 自动修,再喂回 Analyzer——修复本身也是一种纠错动作。 BRepMesh_IncrementalMesh+BRep_Tool::Triangulation()(博客)——把 B-Rep 转三角网,才能算 Chamfer Distance / IoU 这类与参考几何的相似度(Text2CAD/CAD-Coder 都用 Chamfer Distance 做主指标),也是导出给前端可视化的格式。BRepLProp_SLProps(法向、主曲率)——圆角面应是光滑过渡的连续曲率面,抽样曲率可验证"圆角半径是否真为 R"、法向是否朝外。细粒度几何 scorer。TopExp_Explorer——遍历TopAbs_EDGE/FACE/VERTEX统计数量(face/edge/vertex count 是核心拓扑指标),并把 §1 的FaultyContour/Vertex子形状定位回原模型。
3. FreeCAD 作为 OCC 调试/可视化前端
- FreeCAD 架构(DeepWiki|源码布局|中文模块开发指南)——
src/App(无 GUI,可 headless 跑几何)与src/Gui、src/Mod/Part(OCCT 封装层)边界清晰:可只用 App 层做批量沙箱评测,需要人看时再起 Gui。 Part::TopoShape(类参考|拓扑命名 DeepWiki)——FreeCAD 解决了"拓扑命名"问题(圆角后边/面引用如何保持稳定)。你的 harness 若要做"对第 3 条边圆角"这种语义引用,这是现成方案。- FreeCAD ↔ pythonocc 互转:
Part.__toPythonOCC__()/Part.__fromPythonOCC__()(Part API)——在 pythonocc 里跑完整 OCCT 圆角算法,再把结果塞回 FreeCAD 文档可视化,一行打通"计算 vs 展示"。 - OCCT 自带可视化/调试工具(更轻,不依赖 FreeCAD):Inspector(tinspector)(TopoDS_Shape 树视图 + 选中即 3D 显示)|Debugging tools and hints|DRAW Test Harness。DRAW + Inspector 本身就是"OCC debug visualizer",可脚本化(Tcl)批量重现圆角失败、可视化
BadShape()——比搭 FreeCAD 更适合自动化回归。Inspector 需BUILD_Inspector=ON。
4. 跨语言桥接
- pythonocc-core(GitHub|转换教程)——性价比最高的桥:
BRepFilletAPI_MakeFillet、BRepCheck_Analyzer、GProp_GProps几乎全已绑定,Python Agent 层直接调,MVP 阶段几乎不用写 C++。局限:SWIG 自动绑定,新 OCCT 版本跟进慢;Standard_Failure在 Python 侧表现为异常但信号类崩溃仍会杀进程(→ 子进程沙箱必需)。 - pyOCCT(GitHub)——pybind11 方案对照;若要自定义高性能 C++ 服务,它展示了用 pybind11 暴露 OCCT 类的成熟范式(含
TopoDS_Shape的 holder/转换写法)。 - pybind11 暴露
TopoDS_Shape——它是引用计数的轻量句柄,pybind11 用值语义py::class_包装即可,无需自定义 holder。 - 序列化 B-Rep / STEP:
BRepTools::Write/Read(.brep,OCCT 原生无损,进程间传形状最快)、STEPControl_Writer/Reader(.step,跨工具交换)。 - gRPC + Protobuf 几何服务(pybind11_protobuf)——推荐架构 "Python Agent ↔ gRPC ↔ C++ 几何服务进程",gRPC 进程隔离天然就是沙箱边界;圆角崩溃只杀 worker 不影响 Agent。Protobuf 里放
.brepbytes + 元数据(体积/有效性/faulty edge id 列表)。⚠️ 已知坑:grpc+pybind11 同进程加载可能崩(grpc#35947)——独立 worker 进程可规避。
5. 现有"LLM 写 CAD 代码 + 沙箱评测 + 自纠错"项目与基准(最值得抄)
按与目标接近度排序:
- ⭐ CADSmith(arXiv 2603.26512 · ✅ 2026-03 已开源 GitHub)——与你目标几乎同构:"CadQuery 代码生成 + 双循环自纠错"。内环靠 traceback 修代码错误,外环用 OCCT 内核精确测量(bounding box、体积、face/edge/vertex 数、solid validity、重心)+ VLM(Claude) 渲染三视图做 Judge,再由 Refiner 综合数值差异与视觉反馈改代码。五 Agent 分工(Planner/Coder/Executor/Validator/Refiner) + RAG over 155 条 API 文档。mean Chamfer 从 28.37 降到 0.74。直接照搬其反馈量设计你的 fillet scorer(注:repo 仅 ~20★、偏论文附带,工程化程度有限,可借思路自行重写)。
- cad-khana(GitHub)——diagnostics-first 的 build123d 封装(Claude Code skill),"Agent 写脚本→工具跑并写诊断→Agent 读诊断迭代",最接近你想要的工程骨架,可复用其 diagnostics 输出契约。
- CADDesigner(arXiv)——ReAct 式迭代 refine,提供 IoU/SUC 等几何保真度指标。
- Zero-to-CAD(arXiv)——"生成 CadQuery→执行→失败后查文档→修订到验证通过",示范"失败后 documentation lookup"——对应你把
StripeStatus错误码 + OCCT 文档喂回 LLM。 - ⭐ build123d issue #1224 —— "fillet fallback method that returns which edges fail"(issue)——直接命中你的单点突破:已有人实现"哪条边导致圆角失败"的探测原型——先整批
BRepFilletAPI_MakeFillet;失败则从NbFaultyContours()抽边;再对剩余边逐条用独立 builder 试探"静默失败"边;返回原 shape + 坏边 compound。⚠️ 已知局限:OCCT 顺序处理圆角,坏边依赖处理顺序,无法保证抓全。这正是你可改进/复用的现成代码。
数据集/基准:
- 📅 ⭐ MUSE(arXiv 2026-05)—— 近半年最该参考:首个面向"可制造/可装配/有功能"的 text-to-CAD 评测,code→geometry→design-intent 三级 check + VLM judge。你的 fillet harness 可对齐其评测层次。
- 📅 Self-Improving CAD + FEA(arXiv 2026-05)—— 把评测推进到 CalculiX 有限元物理校验;报告 SOTA agent 首轮仅满足约 20% 硬需求。
- 📅 Text2CAD-Bench(arXiv 2026-05)、CADExpert(arXiv 2025-12)、cadqueryeval(GitHub,Inspect-AI 横评)—— 可直接跑/借鉴。
- 老牌:Text-to-CadQuery(170k)|CAD-Coder/GenCAD-Code(163k 图-代码对)。
- ⚠️ 以上没有一个专门针对 FILLET 失败模式——fillet 专项 benchmark 仍是空白机会。
你能填的 gap
上述项目几乎全用 CadQuery/build123d 高层 API,把圆角当黑盒;没有人系统性地利用 OCCT 底层 StripeStatus/ChFiDS_ErrorStatus/FaultyContour/FaultyVertex 做细粒度、可解释的圆角失败诊断与定向纠错,也没有 fillet 专项 benchmark。这就是你 C++/几何背景的差异化突破口。
6. C++ API 文档 / 序列化工具链
- nlohmann/json(GitHub)——序列化 mesh/法向/scorer 结果最省事,
NLOHMANN_DEFINE_TYPE_INTRUSIVE宏一行加 (de)serialization,header-only。 - Protobuf(pybind11_protobuf)——跨语言/跨进程传几何元数据的强类型 schema。
- Doxygen + doxygen-awesome-css(GitHub|文档站)——给 C++ 几何服务生成 cppreference 风格、带暗色/移动端友好的现代 API 文档;纯 CSS 变量定制。OCCT 自身 refman 也是 Doxygen 生成,风格可对齐。便于团队查阅接口、复用技术知识并统一开发约定。
「可直接复用 vs 需自研」Gap 分析
✅ 可直接复用(拿来即用)
- OCCT 圆角错误探测全套:
IsDone/HasResult/BadShape/NbFaultyContours/FaultyContour/NbFaultyVertices/FaultyVertex/StripeStatus(ChFiDS_ErrorStatus) - scorers:
BRepCheck_Analyzer、BRepGProp+GProp_GProps、BRepMesh+BRep_Tool::Triangulation、BRepLProp_SLProps、TopExp_Explorer - 桥接:pythonocc-core 已绑定上述全部,MVP 几乎不写 C++;pyOCCT 提供 pybind11 范式
- 序列化:
BRepTools(.brep)、STEPControl_*(.step)、nlohmann/json、Protobuf - 框架灵感:CADSmith 双循环 + cad-khana diagnostics 契约 + build123d#1224 坏边探测原型 + FreeCAD
Part.__to/fromPythonOCC__与拓扑命名方案 - 文档/可视化:OCCT DRAW + Inspector + doxygen-awesome-css;你自己的
Print(OCC 3D 查看器)可直接当前端
🔨 需自研(你的差异化价值)
- Fillet 专项失败诊断器:把
StripeStatus→ChFiDS_ErrorStatus枚举 +FaultyContour/Vertex子形状 + 体积/曲率/有效性差异,融合成结构化、可解释、可定向纠错的反馈 schema —— 目前无人做。 - 稳健沙箱:OCCT 信号类崩溃无法靠 try/catch 完全兜住 → 子进程/gRPC worker 隔离 +
OSD::SetSignal()/OCC_CATCH_SIGNALS双保险 + 超时杀进程。 - Fillet benchmark:构造覆盖"半径过大 / 凹凸边 / seam 边 / 拓扑塌缩 / 自相交"的正负样本集。
- 拓扑稳定的边引用("对第 N 条边圆角"语义):参考 FreeCAD 拓扑命名,适配到你自己的 IR。
诚实声明(未充分核实项)
ChFiDS_ErrorStatus各枚举语义来自对 refman 的归纳,建议直接核对头文件ChFiDS_ErrorStatus.hxx确认枚举名拼写与全集。- CADSmith / Zero-to-CAD 的 arXiv 编号(2603.26512、2604.24479)日期偏新,引用前请确认页面有效、是否有正式 GitHub。
- doxygen-awesome-css 是否仍由 nlohmann/json 官方采用未逐一核实,但该主题本身活跃可用。
信息来源
OCCT 圆角/异常、scorers、FreeCAD、桥接、LLM-CAD 项目、文档工具链的全部 URL 均见正文行内。核心入口:OCCT refman|OCCT 论坛|FreeCAD 论坛|CADSmith|build123d#1224。