VTK通过线段裁剪

线段拆分网格

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

效果如图:
在这里插入图片描述

连通域分割

使用连通域将已拆分的网格数据进行分割处理

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

效果如下:
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值