【VTK】基于读取出来的 STL 模型,当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点
知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。
文章目录
- `class PointPickedSignal : public QObject`
- `class MouseInteractorCommand : public vtkCommand`
- `void A::on_pushButtonSelected_clicked()`
- `void A::onPointPicked(double* pos)`
- `A.h`
- `A.cpp`
- Ref.
基于读取出来的 STL 模型,实现当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点。
详细流程为:点击 Select 按钮,鼠标具备选择的功能。当按下 Select Done 鼠标删除掉此功能。

主要是通过两个类和一个函数来实现的:
class PointPickedSignal : public QObjectclass MouseInteractorCommand : public vtkCommandvoid A::on_pushButtonSelected_clicked()void A::onPointPicked(double* pos)
下边依次分析。
class PointPickedSignal : public QObject
class PointPickedSignal : public QObject
{Q_OBJECT
public:PointPickedSignal(QObject* parent = nullptr) : QObject(parent) {}signals:void pointPicked(double* pos);
};
这个类继承自 QObject 类,用于实现一个名为 pointPicked 的 Qt 信号,当一个点被选中时发出该信号。这个信号将被用于通知其他对象选中的点的坐标。
class MouseInteractorCommand : public vtkCommand
class MouseInteractorCommand : public vtkCommand
{
public:vtkTypeMacro(MouseInteractorCommand, vtkCommand);static MouseInteractorCommand* New(){return new MouseInteractorCommand;}virtual void Execute(vtkObject* caller, unsigned long eventId, void* vtkNotUsed(callData)){vtkRenderWindowInteractor* interactor = vtkRenderWindowInteractor::SafeDownCast(caller);int* clickPos = interactor->GetEventPosition();vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();picker->SetTolerance(0.0005);if (picker->Pick(clickPos[0], clickPos[1], 0, interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer())){double* pos = picker->GetPickPosition();memcpy(pickedPoint, pos, sizeof(double) * 3);emit signal->pointPicked(pickedPoint);}}double pickedPoint[3];PointPickedSignal* signal; // this will emit the pointPicked signal when a point is picked
};
这个类继承自 vtkCommand 类,其功能是监听鼠标左键的点击事件。当用户点击鼠标左键时,会触发 Execute 方法。在这个方法中,代码首先从事件的发起者中获取交互器,并从交互器中获取点击的位置。然后,它创建一个 vtkCellPicker 对象并尝试拾取点击位置的点。如果成功拾取了一个点,它将获取该点的坐标,并使用 memcpy 将这些坐标复制到 pickedPoint 数组中。最后,它发出 pointPicked 信号,将选中的点的坐标作为参数。
void A::on_pushButtonSelected_clicked()
void A::on_pushButtonSelected_clicked() {ui.textBrowser->insertPlainText("Button Clicked");PointPickedSignal* signal = new PointPickedSignal(this);vtkSmartPointer<MouseInteractorCommand> command = vtkSmartPointer<MouseInteractorCommand>::New();command->signal = signal;ui.qvtkWidget->interactor()->AddObserver(vtkCommand::LeftButtonPressEvent, command);QEventLoop loop;connect(signal, &PointPickedSignal::pointPicked, this, &A::onPointPicked);connect(signal, &PointPickedSignal::pointPicked, &loop, &QEventLoop::quit);loop.exec();onPointPicked(command->pickedPoint);
}
这个方法首先创建一个 PointPickedSignal 对象和一个 MouseInteractorCommand 对象。然后,它将 PointPickedSignal 对象赋值给 MouseInteractorCommand 对象的 signal 成员,然后将这个 MouseInteractorCommand 对象添加为 QVTKWidget 对象的交互器的观察者,这样当交互器收到左键按下事件时,就会执行 MouseInteractorCommand 对象的 Execute 方法。
然后,这个方法创建一个 QEventLoop 对象并开始执行事件循环。在事件循环中,当 pointPicked 信号被发出时,它将调用 A::onPointPicked() 方法,并结束事件循环。
void A::onPointPicked(double* pos)
void A::onPointPicked(double* pos) {ui.textBrowser->insertPlainText(QString("Point picked: %1 %2 %3\n").arg(pos[0]).arg(pos[1]).arg(pos[2]));ui.textBrowser->moveCursor(QTextCursor::End);mandibleActor->SetOrigin(pos);
}
当这个方法被调用时,它将在文本浏览器中显示选中的点的坐标,并将这个点设置为模型的旋转原点。
通过这种方式,当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点。
完整版代码如下:
A.h
// A.h
#pragma once#include <QtWidgets/QMainWindow>
#include "ui_A.h"#include <vtkSmartPointer.h>
#include <vtkSTLReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkRenderWindowInteractor.h>#include <vtkCellPicker.h>
#include <vtkCommand.h>
#include <vtkObjectFactory.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkRendererCollection.h>
#include <vtkPropPicker.h>
#include <QObject>#include <qtimer.h>class A : public QMainWindow
{Q_OBJECTpublic:A(QWidget* parent = nullptr);~A();private slots:void on_pushButtonSelect_clicked();void on_pushButtonSelDone_clicked();void onPointPicked(double* pos);void rotate();private:Ui::AClass ui;void initVTK();vtkSmartPointer<vtkActor> actor;vtkSmartPointer<vtkRenderer> renderer;vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow;QTimer* timer;
};class PointPickedSignal : public QObject
{Q_OBJECT
public:PointPickedSignal(QObject* parent = nullptr) : QObject(parent) {}signals:void pointPicked(double* pos);
};class MouseInteractorCommand : public vtkCommand
{
public:vtkTypeMacro(MouseInteractorCommand, vtkCommand);static MouseInteractorCommand* New(){return new MouseInteractorCommand;}virtual void Execute(vtkObject* caller, unsigned long eventId, void* vtkNotUsed(callData)){vtkRenderWindowInteractor* interactor = vtkRenderWindowInteractor::SafeDownCast(caller);int* clickPos = interactor->GetEventPosition();vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();picker->SetTolerance(0.0005);if (picker->Pick(clickPos[0], clickPos[1], 0, interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer())){double* pos = picker->GetPickPosition();memcpy(pickedPoint, pos, sizeof(double) * 3);emit signal->pointPicked(pickedPoint);}}double pickedPoint[3];PointPickedSignal* signal; // this will emit the pointPicked signal when a point is picked
};
A.cpp
// A.cpp
#include "A.h"A::A(QWidget* parent): QMainWindow(parent)
{ui.setupUi(this);// 配置 VTK 的初始设置initVTK();// 定时器,50ms 更新触发一次 checkPositionChange()timer = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(rotate()));timer->start(100);
}A::~A()
{
}void A::initVTK()
{// 读取 STL 文件vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();reader->SetFileName("skull_50.stl"); // 请替换为你的 STL 文件路径reader->Update();// 创建映射器和演员vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(reader->GetOutputPort());actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);// 创建渲染器renderer = vtkSmartPointer<vtkRenderer>::New();// 添加演员到渲染器renderer->AddActor(actor);// 创建渲染窗口和渲染窗口交互器renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);// 添加到 qvtkWidget 控件中显示ui.qvtkWidget->setRenderWindow(renderWindow);}void A::on_pushButtonSelect_clicked() {ui.textBrowser->insertPlainText("Select button clicked!\n");PointPickedSignal* signal = new PointPickedSignal(this);vtkSmartPointer<MouseInteractorCommand> command = vtkSmartPointer<MouseInteractorCommand>::New();command->signal = signal;ui.qvtkWidget->interactor()->AddObserver(vtkCommand::LeftButtonPressEvent, command);QEventLoop loop;connect(signal, &PointPickedSignal::pointPicked, this, &A::onPointPicked);connect(signal, &PointPickedSignal::pointPicked, &loop, &QEventLoop::quit);loop.exec();onPointPicked(command->pickedPoint);
}void A::onPointPicked(double* pos) {ui.textBrowser->insertPlainText(QString("Point picked: %1 %2 %3\n").arg(pos[0]).arg(pos[1]).arg(pos[2]));ui.textBrowser->moveCursor(QTextCursor::End);actor->SetOrigin(pos);
}void A::on_pushButtonSelDone_clicked() {ui.textBrowser->insertPlainText("Selection done, restore the default interactor style.\n");// 移除左键按下事件的观察者ui.qvtkWidget->interactor()->RemoveObservers(vtkCommand::LeftButtonPressEvent);// 恢复默认的交互器样式。vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();ui.qvtkWidget->interactor()->SetInteractorStyle(style);
}void A::rotate()
{actor->RotateX(5);renderWindow->Render();
}
Ref.
- 骷髅3D打印3D模型
相关文章:
【VTK】基于读取出来的 STL 模型,当用户点击鼠标左键时,程序将获取点击位置的点,显示其坐标,并设置它为模型的旋转原点
知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 文章目录 class PointPickedSignal : public QObjectclass MouseInteractorCommand : public vtkCommandvoid A::on_pushButtonSelected_clicked()void A::on…...
【第一阶段】kotlin的when表达式
1.Java 的if /when是语句 kotlin的if/when是表达式,表达式是有返回值的 java中void是个关键字,Unit在kotlin中是个类 2.当使用when语句的时候必须有一个不满足的值即else: fun main() {var week:Int5val info when(week){1->"今天是星期一"…...
C#中Convert.ToInt32() 和 int.Parse()的区别
都是用于将字符串转换为整数类型(int)的方法,但它们在处理转换过程中有一些区别: 1. 错误处理方式不同: - Convert.ToInt32():如果字符串无法成功转换为整数类型,Convert.ToInt32()…...
安全学习DAY14_JS信息打点
信息打点——前端JS框架 文章目录 信息打点——前端JS框架小节概述-思维导图JS安全概述什么是JS渗透测试?前后端差异JS安全问题流行的Js框架如何判定JS开发应用? 测试方法(JS文件的获取以及分析方法1、手工搜索分析2、半自动Burp分析插件介绍…...
windows下配置vue开发环境
安装nodejs,配置npm 1.下载安装包:下载地址:https://nodejs.org/en/download 2.安装node:下载完成后进行安装,记住安装的文件夹。本人安装路径为 D:\Program Files\nodejs 3.配置环境变量: ①安装完成后…...
AndroidTV 获取焦点View放大效果实现方式
需求 电视开发最常见的就是view获焦后要有放大效果,让用户明显看到。这里总结两个实现方法,以后遇到其他的再补充。 方式一:ViewCompat.animate(view) 1、注册焦点变化监听 mBtnFocus1.setOnFocusChangeListener(this);2、有焦点变化的时…...
访问者模式——操作复杂对象结构
1、简介 1.1、概述 访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分。这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作。访问者模式使得用户可以在不修改现有系统的情况下扩展系…...
指针经典笔试题强训(附图详解)
目录 笔试题1: 解析: 运行结果: 笔试题2 解析: 运行结果: 笔试题3 解析: 运行结果: 笔试题4 解析: 运行结果: 笔试题5 解析: 运行结果:…...
Python:列表(list)与元组(tuple)
列表与元组 列表:list元组:tuple 比较直观的区分:列表是中括号"[ ]“,元组是小括号”( )"元组可以看成列表的只读形式 # 列表 list1 [hello, world] list2 [1, 2, 3, 4, 5] list3 ["a", "b", &…...
常见的相似性度量方法
有如下几种计算相似性方法: 点积相似度 X ⋅ Y ∣ X ∣ ∣ Y ∣ c o s θ ∑ i 1 n x i ∗ y i \begin{aligned} X \cdot Y & |X||Y|cos\theta \\ & \sum_{i1}^n x_i * y_i \end{aligned} X⋅Y∣X∣∣Y∣cosθi1∑nxi∗yi 向量内积的结果是没…...
Day06-JS高级编程
Day01-JS高级编程 一 变量和常量 1 概念 在程序中,变量是值可以改变的量,常量是值不可以改变的量 在ES6以前变量的创建使用var关键字 (可以创建多个同名变量) 从ES6开始变量的创建推荐使用let关键字 (不可以创建多个同名变量) 从ES6开始常量的创建使用const关键 (不可以创建…...
针对高可靠性和高性能优化的1200V硅碳化物沟道MOSFET
目录 标题:1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance摘要信息解释研究了什么文章创新点文章的研究方法文章的结论 标题:1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance 摘要 本文详…...
开发框架软件公司:与之携手,共同开启办公流程化之路!
在快节奏的社会里,如何提高企业的办公效率?如何让各部门之间的协作关系更为顺畅?如何把企业内部的数据真正利用起来,成为高层做出经营决策的重要依据?其实,要做到这些,与开发框架软件公司联手合…...
openCV C++环境配置
文章目录 一、openCV 安装二、新建项目三、配置环境变量四、测试使用 编译器:vs2017 OpenCV:4.5.4 一、openCV 安装 将openCV安装到一个路径下,我安装到了D盘根目录下 二、新建项目 在vs2017新建控制台空项目,打开项目属性 在VC目录 -> 包含目录下…...
8.3 作业 c高级
1.递归实现,输入一个数,输出这个数的每一位: #include<myhead.h>void print_digit(int num) {if(num<10){printf("%d",num);puts("");}else{print_digit(num/10); //递归打印除最后一位外的数printf("%…...
django实现部门表的增删改查界面
1、前期准备 部署好mysql数据库,创建好unicom数据库下载好bootstap的插件下载好jquery的插件下载好mysqlclient-1.4.6-cp36-cp36m-win_amd64.whl的安装包,根据python的版本下载 2、创建项目 在pycharm中创建项目 在pycharm的终端创建虚拟环境 py -m v…...
Tomcat的介绍和安装配置、eclipse中动态web项目的创建和运行、使用IDEA创建web项目并运行
一、Tomcat的介绍和安装配置 安装tomcat: 环境变量的配置: 配置之后重启cmd,执行startup命令,启动tomcat 在localhost:8080,能进入tomcat主界面,说明配置成功 二、eclipse中动态web项目的创建和运行 tomca…...
idea操作——已经push到远程的代码回滚(不保留本地更改)
1. git: 2. 找到相应分支--->找到要回滚的代码的位置----->右键,然后选择如图的选项: 3.下图的选项选择hard,然后选择reset 4.操作完成后等一会,待同步结束后push代码到远程,选择force push.…...
无涯教程-Lua - 垃圾回收
Lua使用自动内存管理,该管理使用基于Lua内置的某些算法的垃圾回收。 垃圾收集器暂停 垃圾收集器暂停用于控制垃圾收集器之前需要等待多长时间; Lua的自动内存管理再次调用它。值小于100意味着Lua将不等待下一个周期。同样,此值的较高值将导…...
DP(各种模型)
数字三角形模型 摘花生 Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。 地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就…...
告别混乱!用这套标准文件夹结构管理你的GD32F103 Keil工程(附完整源码)
嵌入式工程管理的艺术:GD32F103 Keil项目结构设计实战 当你的代码量从几百行膨胀到上万行,突然发现昨天还能正常运行的工程今天却莫名其妙报错;当你试图复用三个月前写的驱动代码,却不得不花一整天时间梳理各种隐式依赖࿱…...
Evaluate 未来展望:AI评估工具的发展趋势
Evaluate 未来展望:AI评估工具的发展趋势 【免费下载链接】evaluate 🤗 Evaluate: A library for easily evaluating machine learning models and datasets. 项目地址: https://gitcode.com/gh_mirrors/ev/evaluate 在人工智能快速发展的今天&am…...
cv_unet_image-colorization效果实测:不同分辨率黑白图上色一致性分析
cv_unet_image-colorization效果实测:不同分辨率黑白图上色一致性分析 1. 项目背景与测试目的 黑白照片上色一直是图像处理领域的热门应用,无论是老照片修复还是艺术创作,都希望能将黑白影像转化为生动的彩色画面。今天我们要评测的是基于U…...
软件冲刺回顾管理化的过程改进反思
软件冲刺回顾管理化的过程改进反思 在敏捷开发中,冲刺回顾(Sprint Retrospective)是团队持续改进的核心实践之一。随着项目规模扩大或团队协作复杂度提升,传统的回顾会议可能流于形式,难以真正推动过程改进。如何将回…...
XUnity.AutoTranslator终极指南:5分钟实现Unity游戏AI实时翻译
XUnity.AutoTranslator终极指南:5分钟实现Unity游戏AI实时翻译 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语Unity游戏的语言障碍而烦恼吗?XUnity.AutoTranslator是一…...
从矢量蓝图到三维世界:基于CityEngine规则与Unity的批量城市建模实战
1. 从二维矢量到三维城市的魔法转换 第一次接触CityEngine时,我被它批量生成建筑群的能力震撼到了。想象一下,你手头只有枯燥的二维建筑轮廓数据(就是那些在地图上看到的方块图形),通过一套神奇的规则脚本,…...
Cursor Free VIP:三步解锁AI编程神器的终极指南
Cursor Free VIP:三步解锁AI编程神器的终极指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial req…...
如何零成本掌握专业音频编辑:5个实战场景+3步高效流程+7个核心技巧
如何零成本掌握专业音频编辑:5个实战场景3步高效流程7个核心技巧 【免费下载链接】audacity Audio Editor 项目地址: https://gitcode.com/GitHub_Trending/au/audacity 想要创作专业级音频内容却担心成本和技术门槛?今天我将为你揭秘一款完全免…...
从《黑神话:悟空》到独立游戏:聊聊Avatar肌肉设置如何塑造角色个性走姿
从《黑神话:悟空》到独立游戏:如何用Avatar肌肉参数打造角色灵魂步态 在《黑神话:悟空》的实机演示中,主角一个转身抖落披风的动作让全网沸腾——这不仅是美术的胜利,更是动画系统的精妙设计。当大多数独立游戏还在使用…...
知识抽取避坑手册:关系抽取中90%人会犯的3个标注错误(附真实案例)
知识抽取避坑手册:关系抽取中90%人会犯的3个标注错误(附真实案例) 在电商平台的商品评论中,当用户评价"这款手机充电速度和官方描述一致"时,新手标注员常会忽略"充电速度"与"官方描述"之…...
