VTK通过线段裁剪

news2024/11/16 11:29:31

线段拆分网格

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法【查找算法的概念】

查找算法概念 1、查找的基本概念2、评价查找算法3、问题: 查找过程中我们要研究什么? 1、查找的基本概念 查找的概念&#xff1a; 根据给定的某个值&#xff0c;在查找表中确定一个其关键字等于给定值的数据元素或者记录。 查找算法也可以叫搜索算法。查找算法就是从一个有序…

Spring Boot 手写starter!!!

原因&#xff1a;为什么要手写starter&#xff1f;&#xff1f;&#xff1f; 原因&#xff1a;简化功能。 实例&#xff1a;以分页为例&#xff1a;写一个starter。 1.首先定义一个PageX注解。 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented p…

独立版表情包小程序完整版源码前后端源码,附带系统搭建教程

搭建要求&#xff1a; 1.系统要求Nginx 1.18.0PHP-7.2mysql5.6&#xff0c;开启 ssl&#xff0c;php需要安装 sg11 扩展 2.设置伪静态 location / { index index.php index.html index.htm; if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s$1; } } location /a…

ESP32 LVGL开发板例程使用记录:自制常用汉字字库(一)

需要工具和文件&#xff1a; 1、LVGL官方在线字体转换工具&#xff1a;Online font converter - TTF or WOFF fonts to C array | LVGL 2、字体和常用汉字字库文件&#xff1a;字体字库.7z - 蓝奏云 一、制作过程 1、首先打开字体转换工具 2、填入需要的内容&#xff0c;这里…

ShardingSphere 5.x 系列【15】分布式主键生成器

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 概述2. 配置3. 内置算法3.1 UUID3.2 Snowflake3.3 NanoId3.4 CosId3.5 Co…

力扣面试经典150 —— 1-5题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 1. [简单] 合并…

【Activiti7】全新Activiti7工作流讲解

一、Activiti7概述 官网地址:https://www.activiti.org/ Activiti由Alfresco软件开发,目前最高版本Activiti 7。是BPMN的一个基于java的软件实现,不过 Activiti 不仅仅包括BPMN,还有DMN决策表和CMMN Case管理引擎,并且有自己的用户管理、微 服务API 等一系列功能,是一…

C#与VisionPro联合开发——INI存储和CSV存储

1、INI存储 INI 文件是一种简单的文本文件格式&#xff0c;通常用于在 Windows 环境中存储配置数据。INI 文件格式由一系列节&#xff08;section&#xff09;和键值对&#xff08;key-value pairs&#xff09;组成&#xff0c;用于表示应用程序的配置信息。一个典型的 INI 文…

Uipath 读取Word模板实现录用通知书PDF批量生成

本文主要讲解如何使用Uipath 读取Excel 面试人员信息表&#xff0c;读取Word模板&#xff0c;再批量生成录用通知书PDF文件&#xff0c;该自动化大大提高了HR 的工作效率。 注&#xff1a;本方案实现采用无代码模式&#xff0c;通过拖拉控件实现。 1. 数据准备 1.1 面试人员…

【力扣】Z 字形变换,模拟 + 直接构造

Z 字形变换原题地址 方法一&#xff1a;利用二维矩阵模拟 对于特殊情况&#xff0c;Z 字形变换后只有一行或只有一列&#xff0c;则变换后的字符串和原字符串相同。 对于一般情况&#xff0c;我们可以考虑按照题目要求&#xff0c;把字符串按照 Z 字形存储到二维数组中&…

高考志愿选择辅助系统

高考志愿选择辅助系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基…

数据结构D4作业

1.实现单向循环链表的功能 loop.c #include "loop.h" loop_p create_loop() { loop_p H(loop_p)malloc(sizeof(loop)); if(HNULL) { printf("创建失败\n"); return NULL; } H->len0; H->nextH; ret…

0基础JAVA期末复习最终版

啊啊啊啊啊啊啊啊啊啊&#xff0c;根据网上各位大佬的复习资料&#xff0c;看了很多大多讲的是基础但对内容的整体把握上缺乏系统了解。但是很不幸最终挂科了&#xff0c;那个出题套路属实把我整神了&#xff0c;所以我决定痛改前非&#xff0c;酣畅淋漓的写下这篇文章。。。。…

做抖店想要快速起店怎么办?产品和流量是关键!新手可收藏!

大家好&#xff0c;我是电商小布。 在抖音小店开通完成后&#xff0c;大家考虑的第一件事情&#xff0c;一定是小店如何能够快速出单&#xff0c;成功起店。 店铺出单的重点&#xff0c;其实就在小店的运营上。 那么这么多的环节&#xff0c;关键点在哪呢&#xff1f; 答案…

unity屏幕受伤特效

//使用用途&#xff1a;同于屏幕掉血的后处理特效 //请结合和脚本&#xff1a;BloodScreen 挂载至摄像机使用本特效 //本特效设计之初未考虑兼容移动设备&#xff0c;请注意//使用说明&#xff1a; //掉血获取此脚本&#xff0c;将showBlood设置为true&#xff0c;如果您需要更…

基础光学系列:(一)光学在机器视觉中的角色:原理、应用与学习途径

光学是一门研究光的产生、传播以及与物质相互作用的科学&#xff0c;对于机器视觉技术的发展至关重要。机器视觉利用计算机和相机系统模拟人类视觉&#xff0c;解释和理解图像&#xff0c;广泛应用于制造业、医疗、安全监控等领域。本文旨在探讨光的传播原理及其在机器视觉中的…

【Python-语法】

Python-语法 ■ Python基础■ 数据类型■ 注释 单行注释&#xff0c;多行注释■ 编码方式 ■■■■■ ■ Python基础 ■ 数据类型 ■ 注释 单行注释&#xff0c;多行注释 ■ 编码方式 ■ ■ ■ ■ ■

花生壳内网穿透教程(图文并茂)

目录 前言&#xff1a; 使用教程&#xff1a; 1.注册账号 2.软件下载及安装&#xff1a; 3.账号绑定及花生壳的使用 4.内网穿透的配置&#xff08;重点&#xff09; 4.2 新增映射页面&#xff1a; 4.3 上面几种映射的区别&#xff1a; 4.4 上面TCP类型的区别&#xff1a;…

【Android 性能优化:内存篇】——ExoPlayer 释放后内存没有恢复问题探索

背景 最近笔者承接项目的内存优化指标&#xff0c;在内存调研的过程中发现项目中视频播放结束后&#xff0c;内存没有恢复到播放前到水平。项目中用的 EXO 版本为2.19.1&#xff0c;并且笔者自己也写了个简单的 Demo&#xff0c;发现也是如此。虽然有一些偏门方法可以优化&…