当前位置: 首页 > news >正文

【OCCT+ImGUI系列】010-BRepMesh-网格化IncrementalMesh

在这里插入图片描述

在三维模型处理中,网格化(Meshing)是将几何模型离散为三角面片的关键步骤。本文基于 OpenCascade 的 BRepMesh_IncrementalMesh 类,结合交互式演示系统,详解网格化参数调节、实时更新与可视化。


一、BRepMesh_IncrementalMesh 核心机制

BRepMesh_IncrementalMesh 是 OpenCascade 的增量式网格生成器,采用动态精度控制算法,支持以下关键参数:

  • LinearDeflection:线性偏差(模型空间单位)
  • AngularDeflection:角度偏差(弧度制)
  • InParallel:启用多线程加速

通过构造球体示例演示核心调用方式:

TopoDS_Shape shape = BRepPrimAPI_MakeSphere(50.0).Shape();
IMeshTools_Parameters params;
params.Deflection = 1.0;
params.Angle = 30 * M_PI / 180;BRepMesh_IncrementalMesh mesher;
mesher.SetShape(shape);
mesher.ChangeParameters() = params;
mesher.Perform(); // 执行网格化

二、交互式教学系统功能

1. 动态参数调节与实时更新

在这里插入图片描述
在这里插入图片描述

通过 ImGui 滑动条实现参数动态调节,修改后触发网格重建:

// 线性偏差调节(0.1~0.7)
if (ImGui::SliderFloat("Linear Deflection", &linearDeflection, 0.1f, 0.7f)) {bMeshDirty = true; // 设置网格更新标志
}// 角度偏差调节(5°~30°)
float angularDeg = angularDeflection * 180 / M_PI;
if (ImGui::SliderFloat("Angular Deflection", &angularDeg, 5.0f, 30.0f)) {angularDeflection = angularDeg * M_PI / 180;bMeshDirty = true;
}

参数修改后通过bMeshDirty标志触发updateMesh函数,保证视图实时响应

2. 网格清除与重置

通过BRepTools::Clean清除模型三角化数据,配合上下文更新实现网格重置:

void clearTriangulation(const TopoDS_Shape& shape) {for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {BRepTools::Clean(TopoDS::Face(exp.Current()));}
}
3. 三角化信息统计

遍历所有面的三角化数据,统计总三角形数量:

int totalTriangles = 0;
for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {Handle(Poly_Triangulation) tri = ...;if (!tri.IsNull()) totalTriangles += tri->NbTriangles();
}
ImGui::Text("Total Triangles: %d", totalTriangles);
4. 网格线框可视化

提取每个三角面片的边线,生成红色线框辅助显示:

