【VTK】VTK框选表面拾取三角面片——通过观察者命令模式

2023-05-16

VTK框选拾取三角面片


最近需要实现拾取三角面片的交互功能,看了官方示例和网友分享,都是使用vtkInteractorStyleRubberBandPick搭配vtkAreaPicker。但是具体实现方法都是选择继承vtkInteractorStyleRubberBandPick的方式,重写里面的方法。我觉得使用观察者命令模式去实现这个功能是更合理便捷的方法


效果预览

在这里插入图片描述
在这里插入图片描述


功能说明

通过鼠标框选模型表面的面片,然后利用红色边框显示被框选的三角面片


方法介绍

  • 利用vtkInteractorStyleRubberBandPick交互方式实现框选。(通过R键切换交互模式和框选模式

  • 利用vtkAreaPicker收集框选的信息。VTK还提供了vtkCellPicker,但是CellPicker只能选中某个对象,不能框选一个集合。

  • 利用观察者命令模式来实现显示被框选面片的逻辑功能。

  • 源代码中已经写好详细注释。


源代码

完整代码可以直接编译运行

#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleRubberBandPick.h>
#include <vtkAreaPicker.h>
#include <vtkCommand.h>
#include <vtkCallbackCommand.h>
#include <vtkExtractPolyDataGeometry.h>
#include <vtkSphereSource.h>
#include <vtkPlanes.h>
#include <vtkDataSetMapper.h>
#include <vtkProperty.h>

/*
* 定义命令:
* 使用vtkInteractorStyleRubberBandPick交互方式时,会自动触发vtkAreaPicker
* 交互时框选的信息会存储在vtkAreaPicker中
* 将vtkAreaPicker的结束拾取事件绑定vtkPickerCallback
* 类似QT中信号与槽的机制
* vtkAreaPicker触发结束拾取信号,然后执行vtkPickerCallback中的Execute函数
*/
class vtkPickerCallback : public vtkCommand
{
public:
	//@brief 定义New函数(固定格式)
	static vtkPickerCallback* New() {return new vtkPickerCallback;}
	//@brief 定义Execute函数(vtkCommand中的Execute为纯虚函数,必须要实现)
	virtual void Execute(vtkObject* caller, unsigned long, void*);
	void SetPolyData(vtkPolyData* input);
	void SetRenderer(vtkRenderer* input);
	
private:
	vtkPolyData* polyData;				//需要处理的几何数据
	vtkRenderer* renderer;				//需要调用的渲染器

	vtkDataSetMapper* mapper;			//用于显示框选面片的mapper
	vtkActor* actor;					//用于显示框选面片的actor
};

int main()
{
	//****************创建球体*****************
	vtkSphereSource* sphere = vtkSphereSource::New();
	sphere->SetThetaResolution(18);
	sphere->SetPhiResolution(18);
	sphere->SetRadius(10);
	sphere->SetCenter(0, 0, 0);
	sphere->Update();

	//****************创建Mapper***************
	vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
	mapper->SetInputConnection(sphere->GetOutputPort());
	//换成此语句效果一致:mapper->SetInputData(sphere->GetOutput());
	
	//****************创建Actor****************
	vtkActor* actor = vtkActor::New();
	actor->SetMapper(mapper);

	//****************创建渲染器***************
	vtkRenderer* renderer = vtkRenderer::New();
	renderer->AddActor(actor);

	//****************创建渲染窗口*************
	vtkRenderWindow* renderWindow = vtkRenderWindow::New();
	renderWindow->AddRenderer(renderer);
	
	//****************创建交互器***************
	vtkRenderWindowInteractor* renderWindowInteractor = vtkRenderWindowInteractor::New();

	//****************创建交互方式*************
	vtkInteractorStyleRubberBandPick* interactorStyle = vtkInteractorStyleRubberBandPick::New();

	//****************创建拾取回调函数*********
	vtkPickerCallback* callback = vtkPickerCallback::New();
	callback->SetPolyData(sphere->GetOutput());
	callback->SetRenderer(renderer);

	//****************创建区域拾取器***********
	vtkAreaPicker* areaPicker = vtkAreaPicker::New();
	areaPicker->AddObserver(vtkCommand::EndPickEvent, callback);		//为“结束拾取”事件绑定“拾取回调函数”
	
	renderWindowInteractor->SetRenderWindow(renderWindow);				//为交互器设置渲染窗口
	renderWindowInteractor->SetInteractorStyle(interactorStyle);		//为交互器设置交互方式
	renderWindowInteractor->SetPicker(areaPicker);						//为交互器设置拾取器

	renderWindowInteractor->Start();

	return 0;
}

void vtkPickerCallback::Execute(vtkObject* caller, unsigned long, void*)
{
	//通过反射获取调用者
	vtkAreaPicker* areaPicker = static_cast<vtkAreaPicker*>(caller);
	//获取框选的视锥体(由六个面组成)
	vtkPlanes* frustum = areaPicker->GetFrustum();
	//提取视锥体内的模型
	vtkExtractPolyDataGeometry* extract = vtkExtractPolyDataGeometry::New();
	extract->SetInputData(polyData);
	extract->SetImplicitFunction(frustum);
	extract->Update();
	//设置actor
	mapper->SetInputConnection(extract->GetOutputPort());
	mapper->ScalarVisibilityOff();
	actor->GetProperty()->SetColor(1, 0, 0);
	actor->GetProperty()->SetPointSize(5);
	actor->GetProperty()->SetRepresentationToWireframe();
	//渲染器加入显示框选的actor
	renderer->AddActor(actor);

}

void vtkPickerCallback::SetPolyData(vtkPolyData* input)
{
	polyData = input;
}

void vtkPickerCallback::SetRenderer(vtkRenderer* input)
{
	renderer = input;
	//初始化用于显示框选面片的mapper和actor
	mapper = vtkDataSetMapper::New();
	actor = vtkActor::New();
	actor->SetMapper(mapper);
}


存在问题

在这里插入图片描述

因为算法上是利用框选后生成的视锥体去切割模型然后提取视锥体内的面片,所以会出现将前面和后面的面片都被囊括进来。我在下一篇文章会解决这个问题。 下一篇:VTK框选表面拾取面片——仅选中前表面

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【VTK】VTK框选表面拾取三角面片——通过观察者命令模式 的相关文章

  • VTK Python 代码详解(五)读取点云数据、旋转平移、合并显示

    VTK Python 代码整理 读取点云 txt 数据并显示 txt 点云数据 代码 效果图 代码2 背面效果 代码封装优化 两个点云模型同时显示 代码 效果图 旋转 平移动点云模型 旋转 平移 变换代码 完整代码 最终效果 读取点云 tx
  • VTK 测量类Widget的应用 与 vtkDistanceWidget 3D测试 问题

    vtkDistanceWidget 用于在二维平面上测量两点之间的距离 vtkAngleWidget 用于在平面的角度测量 AngleWidget 感觉这都是 2D控件 include
  • QT+PCL+VS制作点云显示界面(彩色显示xyz点云)

    前言 最近正学习QVTKWidget插件显示点云 参考博文 https blog csdn net wokaowokaowokao12345 article details 51078495 时发现其提供的官方编译样只能例打开XYZRGB的
  • VTK相机类vtkCamera原理及用法

    vtk是著名的开源三维渲染库 在三维渲染过程中的一个非常重要的内容就是相机即vtkCamera类的设置 在VTK中 相机的实质是一个观测点 VTK的官方Doc对vtkCamera写的十分简略 暗坑很多 在学习和使用vtkCamera的过程中
  • 最小二乘法——拟合平面方程(深度相机外参标定、地面标定)

    1 最小二乘法 最小二乘法 又称最小平方法 是一种数学优化技术 它通过最小化误差的平方和寻找数据的最佳函数匹配 利用最小二乘法可以简便地求得未知的数据 并使得这些求得的数据与实际数据之间误差的平方和为最小 最小二乘法还可用于曲线拟合 其他一
  • vtk教程第三章 计算机图形学入门

    计算机图形学是数据可视化的基础 实际上 可视化是将数据转换为一组图形原语的过程 然后使用计算机图形学的方法将这些原语转换成图片或动画 本章讨论计算机图形学的基本原理 我们从描述光和物理物体如何相互作用形成我们所看到的开始 接下来 我们将研究
  • VTK(0)---CMake工程

    VTK 0 CMake工程 目录 前言 一 指定cmake版本 二 设置工程 三 针对Qt 自动使用moc uic rcc程序预处理 h文件 ui文件等 四 平台移植问题 五 设置编译模式 六 找到包 七 包含头文件等 八 链接库文件 九
  • VTK5.10.1+Cmake+vs2010整合安装

    1 下载 VS2010就自己在网上找了咯 这里不提供具体路径下载了 vtk 5 10 1 zip源程序 vtkdata 5 10 1 zip 数据 vtkDocHtml 5 10 1 tar gz 文档可以不下载 vtk相关安装程序下载 h
  • C++11 chrono计时

    我的C 文章列表 C 中Duration Time point和Clocks 万里归来少年心的博客 CSDN博客 time point C 11中的chrono库 实现时间相关的功能 1 time point time point表示一个时
  • vtk使用之Mapper和actor的关联

    参考博客 VTK的Mapper Dezeming的博客 CSDN博客 vtk mapper VTK 图形进阶 vtkPolyData数据生成与显示 简 单的博客 CSDN博客 vtkpolydata 类vtkMapper及其派生类 把输入的
  • 如何将ASCII和BINARY数据同时写入同一个文件

    我的输出使用 VTK 数据类型 由于我的数据变得越来越大 用 ASCII 编写它需要花费相当多的时间 这就是我到目前为止一直在做的事情 我需要将其更改为二进制格式 但问题是该文件有一些标头 请参阅http www vtk org VTK i
  • 自 Mac OS 10.11 El Capitan 起,具有系统完整性保护的 DYLD_LIBRARY_PATH 技巧的替代方案

    这是我所拥有的 Mac 操作系统 10 11 埃尔卡皮坦 python 2 7 12 从 python org 安装 Library Frameworks Python framework 皮查姆 2016 2 3 vtk 7 1 0 这是
  • 使用 pip 安装 VTK

    我在 Arch Linux 上使用 Python 3 7 我一直在尝试用 pip 安装 Mayavi 但在安装 vtk 时总是失败 所以我发现即使尝试通过 pip 自行安装 vtk 应该有效 那个vtk确实没有安装 我收到此错误 sudo
  • VTK 与真实 X 一起工作,与 Xvfb 一起崩溃

    我正在调试一个第 3 方 Python 脚本 该脚本使用 VTK 库实现无头图像处理 当使用常规 X 窗口会话运行时 它会按预期工作 窗口会瞬间闪烁 当针对 Xvfb 内存中的虚拟帧缓冲区 运行时 它会崩溃 脚本是这样的 省略了一些废话 i
  • vtkRenderer 错误

    我是 vtk 的新手 所以我首先使用 CMake 和 Visual Studio 2017 构建 vtk 8 1 1 并使用默认选项和示例 许多示例运行良好 但其中一些会出现错误 这是 CreateTree 示例 但 HelloWorld
  • 如何在一个 .vtu 文件中写入多个 vtkUnstructedGrid

    我想在一个 vtu 文件中写入多个非结构化网格 我在下面尝试过 MakeHexagonalPrism 和 MakeHexahedron 返回 vtkSmartPointer 类型 结果是输出文件中只有一个非结构化网格 vtkSmartPoi
  • vtk中顶点和点的区别

    顶点和点之间的主要区别是什么VTK http www vtk org 好吧 我正在将一些计算点分配给vtkPolyData http www vtk org doc nightly html classvtkPolyData html ou
  • 将vtk自相交多数据从重复点分离成多个多边形?

    从 vtk 自相交多数据中 我想将其分成多个多边形 请注意 可以从形成多边形的点列表中的重复点检测初始多边形中的交点 从 wget 获取测试文件https thredds su ipsl fr thredds fileServer ipsl
  • 我是否缺少在 Ubuntu 9.04 上使用 Python2.6 绑定构建/安装 VTK-5.4 的步骤?

    我使用源代码的 Python 绑定成功构建并安装了 VTK 5 4 然而 当我尝试在 python 中导入 VTK 时 它给出了以下回溯错误 文件 第 1 行 位于 文件 usr local lib python2 6 dist packa
  • Numpy uint8_t 数组到 vtkImageData

    我正在尝试拍摄一个或三个通道的 2D 图像并使用 VTK 中显示它们vtkImageActor 据我了解 要显示的当前帧可以通过调用来更新SetImageData on vtkImageActor并提供一个实例vtkImageData 我已

随机推荐

  • Linux(CentOS 7)配置静态ip及ping 不通外网问题

    前言 日常学习中 xff0c 如果Linux中安装了MySQL nacos redis等中间件 我们可能会通过navicat dataGrip连接MySQL 会通过ip port nacos访问nacos 会通过ip port连接redis
  • docker run启动镜像容器时忘记添加开机自启动解决方法

    问题描述 在使用以下命令启动mysql容器时 xff0c 忘记添加了 restart 61 always 开启开机自启动 xff0c 导致每次开机 重启后 xff0c 需要重新通过一系列命令手动重启对应的容器 xff0c 极其不方便 doc
  • docker 安装RabbitMQ

    系列文章目录 第一章 RabbitMQ安装 提示 xff1a 写完文章后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一 RabbitMQ安装1 dockerHub 选择镜像2 Cent
  • 记 Content type ‘application/octet-stream‘ not supported

    项目场景 xff1a 实现一个入参方式为 64 RequestPart 43 64 RequestParam files 的接口 xff0c 即该接口要包含文件上传和其它 实体类 入参 示例代码 xff1a 64 PostMapping v
  • Go语言环境搭建

    一 下载开发工具 1 1 Go语言官网 1 2 进入Go官网 xff0c 点击Download xff0c 进入开发工具下载界面 xff0c 根据个人系统选择对应的安装包进行下载 windows 对应下载链接 二 安装开发工具 2 1 双击
  • Go入门教程--Hello,World.

    零 文本编辑器实现Hello World 官方给出的教程主要针对Linux 或Mac系统 但也没关系 xff0c 在windows 中实现也很简单 0 1 创建文件夹 xff0c 名称任意 xff0c 如 xff1a hello 0 2 创
  • 在AWS上开通EC2服务器并部署tomcat

    1 登录aws 2 点击服务 计算 EC2 3 点击启动实例 4 选择linux镜像 5 选择一个实例类型 6 配置实例详细信息 xff0c 保持默认 xff0c 点击下一步 7 添加存储 xff08 选择linux根目录硬盘大小和类型 x
  • android studio gradle 使用阿里源 (修改 settings.gradle)

    默认的地址下载速度极慢 依赖项几个小时也下载不完 改为 阿里源 1分钟就下载ok了 代码 修改根目录中 的 settings gradle 文件 内容 pluginManagement span class token punctuatio
  • 实用!Windows 远程控制 Ubuntu 系统

    点击上方 xff0c 选择 设为星标 优质文章 xff0c 及时送达 上一篇 xff1a 来源 xff1a 头条 互联网上的小蜘蛛 有时需要在实际的电脑上安装Ubuntu的操作系统来搭建免费的网站平台 这就需要使用远程的客户端Windows
  • 并查集——洛谷P3367

    题目描述 如题 xff0c 现在有一个并查集 xff0c 你需要完成合并和查询操作 输入输出格式 输入格式 xff1a 第一行包含两个整数N M xff0c 表示共有N个元素和M个操作 接下来M行 xff0c 每行包含三个整数Zi Xi Y
  • Web项目通过webservice编写一个接口,部署在远程服务器上

    在我的上一片文章中 xff0c 我在本地新建了一个普通的类来编写WebService xff0c 使用终端类 Endpoint 发布这个WebService xff0c 以此来实现让其他类调用这个接口 xff0c 实现接口中定义的功能 通过
  • ubuntu与win10共享LE蓝牙鼠标

    类似的教程网上有很多 xff0c 大部分是找到蓝牙设备目录下info文件中的 linkKey 中的key值复制到win10下注册表中 xff0c 但是对于蓝牙5 0或LE设备来说 xff0c 是没有linKey的 xff0c 这里我也参考了
  • FileZilla搭建FTP服务器图解教程,并允许外网访问NAT内网

    FTP是用来在两台计算机之间传输文件 xff0c 是Internet中应用非常广泛的服务之一 FTP服务是网络中经常采用的资源共享方式之一 FTP协议有PORT和PASV两种工作模式 xff0c 即主动模式和被动模式 今天我分享一个最近我自
  • 十进制转换八进制(C语言基础)

    题目描述编程 xff0c 输入一个 xff11 xff10 进制正整数 xff0c 然后输出它所对应的八进制数 输入无输出无样例输入10样例输出12 include lt stdio h gt int main int num m 61 0
  • 【Godot】对 Godot 节点设计的思考

    对 Godot 中节点设计的思考 单个节点的功能设计的想法 xff0c 体会 Godot 的设计思想 低耦合 设计单个节点可复用的节点时 xff0c 调用方法尽量只对当前节点可获取到的变量或方法进行使用 xff0c 比如我写一个可以控制 K
  • 【Godot】行为树(一)了解与设计行为树代码

    行为树介绍 行为树是个节点树 xff0c 父节点通过不断遍历子节点 xff0c 根据不同类型的节点执行不同的分支 最终调用叶节点执行功能 行为树也不难理解 xff0c 他就像代码逻辑一样 xff0c 只是用节点的方式展现出来 xff0c 而
  • 【Godot 4.0】一个简单的匿名方法的使用lambda

    Godot 4 0 beta3 Godot 4 0 中添加了 lambda 表达式 xff0c 匿名方法等很多方便的特性 xff0c 这里我写个用于扫描目录下所有文件的功能 可以看到代码非常简洁 span class token keywo
  • aur报错(错误:一个或多个文件没有通过有效性检查)

    当我们从aur里安装软件时 xff0c 有时会出现这种报错 xff08 如安装deepin wine wechat xff09 61 61 gt 错误 xff1a 一个或多个文件没有通过有效性检查 xff01 Error downloadi
  • Java使用不同方式获取两个集合List的交集、补集、并集(相加)、差集(相减)

    1 明确概念 首先知道几个单词的意思 xff1a 并集 61 union 交集 61 intersection 补集 61 complement 析取 61 disjunction 减去 61 subtract 1 1 并集 对于两个给定集
  • 【VTK】VTK框选表面拾取三角面片——通过观察者命令模式

    VTK框选拾取三角面片 最近需要实现拾取三角面片的交互功能 xff0c 看了官方示例和网友分享 xff0c 都是使用vtkInteractorStyleRubberBandPick搭配vtkAreaPicker 但是具体实现方法都是选择继承