VTK平面切割

文章目录

    • 一、vtkClipPolyData
    • 二、CapClip
    • 三、SolidClip
    • 四、vtkClipClosedSurface

本文的主要内容:简单介绍VTK中通过平面切割模型的相关功能。
哪些人适合阅读本文:有一定VTK基础的人。

一、vtkClipPolyData

VTK官网描述:
vtkClipPolyData使用用户指定的隐函数剪切多边形数据,如果使用vtkPlane作为隐函数就是平面切割。
vtkClipPolyData是一个过滤器,它使用vtkImplicitFunction的任何子类或输入标量数据来剪辑多边形数据。剪切意味着它实际上“剪切”了数据集的单元格,返回指定隐式函数(或大于标量值)内的所有内容,包括单元格的“片段”。(将其与vtkExtractGeometry进行比较,后者提取整个未切割的单元格。)此过滤器的输出是多边形数据。
要使用此过滤器,必须决定是使用隐式函数进行剪裁,还是使用输入标量数据。如果你想使用隐式函数进行剪裁,你必须:1)定义一个隐式函数2)用SetClipFunction方法设置它3)应用GenerateClipScalarsOn方法如果未指定ClipFunction,或者GenerateClipScalar处于关闭状态(默认设置),则输入的标量数据将用于剪裁polydata。
还可以指定一个标量值,用于决定隐式函数内部和外部的内容。还可以通过设置InsideOut实例变量来颠倒内部/外部的含义。(切割算法通过计算隐式函数值或使用数据集中每个点的输入标量数据来进行。将其与标量值进行比较以确定内部/外部。)
该滤波器可以被配置为计算第二输出。第二个输出是剪切掉的多边形数据。如果要访问此输出数据,请启用GenerateClippedData布尔值。

vtkClipPolyData的使用很简单:

vtkNew<vtkSphereSource> source;
source->SetThetaResolution(20);
source->SetPhiResolution(20);
source->Update();vtkNew<vtkPlane> plane;
plane->SetOrigin(polyData->GetCenter());
plane->SetNormal(1.0, -1.0, -1.0);vtkNew<vtkClipPolyData> clipper;
clipper->SetInputData(source->GetOutput());
clipper->SetClipFunction(plane);
clipper->Update();

在这里插入图片描述
这种方法切完之后是个空壳子,切口不封闭。要想让切割之后的切口封闭,继续往下看。

二、CapClip

此示例显示了如何在剪切的vtkPolyData上生成“上限”。在使用vtkClipPolyData进行裁剪后,它使用了一种巧妙的“技巧”将折线转换为多边形。
就是通过vtkFeatureEdges和vtkStripper将切割之后的边缘进行封闭。

// Extract feature edges
vtkNew<vtkFeatureEdges> boundaryEdges;
boundaryEdges->SetInputData(clipper->GetOutput());
boundaryEdges->BoundaryEdgesOn();
boundaryEdges->FeatureEdgesOff();
boundaryEdges->NonManifoldEdgesOff();
boundaryEdges->ManifoldEdgesOff();vtkNew<vtkStripper> boundaryStrips;
boundaryStrips->SetInputConnection(boundaryEdges->GetOutputPort());
boundaryStrips->Update();// Change the polylines into polygons
vtkNew<vtkPolyData> boundaryPoly;
boundaryPoly->SetPoints(boundaryStrips->GetOutput()->GetPoints());
boundaryPoly->SetPolys(boundaryStrips->GetOutput()->GetLines());vtkNew<vtkPolyDataMapper> boundaryMapper;
boundaryMapper->SetInputData(boundaryPoly);vtkNew<vtkActor> boundaryActor;
boundaryActor->SetMapper(boundaryMapper);
boundaryActor->GetProperty()->SetDiffuseColor(boundaryColor.GetData());

在这里插入图片描述

三、SolidClip

此示例剪裁网格并将背面特性应用于该网格,使其看起来具有实心内部。
还显示了被剪掉的部分的“幽灵”。

其实还是用vtkClipPolyData来切割,然后通过将模型内表面的漫反射和镜面反射光关闭,只保留环境光,造成一种视觉上模型是实心的效果。

