列举三种响应机制:
1.
command/observer模式之callback function模式
2.
command/observer模式之vtkCommand模式
3.interactor style模式
1.command/observer模式之callback function:
vtk中的command/observer模式是最常用的,也是各种处理方式的基础。这里首先介绍如何使用callback function的方法:
void KeyPressCallbackFunction ( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData )
{
vtkRenderWindowInteractor *iren = static_cast<vtkRenderWindowInteractor*>(caller);// 指向调用这个callback函数的对象
vtkBoxWidget *tempWidget = static_cast<vtkBoxWidget*>(clientData);
tempWidget->GetTransform(inverse);
vtkSmartPointer<vtkMyCallback> callback = vtkSmartPointer<vtkMyCallback>::New();
tempWidget->AddObserver(vtkCommand::InteractionEvent, callback);
std::cout << "Pressed: " << iren->GetKeySym() << std::endl;
}
int main()
{
//…
vtkSmartPointer<vtkCallbackCommand> keyPressCallback = vtkSmartPointer<vtkCallbackCommand>::New();
keyPressCallback->SetCallback(KeyPressCallbackFunction);
keyPressCallback->SetClientData(boxWidget);
iren->AddObserver(vtkCommand::KeyPressEvent, keyPressCallback); // 设置callback function和event的联系
//……
}
上述代码片段中,callback function是主要的调用方式。其中caller是调用该callback function的对象,通常是RenderWindowInteractor,或者其他VTKWidget类上述例子中就是iren,caller很重要当你要操作具体某一个交互器或者widget或者视窗都可以通过vtkXXX *rcw = dynamic_cast<
vtkXXX* >(caller)获得;eventId是处理的event代号;clientData是传递到该函数中的数据;callData是随着触发的event一起传递的数据。
2.command/observer模式之vtkCommand:
这种方法与第一种方法的原理相同,只不过这里使用不是一个callback function,而是继承了vtkCommand类来实现自己需要的操作。具体的代码如下:这里可以添加计划学习的时间
class vtkMyCallback : public vtkCommand
{
public:
static vtkMyCallback *New()
{
return new vtkMyCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
<span style="white-space:pre"> </span>vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
<span style="white-space:pre"> </span>vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget*>(caller);
<span style="white-space:pre"> </span>widget->GetTransform(t);
t->PreMultiply();
t->Concatenate(vtkLinearTransform::SafeDownCast(inverse->GetInverse()));
<span style="white-space:pre"> </span>widget->GetProp3D()->SetUserTransform(t);
}
};
int main()
{
// …...
vtkSmartPointer<vtkBoxWidget> boxWidget =
vtkSmartPointer<vtkBoxWidget>::New();
boxWidget->SetInteractor(iren);
boxWidget->SetPlaceFactor(1.0);
boxWidget->SetProp3D(coneActor);
boxWidget->PlaceWidget();
vtkSmartPointer<vtkMyCallback> callback =
vtkSmartPointer<vtkMyCallback>::New();
boxWidget->AddObserver(vtkCommand::InteractionEvent, callback);// 处理event和callback的联系
boxWidget->On();
//……
}
上述代码片段中,Execute是主要的调用方式。其中caller是调用该Execute的对象,通常是RenderWindowInteractor,或者其他VTKWidget类上述例子中就是 boxWidget;eventId是处理的event代号;clientData是传递到该函数中的数据;callData是随着触发的event一起传递的数据。
interactor style模式:
该
方法是继承已有的interactor style来对自己希望设置的事件作出对应的响应,该方法可以看作是对若干个event的集合,缺点是只能对RenderWindowInteractor进行设置。
class MyStyle : public vtkInteractorStyleImage
{
public:
static MyStyle* New();
vtkTypeMacro(MyStyle, vtkInteractorStyleImage);
virtual void OnLeftButtonDown()
{
std::cout << "Pressed left mouse button." << std::endl;
// Forward events
vtkInteractorStyleImage::OnLeftButtonDown();
}
virtual void OnRightButtonDown()
{
std::cout << "Pressed right mouse button." << std::endl;
}
virtual void OnRightButtonUp()
{
std::cout << "Release right mouse button." << std::endl;
}
virtual void OnMouseMove()
{
int *pos = this->GetInteractor()->GetEventPosition();
std::cout << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
}
virtual void OnLeftButtonUp()
{
std::cout << "Release right mouse button." << std::endl;
}
};