znlgis 博客

GIS开发与技术分享

第09章:局部操作 圆角 / 倒角 / 抽壳 / 偏置 / 扫掠 / 放样

布尔运算让我们能组合形体,但工业零件常常依赖“局部操作”塑造细节——圆角、倒角、抽壳、偏置、扫掠、放样、管道、特征。OCCT 把这些放在 BRepFilletAPIBRepOffsetAPIBRepFeatBRepFillChFi3dChFi2d 等工具包中。本章介绍它们的常用 API、关键参数与失败排查。

1. 圆角 BRepFilletAPI_MakeFillet

BRepFilletAPI_MakeFillet f(shape);
f.SetFilletShape(ChFi3d_Rational); // 或 Polynomial
f.Add(2.0, edge);
f.Add(1.5, otherEdge);
f.Build();
TopoDS_Shape r = f.Shape();

特性:

  • 可对多条边设置不同半径;
  • 支持变半径:Add(law, edge),传入 Law_Function
  • 自动处理交汇处的 setback,但复杂拓扑可能失败;
  • 支持 ChFi3d_Rational(NURBS 圆角,更精确)与 Polynomial(兼容性更好)。

失败排查:

  • 半径过大:相邻面无法承载圆角;
  • 边相邻面非 G1:先 BRepLib::EncodeRegularity 标注;
  • 退化或共线边:合并/重建;
  • f.Status(edge) 给出该边的处理状态码。

2. 倒角 BRepFilletAPI_MakeChamfer

BRepFilletAPI_MakeChamfer ch(shape);
ch.Add(1.0, 1.0, edge, face);   // 距离-距离倒角
ch.AddDA(2.0, M_PI/6, edge, face); // 距离-角度
ch.Build();

行为与圆角类似,参数区别在于使用直线截面替代圆弧。

3. 二维倒角与圆角 ChFi2d

ChFi2d_FilletAPIChFi2d_ChamferAPI 处理 2D 线框中的相邻边圆角/倒角,常用于薄壁/钣金的截面草图。

4. 抽壳 BRepOffsetAPI_MakeThickSolid

把实体掏空,保留厚度:

BRepOffsetAPI_MakeThickSolid mt;
TopTools_ListOfShape facesToRemove;
facesToRemove.Append(topFace);
mt.MakeThickSolidByJoin(shape, facesToRemove, /*offset=*/-2.0,
                        /*tolerance=*/1.e-3,
                        BRepOffset_Skin, false, false,
                        GeomAbs_Intersection, false);
TopoDS_Shape hollow = mt.Shape();

参数:

  • offset:负值向内偏置(产生壳腔),正值向外;
  • Skin/Pipe/RectoVerso:偏置模式;
  • Intersection/Arc/Tangent:相邻面交汇处理方式;
  • removeIntEdges:是否删除内部退化边。

5. 偏置 BRepOffsetAPI_MakeOffsetShape

更通用的体偏置:把整体外表面整体外推/内缩。

BRepOffsetAPI_MakeOffsetShape mo;
mo.PerformByJoin(shape, 1.0, 1.e-3, BRepOffset_Skin,
                 false, false, GeomAbs_Intersection, false);

BRepOffsetAPI_MakeOffset 则是 wire 偏置(2D / 3D 路径),用于钣金外轮廓、加工偏置:

BRepOffsetAPI_MakeOffset offsetW(wire, GeomAbs_Arc);
offsetW.Perform(2.0);

6. 拉伸与回转

虽属第 7 章基础体范畴,常与局部操作结合:

  • BRepPrimAPI_MakePrism(profile, vec):直线拉伸;
  • BRepPrimAPI_MakeRevol(profile, axis, angle):回转;
  • BRepFeat_MakePrism/MakeRevol/MakeDPrism/...:特征拉伸(与现有体合并)。

7. 扫掠 BRepOffsetAPI_MakePipe(Shell)

沿路径扫掠截面:

BRepOffsetAPI_MakePipe pipe(spineWire, profileShape);
TopoDS_Shape r = pipe.Shape();

更灵活的 BRepOffsetAPI_MakePipeShell

