线段拆分网格
c++
void retrustMesh(vtkSmartPointer<vtkPolyData> polydata, vtkSmartPointer<vtkPoints> intermediatePoint)
{
vtkSmartPointer<vtkPoints> srcPoints = polydata->GetPoints();
int pointSize = intermediatePoint->GetNumberOfPoints();
//创建PointLocator并构建索引
vtkNew< vtkPointLocator> pointLocator;
pointLocator->SetDataSet(polydata);
pointLocator->BuildLocator();
//执行查询 找到选取点在源数据集中的索引
vtkNew< vtkIdList> result;
vtkNew< vtkIdList> segLinePointList;
vtkNew<vtkPoints> retPoints;
for (int i = 0; i < pointSize; i++)
{
pointLocator->FindClosestNPoints(1, intermediatePoint->GetPoint(i), result);
//vecId.push_back(result->GetId(0));
segLinePointList->InsertNextId(result->GetId(0));
retPoints->InsertNextPoint(srcPoints->GetPoint(result->GetId(0)));
}
int retPointSize = retPoints->GetNumberOfPoints();
vtkNew<vtkPoints> segPoints;
std::map<vtkIdType, vtkIdType> mapSrc2Seg;
std::map<vtkIdType, vtkIdType> mapLineSrc2Seg;
int srcPointSize = srcPoints->GetNumberOfPoints();
for (int i = 0; i < srcPointSize; i++)
{
//不在路径上,添加到字典中(key=源索引,value=分割后的索引)
if (segLinePointList->FindIdLocation(i) == -1)
{
int startIndex = segPoints->GetNumberOfPoints();
segPoints->InsertNextPoint(srcPoints->GetPoint(i)[0], srcPoints->GetPoint(i)[1], srcPoints->GetPoint(i)[2]);
mapSrc2Seg[i] = startIndex;
}
}
vtkNew<vtkPoints> segLinePoints;
std::set<vtkIdType> setLinePointIdType;
int lineSrcPointSize = segLinePointList->GetNumberOfIds();
for (int i = 0; i < lineSrcPointSize; i++)
{
mapLineSrc2Seg[segLinePointList->GetId(i)] = i;
segLinePoints->InsertNextPoint(srcPoints->GetPoint(segLinePointList->GetId(i))[0],
srcPoints->GetPoint(segLinePointList->GetId(i))[1], srcPoints->GetPoint(segLinePointList->GetId(i))[2]);
}
//
vtkSmartPointer<vtkCellArray> srcCellArr = polydata->GetPolys();
int srcDataSize = srcCellArr->GetNumberOfCells();
//创建单元数组,用于存储以上创建的线段
vtkSmartPointer<vtkCellArray> segCellArr = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkCellArray> segLineCellArr = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkCellArray> segLinePointsCellArr = vtkSmartPointer<vtkCellArray>::New();
vtkNew<vtkIdList> idList;
vtkNew<vtkPolygon> polygon;
for (int i = 0; i < srcDataSize; i++)
{
srcCellArr->GetCellAtId(i, idList);
int listSize = idList->GetNumberOfIds();
bool bInsert = true;
if (listSize > 0)
{
for (int j = 0; j < listSize; j++)
{
if (segLinePointList->FindIdLocation(idList->GetId(j)) != -1)
{
bInsert = false;
break;
}
}
}
else
{
bInsert = false;
}
if (bInsert)
{
polygon->GetPointIds()->SetNumberOfIds(listSize);//设置点数
for (int j = 0; j < listSize; j++)
{
polygon->GetPointIds()->SetId(j, mapSrc2Seg[idList->GetId(j)]);
}
segCellArr->InsertNextCell(polygon);
}
else
{
polygon->GetPointIds()->SetNumberOfIds(listSize);//设置点数
for (int j = 0; j < listSize; j++)
{
polygon->GetPointIds()->SetId(j, idList->GetId(j));
}
segLineCellArr->InsertNextCell(polygon);
}
}
// 构建新的网格
vtkNew<vtkPolyData> lineNewPolyData;
lineNewPolyData->SetPoints(srcPoints);
lineNewPolyData->SetPolys(segLineCellArr);
std::string linefile_path = "segLineData.ply";
vtkNew<vtkPolyData> lineNewPointsData;
lineNewPointsData->SetPoints(segLinePoints);
lineNewPointsData->SetPolys(segLinePointsCellArr);
std::string linePointsfile_path = "segLinePointsData.ply";
// 构建新的网格
vtkNew<vtkPolyData> newPolyData;
newPolyData->SetPoints(segPoints);
newPolyData->SetPolys(segCellArr);
std::string file_path = "segSphere.ply";
//写出为PLY格式文件
vtkSmartPointer<vtkPLYWriter> plywriter = vtkSmartPointer<vtkPLYWriter>::New();
plywriter->SetFileName(file_path.c_str());
plywriter->SetInputData(newPolyData);
plywriter->Write();
plywriter->Update();
plywriter->SetFileName(linefile_path.c_str());
plywriter->SetInputData(lineNewPolyData);
plywriter->Write();
plywriter->Update();
plywriter->SetFileName(linePointsfile_path.c_str());
plywriter->SetInputData(lineNewPointsData);
plywriter->Write();
plywriter->Update();
}
效果如图:
连通域分割
使用连通域将已拆分的网格数据进行分割处理
c++
int testClip()
{
PolyData to process
vtkSmartPointer<vtkPolyData> polyData;
vtkNew<vtkPLYReader> reader;
reader->SetFileName("E:\\work\\project\\VTKdemo\\build\\segSphere.ply");
reader->Update();
polyData = reader->GetOutput();
double bounds[6];
polyData->GetPoints()->GetBounds(bounds);
vtkNew<vtkPolyDataConnectivityFilter> connectivityFilter;
connectivityFilter->SetInputData(polyData);
connectivityFilter->SetExtractionModeToAllRegions();
connectivityFilter->Update();
int num = connectivityFilter->GetNumberOfExtractedRegions();
cout << "连通分区的总顶点数量: " << connectivityFilter->GetOutput()->GetNumberOfPoints() << endl;
if (num != 2)
{
return 1;
}
vtkNew<vtkCleanPolyData> clean;
ExtractionRegion(connectivityFilter, 0, clean);
//需要清除孤立点
vtkNew<vtkCleanPolyData> subClean;
ExtractionRegion(connectivityFilter, 1, subClean);
vtkNew<vtkPolyData> mainPoly;
vtkNew<vtkPolyData> subPoly;
JointMesh(clean, subClean, mainPoly, subPoly);
// Create a mapper and actor for original data.
vtkNew<vtkPolyDataMapper> originalMapper;
originalMapper->SetInputData(polyData);
vtkNew<vtkNamedColors> colors;
vtkNew<vtkActor> originalActor;
originalActor->SetMapper(originalMapper);
originalActor->GetProperty()->BackfaceCullingOn();
originalActor->GetProperty()->SetOpacity(0.6);
originalActor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData());
// Create a mapper and actor for extracted data.
vtkNew<vtkPolyDataMapper> extractedMapper;
extractedMapper->SetInputData(mainPoly);
vtkNew<vtkActor> extractedActor;
extractedActor->GetProperty()->SetColor(
colors->GetColor3d("Peacock").GetData());
extractedActor->SetMapper(extractedMapper);
extractedActor->GetProperty()->SetOpacity(0.6);
extractedActor->GetProperty()->BackfaceCullingOn();
// Create a mapper and actor for extracted data.
vtkNew<vtkPolyDataMapper> subExtractedMapper;
subExtractedMapper->SetInputData(subPoly);
vtkNew<vtkActor> subExtractedActor;
subExtractedActor->GetProperty()->SetColor(
colors->GetColor3d("Beige").GetData());
subExtractedActor->SetMapper(subExtractedMapper);
subExtractedActor->GetProperty()->SetOpacity(0.6);
subExtractedActor->GetProperty()->BackfaceCullingOn();
// Create a renderer.
vtkNew<vtkRenderer> renderer;
renderer->AddActor(originalActor);
renderer->AddActor(extractedActor);
renderer->AddActor(subExtractedActor);
renderer->GradientBackgroundOn();
renderer->SetBackground2(colors->GetColor3d("Beige").GetData());
renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());
extractedActor->SetPosition((bounds[1] - bounds[0]) / 1.9, 0, 0);
subExtractedActor->SetPosition((bounds[1] - bounds[0]) / 1.9, 0, 0);
originalActor->SetPosition(-(bounds[1] - bounds[0]) / 1.9, 0, 0);
// Create a render window.
vtkNew<vtkRenderWindow> renwin;
renwin->AddRenderer(renderer);
renwin->SetSize(512, 512);
renwin->SetWindowName("ExtractOutsideSurface");
// Create an interactor.
vtkNew<vtkRenderWindowInteractor> iren;
// 交互方式
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
iren->SetRenderWindow(renwin);
renwin->Render();
iren->Initialize();
iren->Start();
return EXIT_SUCCESS;
}
效果如下: