Open CASCADE Technology(OCCT)

作者:追风剑情 发布于:2025-2-11 13:13 分类:C#

官方在线文档

  欢迎来到 Open CASCADE Technology(OCCT),这是一个为3D曲面和实体建模、CAD数据交换和可视化提供服务的软件开发平台。OCCT的大部分功能都以C++库的形式提供。OCCT可以最好地应用于三维建模(CAD)、制造/测量(CAM)或数值模拟(CAE)软件的开发。

概述

  开放式CASCADE技术(OCCT)是一个面向对象的C++类库,旨在快速生成复杂的特定领域CAD/CAM/CAE应用程序。

  使用OCCT开发的典型应用程序处理通用或专用计算机辅助设计(CAD)系统、制造或分析应用程序、仿真应用程序甚至插图工具中的二维或三维(2D或3D)几何建模。

OCCT库旨在实现真正的模块化和可扩展性,为以下对象提供C++类:

  • 基本数据结构(几何建模、可视化、交互式选择和特定应用服务);
  • 建模算法;
  • 处理网格(刻面)数据;
  • 与中性格式(IGES、STEP)的数据互操作性;

C++类和其他类型被分组到包中。包被组织成工具包(库),您可以将应用程序链接到这些工具包。最后,工具包分为七个模块。

下图展示了这种模块化结构。

technical_overview_schema.png

  • Foundation Classes 该模块是所有其他OCCT类的基础;
  • Modeling Data 该模块提供数据结构,将2D和3D几何图元及其组合表示为CAD模型;
  • Modeling Algorithms 该模块包含大量的几何和拓扑算法;
  • Mesh “建模算法”模块中的工具包实现了对象的镶嵌表示;
  • Visualization 该模块为图形数据表示提供了复杂的机制;
  • Data Exchange 该模块与流行的数据格式互操作,并依赖于 Shape Healing 来提高不同供应商的CAD软件之间的兼容性;
  • Application Framework 该模块提供即用型解决方案,用于处理特定于应用程序的数据(用户属性)和常用功能(保存/恢复、撤消/重做、复制/粘贴、跟踪CAD修改等)

此外,Open CASCADE Test Harness(也称为Draw)提供了库的入口点,可以用作其模块的测试工具。

C++类型与OCCT基元类型的等价性
C++类型 OCCT基元类型
int Standard_Integer
double Standard_Real
float Standard_ShortReal
bool Standard_Boolean
char Standard_Character
char16_t Standard_Utf16Char
char* Standard_CString
void* Standard_Address
char16_t* Standard_ExtString

上面表格的OCCT基元类型定义在 Standard_TypeDef.hxx 文件中可以找到。

通过句柄操作对象

Handle(MyClass) anObject = new MyClass();

在 Open CASCADE Technology 中,Handles 是特定的类,用于通过引用安全地操纵动态内存中分配的对象,提供引用计数机制,并在对象未被引用时自动销毁。

foundation_classes_image004.png

此外,对于大多数OCCT类,为句柄定义了额外的 typedef,作为以 Handle_ 为前缀的类名。例如,下面的示例代码。

//下面两句代码等价
Handle(Geom_Line) aLine;
Handle_Geom_Line aLine;  

定义坐标系

// 定义坐标系的原点
gp_Pnt origin(1.0, 2.0, 3.0);
// 定义 X 轴的方向向量
gp_Dir xAxis(1.0, 0.0, 0.0);
// 定义 Y 轴的方向向量
gp_Dir yAxis(0.0, 1.0, 0.0);
// 使用原点和两个方向向量创建坐标系 gp_Ax2
gp_Ax2 ax2(origin, xAxis, yAxis);  

创建显示窗口

