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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/396868.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搜维尔科技:分析OptiTrack光学动作捕捉应用领域!

虚拟制作 当今虚拟制作阶段低延迟、超精确摄像机跟踪的事实上的标准。 用于运动科学的 OptiTrack OptiTrack 系统提供世界领先的测量精度和简单易用的工作流程&#xff0c;为研究人员和生物力学师的研究提供理想的 3D 跟踪数据。对所有主要数字测力台、EMG 和模拟设备的本机即…

基于STM32F407的coreJSON使用教程

目录 概述 工程建立 代码集成 函数介绍 使用示例 概述 coreJSON是FreeRTOS中的一个组件库&#xff0c;支持key查找的解析器&#xff0c;他只是一个解析器&#xff0c;不能生成json数据。同时严格执行 ECMA-404 JSON 标准。该库用 C 语言编写&#xff0c;设计符合 ISO C90…

书生浦语大模型实战营-课程笔记(5)

LLM部署特点&#xff0c;内存开销大&#xff0c;TOKEN数量不确定 移动端竟然也可以部署LLM。之前以为只能在服务端部署&#xff0c;移动端作为客户端发起请求来调用大模型。 LMDeploy用于模型量化 模型量化&#xff1a;降低内存消耗 推理性能对比 量化主要作用&#xff1a;…

推荐一个内网穿透工具,支持Windows桌面、Linux、Arm平台客户端

神卓互联是一款常用的内网穿透工具&#xff0c;它可以将本地服务器映射到公网上&#xff0c;并提供域名或子域名给外部访问。神卓互联具有简单易用、高速稳定的特点&#xff0c;支持Windows桌面版、Linux版、Arm版客户端&#xff0c;以及硬件等。 神卓互联内网穿透技术简介 企…

JAVA--异常处理

目录 1. 异常概述 1.1 什么是生活的异常 1.2 什么是程序的异常 1.3 异常的抛出机制 1.4 如何对待异常 2. Java异常体系 2.1 Throwable 2.2 Error 和 Exception 2.3 编译时异常和运行时异常 3. 常见的错误和异常 3.1 Error 3.2 运行时异常 3.3 编译时异常 4. 异常…

阿里云ECS服务器如何选择操作系统?

阿里云服务器镜像怎么选择&#xff1f;云服务器操作系统镜像分为Linux和Windows两大类&#xff0c;Linux可以选择Alibaba Cloud Linux&#xff0c;Windows可以选择Windows Server 2022数据中心版64位中文版&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说下阿里云服务器操…

【Redis,Java】Redis的两种序列化方式—nosql数据库

redis和mysql的区别&#xff1a; redis是属于nosql的数据库&#xff0c;而mysql是属于sql数据库&#xff0c;redis是属于nosql数据库。mysql是存储在磁盘中的&#xff0c;redis是存储在内存中的&#xff0c;所以redis的读取书读快。这里所说的redis代表nosql&#xff0c;而mysq…

TiDB 7.5.0 LTS 高性能数据批处理方案

过去&#xff0c;TiDB 由于不支持存储过程、大事务的使用也存在一些限制&#xff0c;使得在 TiDB 上进行一些复杂的数据批量处理变得比较复杂。 TiDB 在面向这种超大规模数据的批处理场景&#xff0c;其能力也一直在演进&#xff0c;其复杂度也变得越来越低&#xff1a; ○ 从…

docker环境常用容器安装

目录 1.安装partainer 2.安装myql 3.安装redis 4.安装Minio 5.安装zibkin 6.安装nacos 7.安装RabbitMq 8.安装RocketMq 8.1启动service 8.2修改对应配置 8.3启动broker 8.4启动控制台 9.安装sentinel 10.安装elasticsearch 11.安装Kibana 12.安装logstash/file…

python遍历键值对kw.items()、 kw.keys()、 kw.values()、enumerate(kw.keys())

代码如下&#xff1a; 运行报错如下&#xff1a; 我想要的输出结果为&#xff1a; 这里引用一段解释&#xff1a; 示例代码中 “for key,value in kw:” 其实是遍历 keys() 但是用了两个参数来接收&#xff0c;所以会报错 “ValueError: too many values to unpack”&#xff…

MySQL5.7.24解压版安装教程

一、MySQL5.7.24解压版安装步骤 1.在指定目录下解压压缩包。比如在D:\Program Files\mysql下解压 2.在D:\Program Files\mysql\mysql-5.7.24-winx64目录下新建data文件夹&#xff0c;如果此目录下没有my.ini也需要手动创建 3.my.ini 文件配置内容如下 [mysqld] # 设置3306端口…

南京哪家证券公司融资融券利率最低?两融利率最低多少?4.5%

融资融券利率 融资融券利率最低是4.5%&#xff0c;市场上两融利率的最低标准&#xff0c;只有个别券商可以办理做到&#xff0c;无门槛利率5%&#xff0c;量大4.5%~4.8%&#xff01; 市场上的融资融券利率差异是较大的&#xff0c;平均利率水平在6%左右&#xff0c;最低利率4…

MySQL环境搭建

目录 一、MySQL安装完成特征 二、MySQL的卸载 三、MySQL安装 四、安装失败原因 五、MySQL的登录 5.1 服务的启动与停止 5.2 登录服务器 六、MySQL的基本操作 七、MySQL图形化管理工具 八、MySQL目录结构 九、常见问题解决 十、总结 一、MySQL安装完成特征 安装好D…

Redis第一关之常规用法

简介 Redis不用多说&#xff0c;已经火了很多年了&#xff0c;也用了很多年了。现在做一些归纳总结。 这篇文章主要介绍Redis的常规知识及用法&#xff0c;包括数据结构、使用场景、特性、过期机制、持久化机制。 Redis与Mysql Mysql是一款基于磁盘的关系型SQL数据库。 Redi…

Debezium发布历史139

原文地址&#xff1a; https://debezium.io/blog/2023/02/04/ddd-aggregates-via-cdc-cqrs-pipeline-using-kafka-and-debezium/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. DDD Aggregates via CDC-CQRS Pi…

MySQL--SQL解析顺序

前言&#xff1a; 一直是想知道一条SQL语句是怎么被执行的&#xff0c;它执行的顺序是怎样的&#xff0c;然后查看总结各方资料&#xff0c;就有了下面这一篇博文了。 本文将从MySQL总体架构—>查询执行流程—>语句执行顺序来探讨一下其中的知识。 一、MySQL架构总览&a…

使用kubeadm快速部署一个k8s集群

前言 此文所使用服务的环境为&#xff1a; docker 版本&#xff1a; v25.0.3 kubernetes版本&#xff1a;v1.25.0 1 安装准备 部署k8s集群的节点按照用途可以分为如下2类角色 master&#xff1a;集群的master节点&#xff0c;集群的初始化节点slave&#xff1a; 集群的slave节…

【力扣白嫖日记】1873.计算特殊奖金

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1873.计算特殊奖金 表&#xff1a;Employees 列名类型employee_idintnamevarcharsalaryint employee_id 是…

展示用HTML编写的个人简历信息

展示用HTML编写的个人简历信息 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

Soul CEO张璐引领社交创新,拓展年轻人的社交体验

随着互联网的迅速崛起,社交方式已经历了翻天覆地的变化,年轻人们对社交的需求也愈发多样化。在这个充满创新和竞争的社交领域,新型开放式社交平台Soul App 在CEO张璐的带领下一直在不断探索和引领着新的方向,以满足年轻一代的社交需求,为他们打造了一个全新、自由、创新的社交平…