作者: 丁林松

邮箱: cnsilan@163.com

微信: @littleatendian

摘要: OpenCASCADE B-Rep建模是创建复杂CAD几何的核心技术,通过组合点、线、面构建精确的三维实体模型。本文档深入讲解从底层拓扑元素(Vertex/Edge/Wire/Face/Shell/Solid)逐步构建B-Rep模型的完整流程,详解扫掠建模(拉伸Prism/旋转Revolve/扫略Pipe)、放样建模(ThruSections)、倒角圆角(Fillet/Chamfer)等高级建模技术。提供丰富的实战案例展示如何创建机械零件(齿轮、螺纹、法兰)、建筑构件、复杂曲面,掌握NURBS曲线曲面建模、拓扑检查与修复、性能优化技巧,为开发专业CAD软件提供完整的技术方案。

目录

1. B-Rep建模概述

B-Rep建模流程:

  • Step 1: 创建几何曲线/曲面(Geom_*)
  • Step 2: 从几何创建拓扑元素(TopoDS_*)
  • Step 3: 组合拓扑元素(Wire/Shell/Solid)
  • Step 4: 应用建模操作(拉伸/旋转/倒角等)

2. 基本形状创建

2.1 从点创建边和线框

#include 
#include 
#include 

// 创建矩形线框
TopoDS_Wire createRectangleWire(double width, double height) {
    gp_Pnt p1(0, 0, 0);
    gp_Pnt p2(width, 0, 0);
    gp_Pnt p3(width, height, 0);
    gp_Pnt p4(0, height, 0);
    
    TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
    TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(p2, p3).Edge();
    TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge(p3, p4).Edge();
    TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge(p4, p1).Edge();
    
    BRepBuilderAPI_MakeWire wireBuilder;
    wireBuilder.Add(e1);
    wireBuilder.Add(e2);
    wireBuilder.Add(e3);
    wireBuilder.Add(e4);
    
    return wireBuilder.Wire();
}

// 创建圆形线框
TopoDS_Wire createCircleWire(double radius) {
    gp_Ax2 axis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
    gp_Circ circle(axis, radius);
    
    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle).Edge();
    return BRepBuilderAPI_MakeWire(edge).Wire();
}

2.2 从线框创建面

#include 

// 平面面
TopoDS_Face face = BRepBuilderAPI_MakeFace(wire).Face();

// 带孔的面
TopoDS_Wire outerWire = createRectangleWire(100, 100);
TopoDS_Wire holeWire = createCircleWire(20);

BRepBuilderAPI_MakeFace faceBuilder(outerWire);
faceBuilder.Add(holeWire);  // 添加内环(孔)

TopoDS_Face faceWithHole = faceBuilder.Face();

3. 扫掠建模

3.1 拉伸(Prism)

#include 

// 拉伸面
TopoDS_Wire profileWire = createRectangleWire(10, 20);
TopoDS_Face profile = BRepBuilderAPI_MakeFace(profileWire).Face();

gp_Vec extrusionVector(0, 0, 30);
TopoDS_Shape extruded = BRepPrimAPI_MakePrism(profile, extrusionVector).Shape();

// 拉伸曲线生成曲面
TopoDS_Edge curveEdge = ...;
TopoDS_Shape surface = BRepPrimAPI_MakePrism(curveEdge, extrusionVector).Shape();

3.2 旋转(Revolve)

#include 

// 旋转面生成实体
TopoDS_Wire profileWire = ...;  // 截面轮廓
TopoDS_Face profile = BRepBuilderAPI_MakeFace(profileWire).Face();

gp_Ax1 axis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));  // 旋转轴
double angle = 2 * M_PI;  // 360度

TopoDS_Shape revolved = BRepPrimAPI_MakeRevol(profile, axis, angle).Shape();

// 创建花瓶
TopoDS_Shape createVase(double baseRadius, double topRadius, double height) {
    // 创建轮廓曲线(贝塞尔曲线)
    TColgp_Array1OfPnt poles(1, 4);
    poles(1) = gp_Pnt(baseRadius, 0, 0);
    poles(2) = gp_Pnt(baseRadius * 1.2, 0, height * 0.3);
    poles(3) = gp_Pnt(topRadius * 0.8, 0, height * 0.7);
    poles(4) = gp_Pnt(topRadius, 0, height);
    
    Handle(Geom_BezierCurve) curve = new Geom_BezierCurve(poles);
    TopoDS_Edge profileEdge = BRepBuilderAPI_MakeEdge(curve).Edge();
    
    gp_Ax1 axis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
    return BRepPrimAPI_MakeRevol(profileEdge, axis).Shape();
}

3.3 扫略(Pipe)

#include 

// 沿路径扫略
TopoDS_Wire profileWire = createCircleWire(2.0);  // 截面
TopoDS_Face profile = BRepBuilderAPI_MakeFace(profileWire).Face();