// 创建显示窗口
// theWnd: 外部窗口或UI控制句柄(指针)
void CreateWindow(System::IntPtr theWnd)
{
    // 1. 创建显示连接
    Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection();
    // 2. 创建图形驱动
    Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection);
    // 3. 创建 3D 查看器
    Handle(V3d_Viewer) aViewer = new V3d_Viewer(aGraphicDriver);
    aViewer->SetDefaultLights(); // 设置默认光源
    aViewer->SetLightOn();       // 打开光源
    // 4. 创建视图
    Handle(V3d_View) aView = aViewer->CreateView();
    // 5. 创建窗口,与外部窗口指针绑定
    Handle(WNT_Window) aWindow = new WNT_Window(reinterpret_cast<HWND> (theWnd.ToPointer()));
    // 6. 将窗口与视图关联
    aView->SetWindow(aWindow);
    if (!aWindow->IsMapped()) {
        aWindow->Map();
    }
    // 7. 初始化视图
    aView->FitAll(); // 调整视图以显示所有内容
    aView->Redraw();
    aView->MustBeResized();
    // 8. 创建交互上下文
    Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext(aViewer);
    aContext->UpdateCurrentViewer();
}  

显示拓扑图形

// 显示拓扑图形
void DisplayShape(Handle(AIS_InteractiveContext) aContext, TopoDS_Shape shape)
{
    Handle(AIS_Shape) aisShape = new AIS_Shape(shape);
    //设置颜色
    aisShape->SetColor(Quantity_NOC_RED);
    //设置边线宽度
    aisShape->SetWidth(1.0);
    aContext->Display(aisShape, Standard_True);
}  

保存为.stl文件

/// <summary>
/// 将拓扑图形保存为.stl文件
/// </summary>
/// <param name="shape">要输出的拓扑图形</param>
/// <param name="theFileName">保存的路径 .../xxx.stl</param>
void ExportSTL(TopoDS_Shape shape, Standard_CString theFileName)
{
    TopoDS_Compound aComp;
    BRep_Builder aBuilder;
    aBuilder.MakeCompound(aComp);
    aBuilder.Add(aComp, shape);

    StlAPI_Writer aWriter;
    aWriter.Write(aComp, theFileName);
}  

保存为.stp文件

