vtk 补洞 两种实现

先说一下,这两种方式,现在感觉都有问题,就是补了之后,法线是错的;

补前

vtk 补洞 两种实现_第1张图片

 

补后

vtk 补洞 两种实现_第2张图片

 方案:

1.提取边界边;2.运用联通性,依次选择边界环;3.边界环连接成面(1.取所有点,取中心点坐标(\sumxi / n,\sumyi / n,\sumzi / n);2.线单元的两个点与中心点形成面单元;3.将点与面单元赋值数据形成新的补洞面数据);4.面与之前的模型结合,clean后形成最终补洞模型。

#include 
#include 
vtkPolyData*  GenerateHoleCover(vtkPolyData* edges)
{
	vtkPolyData* cover = vtkPolyData::New();
	vtkSmartPointer polys = vtkSmartPointer::New();
	vtkSmartPointer scalars = vtkSmartPointer::New();
	vtkSmartPointer points = vtkSmartPointer::New();
	vtkSmartPointer sur_filt = vtkSmartPointer::New();
	sur_filt->SetInputData(edges);
	sur_filt->Update();
	points->DeepCopy(sur_filt->GetOutput()->GetPoints());
	double centr[3] = { 0,0,0 };
	for (int i = 0; i < points->GetNumberOfPoints(); i++)
	{
		for (int j = 0; j < 3; j++)
		{
			centr[j] += points->GetPoint(i)[j];
		}
	}
	for (int j = 0; j < 3; j++)
	{
		centr[j] /= points->GetNumberOfPoints();
	}
	vtkIdType cnt_pt = points->InsertNextPoint(centr);
	for (int i = 0; i < sur_filt->GetOutput()->GetNumberOfCells(); i++)
	{
		vtkCell *cell = sur_filt->GetOutput()->GetCell(i);
		vtkIdType pts3[3];
		pts3[0] = cell->GetPointId(0);
		pts3[1] = cell->GetPointId(1);
		pts3[2] = cnt_pt;
		polys->InsertNextCell(3, pts3);
	}
	cover->SetPoints(points);
	cover->SetPolys(polys);
	return cover;


}
vtkPolyData*  CloseSurface(vtkPolyData* shape)
{
	vtkSmartPointer fe = vtkSmartPointer::New();
	fe->SetInputData(shape);
	fe->BoundaryEdgesOn();
	fe->NonManifoldEdgesOff();
	fe->FeatureEdgesOff();
	fe->ManifoldEdgesOff();
	fe->Update();
	vtkSmartPointer connect
		= vtkSmartPointer::New();
	connect->SetInputData(fe->GetOutput());
	connect->Update();
	const int ncontours = connect->GetNumberOfExtractedRegions();
	vtkSmartPointer append = vtkSmartPointer::New();
	append->AddInputData(shape);
	for (int i = 0; i < ncontours; i++)
	{
		connect->AddSpecifiedRegion(i);
		connect->SetExtractionModeToSpecifiedRegions();
		connect->Update();
		vtkPolyData *edges = connect->GetOutput();
		vtkPolyData* cover = GenerateHoleCover(edges);
		append->AddInputData(cover);
		cover->Delete();
		connect->DeleteSpecifiedRegion(i);

	}
	append->Update();
	vtkSmartPointer cleaner = vtkSmartPointer::New();
	cleaner->SetInputData(append->GetOutput());
	cleaner->Update();
	vtkPolyData *result = vtkPolyData::New();
	result->DeepCopy(cleaner->GetOutput());
	return result;
}

第二种方式是 vtk demo

  vtkNew fillHolesFilter;
  fillHolesFilter->SetInputData(polydata);
  fillHolesFilter->SetHoleSize(100000.0);
  fillHolesFilter->Update();

你可能感兴趣的:(VTK,fillhole)