// Create a mapper and actor
vtkNew<vtkPolyDataMapper> superquadricMapper;
superquadricMapper->SetInputConnection(clipper->GetOutputPort());vtkNew<vtkActor> superquadricActor;
superquadricActor->SetMapper(superquadricMapper);// Create a property to be used for the back faces. Turn off all
// shading by specifying 0 weights for specular and diffuse. Max the
// ambient.
vtkNew<vtkProperty> backFaces;
backFaces->SetSpecular(0.0);
backFaces->SetDiffuse(0.0);
backFaces->SetAmbient(1.0);
backFaces->SetAmbientColor(colors->GetColor3d("Tomato").GetData());superquadricActor->SetBackfaceProperty(backFaces);

在这里插入图片描述

四、vtkClipClosedSurface

VTK官网描述:
使用平面集合剪裁闭合曲面。
vtkClipClosedSurface将使用一组剪裁平面剪裁一个闭合的polydata曲面。它将通过创建剪切输入数据的新多边形面来生成新的闭合曲面。
形成曲面的多边形的方向很重要。多边形有一个正面和一个背面,背面定义了闭合曲面的内部或“实体”区域。当剪切平面剪切穿过“实体”区域时,会生成一个新的剪切面,但当剪切平面切割穿过孔或“空”区域时则不会。在处理复杂曲面时,这种区别至关重要。请注意,如果一个简单曲面的背面朝外,则该曲面在潜在的无限实体中定义了一个孔。
非歧管表面不应用作此过滤器的输入。输入曲面不应有开放边,并且不得有任何由两个以上面共享的边。vtkFeatureEdges过滤器可用于验证数据集是否满足这些条件。此外,输入曲面不应自相交,这意味着曲面的面只应接触其边缘。
如果启用了GenerateOutline,则此过滤器将在剪裁平面与数据相交的任何位置生成轮廓。ScalarMode选项将向输出中添加单元格标量,以便生成的面可以以与原始曲面不同的颜色显示。
InsideOut标志可用于反转剪辑区域内外的含义。这将更改剪裁平面的哪一侧被剪裁掉。
该滤波器可以被配置为计算第二输出。第二个输出是具有新三角面的多边形数据。如果要访问此输出数据,请启用GenerateClipFaceOutput布尔值。

vtkClipClosedSurface需要输入一个polyData和一组vtkPlaneCollection面集合,有两种输出一种是剪切之后的模型,一种是剪切的面的模型。

vtkNew<vtkNamedColors> colors;// PolyData to process
vtkSmartPointer<vtkPolyData> polyData;// Create a sphere
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetThetaResolution(20);
sphereSource->SetPhiResolution(11);
sphereSource->Update();polyData = sphereSource->GetOutput();auto center = polyData->GetCenter();
vtkNew<vtkPlane> plane1;
plane1->SetOrigin(center[0], center[1], center[2]);
plane1->SetNormal(0.0, -1.0, 0.0);
vtkNew<vtkPlane> plane2;
plane2->SetOrigin(center[0], center[1], center[2]);
plane2->SetNormal(0.0, 0.0, 1.0);
vtkNew<vtkPlane> plane3;
plane3->SetOrigin(center[0], center[1], center[2]);
plane3->SetNormal(-1.0, 0.0, 0.0);vtkNew<vtkPlaneCollection> planes;
planes->AddItem(plane1);
planes->AddItem(plane2);
planes->AddItem(plane3);vtkNew<vtkClipClosedSurface> clipper;
clipper->SetInputData(polyData);
clipper->SetClippingPlanes(planes);
clipper->SetActivePlaneId(2);
clipper->SetScalarModeToColors();
clipper->SetClipColor(colors->GetColor3d("Banana").GetData());
clipper->SetBaseColor(colors->GetColor3d("Tomato").GetData());
clipper->SetActivePlaneColor(colors->GetColor3d("Green").GetData());
clipper->GenerateClipFaceOutputOn();
clipper->Update();vtkNew<vtkDataSetMapper> clipMapper;
clipMapper->SetInputConnection(clipper->GetOutputPort());
//clipMapper->SetInputData(clipper->GetClipFaceOutput());vtkNew<vtkActor> clipActor;
clipActor->SetMapper(clipMapper);
clipActor->GetProperty()->SetColor(colors->GetColor3d("tomato").GetData());
clipActor->GetProperty()->SetInterpolationToFlat();