// 创建路径(螺旋线)
TopoDS_Wire pathWire = createHelixWire(5.0, 10.0, 50.0);  // 半径、螺距、高度

TopoDS_Shape pipe = BRepOffsetAPI_MakePipe(pathWire, profile).Shape();

// 创建螺旋线
TopoDS_Wire createHelixWire(double radius, double pitch, double height) {
    int numTurns = static_cast(height / pitch);
    double thetaStep = 0.1;
    
    TColgp_Array1OfPnt points(1, numTurns * 100);
    int idx = 1;
    
    for (double t = 0; t < numTurns * 2 * M_PI; t += thetaStep) {
        double x = radius * std::cos(t);
        double y = radius * std::sin(t);
        double z = (t / (2 * M_PI)) * pitch;
        points(idx++) = gp_Pnt(x, y, z);
    }
    
    // 创建B样条曲线
    // ... 实现略
    
    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve).Edge();
    return BRepBuilderAPI_MakeWire(edge).Wire();
}

4. 放样建模

#include 

// 通过多个截面放样
TopoDS_Shape createLoftedShape() {
    // 创建多个截面
    TopoDS_Wire section1 = createCircleWire(10.0);
    
    gp_Trsf trsf2;
    trsf2.SetTranslation(gp_Vec(0, 0, 20));
    TopoDS_Wire section2 = TopoDS::Wire(
        BRepBuilderAPI_Transform(createCircleWire(15.0), trsf2).Shape());
    
    gp_Trsf trsf3;
    trsf3.SetTranslation(gp_Vec(0, 0, 40));
    TopoDS_Wire section3 = TopoDS::Wire(
        BRepBuilderAPI_Transform(createCircleWire(8.0), trsf3).Shape());
    
    // 放样
    BRepOffsetAPI_ThruSections loft(Standard_True);  // True=创建实体
    loft.AddWire(section1);
    loft.AddWire(section2);
    loft.AddWire(section3);
    loft.Build();
    
    return loft.Shape();
}

5. 倒角与圆角

#include 
#include 

// 圆角
TopoDS_Shape addFillets(const TopoDS_Shape& shape, double radius) {
    BRepFilletAPI_MakeFillet fillet(shape);
    
    // 对所有边添加圆角
    for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) {
        TopoDS_Edge edge = TopoDS::Edge(exp.Current());
        fillet.Add(radius, edge);
    }
    
    fillet.Build();
    return fillet.Shape();
}

// 倒角
TopoDS_Shape addChamfers(const TopoDS_Shape& shape, double distance) {
    BRepFilletAPI_MakeChamfer chamfer(shape);
    
    for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) {
        TopoDS_Edge edge = TopoDS::Edge(exp.Current());
        
        // 获取边相邻的面
        TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFaces;
        TopExp::MapShapesAndAncestors(shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFaces);
        
        const TopTools_ListOfShape& faces = mapEdgeFaces.FindFromKey(edge);
        if (faces.Extent() == 2) {
            TopoDS_Face face = TopoDS::Face(faces.First());
            chamfer.Add(distance, distance, edge, face);
        }
    }
    
    chamfer.Build();
    return chamfer.Shape();
}

6. 装配建模

#include 
#include 
#include 

// 创建装配体
TopoDS_Compound createAssembly() {
    TopoDS_Compound assembly;
    BRep_Builder builder;
    builder.MakeCompound(assembly);
    
    // Part 1: 底座
    TopoDS_Shape base = BRepPrimAPI_MakeBox(100, 100, 10).Shape();
    builder.Add(assembly, base);
    
    // Part 2: 圆柱(平移)
    TopoDS_Shape cylinder = BRepPrimAPI_MakeCylinder(20, 50).Shape();
    
    gp_Trsf transform;
    transform.SetTranslation(gp_Vec(50, 50, 10));
    TopoDS_Shape transformedCylinder = 
        BRepBuilderAPI_Transform(cylinder, transform).Shape();
    
    builder.Add(assembly, transformedCylinder);
    
    // Part 3: 球体(平移+旋转)
    TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(15).Shape();
    
    gp_Trsf transform2;
    transform2.SetTranslation(gp_Vec(50, 50, 60));
    TopoDS_Shape transformedSphere = 
        BRepBuilderAPI_Transform(sphere, transform2).Shape();
    
    builder.Add(assembly, transformedSphere);
    
    return assembly;
}

7. 拓扑检查与修复

#include 
#include 

// 检查形状有效性
bool validateShape(const TopoDS_Shape& shape) {
    BRepCheck_Analyzer analyzer(shape);
    
    if (!analyzer.IsValid()) {
        std::cout << "Shape is invalid!" << std::endl;
        
        // 详细诊断
        for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {
            TopoDS_Face face = TopoDS::Face(exp.Current());
            
            const Handle(BRepCheck_Result)& result = analyzer.Result(face);
            if (!result.IsNull()) {
                const BRepCheck_ListOfStatus& status = result->Status();
                // 打印错误状态
            }
        }
        
        return false;
    }
    
    return true;
}

