与测量类相关的主要Widget如下:
- vtkDistanceWidget:用于在二维平面上测量两点之间的距离。
- vtkAngleWidget:用于在平面的角度测量。
- vtkBiDimensionalWidget:用于测量二维平面上任意两个正交方向的轴长。
创建Widget的一般步骤:
1.实例化Widget;
2.指定渲染窗口交互器。Widget可以通过它来监听用户事件。
3.必要时使用观察者/命令模式创建回调函数。与Widget交互时,它会调用一些通用的VTK事件(94个事件列表),如StartInteractorEvent、InteractorEvent、EndInteractorEvent。用户通过监听这些事件并作出响应,从而可以更新数据、可视化参数或者应用程序的用户图形化界面。
4.创建合适几何表达实体。用SetRepresentation()函数把他与Widget关联起来,或者使用Widget默认的几何表达实体。
5.最后,必须激活Widget,使其在渲染场景中显示。默认情况下按键用于激活Widget,使其在场景中可见。
下面的例子中,首先使用vtkDistanceWidget类来做二维空间的距离测量。先是实例化一个vtkDistanceWidget对象实例,然后调用该类的SetInteractor()函数来设置渲染窗口交互器;接着调用CreatDefaultRepresentation()函数来创建默认的几何表达实体,即用十字形表示两个端点来,端点之间使用带刻度的直线连接。需要注意的是,在程序调用SetLabelFormat()函数来设置两点之间所测量距离的文本表示格式;最后调用On()函数来激活vtkDistanceWidget实例。
角度测量的vtkAngelWidget以及二维正交方向长度测量的vtkBiDimensionalWidgwet的使用方法与vtkDistanceWidget类似,他们的二维几何形式所对应的类为vtkAngelRepresentation2D和vtkBiDistanceRepresentation2D。
#includeVTK_MODULE_INIT(vtkRenderingOpenGL2) VTK_MODULE_INIT(vtkInteractionStyle) VTK_MODULE_INIT(vtkRenderingFreeType) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class vtkBiDimensionalCallback : public vtkCommand { public: static vtkBiDimensionalCallback* New() { return new vtkBiDimensionalCallback; } virtual void Execute(vtkObject* caller, unsigned long, void*) { vtkBiDimensionalWidget* biDimensionalWidget = reinterpret_cast (caller); vtkBiDimensionalRepresentation2D* representation = static_cast (biDimensionalWidget->GetRepresentation()); double p1[3]; representation->GetPoint1DisplayPosition(p1); double p2[3]; representation->GetPoint1DisplayPosition(p2); double p3[3]; representation->GetPoint1DisplayPosition(p3); double p4[3]; representation->GetPoint1DisplayPosition(p4); //显示其中一个点的屏幕坐标(px) std::cout << "P1: " << p1[0] << " " << p1[1] << " " << p1[2] << std::endl; } vtkBiDimensionalCallback() { } }; int main() { int WidgetType; std::cout << "Please select the Measurement Distance WidgetType: " << std::endl; std::cin >> WidgetType; vtkSmartPointer reader = vtkSmartPointer ::New(); reader->SetFileName("data/lena.jpg"); reader->Update(); vtkSmartPointer imgActor = vtkSmartPointer ::New(); imgActor->SetInputData(reader->GetOutput()); vtkSmartPointer render = vtkSmartPointer ::New(); render->AddActor(imgActor); render->SetBackground(0, 0, 0); render->ResetCamera(); vtkSmartPointer rw = vtkSmartPointer ::New(); rw->AddRenderer(render); rw->SetWindowName("MeasurementDistanceApp"); rw->SetSize(320, 320); rw->Render(); vtkSmartPointer rwi = vtkSmartPointer ::New(); rwi->SetRenderWindow(rw); vtkSmartPointer style = vtkSmartPointer ::New(); rwi->SetInteractorStyle(style); //vtkDistanceWidget if (WidgetType == 0) { //实例化Widget vtkSmartPointer distanceWidget = vtkSmartPointer ::New(); //指定渲染窗口交互器,来监听用户事件 distanceWidget->SetInteractor(rwi); //必要时使用观察者/命令模式创建回调函数(此处没用) //创建几何表达实体。用SetRepresentation()把事件与Widget关联起来 //或者使用Widget默认的几何表达实体 distanceWidget->CreateDefaultRepresentation(); static_cast (distanceWidget->GetRepresentation()) ->SetLabelFormat("%-#6.3g px"); //激活Widget distanceWidget->On(); rw->Render(); rwi->Initialize(); rwi->Start(); } //vtkAngleWidget if (WidgetType == 1) { vtkSmartPointer angleWiget = vtkSmartPointer ::New(); angleWiget->SetInteractor(rwi); //创建个性化的实体图标 vtkSmartPointer angleRep = vtkSmartPointer ::New(); angleRep->GetRay1()->GetProperty()->SetColor(0, 1, 0); angleRep->GetRay1()->GetProperty()->SetLineWidth(3); angleRep->GetRay2()->GetProperty()->SetColor(0, 1, 0); angleRep->GetRay1()->GetProperty()->SetLineWidth(3); angleRep->GetArc()->GetProperty()->SetColor(0, 1, 0); angleRep->GetArc()->GetProperty()->SetLineWidth(3); angleWiget->SetRepresentation(angleRep); angleWiget->On(); rw->Render(); rwi->Initialize(); rwi->Start(); } //vtkBiDimensionalWidget if (WidgetType == 2) { vtkSmartPointer bidimensionalWidget = vtkSmartPointer ::New(); bidimensionalWidget->SetInteractor(rwi); //采用默认的图标 bidimensionalWidget->CreateDefaultRepresentation(); //添加“观察者-命令模式(命令子类方案)” vtkSmartPointer bidiCallback = vtkSmartPointer ::New(); bidimensionalWidget->AddObserver(vtkCommand::InteractionEvent, bidiCallback); bidimensionalWidget->On(); rw->Render(); rwi->Initialize(); rwi->Start(); } return 0; }
运行截图:
- reinterpret_cast
reinterpret_cast是强制类型转换符!他是用来处理无关类型转换的,通常为操作数的位模式提供较低层次的重新解释!但是他仅仅是重新解释了给出的对象的比特模型,并没有进行二进制的转换!
他是用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换。int *pi; char *pc = reinterpret_cast(pi);
pc指向的真实对象其实还是int的 - static_cast
《C++primer 第四版》中说编译器隐式执行的任何类型转换都可以由static_cast显式完成!此转换没有运行时检测安全!他不能转换掉expression的const、volatile、或者__unaligned属性。static限定符会造成范围性影响,const只是限定变量或者对象自身!C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。不仅可以应用到指针和引用上,而且还可以应用到基础数据结构和对象上!
double da = 1.1; void *pa = &da; double *dp = static_cast(pa); int ia = static_cast (da); cout << *dp << endl; cout << ia << endl;
static_cast的真正用处不是在指针的引用上,而是在基础类型的转换和对象的转换上!
static_cast也支持指向基类的指针和指向子类的指针之间的转换!



