VTK笔记

您所在的位置:网站首页 拾取坐标系 VTK笔记

VTK笔记

#VTK笔记| 来源: 网络整理| 查看: 265

拾取是可视化应用程序中常见的一种功能。拾取主要是用于选择数据和actor或者获取底层的数据值,比如说,拾取点,拾取actor,拾取cell等。

拾取器

VTK支持多种不同功能的拾取类型。vtkAbstractPicker是所有拾取类的基类,它定义了一些公共的API,允许用户通过GetPickPosition()来获取拾取位置。 继承图如下: 在这里插入图片描述

如何选择

当我们面临太多选择的时候可能会困惑,究竟该用哪个?如何选择?首先我们得知道他们的基本区别。 简单的说,拾取器可分两类: 一类是基于硬件拾取,如vtkPropPicker及其子类、vtkAreaPicker及子类 另一类是基于几何拾取,如vtkPicker和它的子类 硬件拾取的优点是快速,但获取信息有限 几何拾取则获得的信息多,但速度相对要慢一些 vtkPropPicker使用硬件拾取的策略来确定所拾取的vtkProp对象,包括拾取点的世界坐标。它通常比vtkAbstractPropPicker的其它子类速度要快,但它不能返回所拾取对象的详细信息。 vtkAreaPicker及其子类vtkRenderedAreaPicker也是基于硬件实现的,同样无法获取到拾取对象的详细信息,他们的作用是选择屏幕上的对象。 vtkPicker是基于软件实现的拾取类,具体实现是基于vtkProp对象的包围盒来拾取对象的。它在拾取时,会从相机当前位置投射一条光线到拾取点,所投射光线会与某个prop3D对象的包围盒相交,当然,通过这种方式有可能会拾取到多个prop3D对象,最后返回的是所投射光线与对象包围盒相交最多的对象。GetProp3Ds()方法可以返回与投射光线相交的所有prop3D对象。vtkPicker拾取速度相对较快,但无法获取单一拾取。 vtkPicker有三个子类,其中两个分别是vtkPointPicker和vtkCellPicker,它们可以获取所拾取对象的详细信息,如点的ID,单元的ID等。 vtkPointPicker用于拾取单个点,返回ID和坐标值。拾取时,它也是通过相机当前位置投射一条光线到拾取点,然后将光线周围且位于容差范围内的点投射至光线上,最后返回的是距离相机最近的点以及该点所对应的actor。它比父类vtkPicker拾取速度要慢,但比兄弟类vtkCellPicer要快。因为引入了容差,所以可以返回单一的拾取对象。 vtkCellPicker用于拾取某个单元,并返回交点的信息,比如,交点所对应的单元ID、世界坐标和参数化单元坐标。与vtkPointPicker类似,它拾取时也是投射一条光线至拾取点,在一定容差范围内确定光线是否与actor底层几何相交,最后返回沿着光线最靠近相机的单元及其对应的对象。vtkCellPicker是所有拾取类中最慢的一个,但获取信息是最多的。通过指定容差,可以返回单一的拾取对象。

基本用法 using PickerType = vtkPropPicker; // vtkPointPicker

定义picker并初始化

auto picker = vtkSmartPointer::New(); picker->PickFromListOn();

添加拾取的Prop对象

vtkImageActor* imageActor = imageViewer->GetImageActor(); picker->AddPickList(imageActor);

绑定自定义事件

auto callback = vtkSmartPointer::New(); callback->SetPicker(picker);

拾取Pick:

picker->Pick(clickPos[0], clickPos[1], 0.0, renderer);

注意:Pick方法需要一个renderer作为参数。与渲染器相关的actor都是拾取的对象。另外,第三个参数通常都设置为0.0,它是与Z-buffer相关的值。

获取世界坐标

double pos[3]; picker->GetPickPosition(pos);

值得注意: 就上面的需求而言,这里应该选用vtkPropPicker,在vtk7.1.0中,可以拾取到坐标值,但在vtk8.2.0,不能获取到坐标,使用vtkPointPicker可以得到。

示例

示例演示了通过鼠标移动在一个二维图像上拾取像素值,并判断是否在图像区域上。 在这里插入图片描述

