4.VTK数据类型

第二阶段 VTK数据模型

重点:VTK所有可视化,本质就是处理各类数据集。管线里Source输出、Filter输入输出全都是数据集。看不懂数据结构,Filter、读取模型文件都会一头雾水。

2.1 基类 vtkDataSet

vtkDataSet 是所有数据集的父类,所有数据子类都继承它:

  • vtkPolyData 多边形网格(工业最常用,stl/obj都是它)
  • vtkImageData 图像/体数据(CT、体渲染)
  • vtkUnstructuredGrid 非结构化网格(有限元仿真)
  • vtkStructuredGrid 结构化网格

简单理解:vtkDataSet 代表一整块“数据”,里面包含两大部分:

  1. 几何:点的坐标
  2. 拓扑:点怎么连接成面片、线、顶点
  3. 属性:每个点/每个面片附带的数据(颜色、应力、向量等)

2.2 四种数据集快速对比

类型 用途 典型文件
vtkPolyData 曲面、三角面片模型,点、线、三角/四边形面片 stl、obj、ply、vtp
vtkImageData 规则立方体体数据,像素/体素 mhd、dicom医学图像
vtkUnstructuredGrid 任意单元网格,四面体、六面体,有限元结果 vtu
vtkStructuredGrid 规则网格,坐标扭曲,气象仿真 vts

工业三维软件做零部件预览,90%打交道的就是 vtkPolyData,下面重点吃透它。

2.3 vtkPolyData 内部四大组成

vtkPolyData
├─ Points      所有顶点坐标集合
├─ Verts       顶点单元(孤立点)
├─ Lines       线段单元
├─ Polys       多边形面片(三角形、四边形,stl全部存这里)
└─ Strips      三角带(优化绘制用,较少手动构造)

另外两套属性数组:
PointData  → 附着在【点】上的数据(每个点一套值)
CellData   → 附着在【单元Cell】上的数据(每个面片一套值)

名词解释

  1. Points(点) 存储全部三维坐标 (x,y,z),是一个数组。 例如球体有几千个点,全部存在Points。

  2. Cell(单元) Cell就是“图元”:一个点、一条线段、一个三角形都叫一个Cell。 Polys 里面存的就是面片Cell。

    一个三角形Cell,不存坐标,只存点的索引:比如三角形由点0、点1、点2构成。 好处:多个面片可以复用同一个点,节省内存。

举例子:

Points数组:[P0(x0,y0,z0), P1(x1,y1,z1), P2(x2,y2,z2)] 一个三角形Cell:{0,1,2} 意思:拿第0、1、2号三个点拼接成三角形面片。

  1. PointData 点属性 每个点绑定一组数据。 比如每个点一个颜色、每个点法向量。点有多少个,属性数组就有多少条。
  2. CellData 单元属性 每个面片(Cell)绑定一组数据。 比如有限元每个三角面片的应力值,一个面片对应一个数值。面片多少个,属性数组多少条。

✨记忆口诀: Points:存所有坐标; Cell:存点的索引,描述点怎么拼成面片; PointData:跟点走; CellData:跟面片走。

2.4 手写代码:手动构造一个三角形 vtkPolyData

不读文件,纯代码手写点+三角形面片,生成一个三角面片,渲染出来。 目的:直观看懂 Points + Cell 的工作原理。

#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

int main()
{
    // ==========1. 创建Points,定义3个顶点坐标==========
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    // 插入3个点,索引0,1,2
    points->InsertNextPoint(0.0,  0.0, 0.0);
    points->InsertNextPoint(2.0,  0.0, 0.0);
    points->InsertNextPoint(1.0,  2.0, 0.0);

    // ==========2. 创建CellArray,构造三角形面片==========
    vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
    // 插入1个三角形单元:使用点索引 0,1,2
    polys->InsertNextCell(3);   // 3代表这个单元由3个点组成(三角形)
    polys->InsertCellPoint(0);
    polys->InsertCellPoint(1);
    polys->InsertCellPoint(2);

    // ==========3. 组装成vtkPolyData==========
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    polyData->SetPoints(points);       // 设置点集合
    polyData->SetPolys(polys);         // 设置面片单元集合

    // ==========4. 送入管线渲染显示==========
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData(polyData);

    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper.Get());
    actor->GetProperty()->SetColor(0,0.8,0);
    actor->GetProperty()->SetEdgeVisibility(true); // ✅打开面片边线,看清三角形轮廓

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground(0,0,0);

    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(600,400);

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    interactor->Initialize();
    interactor->Start();

    return 0;
}

代码逐段讲解

  1. vtkPoints:专门存放三维点坐标,InsertNextPoint(x,y,z)追加点,自动分配索引,第一个插入索引0,第二个1……
  2. vtkCellArray:存储单元(面片/线段)的索引列表。
    • InsertNextCell(3):告诉它,接下来要定义一个3个点的单元(三角形)。
    • 连续调用InsertCellPoint(索引)填入点编号。
  3. polyData->SetPoints(points); SetPolys(polys); 把点和面片组装成完整的vtkPolyData数据集。
  4. actor->GetProperty()->SetEdgeVisibility(true); 打开边线渲染,可以看到三角形的边框,不然只能看到一片绿色填充,看不出三角轮廓。

运行现象:窗口出现一个绿色三角形,能旋转缩放查看。

重点理解

stl模型文件加载到VTK内部,本质就是做上面这套事情: 解析stl文件 → 读取大量三角点坐标填入vtkPoints → 每个三角面片把点索引写入vtkCellArray → 组装vtkPolyData。

2.5 点属性 PointData / 单元属性 CellData 简单认识

简单示例逻辑(只看逻辑,不用完整跑)

// vtkPolyData* polyData;
// 给每个点附加一个标量数值,后面可以根据数值映射颜色
vtkSmartPointer<vtkFloatArray> pointScalars = vtkSmartPointer<vtkFloatArray>::New();
pointScalars->InsertNextValue(1.0); //0号点的值
pointScalars->InsertNextValue(2.0); //1号点的值
pointScalars->InsertNextValue(3.0); //2号点的值

polyData->GetPointData()->SetScalars(pointScalars);
  • GetPointData()拿到点属性容器;
  • SetScalars()设置标量数组,Mapper就可以依据这个数值自动上色,生成云图效果。
  • GetCellData()就是操作面片单元属性。

后续Filter、仿真结果可视化大量使用这套属性数组。

本节核心总结

  1. vtkDataSet是数据集基类,四个子类记住各自用途;
  2. vtkPolyData = Points(坐标) + Cell(点索引构成面片) + PointData + CellData;
  3. Cell不存坐标,只存点索引,复用Points节省内存;
  4. 手写三角形Demo完整展示PolyData的组装过程;stl加载内部就是这个逻辑。

下一节:第三阶段 VTK管线实战:Source、常用Filter、修改材质、线框模式

这部分听懂了吗?哪里卡住直接说。没问题我们继续往下。

posted @ 2026-08-24 16:11  Drunker•L  阅读(22)  评论(0)    收藏  举报