VTK笔记——Widgets简介

  • Post author:
  • Post category:其他


VTK的交互器样式(vtkInteractorStyle)通常只是控制相机以及提供一些简单的键盘和鼠标事件的交互技术。交互器样式在渲染场景中并没有一种表达形式,也就是说,在交互时我们看不见交互器样式到底是什么样子的,用户在使用这些交互器样式时,必须事先知道哪些键盘和鼠标事件是控制哪些操作的。然而,渲染场景中的大部分操作都需要直接、简单。比如,如果某条线段的端点可以由用户放置的话,那么沿着某条线段改变倾斜度,就变得非常容易。

Widget就是针对这种功能而设计的。与vtkInteractorStyle类似,Widget也是vtkInteractorObserver的子类。换句话说,它们会监听由vtkRenderWindowInteractor所调用的事件。我们知道,vtkRenderWindowInteractor可以将基于具体操作系统的事件转换成VTK事件。但与vtkInteractorStyle不同的是,Widget在渲染场景中可以用多种不同的表达式。

在这里插入图片描述

下面来看Widget的基本使用步骤。

Widget包含两个重要的组成部分:

Interaction



Representation

.



Interaction


Interaction

是一些名叫vtk*Widget的类(比如vtkBoxWidget2)。它包含了交互的所有选项和事件处理。



Representation


Representation

是显示并与之交互的一类对象,以名叫vtk*Representation.



用法

创建一个Widget:

  vtkSmartPointer<vtkBoxWidget2> boxWidget =
    vtkSmartPointer<vtkBoxWidget2>::New();
  boxWidget->SetInteractor( renderWindowInteractor );

大多数Widget都有默认的Representation。如果你想改变它,可以手动创建一个Representation并设置到widget.

  vtkSmartPointer<vtkBoxRepresentation> boxRep =
	vtkSmartPointer<vtkBoxRepresentation>::New();
  boxRep->SetPlaceFactor(1);
  boxRep->PlaceWidget(actor->GetBounds());
  boxWidget->SetRepresentation(boxRep);



事件处理

往往你希望响应用户在Widget上所作的操作,那这时候就需要定义一个vtkCommand的子类,并在一个类似于vtkCallbackFunction回调函数的方法Execute中来处理这些操作。

class vtkBoxCallback : public vtkCommand
{
public:
  static vtkBoxCallback *New()
  {
    return new vtkBoxCallback;
  }

  vtkSmartPointer<vtkActor> m_actor;

  void SetActor(vtkSmartPointer<vtkActor> actor)
  {
    m_actor = actor;
  }

  virtual void Execute(vtkObject *caller, unsigned long, void*)
  {
    vtkSmartPointer<vtkBoxWidget2> boxWidget =
      dynamic_cast<vtkBoxWidget2*>(caller);

    vtkSmartPointer<vtkTransform> t =
      vtkSmartPointer<vtkTransform>::New();

	dynamic_cast<vtkBoxRepresentation*>(boxWidget->GetRepresentation())->GetTransform(t);
	this->m_actor->SetUserTransform(t);
  }

  vtkBoxCallback(){}
};



绑定事件

将自定义的事件添加到Widget上,需要创建vtkCommand对象并调用Widget的AddObserver方法。

  vtkSmartPointer<vtkBoxCallback> boxCallback =
    vtkSmartPointer<vtkBoxCallback>::New();
  boxCallback->SetActor(actor);
  boxWidget->AddObserver(vtkCommand::InteractionEvent, boxCallback);



启用Widget

使用Widget时,一定要注意顺序:

  boxWidget->On();

  renderWindowInteractor->Start();



效果

在这里插入图片描述



示例代码

#include <vtkSmartPointer.h>
#include <vtkConeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkBoxWidget2.h>
#include <vtkBoxRepresentation.h>
#include <vtkCommand.h>
#include <vtkTransform.h>

class vtkBoxCallback : public vtkCommand
{
public:
  static vtkBoxCallback *New()
  {
    return new vtkBoxCallback;
  }

  vtkSmartPointer<vtkActor> m_actor;

  void SetActor(vtkSmartPointer<vtkActor> actor)
  {
    m_actor = actor;
  }

  virtual void Execute(vtkObject *caller, unsigned long, void*)
  {
    vtkSmartPointer<vtkBoxWidget2> boxWidget =
      dynamic_cast<vtkBoxWidget2*>(caller);

    vtkSmartPointer<vtkTransform> t =
      vtkSmartPointer<vtkTransform>::New();

	dynamic_cast<vtkBoxRepresentation*>(boxWidget->GetRepresentation())->GetTransform(t);
	this->m_actor->SetUserTransform(t);
  }

  vtkBoxCallback(){}
};

int main(int argc, char* argv[])
{
  vtkSmartPointer<vtkConeSource> coneSource =
    vtkSmartPointer<vtkConeSource>::New();
  coneSource->SetHeight(1.5);

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

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);
  renderer->ResetCamera(); 

  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);

  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
    vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
  renderWindowInteractor->SetInteractorStyle(style);

  vtkSmartPointer<vtkBoxWidget2> boxWidget =
    vtkSmartPointer<vtkBoxWidget2>::New();
  boxWidget->SetInteractor(renderWindowInteractor);

  vtkSmartPointer<vtkBoxRepresentation> boxRep =
	vtkSmartPointer<vtkBoxRepresentation>::New();
  boxRep->SetPlaceFactor(1);
  boxRep->PlaceWidget(actor->GetBounds());
  boxWidget->SetRepresentation(boxRep);
  
  vtkSmartPointer<vtkBoxCallback> boxCallback =
    vtkSmartPointer<vtkBoxCallback>::New();
  boxCallback->SetActor(actor);
  boxWidget->AddObserver(vtkCommand::InteractionEvent, boxCallback);

  boxWidget->On();

  renderWindowInteractor->Start();

  return 0;
}



Ref


VTK Widgets Tutorials



VTKExamples-Widgets


在这里插入图片描述

在这里插入图片描述



版权声明:本文为minmindianzi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。