BRepOffsetAPI_MakePipeShell mps(spineWire);
mps.Add(profile1, /*WithContact=*/false, /*WithCorrection=*/false);
mps.Add(profile2);
mps.SetMode(true);   // Frenet 框架
mps.SetTransitionMode(BRepBuilderAPI_RoundCorner);
mps.Build();
mps.MakeSolid();

支持多个截面、不同过渡模式(Transformed/RightCorner/RoundCorner)、参考方向、扭转控制。

8. 放样 BRepOffsetAPI_ThruSections

将一系列截面 wire 用一组曲面连接:

BRepOffsetAPI_ThruSections lofter(/*solid*/true, /*ruled*/false, 1e-6);
lofter.AddWire(w1);
lofter.AddWire(w2);
lofter.AddWire(w3);
lofter.Build();

参数:

  • solid:是否封口形成实体;
  • ruled:直纹放样(每段是直线)vs 平滑放样(B 样条);
  • pres3d:精度。

放样要求各 wire 顺序、起点对齐。可用 BRepBuilderAPI_FindPlane 检查同面性,或在算法前重建顶点对齐。

9. 特征建模 BRepFeat

BRepFeat_* 提供基于现有体的特征:

  • BRepFeat_MakePrism:在现有面上做凸台/凹槽;
  • BRepFeat_MakeRevol:旋转特征;
  • BRepFeat_MakePipe:扫掠特征;
  • BRepFeat_MakeDPrism:草图凸台;
  • BRepFeat_Gluer:胶合两体;
  • BRepFeat_Builder:通用基础。

特征算法会自动找面/体并合并,比手动 Cut + Fuse 更精确(参数命名一致、保留面属性)。

10. 中轴与等距 MAT

BRepMAT2d 等用于钣金/抽壳的 2D 等距问题。复杂等距更适合用 OpenCASCADE 的 BRepOffset_MakeOffset 加上 MAT2d_Mat2d

11. 局部操作的“三大坑”

  1. 几何精度:相邻面非 G1、退化边、容差膨胀 → 使用 BRepLib::EncodeRegularityShapeFix_ShapeShapeUpgrade_UnifySameDomain 预处理。
  2. 拓扑歧义:抽壳/圆角依赖正确的“面对面”关系,自交、孤立面会导致失败;先 BRepCheck_Analyzer 检查。
  3. 历史信息:上层 UI 经常需要追踪“哪条边是哪个特征生成的”;及时调用 Modified/Generated,并保存到 OCAF 中。

12. 实战:圆角后再抽壳

TopoDS_Shape b = BRepPrimAPI_MakeBox(100, 80, 50).Shape();

BRepFilletAPI_MakeFillet f(b);
for (TopExp_Explorer ex(b, TopAbs_EDGE); ex.More(); ex.Next())
    f.Add(5.0, TopoDS::Edge(ex.Current()));
f.Build();
TopoDS_Shape rounded = f.Shape();

TopTools_ListOfShape rm;
for (TopExp_Explorer ex(rounded, TopAbs_FACE); ex.More(); ex.Next()) {
    Handle(Geom_Surface) s = BRep_Tool::Surface(TopoDS::Face(ex.Current()));
    if (Handle(Geom_Plane)::DownCast(s)) {
        // 仅去顶面:根据法向 z>0
        gp_Pln pln = Handle(Geom_Plane)::DownCast(s)->Pln();
        if (pln.Axis().Direction().Z() > 0.99) {
            rm.Append(ex.Current());
            break;
        }
    }
}

BRepOffsetAPI_MakeThickSolid mt;
mt.MakeThickSolidByJoin(rounded, rm, -2.0, 1e-3,
                        BRepOffset_Skin, false, false,
                        GeomAbs_Intersection, false);
TopoDS_Shape hollow = mt.Shape();

13. 调试与可视化

  • Draw:fillet f s 5 e1 e2 ...chamfer ch s ...tcopytcheck
  • Qt 应用:用 AIS_InteractiveContext::Display 在不同步骤可视化;
  • 性能:SetRunParallelBRepFilletAPI_MakeFillet 也提供并行选项);
  • 失败时打印 Status(edge)

完成局部操作之后,几何建模的主线已基本贯通。下一章我们将看 OCCT 如何把精确 B-Rep 转成可视化、可仿真、可打印的三角网格。