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 }