void drawTriangulations(...) {for (each triangle in triangulation) {gp_Pnt p1 = tri->Node(n1).Transformed(...);// 创建三角形边线BRepBuilderAPI_MakePolygon poly;poly.Add(p1); poly.Add(p2); poly.Add(p3); poly.Close();Handle(AIS_Shape) aisTri = new AIS_Shape(poly.Shape());aisTri->SetColor(Quantity_NOC_RED);context->Display(aisTri, false);}
}

三、高级技巧与注意事项

  1. 多线程加速
    启用InParallel参数可提升复杂模型处理速度:

    meshParams.InParallel = true; // 开启并行计算
    
  2. 网格生成验证
    检查IsDone()状态确保网格生成成功:

    if (!mesher.IsDone()) {std::cerr << "Mesh generation failed!" << std::endl;
    }
    
  3. 显示模式控制
    强制设置AIS_Shape显示模式,增强可视化效果:

    aisShape->SetDisplayMode(AIS_Shaded); // 实体着色模式
    aisShape->Attributes()->SetFaceBoundaryDraw(true); // 显示面边界
    

四、代码

#pragma once#include "pch.h"
#include <format>
#include <string>
#include <mutex>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepPrimAPI_MakeSphere.hxx> // 新增头文件
#include <BRepLib_ToolTriangulatedShape.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <TopExp_Explorer.hxx>
#include <Poly_Triangulation.hxx>
#include <AIS_Shape.hxx>
#include <TopoDS.hxx>
#include "BaseScene.h"
#include "VisSceneComponents.h"
#include "TutorialWindow.h"
#include "CodeHintAction.h"class BRepMesh010 : public BaseScene, public VisSceneComponents, public TutorialWindow {
public:BRepMesh010() {openTutorialWindow();}void displayScene(const Handle(V3d_View)& view, const Handle(AIS_InteractiveContext)& context) override {if (!bIsSceneInit) {sceneInit(view, context);bIsSceneInit = true;}if (bMeshDirty) {updateMesh(context);bMeshDirty = false; }renderTutorialWindow(context);}void customInitTutorialWindow(const Handle(AIS_InteractiveContext)&) override {}private:Handle(AIS_Shape)       aisShape;CodeHintManager         hintMgr;  TopoDS_Shape            meshShape;IMeshTools_Parameters   meshParams;std::mutex              meshMutex;float linearDeflection = 1.0f;float angularDeflectionDeg = 30.0f;float minSize = 0.0f;bool isProcessing = false;       // 标记是否正在处理bool bMeshDirty = false; // 参数变化刷新标志位void sceneInit(const Handle(V3d_View)&, const Handle(AIS_InteractiveContext)& context) override {meshShape =  BRepPrimAPI_MakeSphere(50.0).Shape();updateMesh(context);}void updateMesh(const Handle(AIS_InteractiveContext)& context) {std::lock_guard<std::mutex> lock(meshMutex); // 自动加锁// 开始处理isProcessing = true;clearTriangulation(meshShape);meshParams.Deflection = linearDeflection;meshParams.Angle = angularDeflectionDeg * M_PI / 180.0;meshParams.InParallel = true;BRepMesh_IncrementalMesh mesher;mesher.SetShape(meshShape);mesher.ChangeParameters() = meshParams;mesher.Perform();hintMgr.AddHint("Mesh", "mesher.Perform();");// 添加网格生成验证if (!mesher.IsDone()) {std::cerr << "Mesh generation failed!" << std::endl;return;}aisShape = new AIS_Shape(meshShape);// 强制设置显示模式为网格//aisShape->SetDisplayMode(AIS_Shaded);  // 或 AIS_WireFrameaisShape->Attributes()->SetFaceBoundaryDraw(true);context->RemoveAll(true);context->Display(aisShape, true);context->UpdateCurrentViewer();  // 强制刷新视图drawTriangulations(meshShape, context);}void clearTriangulation(const TopoDS_Shape& shape) {for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {TopoDS_Face face = TopoDS::Face(exp.Current());BRepTools::Clean(face); // 移除 Poly_Triangulation}}void renderTutorialContent(const Handle(AIS_InteractiveContext)& context) override {ImGui::Text("BRepMesh_IncrementalMesh 教学示例");ImGui::Separator();float oldLinearDeflection = linearDeflection;if (ImGui::SliderFloat("Linear Deflection", &linearDeflection, 0.1f, 0.7f, "%.2f")) {if (oldLinearDeflection != linearDeflection) {bMeshDirty = true;}}float oldAngularDeflectionDeg = angularDeflectionDeg;if (ImGui::SliderFloat("Angular Deflection (deg)", &angularDeflectionDeg, 5.0f, 11.0f, "%.1f")) {if (oldAngularDeflectionDeg != angularDeflectionDeg) {bMeshDirty = true;}}if (ImGui::Button("Clear Triangulation")) {BRepTools::Clean(meshShape);context->RemoveAll(true);hintMgr.AddHint("BRepTools::Clean", "BRepTools::Clean(meshShape);");}if (ImGui::Button("Reset Default")) {linearDeflection = 1.0f;angularDeflectionDeg = 30.0f;minSize = 0.0f;updateMesh(context);}if (aisShape) {ImGui::Separator();ImGui::Text("Triangulation Info:");int totalTriangles = 0;for (TopExp_Explorer exp(meshShape, TopAbs_FACE); exp.More(); exp.Next()) {TopLoc_Location loc;Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), loc);if (!tri.IsNull()) {totalTriangles += tri->NbTriangles();}}ImGui::Text("Total Triangles: %d", totalTriangles);}// 渲染提示窗口hintMgr.RenderWindow();}void drawTriangulations(const TopoDS_Shape& shape, const Handle(AIS_InteractiveContext)& context) {for (TopExp_Explorer faceExp(shape, TopAbs_FACE); faceExp.More(); faceExp.Next()) {TopoDS_Face face = TopoDS::Face(faceExp.Current());TopLoc_Location loc;Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);if (tri.IsNull()) continue;const Poly_Array1OfTriangle& triangles = tri->Triangles();for (int i = triangles.Lower(); i <= triangles.Upper(); ++i) {int n1, n2, n3;triangles(i).Get(n1, n2, n3);// 使用 tri->Node(index) 获取三角形顶点坐标gp_Pnt p1 = tri->Node(n1).Transformed(loc.Transformation());gp_Pnt p2 = tri->Node(n2).Transformed(loc.Transformation());gp_Pnt p3 = tri->Node(n3).Transformed(loc.Transformation());// 创建一个三角形边线展示BRepBuilderAPI_MakePolygon triPoly;triPoly.Add(p1);triPoly.Add(p2);triPoly.Add(p3);triPoly.Add(p1);triPoly.Close();Handle(AIS_Shape) aisTri = new AIS_Shape(triPoly.Shape());aisTri->SetDisplayMode(AIS_WireFrame);aisTri->SetColor(Quantity_NOC_RED);context->Display(aisTri, false);}}context->UpdateCurrentViewer();}};

相关文章:

  • 【Android】非System用户下Persist应用不自动拉起
  • 2025年渗透测试面试题总结-匿名[实习]安全工程师(安全厂商)(题目+回答)
  • 【Android】System分区应用自带库与原生库同名问题分析
  • Java集合框架基础知识点全面解析
  • Go 语言基础1 Slice,map,string
  • 计算机视觉(图像算法工程师)学习路线
  • where is the examples of stm32h743i demo project inside of stm32cubeh7
  • 电商小程序店铺详情页:头部无限分类与筛选功能实现
  • 书生五期--端侧小模型论文分类微调打榜
  • 搭建 C/C++_CMake_Boost_git 开发环境
  • 计算机视觉中的可重复性:深入案例分析与Python代码实现
  • 【MySQL】08.视图
  • TiDB:从快速上手到核心原理与最佳实践
  • 【时时三省】(C语言基础)函数的嵌套调用
  • python学习day28
  • Linux 系统常用核心库----用户态程序运行的基石
  • 广东省省考备考(第二十天5.25)—言语:逻辑填空(听课后强化训练)
  • 前端常见的安全问题
  • java高级 -Junit单元测试
  • 用VMWare架飞牛nas 启用Intel千兆网卡
  • 有专门做ppt的网站有哪些/国内永久免费云服务器
  • asp怎么样做网站后台/google引擎免费入口
  • 企业网站属于广告吗/关键词搜索站长工具
  • 大学一学一做视频网站/公众号开发网站公司
  • 网站建设与案例管理的心得体会/一个网站的seo优化有哪些
  • 网站建设工作分解结构词典/做推广网络