【VTK】vtkAppendPolyData将两条线连接合并为一条连通线

vtkAppendPolyData将两条线连接合并为一条连通线

将两条单独的vtkLineSource连接合并为一条线,合并后的线能够顶点与顶点是连通的,连通分区为1。


效果预览

在这里插入图片描述
在这里插入图片描述


方法介绍

vtkLineSource的数据实际上也是vtkPolyData,合并vtkPolyData自然要用到vtkAppendPolyData工具,但是只使用vtkAppendPolyData工具的话,只是简单把模型数据堆在一个vtkPolyData里作为整体包装,实际上检查后发现结果vtkPolyData还是由多个连通分区组成,意思是合并后多个vtkPolyData并没有连接在一起。

所以关键一步是使用vtkAppendPolyData后,还需要使用vtkCleanPolyData工具去处理连接结果。

要使得模型直接真正连通,需要vtkPolyData之间存在相同坐标的顶点(例如两个模型是分开的,那vtk并不会自动帮你增加连接线将模型连接起来,换句话说,连接线需要自己准备),因为vtkCleanPolyData的作用是去掉模型上重复坐标的顶点,去掉后会把断开的cell接上。

要确认是否连接成为一个连通的模型,可以用vtkPolyDataConnectivityFilter检查vtkPolyData有多少个连通分区,如果连通分区为1,表示模型所有顶点都是连接起来的。


源代码

源代码完整,可以直接复制粘贴编译运行。支持更多顶点的vtkLineSource。想对两个三维模型连接的话,需要改造一下源代码。

//两线段连接
#include <vtkPolyDataConnectivityFilter.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkAppendPolyData.h>
#include <vtkCleanPolyData.h>
#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkLineSource.h>
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkActor.h>
#include <vtkNew.h>

vtkSmartPointer<vtkPolyData> CombineLineData(vtkSmartPointer<vtkPolyData> source1, vtkSmartPointer<vtkPolyData> source2)
{
    
    
	cout << "开始连接" << endl;
	//找出距离最小点对,画一条连接线,然后合并
	vtkIdType a = -1, b = -1;
	double minDist = VTK_DOUBLE_MAX;
	for (vtkIdType i = 0; i < source1->GetNumberOfPoints(); i++)
	{
    
    
		for (vtkIdType j = 0; j < source2->GetNumberOfPoints(); j++)
		{
    
    
			double p[3], q[3];
			source1->GetPoint(i, p);
			source2->GetPoint(j, q);
			double dist2 = vtkMath::Distance2BetweenPoints(p, q);
			if (dist2 < minDist)
			{
    
    
				a = i;
				b = j;
				minDist = dist2;
			}
		}
	}
	//验证a,b确实是两路径的端点
	vtkNew<vtkIdList> aCells, bCells;
	source1->GetPointCells(a, aCells);
	source2->GetPointCells(b, bCells);
	if (aCells->GetNumberOfIds() != 1 || bCells->GetNumberOfIds() != 1)
	{
    
    
		cout << "非端点" << endl;
		return source1->GetNumberOfCells() > source2->GetNumberOfCells() ? source1 : source2;
	}
	//创建两输入模型之间的连接线
	double p[3], q[3];
	source1->GetPoint(a, p);
	source2->GetPoint(b, q);
	vtkSmartPointer<vtkLineSource> line = vtkSmartPointer<vtkLineSource>::New();
	line->SetPoint1(p);
	line->SetPoint2(q);
	line->Update();
	//连接操作
	vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
	append->AddInputData(source1);
	append->AddInputData(line->GetOutput());
	append->AddInputData(source2);
	vtkSmartPointer<vtkCleanPolyData> clean = vtkSmartPointer <vtkCleanPolyData>::New();
	clean->SetInputConnection(append->GetOutputPort());
	clean->Update();
	clean->GetOutput()->BuildLinks();
	vtkNew<vtkPolyDataConnectivityFilter> temp;
	temp->SetInputData(clean->GetOutput());
	temp->SetExtractionModeToAllRegions();
	temp->Update();
	cout << "连接后连通分区数量:" << temp->GetNumberOfExtractedRegions() << endl;
	cout << "连接前source1顶点数量:" << source1->GetNumberOfPoints() << ",Cell数量:" << source1->GetNumberOfCells() << endl;
	cout << "连接前source2顶点数量:" << source2->GetNumberOfPoints() << ",Cell数量:" << source2->GetNumberOfCells() << endl;
	cout << "连接后result顶点数量:" << clean->GetOutput()->GetNumberOfPoints() << ",Cell数量:" << clean->GetOutput()->GetNumberOfCells() << endl;

	return clean->GetOutput();
}

int main()
{
    
    
	//创建两条分开的线
	vtkSmartPointer<vtkLineSource> line1 = vtkSmartPointer<vtkLineSource>::New();
	line1->SetPoint1(-2, 0, 1);
	line1->SetPoint2(-1, 1, 1);
	line1->Update();
	vtkSmartPointer<vtkLineSource> line2 = vtkSmartPointer<vtkLineSource>::New();
	line2->SetPoint1(2, 0, 1);
	line2->SetPoint2(1, 1, 1);
	line2->Update();

	vtkSmartPointer<vtkPolyData> result = CombineLineData(line1->GetOutput(), line2->GetOutput());

	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputData(result);
	
	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);

	vtkNew<vtkRenderer> renderer;
	renderer->AddActor(actor);

	vtkNew<vtkRenderWindow> rw;
	rw->AddRenderer(renderer);

	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetRenderWindow(rw);
	rw->Render();
	renderWindowInteractor->Start();
}

猜你喜欢

转载自blog.csdn.net/qq_37366618/article/details/130357169