VTK: 拾取方式的三种实现
2017-05-30 16:15
435 查看
拾取操作是可视化应用程序中常见的一种功能。拾取主要是用于选择数据和Actor或者获取底层的数据值。在显示位置(以像素为坐标值)中拾取时,就会调用vtkAbstractPicker的Pick()方法。依赖于所用的拾取类不同,拾取时返回的信息也不同,最简单的是返回一个x-y-z的全局坐标值,或者是单元(cell)的ID值,点的ID值,单元参数坐标(CellParametric
Coordinates),所拾取的vtkProp实例,以及Assemblypath。与拾取相关的VTK类的 继承图如下:
本文内容主要介绍一下vtk拾取的实现方式,并不讲解每种拾取器的差别。本文拾取过程以vtkCellPicker为例子讲解。拾取的实现按照vtk交互方式的不同分为两大类:1)重写vtkInteractorStyle完成拾取
2)重写观察者命令模式完成拾取
1) 重写vtkInteractorStyle
2)重写观察者命令模式完成拾取
根据观察者的不同分为两种实现方法:1)观察者为vtkRenderWindowInteractor
2)观察者为vtkcellpicker
1)给vtkRenderWindowInteractor添加回调类,响应的vtk事件是
拾取方式是鼠标左键点击
回调类代码如下:
2)给 vtkCellPicker添加回调类 响应的vtk事件是:
回调类代码如下:
Coordinates),所拾取的vtkProp实例,以及Assemblypath。与拾取相关的VTK类的 继承图如下:
本文内容主要介绍一下vtk拾取的实现方式,并不讲解每种拾取器的差别。本文拾取过程以vtkCellPicker为例子讲解。拾取的实现按照vtk交互方式的不同分为两大类:1)重写vtkInteractorStyle完成拾取
2)重写观察者命令模式完成拾取
1) 重写vtkInteractorStyle
class MouseInteractorStyle : public vtkInteractorStyleTrackballCamera { public: static MouseInteractorStyle* New(); MouseInteractorStyle() { selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New(); selectedActor = vtkSmartPointer<vtkActor>::New(); } virtual void OnLeftButtonDown() { // Get the location of the click (in window coordinates) int* pos = this->GetInteractor()->GetEventPosition(); vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New(); picker->SetTolerance(0.0005); // Pick from this location. picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer()); double* worldPosition = picker->GetPickPosition(); std::cout << "Cell id is: " << picker->GetCellId() << std::endl; if(picker->GetCellId() != -1) { std::cout << "Pick position is: " << worldPosition[0] << " " << worldPosition[1] << " " << worldPosition[2] << endl; 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(); #if VTK_MAJOR_VERSION <= 5 extractSelection->SetInput(0, this->Data); extractSelection->SetInput(1, selection); #else extractSelection->SetInputData(0, this->Data); extractSelection->SetInputData(1, selection); #endif extractSelection->Update(); // In selection vtkSmartPointer<vtkUnstructuredGrid> selected = vtkSmartPointer<vtkUnstructuredGrid>::New(); selected->ShallowCopy(extractSelection->GetOutput()); std::cout << "There are " << selected->GetNumberOfPoints() << " points in the selection." << std::endl; std::cout << "There are " << selected->GetNumberOfCells() << " cells in the selection." << std::endl; #if VTK_MAJOR_VERSION <= 5 selectedMapper->SetInputConnection( selected->GetProducerPort()); #else selectedMapper->SetInputData(selected); #endif selectedActor->SetMapper(selectedMapper); selectedActor->GetProperty()->EdgeVisibilityOn(); selectedActor->GetProperty()->SetEdgeColor(1,0,0); selectedActor->GetProperty()->SetLineWidth(3); this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(selectedActor); } // Forward events vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); } vtkSmartPointer<vtkPolyData> Data; vtkSmartPointer<vtkDataSetMapper> selectedMapper; vtkSmartPointer<vtkActor> selectedActor; };
2)重写观察者命令模式完成拾取
根据观察者的不同分为两种实现方法:1)观察者为vtkRenderWindowInteractor
2)观察者为vtkcellpicker
1)给vtkRenderWindowInteractor添加回调类,响应的vtk事件是
LeftButtonPressEvent
拾取方式是鼠标左键点击
回调类代码如下:
class PickerCallBack : public vtkCommand { public: static PickerCallBack *New() { return new PickerCallBack; } virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData) { //相应拾取结果 if(eventId == vtkCommand::LeftButtonPressEvent){ QVTKInteractor *interactor = QVTKInteractor::SafeDownCast( caller ); vtkRenderer *renderer = interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer(); int event_pos[3] = {0, 0, 0}; interactor->GetEventPosition(event_pos); interactor->GetPicker()->Pick(event_pos[0], event_pos[1], 0, renderer); if(picker->GetCellId() != -1){ double *pos = picker->GetPickPosition(); qDebug() <<"pick coord:" << pos[0] << pos[1] << pos[2]; } } } bool m_enable = false; };main函数中 为vtkRenderWindowInteractor添加该回调类:
vtkSmartPointer<PickerCallBack> callBack = vtkSmartPointer<PickerCallBack>::New(); interactor->AddObserver(vtkCommand::LeftButtonPressEvent,callBack);
2)给 vtkCellPicker添加回调类 响应的vtk事件是:
vtkCommand::EndPickEvent拾取方式是键盘字母P + 移动鼠标
回调类代码如下:
class PickerCallBack : public vtkCommand { public: static PickerCallBack *New() { return new PickerCallBack; } virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData) { if(!m_enable) return; if(eventId == vtkCommand::EndPickEvent){ vtkCellPicker *picker = vtkCellPicker::SafeDownCast(caller); //坐标拾取 if(picker->GetCellId() != -1){ double *pos = picker->GetPickPosition(); qDebug() <<"pick coord:" << pos[0] << pos[1] << pos[2]; } picker->SetPath(nullptr); } } bool m_enable = false; };main函数中 为vtkCellPicker添加该回调类:
vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New(); interactor->SetPicker(picker); vtkSmartPointer<PickerCallBack> callBack = vtkSmartPointer<PickerCallBack>::New(); interactor->GetPicker->AddObserver(vtkCommand::EndPickEvent,callBack);
相关文章推荐
- Java多线程的三种实现方式
- SSO单点登录三种情况的实现方式详解
- jsp页面引入(包含)其他页面的三种实现方式
- 数组三种方式排序实现
- Ajax技术三种实现方式之xmlhttp+httphandler篇 (三)
- c# list排序的三种实现方式
- 详细讲解二叉树三种遍历方式的递归与非递归实现
- MFC三种不同方式实现图形的保存和重绘---方法二: 运用CMetaFileDC
- Spring AOP三种实现方式
- MyBatis学习笔记-06.MyBatis实现模糊查询的三种方式以及在MyBatis中#{}和${}的区别
- axis和xfire以及CXF三种方式实现WebServices分别有什么优缺
- java中List实现的三种方式Vector、ArraryList和LinkedList
- spring bean实现init/destory生命周期方法的三种方式
- .NET中的三种接口实现方式
- C语言实现比特位数组在目标空间左右居中对齐三种方式
- java三种方式实现键盘录入
- 二叉树的前序、中序、后序三种遍历的六种实现方式(递归、非递归)(C++)
- 实现沉浸式的三种方式
- 验证码三种实现方式