VTK知识学习(29)-交互问题

1、窗体类型

1)、RenderWindowControl

UserControl derived implementation of vtkRenderWindow for use in Windows Forms applications. The client area of this UserControl is completely filled with an instance of a vtkRenderWindow.

用于Windows窗体应用程序的vtkRenderWindow的UserControl派生实现。此UserControl的客户端区域完全由vtkRenderWindow的实例填充。

内部包含一个RenderWindow,是我们操作的真正对象。

2)、vtkImageViewer

// Display a 2d image. vtkImageViewer is a convenience class for displaying a 2d

// image. It packages up the functionality found in vtkRenderWindow, vtkRenderer,

// vtkActor2D and vtkImageMapper into a single easy to use class. Behind the scenes

// these four classes are actually used to to provide the required functionality.

// vtkImageViewer is simply a wrapper around them.

显示二维图像。vtkImageViewer是一个用于显示二维图像的便利类。

它将vtkRenderWindow、vtkRenderer、vtkActor2D和vtkImageMapper中的功能打包成一个易于使用的类。

在幕后,这四个类实际上用于提供所需的功能。vtkImageViewer只是它们的包装器。

通过方法获取RenderWindow,是我们进行图像渲染添加的操作对象。(单独一个窗体)

3)、vtkImageViewer2

vtkImageViewer2是一个用于显示2D图像的便利类。它将vtkRenderWindow、vtkRenderer、vtkImageActor和vtkImageMapToWindowLevelColors中的功能打包成一个易于使用的类。

此类还创建了一种图像交互器样式(vtkInteractiorStyleImage),允许缩放和平移图像,并支持对图像进行交互式窗口/级别操作。

请注意,vtkImageViewer2只是这些类的包装器。vtkImageViewer2使用3D渲染和纹理映射引擎在平面上绘制图像。这允许快速渲染、缩放和平移。图像被放置在3D场景中基于特定图像切片的z坐标的深度处。

每次调用SetSlice()都会更改显示的图像数据(切片),并更改3D场景中显示的切片的深度。这可以通过InteractiorStyle成员的AutoAdjustCameraClippingRange ivar进行控制。

通过方法获取RenderWindow,是我们进行图像渲染添加的操作对象。(单独一个窗体)

2、事件

1)、回调

函数指针是一个指向函数的指针变量,通过将函数指针作为参数传递给其他函数,当特定条件满足时,被调用函数可以通过这个指针调用回调函数。

VTK实现用户交互的观察者模式,通过AddObserver函数进行注册即可以。

cpp 复制代码
imagestyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);

当然,在C#中有对应函数,但是报错。

2)、事件

事件处理机制是一种实现回调的常见方式,尤其是在图形用户界面(GUI)编程或基于消息驱动的系统中。当然它是基于回调的。

c#中无法实现观察者模式所提供的AddOberver函数来注册。但是它提供了很多事件,换言之是进行了内部封装,当然这个只有封装库的人才明白。

3、使用

如果使用用户控件进行交互可能是主线程占用问题导致卡死。这里使用vtkImageViewer。

