1.单位拾取
标签:rw,VTK,拾取,vtkSmartPointer,Learning,New,include,selectedActor From: https://blog.51cto.com/u_15926338/5980089示例代码:
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL) VTK_MODULE_INIT(vtkInteractionStyle) VTK_MODULE_INIT(vtkRenderingFreeType) #include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkProperty.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleTrackballCamera.h> #include <vtkDataSetMapper.h> #include <vtkCellPicker.h> #include <vtkSelectionNode.h> #include <vtkSelection.h> #include <vtkRendererCollection.h> #include <vtkExtractSelection.h> #include <vtkObjectFactory.h> /**************************************************************************/ class CellPickerInteractorStyle :public vtkInteractorStyleTrackballCamera { public: static CellPickerInteractorStyle* New(); CellPickerInteractorStyle() { selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New(); selectedActor = vtkSmartPointer<vtkActor>::New(); } virtual void OnLeftButtonDown() { int* pos = this->GetInteractor()->GetEventPosition(); vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New(); picker->SetTolerance(0.0005); picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer()); if (picker->GetCellId() != -1) { vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New(); ids->SetNumberOfComponents(1); ids->InsertNextValue(picker->GetCellId()); vtkSmartPointer<vtkSelectionNode> selectionNode = vtkSmartPointer<vtkSelectionNode>::New(); selectionNode->SetFieldType(vtkSelectionNode::CELL); selectionNode->SetContentType(vtkSelectionNode::INDICES); selectionNode->SetSelectionList(ids); vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New(); selection->AddNode(selectionNode); vtkSmartPointer<vtkExtractSelection> extractSelection = vtkSmartPointer<vtkExtractSelection>::New(); extractSelection->SetInputData(0, polyData); extractSelection->SetInputData(1, selection); extractSelection->Update(); selectedMapper->SetInputData((vtkDataSet*)extractSelection->GetOutput()); selectedActor->SetMapper(selectedMapper); selectedActor->GetProperty()->EdgeVisibilityOn(); selectedActor->GetProperty()->SetEdgeColor(1, 0, 0); selectedActor->GetProperty()->SetLineWidth(3); this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(selectedActor); } vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); } private: vtkSmartPointer<vtkPolyData> polyData; vtkSmartPointer<vtkDataSetMapper> selectedMapper; vtkSmartPointer<vtkActor> selectedActor; }; /*********************************************************************************/ vtkStandardNewMacro(CellPickerInteractorStyle); int main() { vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New(); sphereSource->Update(); vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(sphereSource->GetOutput()); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->GetProperty()->SetColor(0, 1, 0); actor->SetMapper(mapper); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->SetBackground(1, 1, 1); vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->Render(); rw->SetWindowName("CellPicker Interaction"); rw->AddRenderer(renderer); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); rwi->SetRenderWindow(rw); /****************************************************************************/ vtkSmartPointer<CellPickerInteractorStyle> style = vtkSmartPointer<CellPickerInteractorStyle>::New(); style->SetDefaultRenderer(renderer); //style->polyData = sphereSource->GetOutput(); rwi->SetInteractorStyle(style); rw->Render(); rwi->Initialize(); rwi->Start(); return 0; }
输出结果如下:
CellPickerInteractorStyle类同样派生自vtkInteraTrackballCamera,并通过重载该函数类的OnLeftButtonDown()函数来处理鼠标左键消息。PolyData为被拾取的模型数据,需要通过外部设置。在响应鼠标左键消息时,首先定义vtkCellPicker对象,使用Pick()函数实现拾取功能。拾取完毕,即可通过GetCellId()函数来得到当前拾取的单元索取号。
为了更方便地显示拾取的结果,可实现单元边的高亮显示。这里就涉及了vtkPolyData的局部数据提取功能。实现该功能时使用了几个新的类。
- vtkIdTypeArray:对象存储当前选中的单位的索引号,每次只选取一个单元,因此每次该对象仅有一个索引号;
- vtkSelectedNode对象与vtkSelection对象通常搭配使用,vtkSelection实际上是一个vtkSelectionNode的数组,而vtkSelectionNode则声明了要提取的数据的类型,这里SetFiledType()设置数据的类型为单元,SeiContentType()设置数据的内容为索引号。
- vtkExtractSelection:实现了数据提取功能,其第一个输入为被提取的vtkPolyData,第二个输入为vtkSelection对象,标记要提取的数据类型。
提取完毕,即可将提取的结果保存至一个vtkActor对象,并添加至当前的vtkRenderer中显示。