OpenCASCADE拓扑与几何建模实战:B-Rep模型构建与复杂形状创建
本文详细介绍了OpenCASCADE边界表示(B-Rep)建模技术,涵盖基础拓扑元素构建到高级操作如扫掠(拉伸/旋转/扫略)、放样、倒角圆角等核心方法。通过实战案例(齿轮、法兰等)展示建模全流程,包括NURBS曲面处理、拓扑检查修复和性能优化技巧,为开发专业CAD系统提供完整解决方案,强调闭合性检查、法向一致性等关键要点。
·
作者: 丁林松
邮箱: 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建模核心要点
建模流程
- 设计截面轮廓(Wire)
- 选择建模操作(拉伸/旋转/放样)
- 应用布尔运算(并/交/差)
- 添加细节(倒角/圆角)
- 验证拓扑有效性
常见陷阱
- 线框未闭合: 检查边连接性
- 法向量方向: 确保外法向一致
- 容差问题: 使用Precision::Confusion()
- 性能优化: 避免过度细化、使用BRepMesh
高级技巧
- 使用BRepBuilderAPI_Sewing缝合多个面
- 使用ShapeUpgrade分割复杂曲面
- 使用BRepExtrema计算形状间距离
— 本文完 —
B-Rep建模是CAD的核心,掌握OCC就掌握了专业建模的钥匙!
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)