【FastCAE源码阅读5】使用VTK实现鼠标拾取对象并高亮

鼠标拾取对象是很多软件的基本功能。FastCAE的拾取比较简单,是通过VTK实现的。

对几何而言,拾取类型切换在工具栏上,单击后再来单击视图区对象进行拾取,拾取后的对象会高亮显示。效果如下图:
在这里插入图片描述

一、拾取对象

拾取对象是在PropPickerInteractionStyle类实现的,该类是vtkInteractorStyleRubberBandPick的子类,重写原来的鼠标处理函数。当鼠标左键按下,会触发以下代码:

void PropPickerInteractionStyle::clickSelectGeometry(bool preSelect)
{int *clickPos = this->GetInteractor()->GetEventPosition(); // 获取鼠标点击位置int success = -1, index = -1;vtkActor *actor = nullptr;if (_selectModel == GeometryPoint || _selectModel == GeometryWinPoint) // 几何点{vtkSmartPointer<vtkPointPicker> picker = vtkSmartPointer<vtkPointPicker>::New();success = picker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());if (0 != success){index = picker->GetPointId(); // 点的idactor = picker->GetActor(); // 点对应的Actor}}else{vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();if (_selectModel == GeometryCurve || _selectModel == GeometryWinCurve)picker->SetTolerance(0.0025);success = picker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());if (0 != success){index = picker->GetCellId(); // cell的idactor = picker->GetActor(); // 对应的actor}}emit selectGeometry(preSelect, actor, index);
}

这段代码就是鼠标拾取对象的核心逻辑。其实现是借助了VTK提供的vtkPointPicker、vtkCellPicker。其中当拾取模式是点的时候,使用vtkPointPicker,如果拾取成功返回点的id及对应的Actor(一个Actor可能包含多个点)。当拾取模式是线、面、体的时候,使用vtkCellPicker,成功则返回对应cell id及Actor(一个Actor可能包含多个cell)。注意当拾取线的时候,需要提高拾取Tolerance,不然线很难拾取到。

另外要注意的是,当拾取线的时候,面Actor是拾取不到的,同样当拾取面的时候,线Actor也是拾取不到。这是通过在用户切换选择模式的时候,设置面或边Actor是否可以拾取实现的。核心代码在GeometryViewProvider类中,如下:

void GeometryViewProvider::setGeoSelectMode(int m)
{_viewData->updateGraphOption();ModuleBase::SelectModel selectType = (ModuleBase::SelectModel)m;QList<GeoViewObj> viewObjs = _geoViewHash.values();vtkActor *actor = nullptr;for (GeoViewObj vobj : viewObjs){actor = vobj._faceObj.first;if (actor != nullptr)actor->SetPickable(false);actor = vobj._edgeObj.first;if (actor != nullptr)actor->SetPickable(false);actor = vobj._pointObj.first;if (actor != nullptr)actor->SetPickable(false);switch (selectType){case ModuleBase::GeometryBody:case ModuleBase::GeometrySurface:case ModuleBase::GeometryWinBody:case ModuleBase::GeometryWinSurface:actor = vobj._faceObj.first;if (actor != nullptr)actor->SetPickable(true);break;case ModuleBase::GeometryWinCurve:case ModuleBase::GeometryCurve:actor = vobj._edgeObj.first;if (actor != nullptr)actor->SetPickable(true);break;case ModuleBase::GeometryWinPoint:case ModuleBase::GeometryPoint:actor = vobj._pointObj.first;if (actor != nullptr)actor->SetPickable(true);break;default:break;}}
}

这个代码相对比较简单,不再分析。

二、从信号到槽函数

拾取对象之后,会发出emit selectGeometry信号,参数中带有Actor及cell或点的id。这个信号是QT框架提供的编程机制。其对应的槽函数在如下图中能找到:
在这里插入图片描述

三、高亮拾取对象

高亮拾取对象处理过程代码如下:

void GeometryViewProvider::selectGeometry(bool pre, vtkActor *ac, int index)
{if (ac == nullptr || index < 0) // 无效拾取{_viewData->preHighLight(nullptr);_preWindow->reRender();return;}ModuleBase::SelectModel selectMod = _preWindow->getSelectModel(); // 选择模式vtkDataSet *dataSet = ac->GetMapper()->GetInputAsDataSet(); // 获取Actor的多边形数据集vtkPolyDatavtkPolyData *poly = vtkPolyData::SafeDownCast(dataSet);if (poly == nullptr)return;GeometryViewObject *vobj = nullptr;switch (selectMod){case ModuleBase::GeometryWinBody:case ModuleBase::GeometryBody:vobj = _viewData->getSolidViewObj(poly, index);break;case ModuleBase::GeometryWinSurface:case ModuleBase::GeometrySurface:vobj = _viewData->getFaceViewObj(poly, index); // 输入多边形数据+cell idbreak;case ModuleBase::GeometryWinCurve:case ModuleBase::GeometryCurve:vobj = _viewData->getEdgeViewObj(poly, index);break;case ModuleBase::GeometryWinPoint:case ModuleBase::GeometryPoint:vobj = _viewData->getPointViewObj(poly, index);break;default:break;}if (vobj == nullptr)return;if (pre)_viewData->preHighLight(vobj); // 设置预高亮else{vobj->highLight(); // 高亮对象_viewData->preHighLight(nullptr);emit geoShapeSelected(vobj->getGeometySet(), vobj->getIndex());}_preWindow->reRender();
}

