vtk使用vtkCellPicker和vtkPointPicker拾取单元节点的区别

从官方文件介绍看:

  • vtkCellPicker will shoot a ray into a 3D scene and return information about the first object that the ray hits. 
  • vtkPointPicker returns the id of the point projecting closest onto the ray (within the specified tolerance).

翻译成中文,大概意思为:vtkCellPicker会像三维场景发射一条射线,并返回射线第一次击中的对象信息,换种表达方式就是,vtkCellPicker会返回可见面上对象的信息,而vtkPointPicker会返回在指定容差范围内投影到射线上距离最近的点的 id,即vtkPointPicker返回的不一定是可见面上的点信息,所以在使用的时候需要根据自己的情况进行选择。

下面提供了测试代码,可以通过代码157~160行切换拾取器来分别观察效果(Tip:可以在149行选择打开/关闭线框显示模式)。

  1 #include "vtkAutoInit.h" 
  2 VTK_MODULE_INIT(vtkRenderingOpenGL2);
  3 VTK_MODULE_INIT(vtkInteractionStyle);
  4 VTK_MODULE_INIT(vtkRenderingFreeType)
  5 
  6 #include <vtkActor.h>
  7 #include <vtkInteractorStyleTrackballCamera.h>
  8 #include <vtkNamedColors.h>
  9 #include <vtkNew.h>
 10 #include <vtkObjectFactory.h>
 11 #include <vtkPointPicker.h>
 12 #include <vtkPolyDataMapper.h>
 13 #include <vtkProperty.h>
 14 #include <vtkRenderWindow.h>
 15 #include <vtkRenderWindowInteractor.h>
 16 #include <vtkRenderer.h>
 17 #include <vtkRendererCollection.h>
 18 #include <vtkSphereSource.h>
 19 #include <vtkRendererCollection.h>
 20 #include <vtkObjectFactory.h>
 21 #include <vtkCellPicker.h>
 22 #include <vtkSelectionNode.h>
 23 #include <vtkPolyData.h>
 24 #include <vtkUnstructuredGrid.h>
 25 #include <vtkSelection.h>
 26 #include <vtkExtractSelection.h>
 27 #include <vtkNamedColors.h>
 28 #include <vtkDataSetMapper.h>
 29 
 30 namespace {
 31     class MouseInteractorStyle : public vtkInteractorStyleTrackballCamera
 32     {
 33     public:
 34         static MouseInteractorStyle* New();
 35 
 36         vtkTypeMacro(MouseInteractorStyle, vtkInteractorStyleTrackballCamera);
 37 
 38         MouseInteractorStyle() {
 39             displayActor = vtkSmartPointer<vtkActor>::New();
 40             displayActor->GetProperty()->SetColor(1.0, 0.0, 0.0);
 41         }
 42 
 43         virtual void OnLeftButtonDown() override
 44         {
 45             vtkNew<vtkNamedColors> colors;
 46 
 47             // 鼠标点击位置[x, y]
 48             int* pos = this->Interactor->GetEventPosition();
 49             // 上一次的鼠标点击位置
 50             int* lastPos = this->Interactor->GetLastEventPosition();
 51 
 52             auto picker = this->Interactor->GetPicker();
 53             // Pick(x, y, z, vtkRenderer)
 54             picker->Pick(pos[0], pos[1], 0, this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
 55 
 56             // 点击点的世界坐标
 57             double worldPos[3];
 58             picker->GetPickPosition(worldPos);
 59 
 60             if (picker->IsA("vtkCellPicker")) {
 61                 auto cellPicker = vtkCellPicker::SafeDownCast(picker);
 62                 std::cout << "Pick Position: [" << worldPos[0] << ", " << worldPos[1] << ", " << worldPos[2] << "]" << std::endl;
 63                 std::cout << "CellId: " << cellPicker->GetCellId() << std::endl;
 64                 std::cout << "PointId: " << cellPicker->GetPointId() << std::endl;
 65 
 66                 if (cellPicker->GetCellId() != -1)
 67                 {
 68                     if (nullptr == data) {
 69                         std::cout << "Source data not found! " << std::endl;
 70                         return;
 71                     }
 72                     auto pointPos = data->GetPoint(cellPicker->GetPointId());
 73 
 74                     auto displayPoint = vtkSmartPointer<vtkSphereSource>::New();
 75                     displayPoint->SetCenter(pointPos);
 76                     displayPoint->SetRadius(0.02);
 77 
 78                     auto mapper = vtkSmartPointer <vtkPolyDataMapper>::New();
 79                     mapper->SetInputConnection(displayPoint->GetOutputPort());
 80 
 81                     this->Interactor->GetRenderWindow()
 82                         ->GetRenderers()
 83                         ->GetFirstRenderer()
 84                         ->RemoveActor(displayActor);
 85                     displayActor->SetMapper(mapper);
 86                     this->Interactor->GetRenderWindow()
 87                         ->GetRenderers()
 88                         ->GetFirstRenderer()
 89                         ->AddActor(displayActor);
 90                 }
 91 
 92             }
 93             else if (picker->IsA("vtkPointPicker")) {
 94                 auto pointPicker = vtkPointPicker::SafeDownCast(picker);
 95                 std::cout << "PointId: " << pointPicker->GetPointId() << std::endl;
 96                 if (pointPicker->GetPointId() != -1) {
 97                     if (nullptr == data) {
 98                         std::cout << "Source data not found! " << std::endl;
 99                         return;
100                     }
101                     auto pointPos = data->GetPoint(pointPicker->GetPointId());
102 
103                     auto displayPoint = vtkSmartPointer<vtkSphereSource>::New();
104                     displayPoint->SetCenter(pointPos);
105                     displayPoint->SetRadius(0.02);
106 
107                     auto mapper = vtkSmartPointer <vtkPolyDataMapper>::New();
108                     mapper->SetInputConnection(displayPoint->GetOutputPort());
109 
110                     this->Interactor->GetRenderWindow()
111                         ->GetRenderers()
112                         ->GetFirstRenderer()
113                         ->RemoveActor(displayActor);
114                     displayActor->SetMapper(mapper);
115                     this->Interactor->GetRenderWindow()
116                         ->GetRenderers()
117                         ->GetFirstRenderer()
118                         ->AddActor(displayActor);
119                 }
120             }
121             else {
122                 std::cout << "WorldPos: [" << worldPos[0] << ", " << worldPos[1] << ", " << worldPos[2] << "]" << std::endl;
123             }
124 
125             // 事件转发
126             vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
127         }
128 
129         vtkPolyData* data = nullptr;
130         vtkSmartPointer<vtkActor> displayActor = nullptr;
131     };
132     vtkStandardNewMacro(MouseInteractorStyle)
133 
134 }
135 
136 int main(int, char* [])
137 {
138     vtkNew<vtkNamedColors> colors;
139 
140     vtkNew<vtkSphereSource> sphereSource;
141     sphereSource->Update();
142 
143     // Create a mapper and actor
144     vtkNew<vtkPolyDataMapper> mapper;
145     mapper->SetInputConnection(sphereSource->GetOutputPort());
146     vtkNew<vtkActor> actor;
147     actor->SetMapper(mapper);
148     actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
149     //actor->GetProperty()->SetRepresentationToWireframe();
150 
151     // Create a renderer, render window, and interactor
152     vtkNew<vtkRenderer> renderer;
153     vtkNew<vtkRenderWindow> renderWindow;
154     renderWindow->AddRenderer(renderer);
155     renderWindow->SetWindowName("PointPicker");
156 
157     // 使用vtkPointPicker拾取器
158     //vtkNew<vtkPointPicker> picker;
159     // 使用vtkCellPicker拾取器
160     vtkNew<vtkCellPicker> picker;
161     vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
162     renderWindowInteractor->SetPicker(picker);
163     renderWindowInteractor->SetRenderWindow(renderWindow);
164 
165     vtkNew<MouseInteractorStyle> style;
166     style->data = sphereSource->GetOutput();
167     renderWindowInteractor->SetInteractorStyle(style);
168 
169     // Add the actor to the scene
170     renderer->AddActor(actor);
171     renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
172 
173     // Render and interact
174     renderWindow->Render();
175     renderWindowInteractor->Start();
176 
177     return EXIT_SUCCESS;
178 }

 

posted @ 2022-07-20 09:32  禅元天道  阅读(2145)  评论(0编辑  收藏  举报