zoukankan      html  css  js  c++  java
  • VTK 交互部件_测量类Widget的应用

    1.与测量类相关的主要Widget

    与测量类相关的主要Widget如下:
    • vtkDistanceWidget:用于在二维平面上测量两点之间的距离。
    • vtkAngleWidget:用于在平面的角度测量。
    • vtkBiDimensionalWidget:用于测量二维平面上任意两个正交方向的轴长。

    2.创建用于测量距离的Widget应用实例

    先复习一下创建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.额外补充的C++基础

    3.1 reinterpret_cast

    reinterpret_cast是强制类型转换符!他是用来处理无关类型转换的,通常为操作数的位模式提供较低层次的重新解释!但是他仅仅是重新解释了给出的对象的比特模型,并没有进行二进制的转换!
    他是用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换。
    1 int *pi;  
    2 char *pc = reinterpret_cast<char*>(pi);
    OK, 在这里可以看到reinterpret_cast的强大作用,但是要注意的是,他并没有进行二进制的转换,pc指向的真实对象其实还是int的,不是char~
    使用的时候千万记住,不要乱使用!错误使用很容易导致程序的不安全!

    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也支持指向基类的指针和指向子类的指针之间的转换!
    但是在这里要注意的是,我们从基类转换到子类是一个不安全的行为!
     
  • 相关阅读:
    Python
    Python
    Jmeter 学习路线
    Git 学习路线
    数据库学习路线
    Linux 学习路线
    Gitlab(2)- centos7.x 下安装社区版 Gitlab 以及它的配置管理
    云原生学习路线(仅供参考)
    Python
    Python
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14244523.html
Copyright © 2011-2022 走看看