VTK通过线段裁剪

线段拆分网格

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;
}

效果如下:

相关推荐
devilnumber12 小时前
Java 递归算法 详解 + 核心要点 + 实战运用 + 避坑指南
java·开发语言·算法
asdfg125896314 小时前
JavaBean是什么?怎么理解?有什么用途?
java·开发语言
dsyyyyy110114 小时前
JavaScript变量
开发语言·javascript·ecmascript
z落落15 小时前
C#WinForm 窗体切换与窗体传值(登录跳转案例)+WinForm 窗体传值(从上往下传、从下往上传)
开发语言·windows·c#
allway215 小时前
How to Echo Multiline to a File in Bash [3 Methods]
开发语言·chrome·bash
weixin_4624462315 小时前
手把手教你用 Bash 脚本自动更新 /etc/hosts —— 自动绑定网卡 IP 与节点名
开发语言·tcp/ip·bash
一个梦醒了16 小时前
安装git bash选项推荐
开发语言·git·bash
摇滚侠16 小时前
SpringMVC 入门到实战 文件上传 75-77
java·后端·spring·maven·intellij-idea
GIS数据转换器16 小时前
城市排水生命线安全运行监测平台深度解析
java·运维·人工智能·python·安全·数据挖掘·无人机
ct97816 小时前
React 状态管理方案深度对比
开发语言·前端·react