OpenCascade与三角剖分 笔记

2023-05-16

笔记

摘自 http://www.cppblog.com/eryar/archive/2013/05/26/200605.html

概述

三角剖分是平面剖分中的一个重要课题,在数字图像处理、计算机三维曲面造型、有限元计算、逆向工程等领域有着广泛应用。由于三角形是平面域中的单纯形,与其他平面图形相比,其有描述方便、处理简单等特性,很适合于对复杂区域进行简化处理。因此,无论在计算几何、计算机图形处理、模式识别、曲面逼近,还有有限元网格生成方面有广泛的应用。

虽然曲线、曲面等有精确的方程来表示,但是在在计算机中,只能用离散的方式来逼近。如曲线可用直线段来逼近,而曲面可用多边形或三角形来表示。用多边形网格表示曲面是设计中经常使用的形式,可以根据应用要求选择网格的密度。利用三角形面片表示的曲面在计算机图形学中也称为三角形网格。用三角形网格表示曲面需要解决几个问题:三角形的产生、描述、遍历、简化和压缩等,这些问题都是计算几何研究的范畴,相关问题都可以从中找到答案。下图所示的圆柱和立方体是由OpenCascade生成,使用OpenCascade的算法离散成三角网格后在OpenSceneGraph中显示的效果。

1.1

Figure 1.1 Shaded Cylinder and Box

1.2

Figure 1.2 Mesh generated by OpenCascade

从图中可以看出,平面的三角形网格效果还不错,曲面的三角形网格表示只能是近似表示,可以通过提高网格的密度来增加真实性,但相应渲染的数据量就大了。有人说OpenCascade的显示模块做得不是很好,上述方法则可以只使用OpenCascade的造型模块,再结合OpenSceneGraph来对图形进行显示。

三维数据交换STL格式文件中保存的都是三角面片的数据,STL文件格式是由美国3D System公司开发,已被工业界认为是目前快速自动成型领域的准标准零件描述文件格式。它对三维实体描述的解释具有惟一性。几乎所有的几何造型系统都提供STL文件数据交换接口。OpenCascade中的数据交换模块也提供对STL格式的支持,由此可见三角网格在几何造型系统中的重要性。

Delaunay三角剖分在OpenCascade中的应用

OpenCascade中网格剖分的包主要有BRepMesh、MeshAlgo、MeshVS,其中,类MeshAlgo_Delaunay使用算法Watson来进行Delaunay三角剖分。从类StlTransfer中的注释The triangulation is computed with the Delaunay algorithm implemented in package BRepMesh.可以看出包BRepMesh就是Delaunay三角剖分的具体实现。使用方法如下:

BRepMesh::Mesh (aShape, Deflection);

这个函数主要是用来对拓扑形状进行三角剖分。以下通过将一个圆柱三角剖分为例说明如何将一个拓扑形状进行三角剖分并将结果进行可视化。

/** 
*    Copyright (c) 2013 eryar All Rights Reserved. 
* 
*        File    : Main.cpp 
*        Author  : eryar@163.com 
*        Date    : 2013-05-26 
*        Version : 0.1 
* 
*    Description : Use BRepMesh_Delaun class to learn  
*                  Delaunay's triangulation algorithm. 
* 
*/ 

// Open Cascade library. 
#include <gp_Pnt.hxx> 
#include <gp_Pln.hxx> 
#include <BRep_Tool.hxx> 
#include <TopoDS.hxx> 
#include <TopoDS_Edge.hxx> 
#include <TopoDS_Wire.hxx> 
#include <TopoDS_Face.hxx> 
#include <BRepBuilderAPI_MakeEdge.hxx> 
#include <BRepBuilderAPI_MakeWire.hxx> 
#include <BRepBuilderAPI_MakeFace.hxx> 
#include <BRepPrimAPI_MakeBox.hxx> 
#include <BRepPrimAPI_MakeCone.hxx> 
#include <BRepPrimAPI_MakeCylinder.hxx> 
#include <BRepPrimApI_MakeSphere.hxx> 
#include <BRepMesh.hxx> 
#include <TopExp_Explorer.hxx> 
#include <Poly_Triangulation.hxx> 
#include <TShort_Array1OfShortReal.hxx> 

