VTK鼠标点击创建直线

一、实现思路:

1.1 鼠标左击确定直线起点并显示

1.2 鼠标右击确定直线终点并显示

1.3 将两个点连接绘制直线并显示

二、实现代码:

2.1 自定义交互器类

double WorldPoint1[3]{ 0 };
double WorldPoint2[3]{ 0 };

class CustomInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
	static CustomInteractorStyle* New();
	//定义类的元数据,并将其与基类进行关联。vtkTypeMacro 宏接受两个参数:类名和基类名。
	vtkTypeMacro(CustomInteractorStyle, vtkInteractorStyleTrackballCamera);

	// 鼠标按键按下事件处理函数
	virtual void OnLeftButtonDown() override
	{
		//this->Interactor 表示 VTK 渲染器的交互器对象,GetPicker() 方法用于获取与该交互器关联的拾取器对象(vtkPicker)。
		//然后,Pick() 方法通过检测鼠标位置执行拾取操作
		//注册拾取点函数
		this->Interactor->GetPicker()->Pick(
			this->Interactor->GetEventPosition()[0],
			this->Interactor->GetEventPosition()[1], 0,
			this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
		this->Interactor->GetPicker()->GetPickPosition(WorldPoint1);
		//对拾取点进行标记
		vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();
		sphereSource->SetRadius(0.1);
		sphereSource->Update();

		vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();
		mapper->SetInputConnection(sphereSource->GetOutputPort());

		vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
		actor->SetMapper(mapper);
		actor->SetScale(0.05);
		actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
		this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);
		
		this->Interactor->GetRenderWindow()->Render();

		// 调用基类的默认处理
		vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
		
	}

	//鼠标按键右键事件处理函数
	virtual void OnRightButtonDown() override 
	{
		//注册拾取点函数
		this->Interactor->GetPicker()->Pick(
			this->Interactor->GetEventPosition()[0],
			this->Interactor->GetEventPosition()[1], 0,  // always zero.
			this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
		this->Interactor->GetPicker()->GetPickPosition(WorldPoint2);
		//对拾取点进行标记
		vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
		sphereSource->SetRadius(0.1);
		sphereSource->Update();

		
		vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		mapper->SetInputConnection(sphereSource->GetOutputPort());
		vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
		actor->SetMapper(mapper);
		actor->SetScale(0.05);
		actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
		this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);

		this->Interactor->GetRenderWindow()->Render();

		//调用绘制直线函数
		this->connectPoints();

		// 调用基类的默认处理
		vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
	}
	void connectPoints() {
		vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
		lineSource->SetPoint1(WorldPoint1);
		lineSource->SetPoint2(WorldPoint2);
		lineSource->Update();
		vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		mapper->SetInputConnection(lineSource->GetOutputPort());
		vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
		actor->SetMapper(mapper);
		this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);
		this->Interactor->GetRenderWindow()->Render();
		
	}
};

vtkStandardNewMacro(CustomInteractorStyle);

2.2 主函数

int main(int argc, char *argv[])
{
	
	//渲染器
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	//通过 vtkRenderWindow 可以管理窗口的大小、位置、渲染器、渲染操作等,以及处理用户交互事件。
	vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();

	//将一个渲染器添加到渲染窗口,将场景的可视化内容添加到渲染窗口中以进行显示。
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(600, 400);
	renderWindow->SetPosition(800, 400);

	//vtkPointPicker 是用于进行点拾取操作的拾取器类。
	//它可以根据鼠标的屏幕坐标,在渲染窗口中选择最近的点,并提供关于该点的信息。
	vtkSmartPointer<vtkPointPicker> pointPicker =vtkSmartPointer<vtkPointPicker>::New();
	//renderwindow事件处理:使用 vtkRenderWindowInteractor 将渲染窗口与交互器进行关联,从而处理鼠标、键盘事件等用户交互操作。
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();

	//将点拾取器设置给渲染窗口交互器的代码,用于在交互器的处理过程中使用该点拾取器进行点选择操作。
	renderWindowInteractor->SetPicker(pointPicker);
	//将渲染窗口设置给渲染窗口交互器的代码,用于关联渲染窗口与渲染窗口交互器
	renderWindowInteractor->SetRenderWindow(renderWindow);
	
	//创建自定义的交互器样式CustomInteractorStyle
	vtkSmartPointer<CustomInteractorStyle> style = vtkSmartPointer<CustomInteractorStyle>::New();
	
	//将自定义的交互器样式设置给渲染窗口交互器
	renderWindowInteractor->SetInteractorStyle(style);
	//将渲染窗口交互器设置给渲染窗口,使得交互操作能够与渲染窗口关联起来,
	//交互器可以接收用户的输入并把结果显示在渲染窗口上。
	renderWindow->SetInteractor(renderWindowInteractor);
	renderWindowInteractor->SetRenderWindow(renderWindow);


	renderWindow->Render();
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();


	return 0;


}

