1.模型细化

vtk中实现网格细化的累有vtkLinearSubdivisionFilter、vtkLoopsubdivisionFilter、vtkButterflySubdivisionFilter。这三个类都继承自vtkInterpolatingSubdivisionFilter。具体的类的继承关系图如下图所示:
vtkInterpolatingSunvisionFilter内部提供了SetNumberOfSubvisions()函数来设置细化的次数,其中每次细化后模型的三角面片的个数将是细化前的四倍。因此,在对网格模型进行n次细化后,该模型的面片个数将是原始模型面片数目的4*n倍。

1.1 vtkLinearSubdivisionFilter

该类实现了一种线性细分算法,每次细分将每个三角形面片生成四个新的面片,该算法比较简单,速度快,但是细分后不能产生光滑的模型。

1.2 vtkLoopSubdivisionFilter

该类实现的是Loop细分算法,每次细分会将一个三角面片生成4个三角面片,具体算法思想可以参考文献[1];该方法可以生成光滑的连续曲面,应用比较广泛。

1.3 vtkButterflySubdivisionFilter

该类实现了蝶形细分算法,具体的算法思想可以参考文献[2].

2.网格模型细化实验

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyData.h>
#include <vtkLinearSubdivisionFilter.h>
#include <vtkLoopSubdivisionFilter.h>
#include <vtkButterflySubdivisionFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkCamera.h>
#include <vtkRenderWindowInteractor.h>int main()
{//读数据vtkSmartPointer<vtkPolyDataReader> reader =vtkSmartPointer<vtkPolyDataReader>::New();reader->SetFileName("fran_cut.vtk");reader->Update();vtkSmartPointer<vtkPolyData> orig = reader->GetOutput();std::cout << "original" << "-----------------------" << std::endl;std::cout << "模型点数为: " << orig->GetNumberOfPoints() << std::endl;std::cout << "模型面数为: " << orig->GetNumberOfPolys() << std::endl;//线性网格细分滤波器vtkSmartPointer<vtkLinearSubdivisionFilter> linear =vtkSmartPointer<vtkLinearSubdivisionFilter>::New();linear->SetInputData(orig);linear->SetNumberOfSubdivisions(4);linear->Update();vtkSmartPointer<vtkPolyData> linearInfo = linear->GetOutput();std::cout << "linear" << "-----------------------" << std::endl;std::cout << "模型点数为: " << linearInfo->GetNumberOfPoints() << std::endl;std::cout << "模型面数为: " << linearInfo->GetNumberOfPolys() << std::endl;//Loop网格细分滤波器vtkSmartPointer<vtkLoopSubdivisionFilter> loop =vtkSmartPointer<vtkLoopSubdivisionFilter>::New();loop->SetInputData(orig);loop->SetNumberOfSubdivisions(4);loop->Update();vtkSmartPointer<vtkPolyData> loopInfo = loop->GetOutput();std::cout << "loop" << "-----------------------" << std::endl;std::cout << "模型点数为: " << loopInfo->GetNumberOfPoints() << std::endl;std::cout << "模型面数为: " << loopInfo->GetNumberOfPolys() << std::endl;//butterfly网格细分滤波器vtkSmartPointer<vtkButterflySubdivisionFilter> butterfly =vtkSmartPointer<vtkButterflySubdivisionFilter>::New();butterfly->SetInputData(orig);butterfly->SetNumberOfSubdivisions(4);butterfly->Update();vtkSmartPointer<vtkPolyData> butterflyInfo = butterfly->GetOutput();std::cout << "butterfly" << "-----------------------" << std::endl;std::cout << "模型点数为: " << butterflyInfo->GetNumberOfPoints() << std::endl;std::cout << "模型面数为: " << butterflyInfo->GetNumberOfPolys() << std::endl;vtkSmartPointer<vtkPolyDataMapper> origMapper =vtkSmartPointer<vtkPolyDataMapper>::New();origMapper->SetInputData(orig);vtkSmartPointer<vtkActor> origActor =vtkSmartPointer<vtkActor>::New();origActor->SetMapper(origMapper);vtkSmartPointer<vtkPolyDataMapper> linearMapper =vtkSmartPointer<vtkPolyDataMapper>::New();linearMapper->SetInputData(linear->GetOutput());vtkSmartPointer<vtkActor> linearActor =vtkSmartPointer<vtkActor>::New();linearActor->SetMapper(linearMapper);vtkSmartPointer<vtkPolyDataMapper> loopMapper =vtkSmartPointer<vtkPolyDataMapper>::New();loopMapper->SetInputData(loop->GetOutput());vtkSmartPointer<vtkActor> loopActor =vtkSmartPointer<vtkActor>::New();loopActor->SetMapper(loopMapper);vtkSmartPointer<vtkPolyDataMapper> butterflyMapper =vtkSmartPointer<vtkPolyDataMapper>::New();butterflyMapper->SetInputData(butterfly->GetOutput());vtkSmartPointer<vtkActor> butterflyActor =vtkSmartPointer<vtkActor>::New();butterflyActor->SetMapper(butterflyMapper);//double ltView[4] = { 0, 0, 0.5, 0.5 };double rtView[4] = { 0.5, 0, 1, 0.5 };double lbView[4] = { 0, 0.5, 0.5, 1 };double rbView[4] = { 0.5, 0.5, 1, 1 };vtkSmartPointer<vtkRenderer> origRender =vtkSmartPointer<vtkRenderer>::New();origRender->SetViewport(ltView);origRender->AddActor(origActor);origRender->SetBackground(1, 0, 0);vtkSmartPointer<vtkRenderer> linearRender =vtkSmartPointer<vtkRenderer>::New();linearRender->SetViewport(rtView);linearRender->AddActor(linearActor);linearRender->SetBackground(0, 1, 0);vtkSmartPointer<vtkRenderer> loopRender =vtkSmartPointer<vtkRenderer>::New();loopRender->SetViewport(lbView);loopRender->AddActor(loopActor);loopRender->SetBackground(0, 0, 1);vtkSmartPointer<vtkRenderer> butterflyRender =vtkSmartPointer<vtkRenderer>::New();butterflyRender->SetViewport(rbView);butterflyRender->AddActor(butterflyActor);butterflyRender->SetBackground(0, 0, 0);//vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(origRender);rw->AddRenderer(linearRender);rw->AddRenderer(loopRender);rw->AddRenderer(butterflyRender);rw->SetSize(640, 640);rw->SetWindowName("PolyData Subdivision");origRender->GetActiveCamera()->SetPosition(0, -1, 0);origRender->GetActiveCamera()->SetFocalPoint(0, 0, 0);origRender->GetActiveCamera()->SetViewUp(0, 0, 1);origRender->GetActiveCamera()->Azimuth(30);origRender->GetActiveCamera()->Elevation(30);origRender->ResetCamera();//刷新照相机  linearRender->SetActiveCamera(origRender->GetActiveCamera());loopRender->SetActiveCamera(origRender->GetActiveCamera());butterflyRender->SetActiveCamera(origRender->GetActiveCamera());vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Start();rw->Render();return 0;
}

