1.单位拾取

示例代码:

  1 #include <vtkAutoInit.h>
  2 VTK_MODULE_INIT(vtkRenderingOpenGL)
  3 VTK_MODULE_INIT(vtkInteractionStyle)
  4 VTK_MODULE_INIT(vtkRenderingFreeType)
  5  
  6 #include <vtkSmartPointer.h>
  7 #include <vtkSphereSource.h>
  8 #include <vtkPolyDataMapper.h>
  9 #include <vtkActor.h>
 10 #include <vtkProperty.h>
 11 #include <vtkRenderer.h>
 12 #include <vtkRenderWindow.h>
 13 #include <vtkRenderWindowInteractor.h>
 14  
 15 #include <vtkInteractorStyleTrackballCamera.h>
 16 #include <vtkDataSetMapper.h>
 17 #include <vtkCellPicker.h>
 18 #include <vtkSelectionNode.h>
 19 #include <vtkSelection.h>
 20 #include <vtkRendererCollection.h>
 21 #include <vtkExtractSelection.h>
 22 #include <vtkObjectFactory.h>
 23  
 24 /**************************************************************************/
 25 class CellPickerInteractorStyle :public vtkInteractorStyleTrackballCamera
 26 {
 27 public:
 28     static CellPickerInteractorStyle* New();
 29  
 30     CellPickerInteractorStyle()
 31     {
 32         selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();
 33         selectedActor = vtkSmartPointer<vtkActor>::New();
 34     }
 35     virtual void OnLeftButtonDown()
 36     {
 37         int* pos = this->GetInteractor()->GetEventPosition();
 38         vtkSmartPointer<vtkCellPicker> picker =
 39             vtkSmartPointer<vtkCellPicker>::New();
 40         picker->SetTolerance(0.0005);
 41         picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());
 42  
 43         if (picker->GetCellId() != -1)
 44         {
 45             vtkSmartPointer<vtkIdTypeArray> ids =
 46                 vtkSmartPointer<vtkIdTypeArray>::New();
 47             ids->SetNumberOfComponents(1);
 48             ids->InsertNextValue(picker->GetCellId());
 49  
 50             vtkSmartPointer<vtkSelectionNode> selectionNode =
 51                 vtkSmartPointer<vtkSelectionNode>::New();
 52             selectionNode->SetFieldType(vtkSelectionNode::CELL);
 53             selectionNode->SetContentType(vtkSelectionNode::INDICES);
 54             selectionNode->SetSelectionList(ids);
 55  
 56             vtkSmartPointer<vtkSelection> selection =
 57                 vtkSmartPointer<vtkSelection>::New();
 58             selection->AddNode(selectionNode);
 59  
 60             vtkSmartPointer<vtkExtractSelection> extractSelection =
 61                 vtkSmartPointer<vtkExtractSelection>::New();
 62             extractSelection->SetInputData(0, polyData);
 63             extractSelection->SetInputData(1, selection);
 64             extractSelection->Update();
 65  
 66             selectedMapper->SetInputData((vtkDataSet*)extractSelection->GetOutput());
 67             selectedActor->SetMapper(selectedMapper);
 68             selectedActor->GetProperty()->EdgeVisibilityOn();
 69             selectedActor->GetProperty()->SetEdgeColor(1, 0, 0);
 70             selectedActor->GetProperty()->SetLineWidth(3);
 71  
 72             this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(selectedActor);
 73         }
 74         vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
 75     }
 76 private:
 77     vtkSmartPointer<vtkPolyData>      polyData;
 78     vtkSmartPointer<vtkDataSetMapper> selectedMapper;
 79     vtkSmartPointer<vtkActor>         selectedActor;
 80 };
 81 /*********************************************************************************/
 82  
 83 vtkStandardNewMacro(CellPickerInteractorStyle);
 84  
 85 int main()
 86 {
 87     vtkSmartPointer<vtkSphereSource> sphereSource =
 88         vtkSmartPointer<vtkSphereSource>::New();
 89     sphereSource->Update();
 90  
 91     vtkSmartPointer<vtkPolyDataMapper> mapper =
 92         vtkSmartPointer<vtkPolyDataMapper>::New();
 93     mapper->SetInputData(sphereSource->GetOutput());
 94  
 95     vtkSmartPointer<vtkActor> actor =
 96         vtkSmartPointer<vtkActor>::New();
 97     actor->GetProperty()->SetColor(0, 1, 0);
 98     actor->SetMapper(mapper);
 99  
100     vtkSmartPointer<vtkRenderer> renderer =
101         vtkSmartPointer<vtkRenderer>::New();
102     renderer->AddActor(actor);
103     renderer->SetBackground(1, 1, 1);
104  
105     vtkSmartPointer<vtkRenderWindow> rw =
106         vtkSmartPointer<vtkRenderWindow>::New();
107     rw->Render();
108     rw->SetWindowName("CellPicker Interaction");
109     rw->AddRenderer(renderer);
110  
111     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
112         vtkSmartPointer<vtkRenderWindowInteractor>::New();
113     rwi->SetRenderWindow(rw);
114 /****************************************************************************/
115     vtkSmartPointer<CellPickerInteractorStyle> style =
116         vtkSmartPointer<CellPickerInteractorStyle>::New();
117     style->SetDefaultRenderer(renderer);
118     //style->polyData = sphereSource->GetOutput();
119     rwi->SetInteractorStyle(style);
120  
121     rw->Render();
122     rwi->Initialize();
123     rwi->Start();
124     return 0;
125 }
输出结果如下:
VTK 交互与拾取_单位拾取_edn
CellPickerInteractorStyle类同样派生自vtkInteraTrackballCamera,并通过重载该函数类的OnLeftButtonDown()函数来处理鼠标左键消息。PolyData为被拾取的模型数据,需要通过外部设置。在响应鼠标左键消息时,首先定义vtkCellPicker对象,使用Pick()函数实现拾取功能。拾取完毕,即可通过GetCellId()函数来得到当前拾取的单元索取号。
为了更方便地显示拾取的结果,可实现单元边的高亮显示。这里就涉及了vtkPolyData的局部数据提取功能。实现该功能时使用了几个新的类。
  • vtkIdTypeArray:对象存储当前选中的单位的索引号,每次只选取一个单元,因此每次该对象仅有一个索引号;
  • vtkSelectedNode对象与vtkSelection对象通常搭配使用,vtkSelection实际上是一个vtkSelectionNode的数组,而vtkSelectionNode则声明了要提取的数据的类型,这里SetFiledType()设置数据的类型为单元,SeiContentType()设置数据的内容为索引号。
  • vtkExtractSelection:实现了数据提取功能,其第一个输入为被提取的vtkPolyData,第二个输入为vtkSelection对象,标记要提取的数据类型。
提取完毕,即可将提取的结果保存至一个vtkActor对象,并添加至当前的vtkRenderer中显示。