VTK:交互部件——测量类Widget的应用

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

与测量类相关的主要Widget如下:
在这里插入图片描述

  • vtkDistanceWidget:用于在二维平面上测量两点之间的距离。
  • vtkAngleWidget:用于在平面的角度测量。
  • vtkBiDimensionalWidget:用于测量二维平面上任意两个正交方向的轴长。

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

创建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。

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)

#include <vtkCommand.h>
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>

#include <vtkDistanceWidget.h>
#include <vtkDistanceRepresentation.h>
#include <vtkAngleWidget.h>
#include <vtkProperty2D.h>
#include <vtkLeaderActor2D.h>
#include <vtkAngleRepresentation2D.h>
#include <vtkBiDimensionalWidget.h>
#include <vtkBiDimensionalRepresentation2D.h>


class vtkBiDimensionalCallback : public vtkCommand
{
public:
	static	vtkBiDimensionalCallback* New()
	{
		return new vtkBiDimensionalCallback;
	}

	virtual void Execute(vtkObject* caller, unsigned long, void*)
	{
		vtkBiDimensionalWidget* biDimensionalWidget =
			reinterpret_cast<vtkBiDimensionalWidget*> (caller);
		vtkBiDimensionalRepresentation2D* representation =
			static_cast<vtkBiDimensionalRepresentation2D*> (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<vtkJPEGReader> reader =
		vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileName("data/lena.jpg");
	reader->Update();

	vtkSmartPointer<vtkImageActor> imgActor = vtkSmartPointer<vtkImageActor>::New();
	imgActor->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
	render->AddActor(imgActor);
	render->SetBackground(0, 0, 0);
	render->ResetCamera();

	vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();
	rw->AddRenderer(render);
	rw->SetWindowName("MeasurementDistanceApp");
	rw->SetSize(320, 320);
	rw->Render();

	vtkSmartPointer<vtkRenderWindowInteractor> rwi =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	rwi->SetRenderWindow(rw);

	vtkSmartPointer<vtkInteractorStyleImage> style =
		vtkSmartPointer<vtkInteractorStyleImage>::New();
	rwi->SetInteractorStyle(style);
	/****************************************************************/
		//vtkDistanceWidget
	if (WidgetType == 0)
	{
		//实例化Widget
		vtkSmartPointer<vtkDistanceWidget> distanceWidget =
			vtkSmartPointer<vtkDistanceWidget>::New();
		//指定渲染窗口交互器,来监听用户事件
		distanceWidget->SetInteractor(rwi);
		//必要时使用观察者/命令模式创建回调函数(此处没用)
		//创建几何表达实体。用SetRepresentation()把事件与Widget关联起来
		//或者使用Widget默认的几何表达实体
		distanceWidget->CreateDefaultRepresentation();
		static_cast<vtkDistanceRepresentation*> (distanceWidget->GetRepresentation())
			->SetLabelFormat("%-#6.3g px");
		//激活Widget
		distanceWidget->On();

		rw->Render();
		rwi->Initialize();
		rwi->Start();
	}
	//vtkAngleWidget
	if (WidgetType == 1)
	{
		vtkSmartPointer<vtkAngleWidget> angleWiget = vtkSmartPointer<vtkAngleWidget>::New();
		angleWiget->SetInteractor(rwi);
		//创建个性化的实体图标
		vtkSmartPointer<vtkAngleRepresentation2D> angleRep =
			vtkSmartPointer<vtkAngleRepresentation2D>::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<vtkBiDimensionalWidget> bidimensionalWidget =
			vtkSmartPointer<vtkBiDimensionalWidget>::New();
		bidimensionalWidget->SetInteractor(rwi);
		//采用默认的图标
		bidimensionalWidget->CreateDefaultRepresentation();
		//添加“观察者-命令模式(命令子类方案)”
		vtkSmartPointer<vtkBiDimensionalCallback> bidiCallback =
			vtkSmartPointer<vtkBiDimensionalCallback>::New();
		bidimensionalWidget->AddObserver(vtkCommand::InteractionEvent, bidiCallback);
		bidimensionalWidget->On();

		rw->Render();
		rwi->Initialize();
		rwi->Start();
	}
	return 0;
}

运行截图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.基础

  1. reinterpret_cast
    reinterpret_cast是强制类型转换符!他是用来处理无关类型转换的,通常为操作数的位模式提供较低层次的重新解释!但是他仅仅是重新解释了给出的对象的比特模型,并没有进行二进制的转换!
    他是用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换。int *pi; char *pc = reinterpret_cast<char*>(pi);
    pc指向的真实对象其实还是int的
  2. 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<double*>(pa);  
int ia = static_cast<int>(da);  
  
cout << *dp << endl;  
cout << ia << endl;  

static_cast的真正用处不是在指针的引用上,而是在基础类型的转换和对象的转换上!
static_cast也支持指向基类的指针和指向子类的指针之间的转换!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 。单

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值