VTK修炼之道52:图形基本操作进阶_多分辨率策略(模型抽取的三种方法)
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道52:图形基本操作进阶_多分辨率策略(模型抽取的三种方法)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.多分辨率處理策略
模型抽取(Decimation)和細化(Subdivision)是兩個相反的操作,是三角形網格模型多分辨處理中的兩個重要操作。使用這兩個操作可以在保持模型拓撲結構的同時,得到不同分辨率的網格模型。模型抽取的作用是減少模型中的點數據和單元數據,便于模型的后續(xù)處理與交互渲染,這類似于圖像數據的降采樣。而網格細化則是利用一定的細化規(guī)則,在給定的初始網格中插入新的點,從而不斷細化出新的網格單元,在極限細化情況下,該網格能夠收斂一個光華的曲面。2.網格抽取(Decimation)
2.1?vtkDecimatePro
VTK中主要有三種網格抽取類:vtkDecimatePro、vtkQuadricDecimation、vtkQuadricClustering。 vtkDecimatePro是最常用的,該處理方法的原理參考文獻[1],是用一種邊塌陷的方法來刪除點和單元,處理速度比較快,而且可以方便的控制網格抽取的幅度,得到不同級別的模型數據。該類的使用方法,如下: vtkSmartPoint<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New(); decimate->SetInput(input); decimate->SetTargetReduction(0.6); decimate->update();vtkDecimatePro接收一個單元為三角網格的vtkPolyData數據,其中函數SetTargetReduction()用于設置變量TargetReduction的大小,將網格面片抽取的比例控制在0~1.這里設置為0.6,說明有60%的三角面片單元將被移除。使用這個函數可以得到不同程度的簡化網格模型,不過,為確保函數效果,一般需要滿足下面四個條件:
- vtkDecimatePro需要支持模型拓撲的改變,即將PreserveTopology變量的值設置為FALSE。
- 支持網格分裂,即Splitting變量的值設置為TRUE。
- 支持修改模型的邊界,即將變量BoundaryVetexDeletion的值設置為TRUE。
- 設置最大誤差變量MaximumError的值為VTK_DOUBLE_MAX。
2.2 vtkQuadricDecimation
該類也可以實現三角形網格簡化,并能較好地逼近原模型。該簡化算法思想可以參考文獻[2]。該類雖然也提供了SetTargetReduction()函數用于設置模型簡化程度,但是最終簡化率并非嚴格等于程序中設置的簡化率。可以通過GetActualReduction()函數來獲取最終模型簡化率。2.3 vtkQuadricClustering
該類是三種實現模型抽取算法中最快的一種,能夠處理大數據模型。其算法思想可以參考文獻[3]。通過StartAppend()、Append()、EndAppend()函數可以將整個模型分為多個網格片處理,從而避免一次性處理整個模型,減少內存開支,提高處理效率。3.vtkDecimatePro用于模型抽取實驗
作為結果觀測實驗,這里僅僅使用vtkDecimatePro類實現模型抽取。 示例代碼如下: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkRenderingFreeType); VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h> #include <vtkPolyDataReader.h> #include <vtkDecimatePro.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkCamera.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h>int main() {vtkSmartPointer<vtkPolyDataReader> reader =vtkSmartPointer<vtkPolyDataReader>::New();reader->SetFileName("fran_cut.vtk");reader->Update();vtkSmartPointer<vtkPolyData> original = reader->GetOutput();std::cout << "抽取前"<< "-----------------------" << std::endl;std::cout << "模型點數為: " << original->GetNumberOfPoints() << std::endl;std::cout << "模型面數為: " << original->GetNumberOfPolys() << std::endl;vtkSmartPointer<vtkDecimatePro> decimation =vtkSmartPointer<vtkDecimatePro>::New();decimation->SetInputData(reader->GetOutput());decimation->SetTargetReduction(0.6);decimation->Update();vtkSmartPointer<vtkPolyData> decimated = decimation->GetOutput();std::cout << "抽取后"<< "-----------------------" << std::endl;std::cout << "模型點數為:" << decimated->GetNumberOfPoints() << std::endl;std::cout << "模型面數為:" << decimated->GetNumberOfPolys() << std::endl;/vtkSmartPointer<vtkPolyDataMapper> origMapper =vtkSmartPointer<vtkPolyDataMapper>::New();origMapper->SetInputData(reader->GetOutput());vtkSmartPointer<vtkActor> origActor =vtkSmartPointer<vtkActor>::New();origActor->SetMapper(origMapper);vtkSmartPointer<vtkPolyDataMapper> deciMapper =vtkSmartPointer<vtkPolyDataMapper>::New();deciMapper->SetInputData(decimation->GetOutput());vtkSmartPointer<vtkActor> deciActor =vtkSmartPointer<vtkActor>::New();deciActor->SetMapper(deciMapper);///double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> leftRenderer =vtkSmartPointer<vtkRenderer>::New();leftRenderer->SetViewport(leftViewport);leftRenderer->AddActor(origActor);leftRenderer->SetBackground(1.0, 0, 0);vtkSmartPointer<vtkRenderer> rightRenderer =vtkSmartPointer<vtkRenderer>::New();rightRenderer->SetViewport(rightViewport);rightRenderer->AddActor(deciActor);rightRenderer->SetBackground(0, 0, 0);leftRenderer->GetActiveCamera()->SetPosition(0, -1, 0);leftRenderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);leftRenderer->GetActiveCamera()->SetViewUp(0, 0, 1);leftRenderer->GetActiveCamera()->Azimuth(30);leftRenderer->GetActiveCamera()->Elevation(30);leftRenderer->ResetCamera();//刷新照相機rightRenderer->SetActiveCamera(leftRenderer->GetActiveCamera());//同步顯示///vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(leftRenderer);rw->AddRenderer(rightRenderer);rw->SetSize(640, 320);rw->SetWindowName("PolyData Decimation");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Start();return 0; }輸出結果如下圖所示:左圖為原始圖像,右圖為簡化后的效果,從圖總可以看出,簡化后的模型面片數量減少,模型變得非常粗糙。
4.參考文獻
[1].Schroeder W J. Decimation of triangle meshes[J]. Acm Siggraph Computer Graphics, 1992, 26(2):65-70. [2].Garland M. Surface simplification using quadric error metrics[C]// Conference on Computer Graphics and Interactive Techniques. ACM Press/Addison-Wesley Publishing Co. 1997:209-216. [3].Lindstrom P. Out-of-core simplification of large polygonal models[C]// ACM SIGGRAPH. 2000:259-262.5.參看資料
1.《C++ primer》2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發(fā)進階[M]. 機械工業(yè)出版社, 2015. 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的VTK修炼之道52:图形基本操作进阶_多分辨率策略(模型抽取的三种方法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞鸽_飞鸽2007_飞鸽传书_飞鸽传书2
- 下一篇: VTK修炼之道53:图形基本操作进阶_多