/// <summary>
/// 将拓扑图形保存为.stp文件
/// </summary>
/// <param name="shape">要输出的拓扑图形</param>
/// <param name="theFileName">保存的路径 .../xxx.stp</param>
void ExportSTP(TopoDS_Shape shape, Standard_CString theFileName)
{
    TopoDS_Compound aComp;
    BRep_Builder aBuilder;
    aBuilder.MakeCompound(aComp);
    aBuilder.Add(aComp, shape);

    STEPControl_StepModelType aType = STEPControl_AsIs;
    IFSelect_ReturnStatus aStatus;
    STEPControl_Writer aWriter;

    // 使用原始形状
    aStatus = aWriter.Transfer(aComp, STEPControl_AsIs);
    aWriter.Write(theFileName);
}  


  在 Visual Studio 中运行示例代码时要去掉中文注释,否则编译时可能报错:"xxx":未声明的标识符。另外,还需要引入相应的头文件(如 #include <BRepPrimAPI_MakeBox.hxx>)。如果未引入相应头文件,编译器会报 "不允许使用不完整的类型 XXXXXX"。以下示例均在 OCCT 7.8.0 版本测试通过。

示例:生成3D圆环

// 定义圆环的参数
double radius1 = 100.0; // 大半径(中心到圆环表面的距离)
double radius2 = 50.0;  // 小半径(圆环的截面半径)
Standard_Real angleU = 360.0 * M_PI / 180.0; // 角度 U 转换为弧度
Standard_Real angleV = 360.0 * M_PI / 180.0; // 角度 V 转换为弧度
// 创建圆环
TopoDS_Shape torus = BRepPrimAPI_MakeTorus(radius1, radius2, angleU, angleV).Shape();  

1111.png

示例:生成3D盒子

// 创建一个立方体,中心在原点
Standard_Real dx = 100; //长100mm
Standard_Real dy = 10;  //高10mm
Standard_Real dz = 100; //宽100mm
TopoDS_Shape box = BRepPrimAPI_MakeBox(dx, dy, dz).Shape(); 

1111.png

示例:生成3D棱镜

//创建一个2D三角形
BRepBuilderAPI_MakePolygon p;
p.Add(gp_Pnt(0, 0, 0));
p.Add(gp_Pnt(1, 0, 0));
p.Add(gp_Pnt(0, 1, 0));
p.Add(gp_Pnt(0, 0, 0));
//使用扫掠方式生成三棱镜
//第1个参数为三棱镜底面
//第2个参数为沿z轴拉申的高度
TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(p, gp_Vec(0, 0, 3)); 

1111.png

示例:生成边

//边长度
double length = 10.0;
//起点坐标
gp_Pnt startPoint(0.0, 0.0, 0.0);
//沿X轴方向绘制边
gp_Dir direction(length, 0.0, 0.0);
//转成矢量类型
const gp_Vec theV = direction;
//计算边的终点坐标
gp_Pnt endPoint = startPoint.Translated(theV);
//创建边
BRepBuilderAPI_MakeEdge edgeMaker(startPoint, endPoint);
//获取边模型
TopoDS_Shape edge = edgeMaker.Shape();  

1111.png

示例:生成倒圆立方体

//生成一个立方体
double length = 100.0;
double width = 100.0;
double height = 100.0;
TopoDS_Shape aBox = BRepPrimAPI_MakeBox(length, width, height).Shape();
//圆角半径
double radius = 10.0;
TopoDS_Shape aFilletShape;
//声明圆角对象
BRepFilletAPI_MakeFillet aFillet(aBox);
//遍历立方体的各边
TopExp_Explorer anExplorer(aBox, TopAbs_EDGE);
for (; anExplorer.More(); anExplorer.Next())
{
    TopoDS_Edge anEdge = TopoDS::Edge(anExplorer.Current());
    //设置每条边的圆角半径
    aFillet.Add(radius, anEdge);
}
//构建倒圆立方体
aFillet.Build();
//判断是否构建成功
if (aFillet.IsDone())
  aFilletShape = aFillet.Shape();  

1111.png

示例:通过点和边构造三角面

//定义三角形的三个顶点坐标
gp_Pnt p1(0.0, 0.0, 0.0);
gp_Pnt p2(100.0, 0.0, 0.0);
gp_Pnt p3(100.0, 100.0, 0.0);
//定义三角形的三条边
TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
TopoDS_Edge edge2 = BRepBuilderAPI_MakeEdge(p2, p3).Edge();
TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge(p3, p1).Edge();
//线框对象
TopoDS_Wire wire;
//构造线框对象
BRepBuilderAPI_MakeWire mkWire;
mkWire.Add(edge1);
mkWire.Add(edge2);
mkWire.Add(edge3);
wire = mkWire.Wire();
//构造三角面
BRepBuilderAPI_MakeFace aFace(wire);
//返回三角形模型
TopoDS_Shape shape = aFace.Shape();  

1111.png

示例:生成L形

TopoDS_Shape box1 = BRepPrimAPI_MakeBox(100, 20, 20).Shape();
TopoDS_Shape box2 = BRepPrimAPI_MakeBox(20, 100, 20).Shape();
//通过加法运算合并模型
TopoDS_Shape fusedShape = BRepAlgoAPI_Fuse(box1, box2);  

1111.png

示例:生成L面

TopoDS_Shape box1 = BRepPrimAPI_MakeBox(100, 5, 100).Shape();
TopoDS_Shape box2 = BRepPrimAPI_MakeBox(5, 100, 100).Shape();
//通过加法运算合并模型
TopoDS_Shape fusedShape = BRepAlgoAPI_Fuse(box1, box2);
//声明倒角对象
BRepFilletAPI_MakeFillet fillet(fusedShape);
//遍历所有边
TopExp_Explorer anExplorer(fusedShape, TopAbs_EDGE);
for (Standard_Integer i=0; anExplorer.More(); anExplorer.Next(),i++)
{
    TopoDS_Edge anEdge = TopoDS::Edge(anExplorer.Current());
    //将第0号边设置为倒角
    if (i == 0)
        fillet.Add(4.9, anEdge);
}
//构建倒角
fillet.Build();
//获取模型
TopoDS_Shape chamferedShape = fillet.Shape();  

1111.png

示例:2D B样条曲线

TopoDS_Shape CreateBSplineCurve2D()
{
    //构造N个插值点坐标
    const int N = 100;
    //声明存放插值点的数组
    Handle(TColgp_HArray1OfPnt2d) aPoints = new TColgp_HArray1OfPnt2d(1, N);
    for (int i = 0; i < N; i++)
    {
        //圆的参数方程
        double x = 3 * cos(M_PI / 50 * i);
        double y = 3 * sin(M_PI / 50 * i);
        //将插值坐标存入数组
        aPoints->SetValue(i + 1, gp_Pnt2d(x, y));
    }
    //创建Interpolate
    Geom2dAPI_Interpolate aInterpolater(aPoints, Standard_False, Precision::Approximation());
    //执行插值生成曲线
    aInterpolater.Perform();
    //获取BSplineCurve
    Handle(Geom2d_BSplineCurve) aBSplineCurve = aInterpolater.Curve();
    //创建一个平面
    gp_Pln plane = gp_Pln(gp::Origin(), gp::DZ());
    //创建MakeEdge
    BRepBuilderAPI_MakeEdge edgeMaker = BRepBuilderAPI_MakeEdge(GeomAPI::To3d(aBSplineCurve, plane));
    //获取拓扑图形
    TopoDS_Shape shape = edgeMaker.Shape();
    return shape;
}  

1111.png

示例:修剪曲线

//绘制一个圆
Standard_Real radius = 100.0;
gp_Ax2 A2(gp_Pnt(0, 0.0, 0.0), gp_Dir(0.0, 1.0, 0.0));
Handle(Geom_Circle) circle = new Geom_Circle(A2, radius);
//只保留圆[0, PI/2]的弧长
Standard_Real startParam = 0.0;
Standard_Real endParam = M_PI_2;
//修剪掉多余的圆弧
Geom_TrimmedCurve trimmedCircle(circle, startParam, endParam);
//转换为拓扑形状 MakeEdge
Handle(Geom_Curve) curve = new Geom_TrimmedCurve(trimmedCircle);
BRepBuilderAPI_MakeEdge edgeMaker = BRepBuilderAPI_MakeEdge(curve);
//获取拓扑图形
TopoDS_Shape shape = edgeMaker.Shape();  

1111.png

示例:创建线段

TopoDS_Shape CreateLineSegment(gp_Pnt p1, gp_Pnt p2)
{
  //创建矢量
  gp_Vec v(p1, p2);
  //矢量方向(单位向量)
  gp_Dir direction = v.Normalized();
  //矢量长度
  Standard_Real length = v.Magnitude();
  //创建直线
  gp_Lin line(p1, direction);
  Handle(Geom_Line) geomLine = new Geom_Line(line);
  //修剪直线范围[u1, u2]
  Standard_Real u1 = 0.0;
  Standard_Real u2 = length;
  Geom_TrimmedCurve trimmedCircle(geomLine, u1, u2);
  //创建拓扑形状
  Handle(Geom_Curve) curve = new Geom_TrimmedCurve(trimmedCircle);
  BRepBuilderAPI_MakeEdge edgeMaker = BRepBuilderAPI_MakeEdge(curve);
  //获取拓扑图形
  TopoDS_Shape shape = edgeMaker.Shape();

  return shape;
}  

1111.png

示例:创建贝塞尔曲线(BezierCurve)

// 创建控制点
TColgp_Array1OfPnt controlPoints(1, 4);
controlPoints.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
controlPoints.SetValue(2, gp_Pnt(1.0, 2.0, 0.0));
controlPoints.SetValue(3, gp_Pnt(3.0, 3.0, 0.0));
controlPoints.SetValue(4, gp_Pnt(4.0, 0.0, 0.0));
// 创建贝塞尔曲线
Handle(Geom_BezierCurve) bezierCurve = new Geom_BezierCurve(controlPoints);
BRepBuilderAPI_MakeEdge edgeMaker = BRepBuilderAPI_MakeEdge(bezierCurve);
// 获取拓扑图形
TopoDS_Shape shape = edgeMaker.Shape();  

1111.png

示例:旋转立方体

//创建立方体
TopoDS_Shape box = BRepPrimAPI_MakeBox(100, 100, 100).Shape();
//变换1:绕Y轴旋转45度
gp_Trsf trsf1;
gp_Ax1 ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0));
Standard_Real radians1 = M_PI / 4.0;
trsf1.SetRotation(ax1, radians1);
//变换2:绕X轴旋转45度
gp_Trsf trsf2;
gp_Ax1 ax2(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0));
Standard_Real radians2 = M_PI / 4.0;
trsf2.SetRotation(ax2, radians2);
//合并变换1与变换2
gp_Trsf trsf = trsf1.Multiplied(trsf2);
//将变换应用到box上
BRepBuilderAPI_Transform transform(box, trsf, false);
//获取变换后的box拓扑图形
TopoDS_Shape shape = transform.Shape();  

