• VTK 图形基本操作进阶_多分辨率策略(模型细化的三种方法)


    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.网格模型细化实验

      1 #include <vtkAutoInit.h>
      2 VTK_MODULE_INIT(vtkRenderingOpenGL);
      3 VTK_MODULE_INIT(vtkRenderingFreeType);
      4 VTK_MODULE_INIT(vtkInteractionStyle);
      5  
      6 #include <vtkSmartPointer.h>
      7 #include <vtkPolyDataReader.h>
      8 #include <vtkPolyData.h>
      9 #include <vtkLinearSubdivisionFilter.h>
     10 #include <vtkLoopSubdivisionFilter.h>
     11 #include <vtkButterflySubdivisionFilter.h>
     12 #include <vtkPolyDataMapper.h>
     13 #include <vtkActor.h>
     14 #include <vtkRenderer.h>
     15 #include <vtkRenderWindow.h>
     16 #include <vtkCamera.h>
     17 #include <vtkRenderWindowInteractor.h>
     18  
     19 int main()
     20 {
     21     //读数据
     22     vtkSmartPointer<vtkPolyDataReader> reader =
     23         vtkSmartPointer<vtkPolyDataReader>::New();
     24     reader->SetFileName("fran_cut.vtk");
     25     reader->Update();
     26  
     27     vtkSmartPointer<vtkPolyData> orig = reader->GetOutput();
     28     std::cout << "original" << "-----------------------" << std::endl;
     29     std::cout << "模型点数为: " << orig->GetNumberOfPoints() << std::endl;
     30     std::cout << "模型面数为: " << orig->GetNumberOfPolys() << std::endl;
     31     //线性网格细分滤波器
     32     vtkSmartPointer<vtkLinearSubdivisionFilter> linear =
     33         vtkSmartPointer<vtkLinearSubdivisionFilter>::New();
     34     linear->SetInputData(orig);
     35     linear->SetNumberOfSubdivisions(4);
     36     linear->Update();
     37  
     38     vtkSmartPointer<vtkPolyData> linearInfo = linear->GetOutput();
     39     std::cout << "linear" << "-----------------------" << std::endl;
     40     std::cout << "模型点数为: " << linearInfo->GetNumberOfPoints() << std::endl;
     41     std::cout << "模型面数为: " << linearInfo->GetNumberOfPolys() << std::endl;
     42  
     43     //Loop网格细分滤波器
     44     vtkSmartPointer<vtkLoopSubdivisionFilter> loop =
     45         vtkSmartPointer<vtkLoopSubdivisionFilter>::New();
     46     loop->SetInputData(orig);
     47     loop->SetNumberOfSubdivisions(4);
     48     loop->Update();
     49  
     50     vtkSmartPointer<vtkPolyData> loopInfo = loop->GetOutput();
     51     std::cout << "loop" << "-----------------------" << std::endl;
     52     std::cout << "模型点数为: " << loopInfo->GetNumberOfPoints() << std::endl;
     53     std::cout << "模型面数为: " << loopInfo->GetNumberOfPolys() << std::endl;
     54  
     55     //butterfly网格细分滤波器
     56     vtkSmartPointer<vtkButterflySubdivisionFilter> butterfly =
     57         vtkSmartPointer<vtkButterflySubdivisionFilter>::New();
     58     butterfly->SetInputData(orig);
     59     butterfly->SetNumberOfSubdivisions(4);
     60     butterfly->Update();
     61  
     62     vtkSmartPointer<vtkPolyData> butterflyInfo = butterfly->GetOutput();
     63     std::cout << "butterfly" << "-----------------------" << std::endl;
     64     std::cout << "模型点数为: " << butterflyInfo->GetNumberOfPoints() << std::endl;
     65     std::cout << "模型面数为: " << butterflyInfo->GetNumberOfPolys() << std::endl;
     66     
     67     vtkSmartPointer<vtkPolyDataMapper> origMapper =
     68         vtkSmartPointer<vtkPolyDataMapper>::New();
     69     origMapper->SetInputData(orig);
     70     vtkSmartPointer<vtkActor> origActor =
     71         vtkSmartPointer<vtkActor>::New();
     72     origActor->SetMapper(origMapper);
     73  
     74     vtkSmartPointer<vtkPolyDataMapper> linearMapper =
     75         vtkSmartPointer<vtkPolyDataMapper>::New();
     76     linearMapper->SetInputData(linear->GetOutput());
     77     vtkSmartPointer<vtkActor> linearActor =
     78         vtkSmartPointer<vtkActor>::New();
     79     linearActor->SetMapper(linearMapper);
     80  
     81     vtkSmartPointer<vtkPolyDataMapper> loopMapper =
     82         vtkSmartPointer<vtkPolyDataMapper>::New();
     83     loopMapper->SetInputData(loop->GetOutput());
     84     vtkSmartPointer<vtkActor> loopActor =
     85         vtkSmartPointer<vtkActor>::New();
     86     loopActor->SetMapper(loopMapper);
     87  
     88     vtkSmartPointer<vtkPolyDataMapper> butterflyMapper =
     89         vtkSmartPointer<vtkPolyDataMapper>::New();
     90     butterflyMapper->SetInputData(butterfly->GetOutput());
     91     vtkSmartPointer<vtkActor> butterflyActor =
     92         vtkSmartPointer<vtkActor>::New();
     93     butterflyActor->SetMapper(butterflyMapper);
     94     //
     95     double ltView[4] = { 0, 0, 0.5, 0.5 };
     96     double rtView[4] = { 0.5, 0, 1, 0.5 };
     97     double lbView[4] = { 0, 0.5, 0.5, 1 };
     98     double rbView[4] = { 0.5, 0.5, 1, 1 };
     99  
    100     vtkSmartPointer<vtkRenderer> origRender =
    101         vtkSmartPointer<vtkRenderer>::New();
    102     origRender->SetViewport(ltView);
    103     origRender->AddActor(origActor);
    104     origRender->SetBackground(1, 0, 0);
    105  
    106     vtkSmartPointer<vtkRenderer> linearRender =
    107         vtkSmartPointer<vtkRenderer>::New();
    108     linearRender->SetViewport(rtView);
    109     linearRender->AddActor(linearActor);
    110     linearRender->SetBackground(0, 1, 0);
    111  
    112     vtkSmartPointer<vtkRenderer> loopRender =
    113         vtkSmartPointer<vtkRenderer>::New();
    114     loopRender->SetViewport(lbView);
    115     loopRender->AddActor(loopActor);
    116     loopRender->SetBackground(0, 0, 1);
    117  
    118     vtkSmartPointer<vtkRenderer> butterflyRender =
    119         vtkSmartPointer<vtkRenderer>::New();
    120     butterflyRender->SetViewport(rbView);
    121     butterflyRender->AddActor(butterflyActor);
    122     butterflyRender->SetBackground(0, 0, 0);
    123     //
    124     vtkSmartPointer<vtkRenderWindow> rw =
    125         vtkSmartPointer<vtkRenderWindow>::New();
    126     rw->AddRenderer(origRender);
    127     rw->AddRenderer(linearRender);
    128     rw->AddRenderer(loopRender);
    129     rw->AddRenderer(butterflyRender);
    130     rw->SetSize(640, 640);
    131     rw->SetWindowName("PolyData Subdivision");
    132  
    133     origRender->GetActiveCamera()->SetPosition(0, -1, 0);
    134     origRender->GetActiveCamera()->SetFocalPoint(0, 0, 0);
    135     origRender->GetActiveCamera()->SetViewUp(0, 0, 1);
    136     origRender->GetActiveCamera()->Azimuth(30);
    137     origRender->GetActiveCamera()->Elevation(30);
    138     origRender->ResetCamera();//刷新照相机  
    139     linearRender->SetActiveCamera(origRender->GetActiveCamera());
    140     loopRender->SetActiveCamera(origRender->GetActiveCamera());
    141     butterflyRender->SetActiveCamera(origRender->GetActiveCamera());
    142     
    143     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
    144         vtkSmartPointer<vtkRenderWindowInteractor>::New();
    145     rwi->SetRenderWindow(rw);
    146     rwi->Start();
    147     rw->Render();
    148  
    149     return 0;
    150 }
    输出结果:
    红色视窗为原始三角网格模型,绿色视窗采用了线性细分算法;蓝色视窗采用Loop细分算法;黑色视窗采用了Butterfly细分算法。
    鼻子部位的细节图:
    从上面结果上看,我们可以看出:线性细分效果似乎没有起到多大作用??!Loop细分结果得到了很光滑的曲面,Butterfly细分在细节部分处理的并不很理想。
    注意事项 :
    所有模型细化算子仅对三角网格数据有效,因此在处理多边形数据时,需要通过VTKTriangleFilter将多边形网格转换为三角网格才能处理。
  • 相关阅读:
    MinGW 介绍
    Android Gallery组件实现循环显示图像
    白话经典算法系列之六 高速排序 高速搞定
    background-position 使用方法具体介绍
    小程序:目录
    SLC-测试-Postman:Postman 工具
    云-腾讯云:视频解决方案-un
    云-腾讯云:实时音视频
    Tool:XMind
    小程序:微信公众平台:小程序
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14241889.html
Copyright © 2020-2023  润新知