Open Cascade开发实践:落地电风扇建模

原文地址:https://blog.csdn.net/Mechanicoder/article/details/139218495

简介

本文参考Open Geometry Group (OGG)组织的一次建模公开赛比赛要求,选择电风扇为建模对象,使用OCC接口完成所选模型的建模。在电风扇题目做题过程中,涉及拉伸、旋转、阵列、倒圆角等常见的CAD建模功能,以及曲线、曲面的一些基础操作,对OCC初学者可能会有一些帮助,因此整理、总结成这篇文章。

建模

落地扇模型包括底座、立柱、外壳、前罩、后罩、扇叶等零件,建模过程中需要计算确定各零件的几何尺寸信息、彼此之间的相对位置关系,例如立柱高度参数、扇叶相对于立柱的位置参数、前后网罩尺寸参数等。由于这些参数并非直观易得,直接使用OCC建模可能得到尺寸不协调的结果,需要反复调参,增大开发时间。因此,可首先借助于CAD建模软件预先完成设计,然后再通过OCC实现编程建模。

这里采用CrownCAD在线协同建模软件,个人可免费使用建模基础功能,对于落地风扇的设计已足够,设计模型如下图所示,可通过链接在线浏览:落地风扇
落地风扇扇叶部分落地风扇全貌

以下将根据建模思路,完成各个零件的编程实现。自底向上依次为基座、立柱、外壳、电机支架、电机、风扇、风扇轮毂、扇叶、前网罩和后网罩。各小节仅描述了建模步骤以及使用到的OCC关键接口,代码实现可直接跳转至代码实现总结。建模过程采用CSG方式。

基座
立柱
外壳
电机支架
电机
风扇轮毂
扇叶
...

基座

由上、下两个圆台合并而成,用于支撑整个风扇。下半黑色部分是一个下小上大的圆台、上半灰色部分是下大上小的圆台。两个圆台均采用截面旋转360°得到,并将得到的两个实体求并。
建模步骤:

  1. 根据下部分轮廓点,依次连点成线,构造一个封闭的多边形,BRepBuilderAPI_MakePolygon
  2. 将多边形构造成面,BRepBuilderAPI_MakeFace
  3. 由面构造实体,BRepPrimAPI_MakeRevol

上一部分同理可得,最终效果如下:
在这里插入图片描述

立柱

立柱包括下部分柱体、衔接圆锥、按钮圆柱、按钮槽、按钮、数字、衔接球槽特征。
建模步骤:

1. 底部圆柱
2. 衔接圆锥
3.1. 按钮圆柱
3.2. 按钮槽
3.3. 三角裁剪
3.4. 衔接球
5. 倒圆角
立柱
  1. 下部分立柱,构造一个标准圆柱,BRepPrimAPI_MakeCylinder
  2. 衔接圆锥,构造一个标准圆锥,BRepPrimAPI_MakeCone
  3. 按钮圆柱,按钮圆柱上特征较多,采用实体建模的方式逐步获得
    1. 构造标准圆柱,BRepPrimAPI_MakeCylinder
    2. 构造顶部裁剪圆锥,即构造一个拉伸体,BRepPrimAPI_MakePrism
    3. 构造顶部衔接球槽,即构造一个标准球,BRepPrimAPI_MakeSphere
    4. 构造按钮槽,同样头早一个拉伸体,并线性阵列按钮槽,BRepBuilderAPI_Transform
    5. 按钮立柱依次裁剪裁剪圆锥、顶部标准球、按钮槽拉伸体,BRepAlgoAPI_Cut, BRepAlgoAPI_Fuse
  4. 构造按钮,是一个截面为椭圆形的拉伸体,GC_MakeEllipse
  5. 对所有棱边位置倒圆角过渡,BRepFilletAPI_MakeFillet

建模示意图如下所示:

按钮

按钮单独建模,使之可以在3D视图中进行交互操作。例如,鼠标点击按钮①、②、③,实现按钮下沉、风扇按对应级数开始旋转,点击按钮〇实现风扇停转。这些动画交互在之后的动画及交互一节详细说明。
按钮建模步骤:

1. 按钮
2. 按钮线性阵列
3.1. 文字截面
3.2. 文字拉伸
按钮
  1. 构造以椭圆为截面的拉伸体,按钮的截面应比前一步中的按钮槽截面略小,GC_MakeEllipse
  2. 按钮线性阵列,得到四个按钮,BRepBuilderAPI_Transform
  3. 构造按钮表面的文字,分别为0、1、2、3:
    1. 构造文字截面,Font_BRepTextBuilder
    2. 文字截面拉伸,BRepPrimAPI_MakePrism
  4. 每个按钮减去对应文字的拉伸体,可得到带凹陷文字的按钮,BRepAlgoAPI_Cut