1111.png

示例:圆角矩形

/// <summary>
/// 绘制圆弧
/// </summary>
/// <param name="P">圆的中心位置</param>
/// <param name="R">圆的半径</param>
/// <param name="U1">弧的起始角度(弧度制)</param>
/// <param name="U2">弧的结束角度(弧度制)</param>
/// <returns></returns>
TopoDS_Edge CreateArc(gp_Pnt P, Standard_Real R, Standard_Real U1, Standard_Real U2)
{
    //定义坐标系
    gp_Ax2 A2(P, gp_Dir(0.0, 1.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
    //绘制圆
    Handle(Geom_Circle) circle = new Geom_Circle(A2, R);
    //只保留圆[U1, U2]的弧长
    //修剪掉多余的圆弧
    Geom_TrimmedCurve trimmedCircle(circle, U1, U2);
    Handle(Geom_Curve) curve = new Geom_TrimmedCurve(trimmedCircle);
    BRepBuilderAPI_MakeEdge edgeMaker = BRepBuilderAPI_MakeEdge(curve);
    TopoDS_Edge edge = edgeMaker.Edge();
    return edge;
}

/// <summary>
/// 绘制圆角矩形
/// </summary>
/// <param name="W">矩形宽度</param>
/// <param name="H">矩形高度</param>
/// <param name="R">圆角半径</param>
/// <returns></returns>
TopoDS_Shape CreateRoundRect(Standard_Real W, Standard_Real H, Standard_Real R)
{
    //左下圆角
    TopoDS_Edge arc_ld = CreateArc(gp_Pnt(R, 0, R), R, M_PI_2, M_PI);
    //左上圆角
    TopoDS_Edge arc_lu = CreateArc(gp_Pnt(R, 0, H - R), R, M_PI, M_PI + M_PI_2);
    //右上圆角
    TopoDS_Edge arc_ru = CreateArc(gp_Pnt(W - R, 0, H - R), R, M_PI + M_PI_2, 0);
    //右下圆角
    TopoDS_Edge arc_rd = CreateArc(gp_Pnt(W - R, 0, R), R, 0, M_PI_2);

    //下边
    TopoDS_Edge edge_d = BRepBuilderAPI_MakeEdge(gp_Pnt(R, 0, 0), gp_Pnt(W - R, 0, 0)).Edge();
    //左边
    TopoDS_Edge edge_l = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, R), gp_Pnt(0, 0, H - R)).Edge();
    //上边
    TopoDS_Edge edge_u = BRepBuilderAPI_MakeEdge(gp_Pnt(R, 0, H), gp_Pnt(W - R, 0, H)).Edge();
    //右边
    TopoDS_Edge edge_r = BRepBuilderAPI_MakeEdge(gp_Pnt(W, 0, H - R), gp_Pnt(W, 0, R)).Edge();

    BRepBuilderAPI_MakeWire mkWire;
    //依次拼接各边,一定要保证各边首尾相连
    mkWire.Add(arc_ld);
    mkWire.Add(edge_l);
    mkWire.Add(arc_lu);
    mkWire.Add(edge_u);
    mkWire.Add(arc_ru);
    mkWire.Add(edge_r);
    mkWire.Add(arc_rd);
    mkWire.Add(edge_d);
    //获取拓扑图形
    TopoDS_Shape shape = mkWire.Shape();

    return shape;
}  

1111.png

其它相似开源技术

https://openscad.tech/
https://openscad.org/downloads.html
https://github.com/zalo/CascadeStudio
https://www.baoxiaohe.com/
SVG教程
FBX SDK
在线3D模型格式转换
Open Asset Import Library

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号