it编程 > 软件设计 > 交互

VTK实现三视图显示及交互STL模型

102人参与 2024-08-06 交互

vtk实现stl模型的三视图显示及交互

最近收到需求,要实现多视图显示同一个stl模型,并且控制主窗口要其他试图窗口也跟着交互,花了点时间去尝试一下,把这个效果给实现出来了,而且实现也挺简单。


效果演示

在这里插入图片描述


要点

  1. 用同一个vtkrenderer传三次给vtkrenderwindow是不行的,要创建三个vtkrenderer来显示用一个vtkactor,分别传给vtkrenderwindow才行。
  2. 用同一个vtkcamera同时控制三个vtkrenderer是不行的,因为vtkcamera的参数发生改变,会同步影响,要实现不同的视角,还是需要准备三个vtkcamera分别传给三个vtkrenderer。
  3. 既然要实现控制一个主vtkcamera,影响另外两个辅vtkcamera也要同步更新,那最直接的方法就是用回调函数。

代码实现

#include <iostream>
#include <vtkautoinit.h>
#include <vtkstlreader.h>
#include <vtkplyreader.h>
#include <vtkpolydatamapper.h>
#include <vtksmartpointer.h>
#include <vtkactor.h>
#include <vtkcamera.h>
#include <vtkrenderer.h>
#include <vtkrenderwindow.h>
#include <vtktransform.h>

#include <vtkgenericopenglrenderwindow.h>
#include <vtkrenderwindowinteractor.h>
#include <vtkinteractorstyletrackballcamera.h>
#include <vtkcommand.h>
vtk_module_init(vtkrenderingopengl2)
vtk_module_init(vtkinteractionstyle);
vtk_module_init(vtkrenderingfreetype);

class vtkupdatecamera : public vtkcommand
{
public:
	static vtkupdatecamera* new()
	{
		return new vtkupdatecamera;
	}

	void execute(vtkobject* caller, unsigned long vtknotused(event), void* calldata)
	{
		//获取主camera
		vtkrenderer* renderer = dynamic_cast<vtkrenderer*>(caller);
		auto camera = renderer->getactivecamera();
		//更新两个辅助camera的参数
		camera1->setposition(camera->getposition());
		camera1->setfocalpoint(camera->getfocalpoint());
		camera1->setviewup(camera->getviewup());
		camera1->azimuth(90);
		camera1->modified();
		//通过调整摄像头的viewup的旋转角度,为辅助摄像头实现上试图,左视图的朝向
		camera2->setposition(camera->getposition());
		camera2->setfocalpoint(camera->getfocalpoint());
		double* viewup = camera->getviewup();
		double* direction = camera->getdirectionofprojection();
		double view[3];
		vtkmath::cross(direction, viewup, view);
		camera2->setviewup(view);
		camera2->azimuth(-90);
		camera2->modified();
	}

	void setcamera1(vtkcamera* c)
	{
		camera1 = c;
	}

	void setcamera2(vtkcamera* c)
	{
		camera2 = c;
	}

private:
	vtkcamera* camera1;
	vtkcamera* camera2;
};

int main()
{
	vtksmartpointer<vtkstlreader> reader = vtksmartpointer<vtkstlreader>::new();
	reader->setfilename("d://bunny.stl");
	reader->update();

	vtksmartpointer<vtkpolydatamapper> mapper = vtksmartpointer<vtkpolydatamapper>::new();
	mapper->setinputdata(reader->getoutput());

	vtksmartpointer<vtkactor> actor = vtksmartpointer<vtkactor>::new();
	actor->setmapper(mapper);

	double* bounds = reader->getoutput()->getbounds();
	
	vtksmartpointer<vtkcamera> camera = vtksmartpointer<vtkcamera>::new();
	camera->setposition(0, bounds[2]- 200, 0);
	camera->setfocalpoint(reader->getoutput()->getcenter());
	camera->setviewup(0, 0, 1);

	vtksmartpointer<vtkcamera> camera1 = vtksmartpointer<vtkcamera>::new();
	vtksmartpointer<vtkcamera> camera2 = vtksmartpointer<vtkcamera>::new();

	//为主渲染器准备更新摄像头的回调函数
	vtksmartpointer<vtkupdatecamera> callback = vtksmartpointer<vtkupdatecamera>::new();
	callback->setcamera1(camera1);
	callback->setcamera2(camera2);

	//---------设置主渲染器----------
	vtksmartpointer<vtkrenderer> renderer = vtksmartpointer<vtkrenderer>::new();
	renderer->addactor(actor);
	renderer->setactivecamera(camera);
	renderer->setbackground(1, 1, 1);
	renderer->setviewport(0, 0, 0.33, 1);
	//为主渲染器绑定回调函数,使用anyevent为了使任何交互都影响两个辅助摄像头
	renderer->addobserver(vtkcommand::anyevent, callback);
	
	//---------设置第一个辅助渲染器----------
	vtksmartpointer<vtkrenderer> renderer1 = vtksmartpointer<vtkrenderer>::new();
	
	auto actors = renderer->getactors();
	actors->inittraversal();
	for (int i = 0; i < actors->getnumberofitems(); i++)
	{
		renderer1->addactor(actors->getnextactor());
	}
	renderer1->setactivecamera(camera1);
	renderer1->setviewport(0.33, 0, 0.66, 1);
	renderer1->setbackground(1, 1, 1);

	//---------设置第二个辅助渲染器----------
	vtksmartpointer<vtkrenderer> renderer2 = vtksmartpointer<vtkrenderer>::new();
	renderer2->setactivecamera(camera2);
	renderer2->setviewport(0.66, 0, 1, 1);
	renderer2->setbackground(1, 1, 1);
	actors->inittraversal();
	for (int i = 0; i < actors->getnumberofitems(); i++)
	{
		renderer2->addactor(actors->getnextactor());
	}
	
	vtksmartpointer<vtkrenderwindow> renderwindow = vtksmartpointer<vtkrenderwindow>::new();
	renderwindow->addrenderer(renderer);
	renderwindow->addrenderer(renderer1);
	renderwindow->addrenderer(renderer2);
	renderwindow->setsize(1200, 400);

	vtksmartpointer<vtkinteractorstyletrackballcamera> style = vtksmartpointer<vtkinteractorstyletrackballcamera>::new();

	vtksmartpointer<vtkrenderwindowinteractor> rwi = vtksmartpointer<vtkrenderwindowinteractor>::new();
	rwi->setrenderwindow(renderwindow);
	rwi->setinteractorstyle(style);
	rwi->start();
}
(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

[3D Selection]AR/VR/MR虚拟现实环境中的3D场景物体交互方法调研

08-06

Axure的交互与情形

08-06

深度长文 | 解析Apple Vision Pro 的3D功能与LiDAR工作场景,灵明光子ADS 6401 虚实交互的驱动引擎

08-06

用VRTK4.0如何实现与UI交互(保姆级别教程)

08-06

深度强化学习在虚拟现实中的潜力:从游戏到教育

08-06

使用selenium库模拟操作edge

08-06

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论