Quiet
  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我

bajiu

  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我
Quiet主题
  • C#
  • VTK

使用vtkCellArray创建单元格

bajiu
.Net客户端

2024-03-26 10:42:00

vtkCellArray是Visualization Toolkit (VTK)中的一个核心类,用于表示和存储图形数据中的单元(cells),如线段(lines)、多边形(polygons)和多面体(polyhedra)。每个单元由一系列点(vertices)组成,这些点定义了单元的形状和位置。vtkCellArray被广泛用于 VTK 的各种图形对象中,包括vtkPolyData和vtkUnstructuredGrid,允许高效地存储和访问复杂的三维图形数据。

vtkCellArray 的结构

vtkCellArray的结构是为了高效地存储和遍历图形数据中的单元。它主要包括以下部分:

  • 点索引(Point Indexes):这是指向vtkPoint 对象中点的索引,vtkPoints存储了图形数据中所有点的坐标。每个单元由一组点索引组成,这些索引确定了单元的形状和位置。
  • 连接性(Connectivity)数据:这部分数据描述了单元是如何从点构建起来的。对于每个单元,vtkCellArray首先存储一个数字,指示单元中点的数量,接着是构成该单元的点的索引。

使用 vtkCellArray 画线

在使用vtkCellArray时,遵循以下步骤:

  • 创建和初始化:首先创建一个 vtkCellArray 实例,并通过添加点索引来定义单元。
  • 添加单元:使用 InsertNextCell 方法添加新单元,该方法接受一个点的数量和一系列点索引。
  • 绑定到图形对象:将 vtkCellArray 对象设置为某个图形对象(如 vtkPolyData)的一部分,以表示该对象的单元。
// 创建点集
var points = vtkPoints.New();
points.InsertNextPoint(0.0, 0.0, 0.0);
points.InsertNextPoint(1.0, 1.0, 0.0);
points.InsertNextPoint(2.0, 3.0, 0.0);
points.InsertNextPoint(4.0, 5.0, 0.0);

// 创建CellArray来存储线段
var lines = vtkCellArray.New();

// 添加第一条线段(点0和点1)
lines.InsertNextCell(2);
lines.InsertCellPoint(0);
lines.InsertCellPoint(1);

// 添加第二条线段(点2和点3)
lines.InsertNextCell(2);
lines.InsertCellPoint(2);
lines.InsertCellPoint(3);

// 创建PolyData对象
var polyData = vtkPolyData.New();
polyData.SetPoints(points);
polyData.SetLines(lines);

// 创建映射器和actor
var mapper = vtkPolyDataMapper.New();
mapper.SetInput(polyData);

var actor = vtkActor.New();
actor.SetMapper(mapper);

vtkCellArry_1

使用 vtkCellArray 生成四边形网格

创建一个10*10的四边形网格

// 定义网格大小
int gridSize = 10;
// 创建点集
var points = vtkPoints.New();
for (int i = 0; i <= gridSize; ++i)
{
    for (int j = 0; j <= gridSize; ++j)
    {
        points.InsertNextPoint(i, j, 0);
    }
}
// 创建四边形单元
var lines = vtkCellArray.New();
for (int i = 0; i <= gridSize; ++i)
{
    for (int j = 0; j < gridSize; ++j)
    {
        // 水平线段
        lines.InsertNextCell(2);
        lines.InsertCellPoint(i * (gridSize + 1) + j);
        lines.InsertCellPoint(i * (gridSize + 1) + (j + 1));
        // 垂直线段
        lines.InsertNextCell(2);
        lines.InsertCellPoint(j * (gridSize + 1) + i);
        lines.InsertCellPoint((j + 1) * (gridSize + 1) + i);
    }
}
// 创建PolyData对象
var polyData = vtkPolyData.New();
polyData.SetPoints(points);
polyData.SetLines(lines);
var mapper = vtkPolyDataMapper.New();
mapper.SetInputData(polyData);
var actor = vtkActor.New();
actor.SetMapper(mapper);
var renderer = renderWindowControl.RenderWindow.GetRenderers().GetFirstRenderer();
renderer.AddActor(actor);
renderer.SetBackground(0.1, 0.2, 0.4); 

vtkCellArry_2

加上高斯分布的形变场

要创建一个形变场,使得 10×10 的平面网格按照高斯分布形变,需要首先计算每个点在高斯分布下的偏移量,然后应用这些偏移量来更新网格中每个点的位置。

// 定义网格大小
int gridSize = 10;
double a = 5.0; // 高度因子
double mu_x = gridSize / 2.0;
double mu_y = gridSize / 2.0;
double sigma_x = gridSize / 4.0;
double sigma_y = gridSize / 4.0;
var points = vtkPoints.New();
for (int i = 0; i <= gridSize; ++i)
{
    for (int j = 0; j <= gridSize; ++j)
    {
        double x = i;
        double y = j;
        // 应用高斯分布
        double z = a * Math.Exp(-((x - mu_x) * (x - mu_x) / (2 * sigma_x * sigma_x) + (y - mu_y) * (y - mu_y) / (2 * sigma_y * sigma_y)));
        points.InsertNextPoint(x, y, z);
    }
}

同上...

vtkCellArry_3

加上颜色

// 获取颜色范围
double[] colorRange = pointColors.GetRange();
double minColorRange = colorRange[0];
double maxColorRange = colorRange[1];
// 创建映射器并应用颜色查找表
var mapper = vtkPolyDataMapper.New();
mapper.SetInputData(polyData);
mapper.SetScalarRange(minColorRange, maxColorRange); // 根据Z值的范围设置颜色映射范围

var lookupTable = vtkLookupTable.New();
lookupTable.SetRange(minColorRange, maxColorRange); // 设置查找表的标量值范围
lookupTable.SetNumberOfTableValues(512);            // 设置颜色表中颜色的数量
lookupTable.Build();                                // 构建默认渐变
mapper.SetLookupTable(lookupTable);

// 看看Bar
var scalarBar = vtkScalarBarActor.New();
scalarBar.SetLookupTable(mapper.GetLookupTable());
scalarBar.SetTitle("Height");
scalarBar.SetNumberOfLabels(4);

// 别忘了放actor
renderer.AddActor2D(scalarBar);

vtkCellArry_4

然后再往CT里放一下就假装有了一个形变场

vtkCellArry_5

上一篇

WPF调试工具Snoop的用法

下一篇

Conda-forge 使用教程

©2025 By bajiu.