Skip to content

修复抽壳厚度等于圆角半径时的退化构造失败 #174

Description

@vilicvane

向内抽壳厚度恰好等于圆角半径时,合法的长方柱通孔模型仍无法构造。最小复现(采用 #173 修正后的稳定面 ID):

box(50, 3000, 100)
  .fillet(5, [2, 4, 6, 8])
  .shell(5, [3, 4]);

Could not construct shell with thickness 5 and S3, S4 / OpenCascade error (Standard_ConstructionError)#173 已独立修复圆角后的拓扑 ID,开口面选择正确仍可复现本问题。#37 已完成的抽壳功能中记录的是另一类弯曲 loft 开口未形成内壁的限制,未覆盖此次圆角半径临界情况。

当前调查结论:

  • 长度改为 50 或保持 3000 均可复现;无圆角的同尺寸模型可正常抽壳。已测圆角半径 4、5、6 时,向内厚度等于对应半径均失败。两端开口情况下,厚度略小于半径可成功;大于半径时默认 native 参数可能给出无效形状,Core 正确拒绝。
  • 源码线索是圆柱内偏移后的半径降至零:OCCT 将其标为 BRepOffset_Degenerated。这解释了该尺寸边界的退化条件,尚不能单凭此断言异常的最终抛出位置;继续追踪退化后面的移除与相邻内壁重建。OCCT V8_0_1 BRepOffset.cxx
  • 直接测试 MakeThickSolidByJoin 的 Arc/Intersection join、intersection 开/关、RemoveIntEdges 开/关:8 种组合在 R = t = 5 时均未成功。t = 5.1 配合 intersection=true 可得到有效的 14 面实体,但这不解决 t = 5 的临界情形,也尚未确定应更改默认参数。

此特定例子已验证可用的等价建模顺序:

box(50, 3000, 100)
  .shell(5, [3, 4])
  .fillet(5, [2, 4, 6, 8]);

结果有效、14 面,体积 4135619.4490192346,与解析值 (50 * 100 - (4 - Math.PI) * 25 - 40 * 90) * 3000 一致。

进一步与独立构建的 roundedOuter.cut(box(40, 3000, 90)) 比较:两者均有效,体积同为 4135619.4490192346,bounds 均为 [[-25, -1500, -50], [25, 1500, 50]],4 个圆柱面的半径均为 5。双向 native boolean 差集均 IsDone=true、体积 0、面数 0,验证了该 R = t = 5 个例的几何等价性,而不只是体积相同。

等价性仅针对当前 R = t、两端开口的长方柱几何,不能推广为任意 fillet/shell 可以交换。不会自动换序,也不会偷偷将厚度改为 4.999;已定位触发条件并验证可靠建模绕过方法,不代表内核直接处理退化面的失败已修复。

需求已确认,修复方案尚未确定。当前方向是继续定位内核对退化圆角面的处理及后续失败点,评估精确删除退化面、重建相邻内壁的可行性;未承诺采用某一算法或将此类退化纳入通用 shell 支持。应保留有效性/实际内壁检查、不可变输入、拓扑身份与缓存生命周期约束。

相关上游记录(以下关联尚不证明同一根因或存在可直接使用的修复):

  • FreeCAD #21472 最接近当前尺寸边界:OCC 7.8.1、原生 Linux 环境中,圆角 R = 1、抽壳 t = 1 时 fillet → thickness 失败,t = 0.99 或 thickness → fillet 可成功。该 issue 于 2025-10-13 关闭,但末次讨论建议将处理顺序问题和圆角后抽壳失败分开另报,没有列出这个零半径个例的修复。
  • FreeCAD #24132 当前打开,带 Confirmed 和 3rd party: OCC 标签,收录圆角、圆锥、球面等 thickness 失败;属于相关案例,几何和触发条件并非完全相同。
  • OCCT 历史工单 #0025220 报告圆角矩形使用 BRepFill_OffsetWire 内缩 5 时圆弧半径约 1e-15 导致失败,内缩 5.01 可成功。工单标为已于 7.1.0 修复,2016 年评论说明 master 不再复现并补充测试。它处理的是二维 wire offset,不能等同于当前三维 MakeThickSolidByJoin 的修复。
  • OCCT PR #301 于 2025-01-28 合并:BRepOffset_Tool::TryProject 在曲线为空且无法 BuildCurve3d 时,由返回失败改为继续遍历,跳过退化曲线。已核对 V8_0_1 中存在相同处理,不能通过重复回补该补丁解决当前复现。
  • FreeCAD #5829 是需要排除的归因线索:它曾长期标为上游 OCC 问题,但由 2026-09-01 合并的 FreeCAD PR #32322 修复,原因是传给内核的局部/全局坐标处理错误,属于 FreeCAD 封装侧。不能把所有类似 thickness 失败归因于 OCCT;当前 Code3D 最小复现并不经过 FreeCAD。
  • CadQuery #963 / #1399 涉及 shell/fillet 生成无效形状后以 Shape.fix() 修复。当前 R = t 个例在 builder 生成阶段就失败,不能直接套用生成后修复。

这些公开报告说明类似圆角与抽壳组合问题也出现在原生环境,并非只有 WASM 出现;尚未证明当前 OCCT 8.0.1 复现与其中某个报告同根因。后续仍需独立原生复现或调用栈定位。仅整理既有资料,未向上游提交 issue 或评论。

执行会话 model-perf-root-0913,沿用分支 issue-167-model-perf-root-0913 和开发入口 http://localhost:5179/#173 的提交 67228dd 已合并、推送并关闭,已核实包含于远端 main 127ff40725dfe61a22f93c1d754e55a138a925e1;本问题仍独立调查中,用户原私有模型文件未修改。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstatus:in-progressImplementation is in progress

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions