当前位置:   article > 正文

VTK 三维模型的简单拾取交互_vtk 获取三维切面上任意点

vtk 获取三维切面上任意点

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

先贴参考:
https://blog.csdn.net/qq_42570058/article/details/107914377:看完可以对vtk有个大概的了解

https://blog.csdn.net/webzhuce/article/details/72802322:了解一下vtk里的拾取类

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

https://blog.csdn.net/asimov_liu/article/details/78748785:拾取点/显示当前点选点并删除上次的点选点

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

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

 #include <vtkSTLReader.h>
 
  vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
  reader->SetFileName("1.stl");
  reader->Update();

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
#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 events
		vtkInteractorStyleTrackballCamera::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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157

补充-----------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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

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

	if (interactor) interactor->ExitCallback();
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/535471
推荐阅读
相关标签
  

闽ICP备14008679号