三、实现效果:

鼠标点击绘制点参考的VTK:交互与拾取——点拾取_vtk拾取流程_简 。单的博客-CSDN博客

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt中使用VTK库,可以实现VTK的可视化功能,并且可以通过Qt的事件机制来处理鼠标点击事件。下面是一个简单的示例代码,演示了如何在VTK中处理鼠标左键点击事件: 首先,需要在Qt创建一个VTK窗口,并将其作为一个QWidget的子类来使用。然后,通过重写QWidget的鼠标事件函数来处理鼠标点击事件。 ```cpp #include <QVTKWidget.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkSmartPointer.h> #include <vtkCommand.h> class MyVTKWidget : public QVTKWidget { public: MyVTKWidget(QWidget* parent = nullptr) : QVTKWidget(parent) { // 创建VTK渲染器和交互器 renderer = vtkSmartPointer<vtkRenderer>::New(); interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(GetRenderWindow()); GetRenderWindow()->AddRenderer(renderer); // 设置交互器样式为默认样式 interactor->SetInteractorStyle(vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New()); // 添加鼠标左键点击事件监听器 vtkSmartPointer<MouseClickListener> clickListener = vtkSmartPointer<MouseClickListener>::New(); clickListener->SetVTKWidget(this); interactor->AddObserver(vtkCommand::LeftButtonPressEvent, clickListener); } private: vtkSmartPointer<vtkRenderer> renderer; vtkSmartPointer<vtkRenderWindowInteractor> interactor; class MouseClickListener : public vtkCommand { public: static MouseClickListener* New() { return new MouseClickListener; } void SetVTKWidget(MyVTKWidget* widget) { vtkWidget = widget; } virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) { if (eventId == vtkCommand::LeftButtonPressEvent) { // 处理鼠标左键点击事件 vtkRenderWindowInteractor* interactor = static_cast<vtkRenderWindowInteractor*>(caller); int* pos = interactor->GetEventPosition(); // 在这里可以根据鼠标点击的位置进行相应的操作 // 输出鼠标点击的位置 std::cout << "Mouse left button clicked at position: " << pos[0] << ", " << pos[1] << std::endl; } } private: MyVTKWidget* vtkWidget; }; }; int main(int argc, char** argv) { QApplication app(argc, argv); // 创建一个Qt窗口 QWidget window; window.resize(800, 600); // 创建一个VTK窗口,并将其添加到Qt窗口中 MyVTKWidget vtkWidget(&window); vtkWidget.resize(800, 600); window.show(); return app.exec(); } ``` 在上述代码中,我们创建了一个名为`MyVTKWidget`的类,继承自`QVTKWidget`,并重写了鼠标事件函数`Execute`。在`MyVTKWidget`的构造函数中,我们创建VTK渲染器和交互器,并将其与VTK窗口关联起来。然后,我们创建了一个名为`MouseClickListener`的内部类,继承自`vtkCommand`,用于处理鼠标左键点击事件。在`MouseClickListener`的`Execute`函数中,我们可以根据鼠标点击的位置进行相应的操作。 请注意,上述代码只是一个简单示例,实际使用时可能需要根据具体需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值