#pragma comment(lib, "TKernel.lib") 
#pragma comment(lib, "TKMath.lib") 
#pragma comment(lib, "TKBRep.lib") 
#pragma comment(lib, "TKPrim.lib") 
#pragma comment(lib, "TKMesh.lib") 
#pragma comment(lib, "TKTopAlgo.lib") 

// OpenSceneGraph library. 
#include <osgDB/ReadFile> 
#include <osgViewer/Viewer> 
#include <osgViewer/ViewerEventHandlers> 
#include <osgGA/StateSetManipulator> 

#pragma comment(lib, "osgd.lib") 
#pragma comment(lib, "osgDbd.lib") 
#pragma comment(lib, "osgGAd.lib") 
#pragma comment(lib, "osgViewerd.lib") 

osg::Node* BuildShapeMesh(const TopoDS_Shape& aShape) 
{ 
    osg::ref_ptr<osg::Group> root = new osg::Group(); 
    osg::ref_ptr<osg::Geode> geode = new osg::Geode(); 
    osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry(); 
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(); 
    osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(); 

    BRepMesh::Mesh(aShape, 1); 
    TopExp_Explorer faceExplorer; 
    for (faceExplorer.Init(aShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next()) 
    { 
        TopLoc_Location loc; 
        TopoDS_Face aFace = TopoDS::Face(faceExplorer.Current()); 
        Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc); 
        Standard_Integer nTriangles = triFace->NbTriangles(); 

        gp_Pnt vertex1; 
        gp_Pnt vertex2; 
        gp_Pnt vertex3; 
        Standard_Integer nVertexIndex1 = 0; 
        Standard_Integer nVertexIndex2 = 0; 
        Standard_Integer nVertexIndex3 = 0; 

        TColgp_Array1OfPnt nodes(1, triFace->NbNodes()); 
        Poly_Array1OfTriangle triangles(1, triFace->NbTriangles()); 
        nodes = triFace->Nodes(); 
        triangles = triFace->Triangles(); 

        for (Standard_Integer i = 1; i <= nTriangles; i++) 
        { 
            Poly_Triangle aTriangle = triangles.Value(i); 
            aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3); 
            vertex1 = nodes.Value(nVertexIndex1); 
            vertex2 = nodes.Value(nVertexIndex2); 
            vertex3 = nodes.Value(nVertexIndex3); 

            gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ()); 
            gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ()); 
            gp_XYZ normal = vector12.Crossed(vector13); 
            Standard_Real rModulus = normal.Modulus(); 

            if (rModulus > gp::Resolution()) 
            { 
                normal.Normalize(); 
            } 
            else 
            { 
                normal.SetCoord(0., 0., 0.); 
            } 

            vertices->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z())); 
            vertices->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z())); 
            vertices->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z())); 
            normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z())); 
        } 
    } 

    triGeom->setVertexArray(vertices.get()); 
    triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size())); 
    triGeom->setNormalArray(normals); 
    triGeom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE); 

    geode->addDrawable(triGeom); 
    root->addChild(geode); 

    return root.release(); 
} 

