与测量类相关的主要Widget如下:
- vtkDistanceWidget:用于在二维平面上测量两点之间的距离。
- vtkAngleWidget:用于在平面的角度测量。
- vtkBiDimensionalWidget:用于测量二维平面上任意两个正交方向的轴长。
先复习一下创建Widget的一般步骤:1.实例化Widget;实例代码如下:
2.指定渲染窗口交互器。Widget可以通过它来监听用户事件。
3.必要时使用观察者/命令模式创建回调函数。与widget交互时,它会调用一些通用的VTK事件(94个事件列表),如StartInteractionEvent、InteractionEvent、EndInteractionEvent。用户通过监听这些事件并作出响应,从而可以更新数据、可视化参数或者应用程序的用户图形界面。
4.创建合适几何表达实体。用SetRepresentation()函数把他与Widget关联起来,或者使用Widget默认的几何表达实体。
5.最后,必须激活Widget,使其在渲染场景中显示。默认情况下,按键<I>用于激活Widget,使其在场景中可见。1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL) 3 VTK_MODULE_INIT(vtkInteractionStyle) 4 VTK_MODULE_INIT(vtkRenderingFreeType) 5 6 #include <vtkCommand.h> 7 #include <vtkSmartPointer.h> 8 #include <vtkJPEGReader.h> 9 #include <vtkImageActor.h> 10 #include <vtkRenderer.h> 11 #include <vtkRenderWindow.h> 12 #include <vtkRenderWindowInteractor.h> 13 #include <vtkInteractorStyleImage.h> 14 15 #include <vtkDistanceWidget.h> 16 #include <vtkDistanceRepresentation.h> 17 #include <vtkAngleWidget.h> 18 #include <vtkProperty2D.h> 19 #include <vtkLeaderActor2D.h> 20 #include <vtkAngleRepresentation2D.h> 21 #include <vtkBiDimensionalWidget.h> 22 #include <vtkBiDimensionalRepresentation2D.h> 23 24 25 class vtkBiDimensionalCallback: public vtkCommand 26 { 27 public: 28 static vtkBiDimensionalCallback* New() 29 { 30 return new vtkBiDimensionalCallback; 31 } 32 33 virtual void Execute(vtkObject* caller, unsigned long, void*) 34 { 35 vtkBiDimensionalWidget* biDimensionalWidget = 36 reinterpret_cast<vtkBiDimensionalWidget*> (caller); 37 vtkBiDimensionalRepresentation2D* representation = 38 static_cast<vtkBiDimensionalRepresentation2D*> (biDimensionalWidget->GetRepresentation()); 39 double p1[3]; 40 representation->GetPoint1DisplayPosition(p1); 41 double p2[3]; 42 representation->GetPoint1DisplayPosition(p2); 43 double p3[3]; 44 representation->GetPoint1DisplayPosition(p3); 45 double p4[3]; 46 representation->GetPoint1DisplayPosition(p4); 47 //显示其中一个点的屏幕坐标(px) 48 std::cout << "P1: " << p1[0] << " " << p1[1] << " " << p1[2] << std::endl; 49 } 50 vtkBiDimensionalCallback() { } 51 }; 52 int main() 53 { 54 int WidgetType; 55 std::cout << "Please select the Measurement Distance WidgetType: " << std::endl; 56 std::cin >> WidgetType; 57 58 vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); 59 reader->SetFileName("vtk.jpg"); 60 reader->Update(); 61 62 vtkSmartPointer<vtkImageActor> imgActor = vtkSmartPointer<vtkImageActor>::New(); 63 imgActor->SetInputData(reader->GetOutput()); 64 65 vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New(); 66 render->AddActor(imgActor); 67 render->SetBackground(0, 0, 0); 68 render->ResetCamera(); 69 70 vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); 71 rw->AddRenderer(render); 72 rw->SetWindowName("MeasurementDistanceApp"); 73 rw->SetSize(320, 320); 74 rw->Render(); 75 76 vtkSmartPointer<vtkRenderWindowInteractor> rwi = 77 vtkSmartPointer<vtkRenderWindowInteractor>::New(); 78 rwi->SetRenderWindow(rw); 79 80 vtkSmartPointer<vtkInteractorStyleImage> style = 81 vtkSmartPointer<vtkInteractorStyleImage>::New(); 82 rwi->SetInteractorStyle(style); 83 /****************************************************************/ 84 //vtkDistanceWidget 85 if (WidgetType == 0) 86 { 87 //实例化Widget 88 vtkSmartPointer<vtkDistanceWidget> distanceWidget = 89 vtkSmartPointer<vtkDistanceWidget>::New(); 90 //指定渲染窗口交互器,来监听用户事件 91 distanceWidget->SetInteractor(rwi); 92 //必要时使用观察者/命令模式创建回调函数(此处没用) 93 //创建几何表达实体。用SetRepresentation()把事件与Widget关联起来 94 //或者使用Widget默认的几何表达实体 95 distanceWidget->CreateDefaultRepresentation(); 96 static_cast<vtkDistanceRepresentation*> (distanceWidget->GetRepresentation()) 97 ->SetLabelFormat("%-#6.3g px"); 98 //激活Widget 99 distanceWidget->On(); 100 101 rw->Render(); 102 rwi->Initialize(); 103 rwi->Start(); 104 } 105 //vtkAngleWidget 106 if (WidgetType == 1) 107 { 108 vtkSmartPointer<vtkAngleWidget> angleWiget = vtkSmartPointer<vtkAngleWidget>::New(); 109 angleWiget->SetInteractor(rwi); 110 //创建个性化的实体图标 111 vtkSmartPointer<vtkAngleRepresentation2D> angleRep = 112 vtkSmartPointer<vtkAngleRepresentation2D>::New(); 113 angleRep->GetRay1()->GetProperty()->SetColor(0, 1, 0); 114 angleRep->GetRay1()->GetProperty()->SetLineWidth(3); 115 angleRep->GetRay2()->GetProperty()->SetColor(0, 1, 0); 116 angleRep->GetRay1()->GetProperty()->SetLineWidth(3); 117 angleRep->GetArc()->GetProperty()->SetColor(0, 1, 0); 118 angleRep->GetArc()->GetProperty()->SetLineWidth(3); 119 angleWiget->SetRepresentation(angleRep); 120 angleWiget->On(); 121 122 rw->Render(); 123 rwi->Initialize(); 124 rwi->Start(); 125 } 126 //vtkBiDimensionalWidget 127 if (WidgetType == 2) 128 { 129 vtkSmartPointer<vtkBiDimensionalWidget> bidimensionalWidget = 130 vtkSmartPointer<vtkBiDimensionalWidget>::New(); 131 bidimensionalWidget->SetInteractor(rwi); 132 //采用默认的图标 133 bidimensionalWidget->CreateDefaultRepresentation(); 134 //添加“观察者-命令模式(命令子类方案)” 135 vtkSmartPointer<vtkBiDimensionalCallback> bidiCallback = 136 vtkSmartPointer<vtkBiDimensionalCallback>::New(); 137 bidimensionalWidget->AddObserver(vtkCommand::InteractionEvent, bidiCallback); 138 bidimensionalWidget->On(); 139 140 rw->Render(); 141 rwi->Initialize(); 142 rwi->Start(); 143 } 144 return 0; 145 }
输出结果如下所示:
上面的例子中,使用了vtkDistanceWidget类来做二维空间的距离测量。先是实例化一个vtkDistanceWidget对象实例,然后调用该类的SetInteractor()函数来设置渲染窗口交互器;接着调用CreatDefaultRepresentation()函数来创建默认的几何表达实体,急用十字形表示两个端点来,端点之间使用带有刻度的直线连接。需要注意的是,在程序调用SetLabelFormat()函数来设置两点之间所测距离的文本表示格式;最后调用On()函数来激活vtkDistanceWidget实例。角度测量的vtkAngleWidget以及二维正交方向长度测量的vtkBiDimensionalWidget的使用方法与vtkDistanceWidget类似,他们的二维几何表达形式所所对应的类为vtkAngleRepresentation2D和vtkBiDimensionalRepresentation2D.
3.1 reinterpret_cast
reinterpret_cast是强制类型转换符!他是用来处理无关类型转换的,通常为操作数的位模式提供较低层次的重新解释!但是他仅仅是重新解释了给出的对象的比特模型,并没有进行二进制的转换!
他是用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换。OK, 在这里可以看到reinterpret_cast的强大作用,但是要注意的是,他并没有进行二进制的转换,pc指向的真实对象其实还是int的,不是char~1 int *pi; 2 char *pc = reinterpret_cast<char*>(pi);
使用的时候千万记住,不要乱使用!错误使用很容易导致程序的不安全!3.2 static_cast
《C++primer 第四版》中说编译器隐式执行的任何类型转换都可以由static_cast显式完成!
要注意的是,此转换没有运行时检测安全!他不能转换掉expression的const、volatile、或者__unaligned属性。他也不是用来去掉static属性的! 大家应该清楚static限定符吧,他会造成范围性的影响,而const则不同,他只是限定变量或对象自身!
当使用static限定符限定一个变量的时候,就拿类中吧,他会随类的第一个实例对象的出现而出现,并且可以被这个类的所有对象所使用!!
C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。
对于我们的static_cast转换符,他不仅可以应用到指针和引用上,而且还可以应用到基础数据结构和对象上!1 double da = 1.1; 2 void *pa = &da; 3 double *dp = static_cast<double*>(pa); 4 int ia = static_cast<int>(da); 5 6 cout << *dp << endl; 7 cout << ia << endl;
OK,代码编译通过!
《C++primer》告诉我们,对于一个由较大的算术类型到一个较小的类型的赋值,编译器通常会报错,然后当我们显示地提供强制类型转换的时候,警告信息就关闭了!
要知道我们的static_cast的真正用处不是在指针的引用上,而是在基础类型的转换和对象的转换上!
static_cast也支持指向基类的指针和指向子类的指针之间的转换!但是在这里要注意的是,我们从基类转换到子类是一个不安全的行为!
原文:https://www.cnblogs.com/ybqjymy/p/14244523.html