在这里插入图片描述
在这里插入图片描述
vtkClipClosedSurface和SolidClip这两种方法都有一个小问题,就是模型被一刀切完。如果只想切一半的话就没办法实现。

如果只想切一部分的话,在vtkClipClosedSurface里面SetClippingPlanes设置一个面的集合就可以,但是这个面集必须是闭合的,得到的效果如下图所示。
在这里插入图片描述
可以看出这种方法切出来的必然是一个凸集,要想切一个凹面如下图所示的效果,这种方法就做不了。
为什么会这样?是因为vtkClipClosedSurface的原理是把每个切割面法相对应的模型全部切掉,如下图所示。最后只剩下闭合平面包络中心的模型被保留。
在这里插入图片描述
可以想想看,无论怎么设计闭合平面以及平面法线如何指向,都无法得到下图所示的切割模型。
那么要如何实现切割凹面模型?可以尝试vtk的纹理切割,主要用到的是vtkImplicitTextureCoords,具体可以看官方例子,切出的效果是这样的。
在这里插入图片描述
可以看出也没有封口,要封口也不难,改变一下纹理就可以。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络各层的安全实例:从物理层到应用层的保护

在前面的各节中&#xff0c;我们学习了利用密码学技术实现机密性、完整性、数字签名和实体鉴别等安全服务的基本方法。在本节中&#xff0c;我们将讨论这些方法在网络各层的具体应用实例。这些安全应用实例涉及从物理层到应用层的所有层次。 1. 为什么需要在网络各层提供安全服…

GoLang:Go语言开发环境的配置

Go语言 Go语言开发环境的配置 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/a…

【Matlab】时间序列模型(ARIMA)

文章目录 前言一、示例二、代码实现----Matlab全部数据的平稳性检验ADF检验图检验法 划分训练集平稳性检验确定 p&#xff0c;q结果分析和模型检验模型预测 前言 接上一篇博客&#xff0c;用 Matlab 完成代码编写。 【学习笔记】时间序列模型(ARIMA) 一、示例 已知一个上市公…

Pandas 9-绘制柱状图

1. 准备数据 首先&#xff0c;需要准备一个DataFrame。 import pandas as pd # 创建一个DataFrame data { Name: [Alice, Bob, Charlie, David], Age: [24, 27, 22, 32], City: [New York, Los Angeles, Chicago, Houston], Score: [85, 92, 78, 88]} df pd.…

sql-labs46-50通关攻略

第46关 一.查询数据库 http://172.16.1.142/Less-46/?sort1%20and%20updatexml(1,concat(0x7e,(select%20database()),0x7e),1)--http://172.16.1.142/Less-46/?sort1%20and%20updatexml(1,concat(0x7e,(select%20database()),0x7e),1)-- 二.查表 http://172.16.1.142/Les…

软件测试 | 测试用例

测试用例&#xff08;Test Case&#xff09;是为了实施测试而向被测试的系统提供的一组集合&#xff0c;这组集合包含&#xff1a;测试环境&#xff0c;测试步骤&#xff0c;测试数据&#xff0c;预期结果等要素。 设计测试用例原则⼀&#xff1a; 测试用例中⼀个必需部分是对…

【微机原理】指令JZ和JNZ的区别

&#x1f31f; 嗨&#xff0c;我是命运之光&#xff01; &#x1f30d; 2024&#xff0c;每日百字&#xff0c;记录时光&#xff0c;感谢有你一路同行。 &#x1f680; 携手启航&#xff0c;探索未知&#xff0c;激发潜能&#xff0c;每一步都意义非凡。 JZ&#xff08;Jump …

php特性刷题

93 上面注释的是一些配置信息 然后包含flag.php页面 高亮显示 如果&#xff0c;先判断是否存在GET传参的参数num&#xff0c;如果弱比较等于4476&#xff0c;就会输出“no non no !” 如果包含字母那么就错误&#xff08;包含大小写&#xff09; 判断变量 $num 是否等于 4…

QEMU - user network

Documentation/Networking - QEMUQEMU/KVM中的网络虚拟化--Part2 User Networking | Xiaoye Zhengs blog (zxxyy.github.io)QEMU Network — ARM SoC Device Assignment Notes documentation (cwshu.github.io)slirp / libslirp GitLabGitHub - virtualsquare/libvdeslirp: li…

