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

}
相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意10 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码10 天前
嵌入式学习路线
学习
毛小茛10 天前
计算机系统概论——校验码
学习
babe小鑫10 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms10 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下10 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。10 天前
2026.2.25监控学习
学习
im_AMBER10 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J10 天前
从“Hello World“ 开始 C++
c语言·c++·学习