VTK 三维模型的简单拾取交互

阅读: 评论:0

VTK 三维模型的简单拾取交互

VTK 三维模型的简单拾取交互

最近需要对stl三维模型表面的点进行拾取,然后也需要点云配准,所以之前都是把stl转成pcd,用pcl瞎搞。pcl里也也能实现对点云的点拾取,但是pcl的viewer显示点云没有光源(PCL小白,不知道能不能设置,我是没找到的),这就看不到三维模型的表面特征了(我要根据表面特征手动选点)。网上看到的资料都是用VTK,就研究一下(VTK小白中的小白,有不对的地方请谅解)。

先贴参考:
:看完可以对vtk有个大概的了解

:了解一下vtk里的拾取类

:三维模型点拾取,但是对于复杂的三维模型,可能会拾取错误(即选到了背面的点,这里仔细看了vtkPointPicker的描述,拾取错误的原因应该是是背面的点离射线更近,想象一下射线重三角面片中穿过)上面是我个人的理解,不知道对不对。

:拾取点/显示当前点选点并删除上次的点选点

:拾取三角面片。这里我们可以参考使用vtkCellPicker,就应该可以避免选到背面了(我的理解是射线碰到三角面片直接返回信息)。

然后参考上面拾取三角面片的例子,我们这里不显示三角面片,用一个球代替显示,达到所谓的点拾取。这了我读的是vtk文件,stl得加个头文件

 #include <vtkSTLReader.h>vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();reader->SetFileName("1.stl");reader->Update();
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkDataSetMapper.h>
#include <vtkCellPicker.h>
#include <vtkSelectionNode.h>
#include <vtkSelection.h>
#include <vtkRendererCollection.h>
#include <vtkExtractSelection.h>
#include <vtkObjectFactory.h>
#include <vtkNamedColors.h>
#include <vtkUnstructuredGrid.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataReader.h>// Catch mouse events
class MouseInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public://double picked[3];//选取的点坐标double* worldPosition;static MouseInteractorStyle* New();MouseInteractorStyle(){last_picked_actor = NULL;selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();selectedActor = vtkSmartPointer<vtkActor>::New();}virtual void OnLeftButtonDown() override{vtkNew<vtkNamedColors> colors;// Get the location of the click (in window coordinates)int* pos = this->GetInteractor()->GetEventPosition();vtkNew<vtkCellPicker> picker;picker->SetTolerance(0.0005);// Pick from this location.picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());worldPosition = picker->GetPickPosition();std::cout << "Cell id is: " << picker->GetCellId() << std::endl;if (picker->GetCellId() != -1){std::cout << "Pick position is: (" << worldPosition[0] << ", "<< worldPosition[1] << ", " << worldPosition[2] << ")" << endl;//如果之前选择了其他点,删除上一次的标记点if (this->last_picked_actor){this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->RemoveActor(last_picked_actor);//last_picked_actor->Delete();//last_picked_actor=vtkActor::New();}//获取此次的标记点this->last_picked_actor = GetActor();if (this->last_picked_actor){//标记出来,this->last_picked_actor->SetScale(2.0);this->last_picked_actor->GetProperty()->SetColor(1.0, 0.0, 0.0);this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(this->last_picked_actor);}}// Forward eventsvtkInteractorStyleTrackballCamera::OnLeftButtonDown();}vtkSmartPointer<vtkPolyData> Data;vtkSmartPointer<vtkDataSetMapper> selectedMapper;vtkSmartPointer<vtkActor> selectedActor;private:vtkActor* last_picked_actor;inline vtkActor* GetActor(){vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();sphereSource->Update();vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(sphereSource->GetOutputPort());vtkActor* actor = vtkActor::New();actor->SetMapper(mapper);actor->SetPosition(worldPosition);return actor;}};vtkStandardNewMacro(MouseInteractorStyle);int main(int, char* [])
{vtkNew<vtkNamedColors> colors;vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();reader->SetFileName("Mesh.vtk");reader->Update();vtkNew<vtkPolyDataMapper> mapper;mapper->SetInputConnection(reader->GetOutputPort());vtkNew<vtkActor> actor;actor->GetProperty()->SetColor(colors->GetColor3d("SeaGreen").GetData());actor->SetMapper(mapper);vtkNew<vtkRenderer> renderer;renderer->AddActor(actor);renderer->ResetCamera();renderer->SetBackground(colors->GetColor3d("PaleTurquoise").GetData());vtkNew<vtkRenderWindow> renderWindow;renderWindow->Render();renderWindow->AddRenderer(renderer);renderWindow->SetWindowName("CellPicking");vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();// Set the custom stype to use for interaction.vtkNew<MouseInteractorStyle> style;style->SetDefaultRenderer(renderer);style->Data = reader->GetOutput();renderWindowInteractor->SetInteractorStyle(style);renderWindow->Render();renderWindowInteractor->Start();return EXIT_SUCCESS;
}

补充-----------2024.1.16---------------
使用QT+VTK显示时,导入自定义交互后,关闭qt主窗口后,程序仍在运行问题:

		//VTK交互器vtkNew<vtkRenderWindowInteractor> interactor;interactor->SetRenderWindow(renderWindow);// 设置交互器样式vtkNew<vtkMyInteractorStyle_Single_point_pickup> style;style->SetDefaultRenderer(renderer);//导入自定义交互interactor->SetInteractorStyle(style);interactor->Initialize();interactor->Start();

Start()后应该是会启动一个线程进行循环。在关闭qt主窗口后,这个交互器的循环仍在执行,导致整个程序仍在运行。

解决:在qt窗口关闭时执行以下程序(即退出自定义交互的循环

	if (interactor) interactor->ExitCallback();

本文发布于:2024-01-28 04:20:45,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063868514727.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模型   简单   VTK
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23