Python中排序算法之选择排序

选择排序算法是对《Python中排序算法之冒泡排序》中提到的冒泡排序算法的改进。 1 选择排序原理 选择排序是在参加排序的所有元素中找到数值最小&#xff08;或最大&#xff09;的元素&#xff0c;如果它不是左侧第一个元素&#xff0c;就使它与左侧第一个元素中的数据相互交…

Mysql8利用binlog实现数据恢复

文章目录 1binlog基本概念2 binlog相关常用命令3 binlog工具mysqlbinlog4 测试数据准备&导入数据5 模拟误删表6 数据恢复方式说明7 数据恢复分析(偏移量方式恢复)8 数据恢复9 验证10 数据恢复的局限性11 总结 1binlog基本概念 binlog即binary log&#xff0c;二进制日志文件…

Python爬虫02

xml 和html 区别 jsonpath模块 场景 多层嵌套的复杂字典直接提取数据 安装 pip install jsonpath使用 from jsonpath import jsonpathret jsonpath(dict, jaonpath语法规则字符串)语法规则 eg:

基于PHP评论区的存储型XSS漏洞

评论区的XSS漏洞是指攻击者在评论区输入恶意脚本&#xff0c;当其他用户浏览该页面时&#xff0c;这些恶意脚本会被执行&#xff0c;从而造成安全威胁。这种漏洞通常出现在网站没有对用户输入进行充分过滤和转义的情况下&#xff0c;为存储型XSS。存储型XSS攻击是指攻击者在目标…

使用 EasyExcel 高效读取大文件 Excel

使用 EasyExcel 高效读取大文件 Excel 的最佳实践 在现代应用中&#xff0c;数据处理经常涉及到大规模数据集的处理&#xff0c;Excel 作为一种常见的文件格式&#xff0c;经常用于数据导入和导出。然而&#xff0c;传统的 Excel 处理库如 Apache POI 在处理大文件时可能会面临…

实战项目:俄罗斯方块(一)

文章目录 &#x1f34a;自我介绍&#x1f34a;vt100 控制码1.概述2.数字格式①常用数字控制码②常用控制码 &#x1f34a;绘制方格 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我…

关于VUE3开发频繁引入ref,reactive,computed等基础函数。

利用unplugin-auto-import插件可以避免频繁引入ref&#xff0c;reactive&#xff0c;computed等基础函数。 1.安装unplugin-auto-import依赖 npm i -D unplugin-auto-import 2.在vite.config.ts中注入依赖 效果

Webfunny前端监控如何搭建高并发使用场景

Webfunny可以支持千万级别PV的日活量了。但是&#xff0c;我们默认的部署配置&#xff0c;是无法支持这么高的日活量的&#xff0c;需要我们做一些支持高并发的配置和操作&#xff0c;下面让我们一起看下如何让webfunny支持更高的并发量吧&#xff0c;下图为webfunny高并发架构…

AI安全前沿:模型攻击与防御策略

引言 随着chatGPT的横空出世&#xff0c;通用人工智能的时代正式开启。人工智能极大地影响了人类的生活方式和生产方式&#xff0c;例如以ChatGPT为代表的各类大模型&#xff0c;能够理解和生成人类语言&#xff0c;并以对话的方式同人类进行互动&#xff0c;能够执行撰写文本…

Hot Chips 2024:博通(Broadcom)展示AI计算ASIC的光学连接

引言 在2024年的Hot Chips会议上&#xff0c;博通展示了其最新的AI计算专用集成电路&#xff08;ASIC&#xff09;&#xff0c;这款ASIC集成了光学连接技术。这一展示不仅体现了博通在定制AI加速器领域的领先地位&#xff0c;也预示着未来数据中心网络技术的一个重要发展方向。…

重塑视频监控体验:WebRTC技术如何赋能智慧工厂视频高效管理场景

视频汇聚EasyCVR视频监控平台&#xff0c;作为一款智能视频监控综合管理平台&#xff0c;凭借其强大的视频融合汇聚能力和灵活的视频能力&#xff0c;在各行各业的应用中发挥着越来越重要的作用。 EasyCVR平台不仅兼容多种主流标准协议及私有协议/SDK的接入&#xff08;如&…