int main(int argc, char* argv[]) 
{ 
    osgViewer::Viewer myViewer; 
    osg::ref_ptr<osg::Group> root = new osg::Group(); 
    root->addChild(BuildShapeMesh(BRepPrimAPI_MakeCylinder(.6, 1))); 

    myViewer.setSceneData(root); 
    myViewer.addEventHandler(new osgGA::StateSetManipulator(myViewer.getCamera()->getOrCreateStateSet())); 
    myViewer.addEventHandler(new osgViewer::StatsHandler); 
    myViewer.addEventHandler(new osgViewer::WindowSizeHandler); 

    return myViewer.run(); 
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCascade与三角剖分 笔记 的相关文章

  • MySql 8.0 设置允许远程登录授权

    MySQL 连接出现 is not allowed to connect to this MySQL Server错误提示 打开 MySQL8 0 Command Line Client 1 打开远程连接 mysql span class
  • 基于Jeecg的权限获取

    Jeecg的权限 xff0c 是通过菜单管理中的 按钮 权限 实现的 xff0c 前端和后端怎么获取这个权限呢 xff0c 本文简单做个记录 1 前端 import USER AUTH from 34 64 store mutation t
  • 基于Jeecg使用vue-konva

    konva是一个基于canvas的可视化框架 xff08 https konvajs org xff09 xff0c vue konva则是基于vue的 当前的一个小项目是基于Jeecg开发的 xff0c 想做可视化的功能 xff0c 于是
  • 基于JeecgBoot的v-has权限控制

    v has是一个很方便的前端权限控制标签 xff0c 但是只支持一个授权标识 xff0c 如果需要两个或以上的权限与或运算就不支持了 解决方案 xff1a 修改文件 64 utils hasPermission js 中的方法filterG
  • 前后端离线开发相关软件下载地址大全

    一 后端开发 xff1a 1 IDEA Windows xff1a https www jetbrains com zh cn idea download section 61 windows 2 JDK Windows xff1a htt
  • 离线部署GitLab

    一 背景 公司是局域网开发环境 xff0c 资源文件用svn管理 xff0c 代码用git管理 GitLab有点大 xff0c 而且只能在Linux下使用 xff0c 所以选择了轻巧的GitBlit 后来GitBlit被暴漏洞 xff0c
  • C# WPF实战项目升级了

    概述 之前用Caliburn Micro搭建的WPF实战项目 xff0c CM框架选用了 3 0 3 xff0c 实际上CM框架目前最新版已经到4 0 173了 xff0c 所有很有必须升级一下项目了 本来打算把平台框架也直接升级到 NET
  • 接入Swagger2(1) —— SwaggerUI

    关于Swagger不再多述 xff0c 这里只分享接入方式 1 接入 SpringBoot中引入Swagger相当简单 xff0c 只需要添加一个依赖就行 xff0c 如下 xff1a lt dependency gt lt groupId
  • 接入Swagger2(2) —— knife4j

    上一篇文章介绍了Swagger2默认UI的接入方式 xff0c 但是UI实在太丑 xff0c 而且布局也很难用 xff0c 这里介绍一个相对漂亮点的UI knife4j knife4j是基于swagger2开发的 xff0c 是swagge
  • SpringSecurity的使用(1)—— 起步

    年初就关注到SpringSecurity了 xff0c 看官网 xff0c 看不懂 xff1b 查资料 xff0c 跟我预想的不一样 xff0c 所以一直入不了门 有博文说添加依赖 xff0c 再次启动项目就会跳转到登录页面 我是前后端分离

随机推荐

  • 离线模式:Unresolved dependency: ‘com.xx.xx:xx-xx:jar:x.x.x‘

    SpringBoot最常用的编译器就是IDEA xff0c 如果不能联网 xff0c 则需要将工程设置为离线模式 1 遇到的问题 这两天遇到了这样的问题 xff1a JeecgBoot的工程中有添加依赖包 knifej spring boo
  • SpringBoot中Java调用dll

    1 背景 最近接手的项目 xff0c 底层算法是C 43 43 写的 xff0c 并且封装成了dll 而目前的需求 xff0c 需要把这些算法移到服务端执行 不可能把C 43 43 写的算法库改用Java重写一遍 xff0c 而且也基于执行
  • 接入Shiro(1)——极简登录认证

    Shiro是一个强大易用的Java安全框架 xff0c 提供了认证 授权 加密和会话管理等功能 之前的开发都是在低代码上直接使用Shiro xff0c 一般也不需要修改 在SpringBoot的基础上 xff0c 只接入Shiro的登录认证
  • 接入Shiro(2)——基于JWT的登录认证

    前文讲到基于Shiro的登录认证 xff0c 只是对前端传来的token长度做了判断 xff0c 并没有与用户关联 本文将分享用户登录 Token创建 Token验证三个关键环节的用法 xff0c 其中用户登录只对用户名和密码做简单的比对
  • VS2017离线安装

    因开发环境限制 xff0c 不联外网开发是一种很常见的情况 xff0c 但官方似乎不提供vs2017离线安装包 几经周折 xff0c 终于找到了解决办法 1 vs2017下载地址 Visual Stduio 旧版本下载地址 Visual S
  • Invalid or corrupt jarfile xxx.jar

    一 遇到的问题 Artifacts打包的特点是 xff0c 目录下会生成一大堆jar包 xff0c 各个依赖包都是独立存在的 xff0c 更新时只替换开发包即可 之前一直用Artifacts打的包 xff0c 会生成MANIFEST MF文
  • GitLab的备份与还原

    一 现状 前段时间在麒麟系统上部署了GitLab xff0c 后来发现太占资源 xff0c 于是准备在Ubuntu Desktop版本上部署GitLab Ubuntu Desktop出预装了浏览器 xff0c 感觉不会比麒麟轻太多 之前安装
  • 如何使用Sublime的插件(以HexViewer为例)

    1 打开Package Control功能 xff1a 在sublime任意界面按下ctrl 43 xff08 注意是键盘左上角的 xff09 xff0c 会在界面最下方弹出一个编辑框 xff0c 输入如下内容 xff08 注意区分Subl
  • Java和Qt如何实现multipartfile表单的请求

    一 背景 做项目经常需要跟其他单位 公司对接 xff0c 由于成本等方面的考虑 xff0c 不可能多家单位一直坐在一起开发 一般的解决办法是 xff0c 自己的B端 C端先与自己的服务端对接 xff0c 基本功能开发完成 xff0c 再将自
  • 树的排布、展开与折叠算法

    一 背景 原项目是纯C端程序 xff0c 未来要移植成BS架构 其中一个功能是界面上展示树 xff0c 基本要求是 xff1a xff08 1 xff09 按层次展示树各个结点 xff08 2 xff09 根结点以及各个子树结点可以点击 x
  • 常用git命令

    一 背景 做Qt开发一直在Windows平台上 xff0c 客户要求移植到麒麟系统 Windows和麒麟共用一套代码 xff0c 所以麒麟系统上的代码也需要与Git服务器同步 好用的Sourcetree没有Linux版本 xff0c 无奈只
  • 用Qt实现文件转码

    一 背景 用VS做Qt开发 xff0c 源码文件默认是GBK编码 但做跨平台 xff0c 同样的源码复制到麒麟的QtCreator xff0c 必须手动选择GB2312编码才能修改代码 另外 xff0c Windows的Sourcetree
  • 我的程序员之路(20)——2022年年度总结

    在现在的公司工作一年半了 过去的一年收获很多 xff0c 与以往最大的区别是肩上压了一个项目 尽管我只负责技术方面的工作 xff0c 但是要协调各方面 xff0c 也是件很麻烦的事 尤其是跟用户方的接触 xff0c 是极大的提升了业务知识
  • C++中回调函数的一个简单例子?

    回调函数应用实例 xff1a 1 定义一个Person类 xff08 Person h xff09 文件 xff1a 注意 xff1a 在这个类中指定了回调函数 xff0c 回调函数的执行者 xff0c 和回调函数指针 重要的是 回调函数
  • Docker容器的端口映射

    在Docker容器的日常使用中 xff0c 有以下5种常见的端口映射方式 1 对容器暴露的所有端口 xff0c 随机映射宿主机端口 P xff0c publish all 61 true false xff0c 默认为false span
  • wsl不动了,wsl2不动了。不响应

    原来是用vim编辑时 xff0c 习惯了 xff0c 按了ctrl 43 s的原因 Ctrl 43 s 在终端下是有特殊用途的 xff0c 那就是暂停该终端 xff0c Ctrl 43 q 退出这种状态 xff0c 让终端继续运行
  • Ubuntu Server 20.04最小部署openstack Wallaby(四)——Nova

    Compute服务与其他OpenStack服务协作 xff0c 协调各种工作 xff0c 是OpenStack的核心服务 xff0c 这里需要操作Controller和Compute两个节点 1 Controller节点配置 创建数据库 注
  • debian8 安装&配置 zsh

    请访问我的个人博客 sourcod 安装zshsudo apt get install zsh安装oh my zsh sh c 34 curl fsSL https raw githubusercontent com robbyrussel
  • Conda错误:Collecting package metadata (current_repodata.json): failed

    conda新安装设置清华源后发现并没有使用 xff0c 且会出现错误 Collecting package metadata current repodata json failed 换了科大源也没成功 xff0c 考虑可能是默认源的问题
  • OpenCascade与三角剖分 笔记

    笔记 摘自 http www cppblog com eryar archive 2013 05 26 200605 html 概述 三角剖分是平面剖分中的一个重要课题 xff0c 在数字图像处理 计算机三维曲面造型 有限元计算 逆向工程等