// 修复形状
TopoDS_Shape repairShape(const TopoDS_Shape& shape) {
    Handle(ShapeFix_Shape) fixer = new ShapeFix_Shape(shape);
    
    fixer->Perform();
    
    return fixer->Shape();
}

8. 实战案例集锦

案例1:齿轮建模
TopoDS_Shape createGear(double outerRadius, double innerRadius, 
                        int numTeeth, double toothHeight, double thickness) {
    // 创建齿轮轮廓
    BRepBuilderAPI_MakeWire wireBuilder;
    
    double angleStep = 2 * M_PI / numTeeth;
    
    for (int i = 0; i < numTeeth; i++) {
        double angle1 = i * angleStep;
        double angle2 = (i + 0.4) * angleStep;
        double angle3 = (i + 0.6) * angleStep;
        double angle4 = (i + 1) * angleStep;
        
        // 齿根圆弧
        gp_Pnt p1(outerRadius * std::cos(angle1), 
                  outerRadius * std::sin(angle1), 0);
        gp_Pnt p2(outerRadius * std::cos(angle2), 
                  outerRadius * std::sin(angle2), 0);
        
        // 齿顶
        gp_Pnt p3((outerRadius + toothHeight) * std::cos(angle2 + 0.05), 
                  (outerRadius + toothHeight) * std::sin(angle2 + 0.05), 0);
        gp_Pnt p4((outerRadius + toothHeight) * std::cos(angle3 - 0.05), 
                  (outerRadius + toothHeight) * std::sin(angle3 - 0.05), 0);
        
        gp_Pnt p5(outerRadius * std::cos(angle3), 
                  outerRadius * std::sin(angle3), 0);
        
        wireBuilder.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge());
        wireBuilder.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge());
        wireBuilder.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge());
        wireBuilder.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge());
    }
    
    TopoDS_Wire gearProfile = wireBuilder.Wire();
    TopoDS_Face gearFace = BRepBuilderAPI_MakeFace(gearProfile).Face();
    
    // 减去中心孔
    TopoDS_Wire holeWire = createCircleWire(innerRadius);
    BRepBuilderAPI_MakeFace faceBuilder(gearFace);
    faceBuilder.Add(holeWire);
    gearFace = faceBuilder.Face();
    
    // 拉伸
    gp_Vec extrusionVec(0, 0, thickness);
    return BRepPrimAPI_MakePrism(gearFace, extrusionVec).Shape();
}
案例2:法兰建模
TopoDS_Shape createFlange(double diameter, double holeDiameter, 
                          double boltCircleDiameter, int numBolts,
                          double boltHoleDiameter, double thickness) {
    // 主体圆盘
    gp_Ax2 axis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
    TopoDS_Shape disk = BRepPrimAPI_MakeCylinder(axis, diameter/2, thickness).Shape();
    
    // 中心孔
    TopoDS_Shape centerHole = BRepPrimAPI_MakeCylinder(
        axis, holeDiameter/2, thickness).Shape();
    disk = BRepAlgoAPI_Cut(disk, centerHole).Shape();
    
    // 螺栓孔
    for (int i = 0; i < numBolts; i++) {
        double angle = i * 2 * M_PI / numBolts;
        double x = (boltCircleDiameter/2) * std::cos(angle);
        double y = (boltCircleDiameter/2) * std::sin(angle);
        
        gp_Ax2 boltAxis(gp_Pnt(x, y, 0), gp_Dir(0, 0, 1));
        TopoDS_Shape boltHole = BRepPrimAPI_MakeCylinder(
            boltAxis, boltHoleDiameter/2, thickness).Shape();
        
        disk = BRepAlgoAPI_Cut(disk, boltHole).Shape();
    }
    
    // 倒圆角
    return addFillets(disk, 2.0);
}

9. 总结与最佳实践

B-Rep建模核心要点

建模流程
  1. 设计截面轮廓(Wire)
  2. 选择建模操作(拉伸/旋转/放样)
  3. 应用布尔运算(并/交/差)
  4. 添加细节(倒角/圆角)
  5. 验证拓扑有效性
常见陷阱
  • 线框未闭合: 检查边连接性
  • 法向量方向: 确保外法向一致
  • 容差问题: 使用Precision::Confusion()
  • 性能优化: 避免过度细化、使用BRepMesh
高级技巧
  • 使用BRepBuilderAPI_Sewing缝合多个面
  • 使用ShapeUpgrade分割复杂曲面
  • 使用BRepExtrema计算形状间距离

— 本文完 —
B-Rep建模是CAD的核心,掌握OCC就掌握了专业建模的钥匙!

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