笔记

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

概述

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

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

Figure 1.1 Shaded Cylinder and Box

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();
} 

OpenCascade与三角剖分 笔记相关推荐

  1. OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移、缩放和旋转操作

    OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移.缩放和旋转操作 C3DWidget.h #pragma once#include <QtWidgets/QApplic ...

  2. OpenCascade学习笔记-创建一个简单的OpenCascade单文档

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Open ...

  3. OpenCascade笔记:gp包

    gp包 gp(Geometric Processor package).包中的类是非持续性(non-persistent),即按值的方式处理,而不是按引用. 包gp提供以下类(参看): gp gp_A ...

  4. 笔记:Delaunay三角剖分(Delaunay Triangulation)相关知识

    最近接触到计算Delaunay三角剖分的问题,也算是计算几何的一个经典问题了.按照别人的算法,也自己实现了个( 源代码下载 ),发现点集大的时候,程序计算起来特慢.后来分析发现,别人程序号称的都是O( ...

  5. 近期知识图谱顶会论文推荐,另附超详笔记解读

    精选 4 篇来自 WSDM 2019.NeurIPS 2018.WWW 2018 和 COLING 2018 的知识图谱相关工作,带你快速了解知识图谱领域最新研究进展. 本期内容选编自微信公众号「开放 ...

  6. OpenCASCADE:使用扩展数据交换 XDE之自定义注释note

    OpenCASCADE:使用扩展数据交换 XDE之自定义笔记 自定义注释 初始化 创建注释 编辑注释 添加注释 查找注释 移除注释 删除注释 自定义注释 在 XDE 文档中,自定义注释由类XCAFDo ...

  7. OpenCASCADE:扩展数据交换(XDE)的简介

    OpenCASCADE:扩展数据交换(XDE)的简介 基本术语 XDE组织 组件 验证属性 名称 颜色和图层 几何尺寸和公差 (GD&T) 剪裁平面 保存的视图 自定义笔记 扩展数据交换 (X ...

  8. OpenCASCADE:网格之BRepMesh 架构

    OpenCASCADE:网格之BRepMesh 架构 目标 一般工作流程 通用接口 创建模型数据结构 离散化边缘 3D 和 2D 曲线 治愈离散模型 离散化人脸 离散化人脸 目标 所选架构的主要目标是 ...

  9. OpenCASCADE: CMake 工具构建OCCT

    OpenCASCADE:编译OCCT OpenCASCADE:编译OCCT 使用 CMake 工具构建 启动 CMake 配置流程 项目生成 建造 OpenCASCADE:编译OCCT 笔记 在构建 ...

最新文章

  1. ffmpeg 编译Android
  2. 某程序员对比美团和阿里的卷文化区别:美团重过程,死抠没用细节;阿里更自由,注重结果!...
  3. 绿色版mysql安装步骤
  4. python 求两条曲线的交点_这几种问法都是考察张角问题,高考数学圆锥曲线的焦点弦张角定理...
  5. 自己编写一个前端精确打印控件
  6. SQL-用JOIN连接多个表
  7. 8.1 异常(Exceptions)
  8. 姿态估计4-02:voxelpose(多视角3D人体姿态估算)-官方数据训练测试,环境搭建等
  9. python字符画绘制代码_python图片转字符画代码是什么
  10. java混淆工具zelix比较_常用的5款java混淆器
  11. 清华大学计算机系学术委员会,清华大学学术委员会召开2018年度全体会议
  12. 挖矿病毒audiodg.exe\taskhost.exe溯源与手动查杀方法
  13. java解析图片GPS等信息,springboot项目获得图片GPS
  14. ps怎么创建双曲线图层如何添加
  15. 2019年5G创新深度研究报告
  16. XV6 RISCV源码阅读报告之中断
  17. 500G 史上最全的JAVA全套视频教程网盘
  18. 快手只发作品不直播的赚钱方法
  19. python股票全套系统_熬了一晚上,小白用Python写了一个股票提醒系统
  20. UiPath被Everest Group评为PEAK Matrix®流程挖掘产品领导者和明星企业

热门文章

  1. 【转载】社交的蒸发冷却效应
  2. 【CEO访谈】银客网林恩民:特立独行的互联网人
  3. pytorch笔记:contiguous tensor 存储知识
  4. 计算机组成原理——关于原码、补码、移码运算及浮点数运算的总结
  5. sha256 C语言实现
  6. 科普|电脑配置明明不低,为什么越用越卡?
  7. overflow属性的使用
  8. 2013年11月5日 14:49:03
  9. jupyter批量删除文件夹
  10. 嚼得菜根做得大事·《菜根谭》·一