沈阳快速网站建设网站开发,中国工厂网下载,织梦 网站图标,做效果图网站有哪些VTK中鼠标消息是在交互类型对象#xff08;interactorstyle#xff09;中响应#xff0c;因此通过为交互类型对象#xff08;interactorstyle#xff09;添加观察者#xff08;observer#xff09;来监听相应的消息#xff0c;当消息触发时#xff0c;由命令模式执行相…VTK中鼠标消息是在交互类型对象interactorstyle中响应因此通过为交互类型对象interactorstyle添加观察者observer来监听相应的消息当消息触发时由命令模式执行相应的回调函数。
vtkImageInteractionCallback继承自vtkCommand类并覆盖父类函数Execute()。 该类提供了两个接口SetImageReslice和SetInteractor。 SetImageReslice用以设置vtkImageSlice对象vtkImageSlice根据设置的变换矩阵提取三维图像切片。SetInteractor用以设置vtkRenderWindowInteractorvtkRenderWindowInteractor类对象负责每次提取切片后刷新视图。
class vtkImageInteractionCallback : public vtkCommand
{
public:static vtkImageInteractionCallback *New() //回调函数初始化函数{return new vtkImageInteractionCallback;}vtkImageInteractionCallback(){this-Slicing 0;//切片提取标志位为1时提取切片。用来检验鼠标左键是否已经按下this-ImageReslice 0;//vtkImageSlice对象的变换矩阵用来确定切面在三维图像中的位置this-Interactor 0;}void SetImageReslice(vtkImageReslice *reslice){this-ImageReslice reslice;}vtkImageReslice *GetImageReslice(){return this-ImageReslice;}void SetInteractor(vtkRenderWindowInteractor *interactor){this-Interactor interactor;}vtkRenderWindowInteractor *GetInteractor(){return this-Interactor;}virtual void Execute(vtkObject * ,unsigned long event,void *){//具体内容放下面}
private:int Slicing;vtkImageReslice *ImageReslice;vtkRenderWindowInteractor *Interactor;
};需要设置四个参数窗位(ColorLevel)、窗宽(ColorWindow)、切片(Slice)和切片方向(Orientation)。按下鼠标左键拖动鼠标可以调节图像的窗宽窗位从而显示不同灰度范围内容按下鼠标右键拖动鼠标可以放缩图像。当然这些交互操作可以由用户根据需要自己定义vtkInteractorStyle子类并响应相应的操作。 而显示三维图像时需要确定当前显示切片和方向。vtkImageViewer2提供了SetSlice()函数设置切片号SetSliceOrientationToXY()则将切片的方向设置为垂直XY平面方向。此外还可以设置为垂直YZ或者XZ平面方向其对应函数分别为SetSliceOrientationToYZ()和SetSliceOrientationToXZ()。默认情况下切片方向为垂直于XY平面即沿着Z轴方向根据设置的切片号获取Z轴方向的具体切片进行显示。
下面重点看Execute函数该函数提供了具体的切片提取功能。在该函数里面主要监听了三个消息 vtkCommand::LeftButtonPressEvent vtkCommand::LeftButtonReleaseEvent vtkCommand::MouseMoveEvent 前两个消息分别是鼠标左键的按下和弹起消息。当鼠标左键按下时就设置切片提取标志为1而当弹起时将标志置为0。这样在鼠标移动时只有在确定切片提取标志为1时执行切片提取功能。 vtkCommand::MouseMoveEvent即为鼠标移动消息。当检测到该消息时首先检查切片提取标志当为1时提取切片。提取切片时需要为vtkImageSlice对象设置变换矩阵。这里在函数开始时首先获取了鼠标滑动的前后两次点的位置lastPos和currPos。然后根据两点的Y坐标差deltaY计算新的中心点center并变换至vtkImageSlice当前变换矩阵中得到变换中心点将其设置到原来的变换矩阵matrix中并设置到vtkImageSlice中最后执行interactor-Render()即可不断的根据鼠标移动刷新图像。
virtual void Execute(vtkObject * ,unsigned long event,void *)
{vtkRenderWindowInteractor *interactor GetInteractor();int lastPos[2];interactor-GetLastEventPosition(lastPos);int currPos[2];interactor-GetEventPosition(currPos);if (event vtkCommand::LeftButtonPressEvent)//如果当前事件是鼠标左键按下{this-Slicing 1; //标志位。当鼠标左键按下时就设置切片提取标志为1}else if (event vtkCommand::LeftButtonReleaseEvent)/如果当前事件是鼠标右键按下{this-Slicing 0; //标志位 }else if (event vtkCommand::MouseMoveEvent)/如果当前事件是鼠标移动{if (this-Slicing)//检验鼠标左键已经按下{vtkImageReslice *reslice this-ImageReslice;//设置当前切片图像位置的矩阵为this-ImageReslice;但在更新之前不会将这个矩阵数据填充到reslice中去//记下鼠标Y向变化的幅值大小int deltaY lastPos[1] - currPos[1];//计算鼠标滑动的前后两次点的位置lastPos和currPos。然后计算两点的Y坐标的差deltaYreslice-Update();//使用更新操作为reslice获取当前切片图像位置的矩阵double sliceSpacing reslice-GetOutput()-GetSpacing()[2];获取reslice矩阵中的参数vtkMatrix4x4 *matrix reslice-GetResliceAxes();//定义需要使用的新的中心店center转换至vtkImageSlice当前变换矩阵中的转换矩阵但这里没有更新就没有填充//重新定位切片需要经过的中心点double point[4];double center[4];point[0] 0;point[1] 0;point[2] sliceSpacing*deltaY;point[3] 1.0;matrix-MultiplyPoint(point, center);//填充矩阵matrix-SetElement(0, 3, center[0]);//填充矩阵matrix-SetElement(1, 3, center[1]);//填充矩阵matrix-SetElement(2, 3, center[2]);//填充矩阵interactor-Render();}else//没有触发上述三个事件{vtkInteractorStyle *style vtkInteractorStyle::SafeDownCast(interactor-GetInteractorStyle());if (style){style-OnMouseMove();}}}
}
Command对象定义完毕后即可为交互对象InteractorStyle添加观察者响应鼠标消息。 这里主要是定义了vtkImageInteractionCallback对象并设置vtkImageSlice对象和vtkRenderWindowInteractor对象。然后为交互对象vtkInteractorStyle添加观察者来监控相应的消息。
vtkSmartPointervtkRenderWindowInteractor renderWindowInteractor vtkSmartPointervtkRenderWindowInteractor::New();//定义交互对象vtkSmartPointervtkInteractorStyleImage imagestyle vtkSmartPointervtkInteractorStyleImage::New();//定义交互模式renderWindowInteractor-SetInteractorStyle(imagestyle);//设置交互模式renderWindowInteractor-SetRenderWindow(renderWindow);//连接交互器与显示窗口renderWindowInteractor-Initialize();//交互器初始化//****************建立 观察者-命令 模式****************//vtkSmartPointervtkImageInteractionCallback callback vtkSmartPointervtkImageInteractionCallback::New();//设置回调函数callback-SetImageReslice(reslice);//为vtkImageSlice对象设置变换矩阵,确定矩阵对应的切片位置callback-SetInteractor(renderWindowInteractor);imagestyle-AddObserver(vtkCommand::MouseMoveEvent, callback);//鼠标移动对应的回调函数imagestyle-AddObserver(vtkCommand::LeftButtonPressEvent, callback);//按下鼠标左键对应的回调函数imagestyle-AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);//按下鼠标右键对应的回调函数renderWindowInteractor-Start();
这里主要是三个消息 vtkCommand::LeftButtonPressEvent vtkCommand::LeftButtonReleaseEvent vtkCommand::MouseMoveEvent 当响应到这三个消息时立即执行vtkImageInteractionCallback的Execute函数以便实现切片的实时提取和更新。完成以后运行程序当鼠标在图像上移动时会发现图像会跟着鼠标的移动而变化。