输出结果:

红色视窗为原始三角网格模型,绿色视窗采用了线性细分算法;蓝色视窗采用Loop细分算法;黑色视窗采用了Butterfly细分算法。
鼻子部位的细节图:
从上面结果上看,我们可以看出:线性细分效果似乎没有起到多大作用??!Loop细分结果得到了很光滑的曲面,Butterfly细分在细节部分处理的并不很理想。
注意事项
所有模型细化算子仅对三角网格数据有效,因此在处理多边形数据时,需要通过VTKTriangleFilter将多边形网格转换为三角网格才能处理。

3.参考文献

[1] Loop C T. Smooth Subdivision Surfaces Based on Triangles[J]. Department of Mathematics the University of Utah Masters Thesis, 1987.
[2] Zorin D, Der P, Sweldens W. Interpolating Subdivision for meshes with arbitrary topology[C]// Conference on Computer Graphics and Interactive Techniques. ACM, 1996:189-192.

4.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

VTK修炼之道53:图形基本操作进阶_多分辨率策略(模型细化的三种方法)相关推荐

  1. VTK修炼之道52:图形基本操作进阶_多分辨率策略(模型抽取的三种方法)

    1.多分辨率处理策略 模型抽取(Decimation)和细化(Subdivision)是两个相反的操作,是三角形网格模型多分辨处理中的两个重要操作.使用这两个操作可以在保持模型拓扑结构的同时,得到不同 ...

  2. VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒

    1.基本图形操作意义 图形处理,比如图形平滑.多分辨率分析.特征提取等都离不开一些基本的图形操作.掌握这些基本的图形操作有助于理解和深入学习图形处理和分析方法. VTK中提供了多种图形的基本操作,其中 ...

  3. VTK修炼之道59:图形基本操作进阶_纹理映射

    1.纹理映射 纹理映射是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程.纹理生成过程实质上是将所定义的纹理映射为某种三维物体表面的属性,并参与后续的光照计算.在三维图形中,纹理映射运用的十分广泛, ...

  4. VTL:图形基本操作进阶——多分辨率策略(模型抽取的三种方法)

    1.多分辨率处理策略 模型抽取Decimation)和细化(Subdivision)是两个相反的操作,是三角形网格模型多分辨率处理中的两个重要的操作.使用这两个操作可以在保持模型拓扑结构的同时,得到不 ...

  5. VTK修炼之道58:图形基本操作进阶_点云配准技术(迭代最近点ICP算法)

    1.Iterative Closest Points算法 点云数据配准最经典的方法是迭代最近点算法(Iterative Closest Points,ICP).ICP算法是一个迭代的过程,每次迭代中对 ...

  6. VTK修炼之道57:图形基本操作进阶_点云配准技术(LandMark标记点算法和坐标系显示方法)

    1.点云配准 在计算机逆向工程中,通过三维扫描等实物数字化技术可以获取各种点云数据.但是受到测量环境和设备的影响,再一次测量的情况下,难以获取实物整体的点云数据,因此需要多次从不同角度进行测量.但不同 ...

  7. VTK修炼之道56:图形基本操作进阶_表面重建技术(三维点云曲面重建)

    1.点云重建 虽然Delaunay三角剖分算法可以实现网格曲面重建,但是其应用主要在二维剖分,在三维空间网格生成中遇到了问题.因为在三维点云曲面重建中,Delaunay条件不在满足,不仅基于最大最小角 ...

  8. VTK修炼之道55:图形基本操作进阶_表面重建技术(等值面提取)

    1.等值面提取 等值面(线)提取是一种常用的可视化技术,常应用于医学.地质.气象等领域.例如,在医学图像处理中,由于CT.MRI等图像分辨率越来越高,虽然体绘制技术可以清晰地对数据内部结构进行可视化, ...

  9. VTK修炼之道54:图形基本操作进阶_表面重建技术(三角剖分)

    1.表面重建 通过三维扫描仪所获取的实际物体的空间点云数据仅仅表示物体的几何形状,而无法表达其内部的拓扑结构.拓扑结构对于实际图形处理以及可视化具有更重要的意义.因此,这就需要利用表面重建技术奖点云数 ...

