VTK笔记——Widgets简介

VTK的交互器样式(vtkInteractorStyle)通常只是控制相机以及提供一些简单的键盘和鼠标事件的交互技术。交互器样式在渲染场景中并没有一种表达形式,也就是说,在交互时我们看不见交互器样式到底是什么样子的,用户在使用这些交互器样式时,必须事先知道哪些键盘和鼠标事件是控制哪些操作的。然而,渲染场景中的大部分操作都需要直接、简单。比如,如果某条线段的端点可以由用户放置的话,那么沿着某条线段改变倾斜度,就变得非常容易。
Widget就是针对这种功能而设计的。与vtkInteractorStyle类似,Widget也是vtkInteractorObserver的子类。换句话说,它们会监听由vtkRenderWindowInteractor所调用的事件。我们知道,vtkRenderWindowInteractor可以将基于具体操作系统的事件转换成VTK事件。但与vtkInteractorStyle不同的是,Widget在渲染场景中可以用多种不同的表达式。
VTK笔记——Widgets简介_第1张图片
下面来看Widget的基本使用步骤。
Widget包含两个重要的组成部分:InteractionRepresentation.

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();

效果

VTK笔记——Widgets简介_第2张图片

示例代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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
VTK笔记——Widgets简介_第3张图片
VTK笔记——Widgets简介_第4张图片

你可能感兴趣的:(VTK笔记,vtk,widget,Interaction,Representation)