锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2022-10-28 17:00:00 rwi电阻br4x121rok

原文链接:https://blog.csdn.net/shenziheng1/article/details/54850678

1.多分辨率处理策略

模型抽取(Decimation)和细化(Subdivision)三角形网格模型多分辨处理中的两个重要操作是两个相反的操作。在保持模型拓扑结构的同时,使用这两种操作可以获得不同分辨率的网格模型。模型提取的功能是减少模型中的点数据和单元数据,便于模型的后续处理和交互渲染,类似于图像数据的降采样。网格细化是利用一定的细化规则,在给定的初始网格中插入新的点,从而不断细化新的网格单元,在极端细化的情况下,网格可以收敛一个明亮的曲面

2.网格抽取(Decimation)

2.1 vtkDecimatePro

VTK网格抽取主要有三种:vtkDecimatePro、vtkQuadricDecimation、vtkQuadricClustering。
vtkDecimatePro最常用的处理方法原理参考文献[1]文献[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  VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkRenderingFreeType); VTK_MODULE_INIT(vtkInteractionStyle);   #include  #include  #include  #include 
#include 
#include 
#include 
#include 
#include 
 
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.资料

2.《The VTK User’s Guide – 11thEdition》

参考博客:https://blog.csdn.net/shenziheng1/article/details/54850678

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章