最新文章

  1. 如何解决机器学习中的数据不平衡问题?
  2. matlab rootdir,Python cfg.ROOT_DIR属性代码示例
  3. 数据结构之顺序循环队列
  4. git学习(四):理解git暂存区(stage)
  5. 10天学安卓-第七天
  6. JAVA大数据-Week2-DAY5
  7. zoj1134 Strategic Game(DP/图论)
  8. 浅谈volatile的原理
  9. Leetcode122. 买卖股票的最佳时机 II(贪心)
  10. 【电磁场与电磁波课程设计】基于HFSS的双频微带天线仿真及设计
  11. C# 火星文转化 算法 dictionary 的使用案例
  12. 一文读懂背照式CMOS图像传感器
  13. pdf的下载和在线预览
  14. element vue 上传模板_Vue Element UI upload 组件上传文件之后 file list 依旧是空数组
  15. SQL语句报错:1062, “Duplicate entry ‘XXX‘ for key ‘XXX‘
  16. 2020年12月陕西计算机等级考试,2020年12月陕西全国计算机应用水平考试报名时间...
  17. python输出一个函数多项式_python实现PolynomialFeatures多项式的方法
  18. LeetCode4.python实现:寻找两个有序数组中的中位数问题☆☆☆
  19. 打印系统开发(15)——WinForm开发(43)——winform 使用打印机
  20. 图片上添加文字及图片

热门文章

  1. 实战:搭建CA认证中心,使用CA证书搭建HTTPS
  2. Bootstrap – 1.认识
  3. OSPF网络类型详解
  4. Matplotlib图例中文乱码
  5. NYOJ 559 报数游戏
  6. OPCDAAuto.dll的C#使用方法浅析(转载)
  7. 「Python」10个python项目
  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(73)-微信公众平台开发-消息管理
  9. [动规] hihocoder 1149 回文字符序列
  10. 如何实现在O(n)时间内排序,并且空间复杂度为O(1)