PickPixel2.cxx #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using PickerType = vtkPointPicker; // Template for image value reading template void vtkValueMessageTemplate(vtkImageData* image, int* position, std::string& message) { T* tuple = ((T*)image->GetScalarPointer(position)); int components = image->GetNumberOfScalarComponents(); for (int c = 0; c message += ", "; } } message += " )"; } // The mouse motion callback, to pick the image and recover pixel values class vtkImageInteractionCallback : public vtkCommand { public: static vtkImageInteractionCallback* New() { return new vtkImageInteractionCallback; } vtkImageInteractionCallback() { this->Viewer = NULL; this->Picker = NULL; this->Annotation = NULL; } ~vtkImageInteractionCallback() { this->Viewer = NULL; this->Picker = NULL; this->Annotation = NULL; } void SetPicker(PickerType* picker) { this->Picker = picker; } void SetAnnotation(vtkCornerAnnotation* annotation) { this->Annotation = annotation; } void SetViewer(vtkImageViewer2* viewer) { this->Viewer = viewer; } virtual void Execute(vtkObject*, unsigned long vtkNotUsed(event), void*) { vtkRenderWindowInteractor* interactor = this->Viewer->GetRenderWindow()->GetInteractor(); int* clickPos = interactor->GetEventPosition(); vtkRenderer* renderer = this->Viewer->GetRenderer(); //vtkRenderer* renderer = interactor->FindPokedRenderer(clickPos[0], clickPos[1]); vtkImageActor* actor = this->Viewer->GetImageActor(); vtkImageData* image = this->Viewer->GetInput(); vtkInteractorStyle* style = dynamic_cast(interactor->GetInteractorStyle()); // Pick at the mouse location provided by the interactor this->Picker->Pick(clickPos[0], clickPos[1], 0.0, renderer); // There could be other props assigned to this picker, so // make sure we picked the image actor vtkAssemblyPath* path = this->Picker->GetPath(); bool validPick = false; if (path) { vtkCollectionSimpleIterator sit; path->InitTraversal(sit); for (int i = 0; i GetNumberOfItems() && !validPick; ++i) { auto node = path->GetNextNode(sit); if (actor == dynamic_cast(node->GetViewProp())) { validPick = true; } } } if (!validPick) { this->Annotation->SetText(0, "Off Image"); interactor->Render(); // Pass the event further on style->OnMouseMove(); return; } // Get the world coordinates of the pick double pos[3]; this->Picker->GetPickPosition(pos); int image_coordinate[3]; int axis = this->Viewer->GetSliceOrientation(); switch (axis) { case vtkImageViewer2::SLICE_ORIENTATION_XZ: image_coordinate[0] = vtkMath::Round(pos[0]); image_coordinate[1] = this->Viewer->GetSlice(); image_coordinate[2] = vtkMath::Round(pos[2]); break; case vtkImageViewer2::SLICE_ORIENTATION_YZ: image_coordinate[0] = this->Viewer->GetSlice(); image_coordinate[1] = vtkMath::Round(pos[1]); image_coordinate[2] = vtkMath::Round(pos[2]); break; default: // vtkImageViewer2::SLICE_ORIENTATION_XY image_coordinate[0] = vtkMath::Round(pos[0]); image_coordinate[1] = vtkMath::Round(pos[1]); image_coordinate[2] = this->Viewer->GetSlice(); break; } std::string message = "Location: ( "; message += vtkVariant(image_coordinate[0]).ToString(); message += ", "; message += vtkVariant(image_coordinate[1]).ToString(); message += ", "; message += vtkVariant(image_coordinate[2]).ToString(); message += " )\nValue: ( "; switch (image->GetScalarType()) { vtkTemplateMacro( (vtkValueMessageTemplate(image, image_coordinate, message))); default: return; } this->Annotation->SetText(0, message.c_str()); interactor->Render(); style->OnMouseMove(); } private: vtkImageViewer2* Viewer; // Pointer to the viewer PickerType* Picker; // Pointer to the picker vtkCornerAnnotation* Annotation; // Pointer to the annotation }; int main(int argc, char* argv[]) { auto imageViewer = vtkSmartPointer::New(); // Verify input arguments if (argc != 2) { std::cout std::cout SetupInteractor(renderWindowInteractor); imageViewer->SetSize(600, 600); vtkRenderer* renderer = imageViewer->GetRenderer(); renderer->ResetCamera(); renderer->GradientBackgroundOn(); renderer->SetBackground(0.6, 0.6, 0.5); renderer->SetBackground2(0.3, 0.3, 0.2); // Annotate the image with window/level and mouse over pixel // information auto cornerAnnotation = vtkSmartPointer::New(); cornerAnnotation->SetLinearFontScaleFactor(2); cornerAnnotation->SetNonlinearFontScaleFactor(1); cornerAnnotation->SetMaximumFontSize(20); cornerAnnotation->SetText(0, "Off Image"); cornerAnnotation->SetText(3, "\n"); cornerAnnotation->GetTextProperty()->SetColor(1, 0, 0); imageViewer->GetRenderer()->AddViewProp(cornerAnnotation); // Callback listens to MouseMoveEvents invoked by the interactor's style auto callback = vtkSmartPointer::New(); callback->SetViewer(imageViewer); callback->SetAnnotation(cornerAnnotation); callback->SetPicker(picker); // InteractorStyleImage allows for the following controls: // 1) middle mouse + move = camera pan // 2) left mouse + move = window/level // 3) right mouse + move = camera zoom // 4) middle mouse wheel scroll = zoom // 5) 'r' = reset window/level // 6) shift + 'r' = reset camera vtkInteractorStyleImage* imageStyle = imageViewer->GetInteractorStyle(); imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback); renderWindowInteractor->Initialize(); renderWindowInteractor->Start(); return EXIT_SUCCESS; } Ref

VTK交互之拾取 VTKExamples/Cxx/Images/PickPixel2 vtkAbstractPicker Class Reference 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3