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");

}
相关推荐
Smartdaili China15 分钟前
掌握Java网页抓取:技术与示例完整指南
java·网络·学习·指南·网页·住宅ip·爬虫api
charlie1145141912 小时前
如何快速在 VS2026 上使用 C++ 模块 — 完整上手指南
开发语言·c++·笔记·学习·现代c++
炽烈小老头3 小时前
【每天学习一点算法 2025/12/15】环形链表
学习·算法·链表
白帽子凯哥哥5 小时前
转行网络安全学习计划与报班建议
学习·安全·web安全·网络安全·渗透测试·漏洞挖掘·网安培训
ReaF_star6 小时前
【基线】关于Debian的一些简单安全配置及验证
学习·安全·debian
理人综艺好会6 小时前
Redis学习之go-redis
redis·学习·golang
石像鬼₧魂石7 小时前
Fail2Ban核心架构学习
linux·学习·ubuntu
逑之7 小时前
学习使用typora
学习
走在路上的菜鸟7 小时前
Android学Dart学习笔记第十三节 注解
android·笔记·学习·flutter
sszdlbw8 小时前
后端springboot框架入门学习--第一篇
java·spring boot·学习