按钮建模

外壳

外壳用于支撑风扇电机、衔接前后网罩。
建模步骤:

偏置
旋转
1.1. 衔接球
1.2. 外壳内腔
2. 电机立柱
3. 电机
4. 前后连接环
5.1. 样条轮廓
连接
5.2. 样条偏置
5.3. 横截面
5. 风扇罩子
外壳
  1. 构造衔接球
    1.1. 首先构造一个标准球,同前,BRepPrimAPI_MakeSphere
    1.2. 构造外壳内腔,该内腔将容纳风扇,是一个标准的圆柱,BRepPrimAPI_MakeCylinder
    1.3. 球减去外壳内腔,即可削去球的顶部,用于承接风扇外壳
  2. 构造电机立柱,标准圆柱,用于承接电机,BRepPrimAPI_MakeSphere
  3. 使用一个标准圆柱,代表电机
  4. 构造前后衔接环,即一个标准的圆环,用于连接前端风扇外壳、后端网罩。由于风扇罩子横截面外形将是一条样条曲线,为方便建模、衔接,特地构造一小段圆环。使用两个圆柱相减即可得到
  5. 风扇罩子横截面外形是一条样条曲线,是风扇建模中首次出现样条曲线。
    5.1. 构造样条外形,Geom2d_BezierCurve
    5.2. 样条偏置,Geom2d_OffsetCurve
    5.3. 将两段样条首尾相连,即可得到封闭轮廓、横截面,BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeFace
    5.4. 横截面旋转即得到外壳,BRepPrimAPI_MakeRevol
  6. 对以上所得 1~5 结果求并即可得到完整的风扇外壳

需要特殊说明的是,上述步骤 5.1. 中的样条曲线建模及偏置均在 XOY 平面上进行,这是根据作者对OCC的使用经验,2D偏置比3D更稳定一些。当然直接进行3D样条曲线,或许也是可以的。
另外由于OCC底层几何算法一般使用3D曲线 Geom_Curve,对2D曲线 Geom2d_Curve 所作的适配有限,因此,对于2D即 XOY 平面上所得的轮廓,在进行构造面进而旋转之前,需要额外构造几何3D曲线,即确保执行 BRep_Tool::Curve(Edge) 可以得到正确的结果。

BRepLib::BuildCurves3d(Shape)

在这里插入图片描述

风扇

风扇包括连接扇叶的轮毂、叶片两大部分,其中叶片为样条曲面,是整个落地风扇建模过程中最为复杂的部分。
建模步骤:

采样
拟合/放样
阵列
采样
采样
1. 电机轴
2. 风扇轮毂
3.1.1. 截面1
构造
3.1. 面上曲线1
3.2.1. 截面2
构造
3.2. 面上曲线2
截面N
构造
面上曲线N
3.1.2 参数曲线1
3.2.2. 参数曲线2
参数曲线N
二维点集
4. 叶片
M个叶片
风扇
  1. 电机轴,构造一个标准圆柱,BRepPrimAPI_MakeCylinder
  2. 风扇轮毂,同样是一个标准圆柱,BRepPrimAPI_MakeCone
  3. 扇叶,每个扇叶是自由曲面,可由二维点集构造获得,因此第一步是构造点集。在风扇轮毂、外壳内壁之间构造若干个曲面,并在曲面上构造出风扇的截面线,分别对截面线采样,即可得到二维点集:
    3.1. 构造第一个面上曲线,BRep_CurveOnSurface
    3.1.1. 构造一个分层B样条曲面,Geom_BSplineSurface
    3.1.2. 构造一条参数曲线,Geom2d_Curve
    3.1. 构造第二个面上曲线,

    共构造得到 N 个面上曲线
  4. 二维点集拟合,即可得到二维曲面,``
  5. 按一周分布 M 个叶片进行旋转阵列,即可得到 M 个叶片
  6. 另外,为了增强展示效果,为每个叶片分配了不同颜色。

在这里插入图片描述

前网罩

前网罩包括网条和中心logo环两大部分,其中网条使用Bezier构造。
建模步骤:

构造Bezier
偏置
拉伸
构造Bezier
构造Bezier
拉伸
阵列
拉伸
控制点
网条曲线
偏置线
封闭
网条轮廓
单个网条
裁剪控制点
裁剪轮廓1
封闭
裁剪轮廓
裁剪控制点
裁剪轮廓2
外形修建体
全部网条
中心圆柱
字体轮廓
字体
中心logo圆饼
外圆柱
内圆柱
网罩外环
前网罩
  1. 前网罩网条通过Bezier曲线及其偏置曲线封闭所得;
  2. 风扇前网罩成弧形而非平面,因此再构造一个外形修剪体用来裁剪网条。外形修剪体由两条Bezier曲线封闭得到;
  3. 中心圆环以及logo字体通过圆柱体减去字体的拉伸体所得,通用使用外形修剪体进行修剪
    在这里插入图片描述

