思路分析:模型表面漏洞,肯定有边界边,可能不止一个洞。1.提取边界边;2.运用联通性,依次选择边界环;3.边界环连接成面(1.取所有点,取中心点坐标(xi / n,yi / n,zi / n);2.线单元的两个点与中心点形成面单元;3.将点与面单元赋值数据形成新的补洞面数据);4.面与之前的模型结合,clean后形成最终补洞模型。
vtkPolyData* CommonMesh::CloseSurface(vtkPolyData* shape)
{
vtkSmartPointer<vtkFeatureEdges> fe = vtkSmartPointer<vtkFeatureEdges>::New();
fe->SetInputData(shape);
fe->BoundaryEdgesOn();
fe->NonManifoldEdgesOff();
fe->FeatureEdgesOff();
fe->ManifoldEdgesOff();
fe->Update();
vtkSmartPointer<vtkPolyDataConnectivityFilter> connect
= vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
connect->SetInputData(fe->GetOutput());
connect->Update();
const int ncontours = connect->GetNumberOfExtractedRegions();
vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::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<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New();
cleaner->SetInputData(append->GetOutput());
cleaner->Update();
vtkPolyData *result = vtkPolyData::New();
result->DeepCopy(cleaner->GetOutput());
return result;
}
vtkPolyData* CommonMesh::GenerateHoleCover(vtkPolyData* edges)
{
vtkPolyData* cover = vtkPolyData::New();
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCleanPolyData> sur_filt = vtkSmartPointer<vtkCleanPolyData>::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;
}