cs 复制代码
private  void TestInteractorStyle()
{
    vtkMetaImageReader reader = vtkMetaImageReader.New();
    reader.SetFileName("F:\\code\\VTK\\TestActiViz\\bin\\Debug\\data\\brain.mhd");
    reader.Update();

    int[] extent = reader.GetOutput().GetExtent();
    double[] spacing = reader.GetOutput().GetSpacing();
    double[] origin = reader.GetOutput().GetOrigin();

    double[] center = new double[3];
    center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
    center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
    center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);

    double[] axialElements ={
       1, 0, 0, 0,
       0, 1, 0, 0,
       0, 0, 1, 0,
       0, 0, 0, 1
   };//提取平行于YZ平面的切片

    IntPtr ptrData = Marshal.AllocHGlobal(sizeof(double) * axialElements.Length);
    Marshal.Copy(axialElements, 0, ptrData, axialElements.Length);
    vtkMatrix4x4 resliceAxes = vtkMatrix4x4.New();
    resliceAxes.DeepCopy(ptrData);
    resliceAxes.SetElement(0, 3, center[0]);
    resliceAxes.SetElement(1, 3, center[1]);
    resliceAxes.SetElement(2, 3, center[2]);

    vtkImageReslice reslice = vtkImageReslice.New();
    reslice.SetInputData(reader.GetOutput());
    reslice.SetOutputDimensionality(2);
    reslice.SetResliceAxes(resliceAxes);
    reslice.SetInterpolationModeToLinear(); //指定切面提取中的插值方式为线性插值
    reslice.Update();

    vtkLookupTable colorTable = vtkLookupTable.New();
    colorTable.SetRange(0, 1000);
    colorTable.SetValueRange(0, 1);
    colorTable.SetSaturationRange(0, 0);
    colorTable.SetRampToLinear();
    colorTable.Build();

    vtkImageMapToColors colorMap = vtkImageMapToColors.New();
    colorMap.SetLookupTable(colorTable);
    colorMap.SetInputConnection(reslice.GetOutputPort());
    colorMap.Update();

    vtkImageActor orgActor = vtkImageActor.New();
    orgActor.SetInputData(colorMap.GetOutput());

    vtkRenderer renderer3 = vtkRenderer.New();
    renderer3.AddActor(orgActor);
    renderer3.ResetCamera();
    renderer3.SetBackground(0.4, 0.5, 0.6);

    //  vtkRenderWindow renderWindow = renderWindowControl.RenderWindow;
    vtkImageViewer2 imageViewer = vtkImageViewer2.New();
    imageViewer.SetSize(500, 500);
    vtkRenderWindow renderWindow = imageViewer.GetRenderWindow();
    renderWindow.AddRenderer(renderer3);

    vtkRenderWindowInteractor windowInteractor = vtkRenderWindowInteractor.New();
    vtkInteractorStyleTrackballCamera style = new vtkInteractorStyleTrackballCamera();
    windowInteractor.SetInteractorStyle(style);
    windowInteractor.SetRenderWindow(renderWindow);
    windowInteractor.Initialize();
    //vktImageInteractionCallback callback = new vktImageInteractionCallback();
    //callback.SetImageReslice(reslice);
    //callback.SetInteractor(renderWindow);


    //imageViewer.AddObserver((uint)vtkCommand.EventIds.LeftButtonPressEvent, callback, 0);
    //imageViewer.AddObserver((uint)vtkCommand.EventIds.MouseMoveEvent, callback, 0);
    // imageViewer.AddObserver((uint)vtkCommand.EventIds.LeftButtonReleaseEvent, callback, 0);
    windowInteractor.LeftButtonPressEvt += ImageStyle_LeftButtonPressEvt;
    windowInteractor.LeftButtonReleaseEvt += ImageStyle_LeftButtonReleaseEvt;
    windowInteractor.MouseMoveEvt += ImageStyle_MouseMoveEvt;
   windowInteractor.Start();
}

private void ImageStyle_MouseMoveEvt(vtkObject sender, vtkObjectEventArgs e)
{
    Console.WriteLine("ImageStyle_MouseMoveEvt");
}

private void ImageStyle_LeftButtonReleaseEvt(vtkObject sender, vtkObjectEventArgs e)
{
    Console.WriteLine("ImageStyle_LeftButtonReleaseEvt");

}

private void ImageStyle_LeftButtonPressEvt(vtkObject sender, vtkObjectEventArgs e)
{
    Console.WriteLine("ImageStyle_LeftButtonPressEvt");

}
相关推荐
PyAIGCMaster40 分钟前
docker学习记录:部署es+kibana
学习·elasticsearch·docker
蜗牛_snail1 小时前
学习笔记 : MySQL进阶篇一之架构和日志文件
笔记·学习·mysql
小大力1 小时前
简单的jmeter数据请求学习
java·学习·jmeter
要加油哦~2 小时前
尚硅谷· vue3+ts 知识点学习整理 |14h的课程(持续更ing)
javascript·vue.js·学习
sensen_kiss3 小时前
CAN201 Introduction to Networking(计算机网络)Pt.5 网络安全
学习·计算机网络·web安全·智能路由器
网络安全King4 小时前
网络安全系统学习实验1:RDP远程登录配置
学习·安全·web安全
LiuIleCPP_Golang5 小时前
【2025 Rust学习 --- 10 运算符重载】
学习·rust
杂货铺的小掌柜7 小时前
spring mvc源码学习笔记之六
学习·spring·mvc
练小杰9 小时前
我在广州学 Mysql 系列——有关数据表的插入、更新与删除相关练习
android·运维·数据库·经验分享·学习·mysql·adb
IT古董10 小时前
【机器学习】机器学习的基本分类-自监督学习-生成式方法(Generative Methods)
学习·机器学习·分类