后网罩

后网罩与前网罩采用相似的方式构造,区别在于后网罩除了外形是弧面之外,内腔亦是弧面,因此进行了两次裁剪。
在这里插入图片描述

动画及交互

在建模之外,增加了一点交互功能,增加这次实践的趣味。即通过鼠标或数字键实现对风扇转速的控制,同时实现按钮被按下的效果。
风扇有1、2、3、0四档,每档转速不同,经测试效果,分别设置转速(RPM)为30、60、90、0。
在这里插入图片描述

进一步地,可以在衔接球位置实现风扇的左右、上下摇头动画。

代码实现总结

以上各步骤的基础建模功能包括拉伸、旋转、阵列、裁剪、合并、倒圆角等。

拉伸

TopoDS_Shape FanMaker::Extrude(const std::vector<TopoDS_Edge>& edges, const gp_Vec& vec) const
{
    TopoDS_Face face = MakeFace(edges);
    if (face.IsNull())
    {
        return TopoDS_Shape();
    }
    TopoDS_Shape extrude_shape = BRepPrimAPI_MakePrism(face, vec);
    return extrude_shape;
}

旋转

TopoDS_Shape FanMaker::Revolve(const std::vector<TopoDS_Edge>& edges, const gp_Ax1& axis) const
{
    TopoDS_Face face = MakeFace(edges);
    if (face.IsNull())
    {
        return TopoDS_Shape();
    }
    TopoDS_Shape revol = BRepPrimAPI_MakeRevol(face, axis);
    return revol;
}

阵列

TopoDS_Shape FanMaker::CircularPattern(const TopoDS_Shape& shape, const gp_Ax1& axis, int num) const
{
    // 网条阵列
    gp_Trsf trsf;
    trsf.SetRotation(axis, M_PI * 2.0 / double(num));
    std::vector<TopoDS_Shape> pattern(num);
    pattern[0] = shape;
    for (size_t i = 1; i < num; i++)
    {
        pattern[i] = BRepBuilderAPI_Transform(pattern[i - 1], trsf);
    }

    return Compound(pattern);
}

字体拉伸

TopoDS_Shape FanMaker::PrismText(const NCollection_String& text,
    const gp_Ax2& loc, const gp_Vec& prism_vec, int pt_size/* = 12*/) const
{
    Font_BRepFont font("consola", Font_FontAspect::Font_FontAspect_Regular, (double)pt_size);
    Graphic3d_HorizontalTextAlignment halign = Graphic3d_HTA_CENTER;
    Graphic3d_VerticalTextAlignment valign = Graphic3d_VTA_CENTER;

    Font_BRepTextBuilder font_brep;
    TopoDS_Shape text_face = font_brep.Perform(font, text, loc, halign, valign);
    TopoDS_Shape text_solid = BRepPrimAPI_MakePrism(text_face, prism_vec);
    return text_solid;
}

布尔运算

合并:

TopoDS_Shape FanMaker::Fuse(const std::vector<TopoDS_Shape>& shapes) const
{
    if (shapes.empty())
    {
        return {};
    }
    else if (shapes.size() == 1)
    {
        return shapes[0];
    }
    else
    {
        TopoDS_Shape result = BRepAlgoAPI_Fuse(shapes[0], shapes[1]);
        for (size_t i = 2; i < shapes.size(); i++)
        {
            if (!shapes[i].IsNull())
            {
                result = BRepAlgoAPI_Fuse(result, shapes[i]);
            }
        }
        return result;
    }
}

裁剪:

TopoDS_Shape FanMaker::Cut(const TopoDS_Shape& s,
    const std::vector<TopoDS_Shape>& cutters) const
{
    BRepAlgoAPI_Cut cut;
    TopTools_ListOfShape args, tools;
    args.Append(s);
    for (const auto& cutter : cutters)
    {
        tools.Append(cutter);
    }

    cut.SetArguments(args);
    cut.SetTools(tools);
    cut.Build();

    if (!cut.IsDone())
    {
        return TopoDS_Shape();
    }

    return cut.Shape();
}

总结

建模过程思路简单,难点在于合理确定各部分零件建模的基准、衔接位置。先通过CAD软件完成草稿建模,基本确定各几何参数,然后再由OCC实现建模,从而可专注于逻辑实现而非参数调试。

完整源代码链接:https://gitee.com/mechanicoder/occt_-upgrade-test/tree/master/others/fan_modeling

原文地址:https://blog.csdn.net/Mechanicoder/article/details/139218495

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值