VTK(2)—— 双view,显示并联动操作

本文介绍如何在VTK中实现双视图显示并联动操作,详细阐述了两种实现方式:一种通过继承vtkCommand,另一种通过重写vtkInteractorStyleTrackballCamera响应事件。文中提及了相机状态同步、事件捕获、相机共享等关键步骤,并提供了一个窗口中四个视图联动的完整工程源码示例。
摘要由CSDN通过智能技术生成

前言:接到一个新的需求

window单窗口程序,双view,显示并联动操作,做了两种方式进行实现,代码思路和源码如下:


(一)代码思路

一、判定谁动了?

方法1:通过当前事件的窗口位置与窗口大小中心轴进行比对

方法2:通过移动后的相机位置与两个view中相机的位置进行比对

方法3:获取当前renderer, 与两个renderer 做对比

 

二、如何捕获事件?
方法1:继承自vtkCommand重写回调
         Step1: 定义回调函数,继承自vtkCommand
         Step2: 设置回调函数
         Step3: 为两个view的相机添加观察者,通过AddObserver(vtkCommand::ModifiedEvent,callback)
         (其中ModifiedEvent可以接收任意发生事件,
         当有事件产生时,interactor底层会调用ModifiedEvent事件,callback为step1自定义的回调函数)

方法2:vtkInteractorStyleTrackballCamera 重写响应事件
         Step1: 自定义交互类型,继承自vtkInteractorStyleTrackballCamera
         Step2: 重写OnMouseMove()等方法

 

三、如何根据一个view变化设置另一个view?
方法1:将要设置的view中的相机的状态设置为变化的相机状态
           (因为在vtk中图像变化默认采用的是相机移动方式,在此先不讨论actor变化方式)
           (注:vtk中的相机,主要由三个因素决定:1.焦点 2.相机位置 3.向上方向)(另外也可以通过直接获取相机来设置想让变化的相机状态)
         Step1: 获取改变的相机的状态,通过GetPosition(), GetFocalPoint(), GetViewUp() 进行获得
         Step2: 设置要改变的相机的状态,通过SetPosition(), SetFocalPoint(), SetViewUp() 进行设置

         Step3: 使用vtkRenderer的ResetCameraClippingRange()方法重置图像的法向量
         Step4: 如果信号没有进行同步,需要手动调用vtkRendererWindow的Render()方法

方法2:创建一个相机对象,给左右两个renderer添加同一个相机对象

方法3:通过获取当前相机,将两个renderer的相机设置为当前相机

 

四、同类型问题思考?

一个view中,两个actor,根据鼠标指向不同,可挪动不同的物体。(这个实现起来相对简单一点,vtk有现成的函数)

方法:使用 vtkInteractorStyleTrackballActor 的互动模式即可实现


(二)Demo源码

 

第1种实现方式:

方法说明:

  • 实现方式:继承自vtkCommand重写回调
  • 相机设置:两个 renderer 公用一个相机(注:当不使用一个 camera 设置两个 renderer 的时候,如果viewsation不是对称的 会出现互动最开始两个相机相对物体的位置进行同步)
  • 联动函数:通过判断当前相机 与左右两个相机比对判定哪边动了,包含两种判断方法
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCallbackCommand.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <QDateTime>


class myCallbackFunc:public vtkCommand
{
public:
    static  myCallbackFunc *New()
    {
        return new myCallbackFunc;
    }
    
    void SetLeftRender(vtkRenderer *leftRender)
    {
        this->m_leftRender = leftRender;
    }
    void SetRightRender(vtkRenderer *rightRender)
    {
        this->m_rightRender = rightRender;
    }
    
  
    virtual void Execute(vtkObject *caller, unsigned long eventId, void* callData)
    {
        vtkCamera *camera = reinterpret_cast<vtkCamera*>(caller);
        vtkCamera *leftCamera = m_leftRender->GetActiveCamera();
        vtkCamera *rightCamera = m_rightRender->GetActiveCamera();
 
        double *act_position     = camera->GetPosition();
        double *act_FocalPoint   = camera->GetFocalPoint();
        double *act_ViewUp       = camera->GetViewUp();
      
        //方法一:指针判断
        if (leftCamera == camera)
        {
            if (rightCamera->GetPosition() != act_position)
            {
                rightCamera->SetPosition(act_position);
            }
            if (rightCamera->GetViewUp() != act_ViewUp)
            {
                rightCamera->SetFocalPoint(act_FocalPoint);
            }
            if (rightCamera->GetViewUp() != act_ViewUp)
            {
                rightCamera->SetViewUp(act_ViewUp);
            }
        }
        else if (rightCamera == camera)
        {
            if (leftCamera->GetPosition() != act_position)
            {
                leftCamera->SetPosition(act_position);
            }
            if (leftCamera->GetViewUp() != ac
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值