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

效果如下:

相关推荐
rannn_11117 小时前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
杜子不疼.17 小时前
PyPTO:面向NPU的高效并行张量编程范式
开发语言
qq_124987075317 小时前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
lly20240617 小时前
C# 结构体(Struct)
开发语言
短剑重铸之日18 小时前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
YMWM_18 小时前
python3继承使用
开发语言·python
Once_day18 小时前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
若鱼191918 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
觉醒大王18 小时前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法