拾取最经典的例子就是,在玩3D游戏时,场景中可能会存在多个角色,有时候需要用鼠标来选择所要控制的角色,这时候要用到拾取功能。
另外,在某些三维图形图形的编译软件中,经常需要编辑其中的一个点,一个片面或者一个局部区域,这也需要通过拾取功能来完成。
多个拾取功能:
VTK中所有的拾取类都继承自vtkAbstractPicker类,在这些类的基础上可以实现非常复杂的功能。
完成点拾取功能的类是vtkPointPicker。
vtk中的消息是通过vtkRenderWindowInteractor类处理的,在类vtkRenderWindowInteractor中,定义如下函数:
virtual void SetPicker(vtkAbstractPicker* );
该函数用来设置具体的VTKAbstractPicker对象,并执行相应的拾取操作。因此对于点拾取,实际就是设置VTKPointPicker的过程。
比如拾取某个点时,应该响应鼠标的左键按下消息,并在响应该消息的函数中根据鼠标的当前窗口坐标来完成拾取操作。
#include
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkInteractionStyle)
#include
#include
#include
#include
#include
#include
#include
#include
//this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()
#include
#include
#include //vtkStandardNewMacro();
#include
#include
#include
/**************************************************************************************************/
class PointPickerInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static PointPickerInteractorStyle* New();
vtkTypeMacro(PointPickerInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnLeftButtonDown()
{
//打印鼠标左键像素位置
std::cout << "Picking pixel: " << this->Interactor->GetEventPosition()[0]
<< " " << this->Interactor->GetEventPosition()[1] << std::endl;
//注册拾取点函数
this->Interactor->GetPicker()->Pick(
this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1], 0, // always zero.
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()
);
//打印拾取点空间位置
double picked[3];
this->Interactor->GetPicker()->GetPickPosition(picked);
std::cout << "Picked value: " << picked[0] << " " << picked[1] << " " << picked[2] << std::endl;
//对拾取点进行标记
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->SetPosition(picked);
actor->SetScale(0.05);
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);
vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}
};
/**************************************************************************************************/
vtkStandardNewMacro(PointPickerInteractorStyle);
int main()
{
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(1, 1, 1);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->Render();
renderWindow->SetWindowName("PointPicker");
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkPointPicker> pointPicker =
vtkSmartPointer<vtkPointPicker>::New();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetPicker(pointPicker);
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer<PointPickerInteractorStyle> style =
vtkSmartPointer<PointPickerInteractorStyle>::New();
renderWindowInteractor->SetInteractorStyle(style);
//
vtkSmartPointer<vtkAxesActor> Axes = vtkSmartPointer<vtkAxesActor>::New();
vtkSmartPointer<vtkOrientationMarkerWidget> widget =
vtkSmartPointer<vtkOrientationMarkerWidget>::New();
widget->SetInteractor(renderWindowInteractor);
widget->SetOrientationMarker(Axes);
widget->SetOutlineColor(1, 1, 1);
widget->SetViewport(0, 0, 0.2, 0.2);
widget->SetEnabled(1);
widget->InteractiveOn();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
vtkSmartPointer renderWindowInteractor =
vtkSmartPointer::New();
renderWindowInteractor->SetPicker(pointPicker);
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer style =
vtkSmartPointer::New();
renderWindowInteractor->SetInteractorStyle(style);`