同样,这里也只分析面的高亮,其他的高亮逻辑类似。高亮处理的时候,直接先根据Actor获取了其vtkPolyData数据集,找到哪个面需要高亮,最后更改其颜色。如何根据cell id找到这个面,需要理解其数据结构才能看懂其逻辑。对于面的数据结构,这篇文章【FastCAE源码阅读3】几何模型显示:从OCC对象到VTK对象有详细描述。其核心原理是查找cell id落在哪个面包含的cell区间上,确定高亮哪个面。最后调用_preWindow->reRender()重新绘制整个场景。

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

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

相关文章

京东数据分析:2023年9月京东打印机行业品牌销售排行榜

鲸参谋监测的京东平台9月份打印机市场销售数据已出炉&#xff01; 鲸参谋数据显示&#xff0c;今年9月&#xff0c;京东平台打印机的销量为60万&#xff0c;环比增长约32%&#xff0c;同比下滑约25%&#xff1b;销售额为5亿&#xff0c;环比增长约35%&#xff0c;同比下滑约29%…

Spark 基础知识点

Spark 基础 本文来自 B站 黑马程序员 - Spark教程 &#xff1a;原地址 什么是Spark 什么是Spark 1.1 定义&#xff1a;Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎 Spark最早源于一篇论文 Re…

MySQL第八讲·如何进行数学计算、字符串处理和条件判断?

你好&#xff0c;我是安然无虞。 文章目录 如何进行数学计算、字符串处理和条件判断&#xff1f;数学函数字符串函数条件判断函数总结 如何进行数学计算、字符串处理和条件判断&#xff1f; MySQL 提供了很多功能强大&#xff0c;而且使用起来非常方便的函数&#xff0c;包括…

「掌握创意,释放想象」——Photoshop 2023,你的无限可能!

Adobe Photoshop 2023(PS2023) 来了,全世界数以百万计的设计师、摄影师和艺术家使用 Photoshop 将不可能变为可能。从海报到包装&#xff0c;从基本的横幅到漂亮的网站&#xff0c;从令人难忘的徽标到引人注目的图标&#xff0c;Photoshop 2023让创意世界不断前进。借助直观的工…

C语言编写一个程序采集招聘信息

因为在这里无法详细解释每行代码和步骤。但是&#xff0c;我可以给大家一个使用Python和requests库编写的简单爬虫程序的例子&#xff0c;它可以从网站上获取招聘信息。你可以根据这个例子&#xff0c;将其改写为使用C语言编写的爬虫程序。 import requests# 指定爬虫IP信息 pr…

visual studio Python 配置QGIS(qgis)教程

visual studio Python 配置QGIS&#xff08;qgis&#xff09;教程 这个教程全网独一份啊&#xff0c;博主是自己摸索出来的。 visual studio Python 配置QGIS&#xff08;qgis&#xff09;环境一共分为两部&#xff1a; 第一步安装QGIS&#xff1a; 下载链接如下 https://www…

apachesolr启动带调试

这里solr.cmd报错&#xff0c;报错原因是java版本问题&#xff0c;后面发现这是因为多个java版本导致读取java_home失败&#xff0c; 那么我们修改solr.cmd中的JAVA_HOME为SOLR_JAVA_HOME IF DEFINED SOLR_JAVA_HOME set "JAVA_HOME%SOLR_JAVA_HOME%"环境变量将SOLR…

thinkphp的路径参数(RESTFul风格),把参数写在路径里

thinkphp官方文档 https://www.kancloud.cn/manual/thinkphp5_1/353969 有一个Blog控制器&#xff0c;里面的read方法是固定的&#xff0c;不能该 route.php里添加如下代码&#xff0c;访问 blog对应的就是 android/blog Route::resource(blog,android/blog);然后访问路径

flutter笔记:骨架化加载器

flutter笔记 骨架化加载器 - 文章信息 - Author: Jack Lee (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/article/details/134224135 【介绍】&#xff1a;本文介…

云南省各民族非遗巡演活动走进北京,奏响非遗传承乐章

云南&#xff0c;一个拥有丰富民族文化的边陲省份&#xff0c;各族人民在这片土地上创造了独具特色的民间艺术和非物质文化遗产。近日&#xff0c;以“边疆民族心向党 同心共圆中国梦”为主题的 2023 年云南省各民族非遗巡演活动走进北京专场顺利闭幕。来自西双版纳州、大理州、…

ZZ038 物联网应用与服务赛题第I套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 &#xff08;I卷&#xff09; 赛位号&#xff1a;______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等; 2.竞赛任务中所使用的各类软件工…

深入理解WPF中的依赖注入和控制反转

在WPF开发中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff09;和控制反转&#xff08;Inversion of Control&#xff09;是程序解耦的关键&#xff0c;在当今软件工程中占有举足轻重的地位&#xff0c;两者之间有着密不可分的联系。今天就以一个简单的小例子&…