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


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

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


    效果演示

    在这里插入图片描述


    要点

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

    代码实现

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    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();
    }
    
  • 相关阅读:
    Java夏招必知必会八股文198题,看完offer拿到手软
    用户登录管理中的Bug修复与技术思考
    Go插件:轻松实现模块化开发与动态功能扩展
    Java项目:SSM在线租房售房平台多城市版本
    平面和射线交点
    ABP中的数据过滤器
    QML的Popup遇到的坑
    新版本Spring Security 2.7 + 用法,直接旧正版粘贴
    7-14 整数拆分——递归/推
    【Minecraft】【ModPC】【我的世界】 我的世界电脑版如何进入网络游戏?
  • 原文地址:https://blog.csdn.net/qq_37366618/article/details/139296179