VTK修炼之道78:交互与拾取_点拾取
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道78:交互与拾取_点拾取
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.拾取
選擇拾取是人機交互過程的一個重要功能。 一個最經典的例子就是,在玩3D游戲時,場景中可能會存在多個角色,有時需要用鼠標來選擇所要控制的角色,這就要用到拾取功能。 另外,在某些三維圖形的編輯軟件中,經常需要編輯其中的一個點、一個面片或者一個局部區域,這也需要通過拾取功能來完成。 VTK中定義了多個拾取功能的類,具體的繼承關系如下:VTK中所有的拾取類都繼承自vtkAbstractPicker類,在這些類的基礎之上可以實現非常復雜的功能。
2.點拾取
從上圖中能夠知曉,完成點拾取功能的類是vtkPointPicker。 vtk中的消息是通過vtkRenderWindowInteractor類處理的,在類vtkRenderWindowInteractor中,定義如下函數: virtual void SetPicker(vtkAbstractPicker* ?); 該函數用來設置具體的VTKAbstractPicker對象,并執行相應的拾取操作。因此對于點拾取,實際就是設置VTKPointPicker的過程。 之前,曾經細致的研究過,vtkRenderWindowInteractor內部定義了一個vtkInteractorStyle對象。vtkInteractorStyle類是一個虛基類,其子類定義了多種鼠標和鍵盤消息的處理方法,在實現拾取操作是,需要定制相應的鼠標消息處理函數。比如拾取某個點時,應該響應鼠標的左鍵按下消息,并在響應該消息的函數中根據鼠標的當前窗口坐標來完成拾取操作。 點拾取的示例代碼如下: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL) VTK_MODULE_INIT(vtkRenderingFreeType) VTK_MODULE_INIT(vtkInteractionStyle)#include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h>#include <vtkPointPicker.h> //this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer() #include <vtkRendererCollection.h> #include <vtkInteractorStyleTrackballCamera.h> #include <vtkObjectFactory.h> //vtkStandardNewMacro(); #include <vtkProperty.h>#include <vtkAxesActor.h> #include <vtkOrientationMarkerWidget.h> /**************************************************************************************************/ 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; } 實際操作細節分析:- vtkInteractorStyleTrackballCemera派生類設計
- 拾取函數Pick()設計
- GetPackPosition()是指世界坐標系下拾取點的坐標
- mian()函數中設計拾取調用流程
2.參看資料
1.《C++ primer》2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發進階[M]. 機械工業出版社, 2015.
總結
以上是生活随笔為你收集整理的VTK修炼之道78:交互与拾取_点拾取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VTK修炼之道77:交互部件_分割/配准
- 下一篇: 飞鸽传书使用介绍