vtkPolyData 类的特点和用途
vtkPolyData
是 VTK (Visualization Toolkit) 库中的一个核心数据结构,用于表示和处理三维几何数据。它主要由以下几部分组成:
- Points (点):存储几何对象的顶点坐标。
- Vertices (顶点):表示独立的点。
- Lines (线):表示连接两个或多个点的线段。
- Polygons (多边形):表示由三个或更多点组成的多边形。
- TriangleStrips (三角带):一种高效存储三角形的方法,通过共享边来减少数据冗余。
- CellData (单元数据):存储与几何对象相关的属性数据,如颜色、纹理坐标等。
- PointData (点数据):存储与点相关的属性数据,如法线、标量值等。
vtkPolyData
在三维可视化中非常常用,可以表示各种几何形状,如表面、网格、线框等。它支持复杂的几何变换和属性操作,是 VTK 中进行三维数据处理和可视化的基础。
vtkPolyData
用于表示和操作多边形数据的基本类。它主要用于存储顶点、线、多边形和标量、向量等属性数据。以下是 vtkPolyData
类的主要成员及其作用:
1. vtkPoints
- 顶点数据
- 作用:存储几何数据的点坐标。
- 类型 :
vtkPoints
对象。 - 成员函数 :
SetNumberOfPoints(int numPoints)
:设置点的数量。InsertNextPoint(double x, double y, double z)
:插入一个新的点。GetPoint(int id, double p[3])
:获取指定索引的点坐标。
2. vtkCellArray
- 顶点连接信息
- 作用:存储顶点之间的连接关系,用于定义线、多边形等几何体。
- 类型 :
vtkCellArray
对象。 - 成员函数 :
InsertNextCell(int npts, int* pts)
:插入一个新的单元(线、多边形等)。InsertNextCell(int npts, vtkIdType* pts)
:插入一个新的单元(支持vtkIdType
类型的索引)。Reset()
:重置单元数组。
3. vtkDataArray
- 属性数据
- 作用:存储与顶点或单元相关的属性数据,如标量、向量、张量等。
- 类型 :
vtkDataArray
对象。 - 成员数据 :
Scalars
:标量数据。Vectors
:向量数据。Normals
:法向量数据。TCoords
:纹理坐标数据。Tensors
:张量数据。
- 成员函数 :
GetPointData()
:获取与顶点相关的数据。GetCellData()
:获取与单元相关的数据。SetScalars(vtkDataArray* array)
:设置标量数据。SetVectors(vtkDataArray* array)
:设置向量数据。SetNormals(vtkDataArray* array)
:设置法向量数据。SetTCoords(vtkDataArray* array)
:设置纹理坐标数据。SetTensors(vtkDataArray* array)
:设置张量数据。
4. vtkFieldData
- 字段数据
- 作用:存储与整个数据集相关的字段数据。
- 类型 :
vtkFieldData
对象。 - 成员函数 :
GetFieldData()
:获取字段数据。
5. vtkPolyDataNormals
- 法向量计算
- 作用:计算并生成顶点和单元的法向量。
- 类型 :
vtkPolyDataNormals
对象。 - 成员函数 :
SetInputData(vtkPolyData* input)
:设置输入的vtkPolyData
。Update()
:更新法向量计算。GetOutput()
:获取计算后的vtkPolyData
。
6. vtkPointData
和 vtkCellData
- 属性数据容器
- 作用:分别存储与顶点和单元相关的属性数据。
- 类型 :
vtkPointData
和vtkCellData
对象。 - 成员函数 :
GetPointData()
:获取与顶点相关的数据。GetCellData()
:获取与单元相关的数据。SetScalars(vtkDataArray* array)
:设置标量数据。SetVectors(vtkDataArray* array)
:设置向量数据。SetNormals(vtkDataArray* array)
:设置法向量数据。SetTCoords(vtkDataArray* array)
:设置纹理坐标数据。SetTensors(vtkDataArray* array)
:设置张量数据。
7. vtkPolyDataMapper
- 数据映射
- 作用 :将
vtkPolyData
映射到图形对象,用于渲染。 - 类型 :
vtkPolyDataMapper
对象。 - 成员函数 :
SetInputData(vtkPolyData* polyData)
:设置输入的vtkPolyData
。ScalarVisibilityOn()
:启用标量可见性。Update()
:更新映射。
示例代码
以下是一个简单的示例,展示如何创建 vtkPolyData
并设置其顶点和单元:
cpp
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
int main()
{
// 创建点数据
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(0.0, 0.0, 0.0); // 顶点 0
points->InsertNextPoint(1.0, 0.0, 0.0); // 顶点 1
points->InsertNextPoint(0.0, 1.0, 0.0); // 顶点 2
// 创建单元数据
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
cells->InsertNextCell(3); // 三角形有 3 个顶点
cells->InsertCellPoint(0); // 顶点 0
cells->InsertCellPoint(1); // 顶点 1
cells->InsertCellPoint(2); // 顶点 2
// 创建 vtkPolyData 对象
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetPolys(cells);
// 打印点数据和单元数据
for (vtkIdType i = 0; i < polyData->GetNumberOfPoints(); i++)
{
double point[3];
polyData->GetPoint(i, point);
std::cout << "Point " << i << ": (" << point[0] << ", " << point[1] << ", " << point[2] << ")\n";
}
for (vtkIdType i = 0; i < polyData->GetNumberOfCells(); i++)
{
vtkIdType npts;
const vtkIdType* pts;
polyData->GetCellPoints(i, npts, pts);
std::cout << "Cell " << i << ": ";
for (vtkIdType j = 0; j < npts; j++)
{
std::cout << pts[j] << " ";
}
std::cout << "\n";
}
return 0;
}
透明绿色的 vtkPolyData 构成的三维形体表面(如人体肿瘤)
以下是一个使用 VTK 创建一个透明绿色的三维肿瘤表面的示例代码。这个例子中,我们假设已经有一个肿瘤的三维点数据和多边形数据。
cpp
import vtk
# 创建点数据
points = vtk.vtkPoints()
points.InsertNextPoint(0, 0, 0)
points.InsertNextPoint(1, 0, 0)
points.InsertNextPoint(1, 1, 0)
points.InsertNextPoint(0, 1, 0)
points.InsertNextPoint(0, 0, 1)
points.InsertNextPoint(1, 0, 1)
points.InsertNextPoint(1, 1, 1)
points.InsertNextPoint(0, 1, 1)
# 创建多边形数据
polys = vtk.vtkCellArray()
polys.InsertNextCell(4)
polys.InsertCellPoint(0)
polys.InsertCellPoint(1)
polys.InsertCellPoint(2)
polys.InsertCellPoint(3)
polys.InsertNextCell(4)
polys.InsertCellPoint(4)
polys.InsertCellPoint(5)
polys.InsertCellPoint(6)
polys.InsertCellPoint(7)
polys.InsertNextCell(4)
polys.InsertCellPoint(0)
polys.InsertCellPoint(1)
polys.InsertCellPoint(5)
polys.InsertCellPoint(4)
polys.InsertNextCell(4)
polys.InsertCellPoint(1)
polys.InsertCellPoint(2)
polys.InsertCellPoint(6)
polys.InsertCellPoint(5)
polys.InsertNextCell(4)
polys.InsertCellPoint(2)
polys.InsertCellPoint(3)
polys.InsertCellPoint(7)
polys.InsertCellPoint(6)
polys.InsertNextCell(4)
polys.InsertCellPoint(3)
polys.InsertCellPoint(0)
polys.InsertCellPoint(4)
polys.InsertCellPoint(7)
# 创建 vtkPolyData
polyData = vtk.vtkPolyData()
polyData.SetPoints(points)
polyData.SetPolys(polys)
# 创建 mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polyData)
# 创建 actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# 设置颜色和透明度
actor.GetProperty().SetColor(0, 1, 0) # 绿色
actor.GetProperty().SetOpacity(0.5) # 透明度
# 创建渲染器
renderer = vtk.vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(1, 1, 1) # 白色背景
# 创建渲染窗口
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.SetSize(800, 800)
# 创建渲染窗口交互器
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
# 开始渲染
renderWindow.Render()
renderWindowInteractor.Start()
说明
- 创建点数据 :使用
vtkPoints
类来存储肿瘤表面的顶点坐标。 - 创建多边形数据 :使用
vtkCellArray
类来定义这些顶点如何组成多边形。 - 创建
vtkPolyData
:将点数据和多边形数据组合成一个vtkPolyData
对象。 - 创建
vtkPolyDataMapper
:将vtkPolyData
映射到图形对象。 - 创建
vtkActor
:定义图形对象并将vtkPolyDataMapper
关联到vtkActor
。 - 设置颜色和透明度 :使用
vtkProperty
类设置vtkActor
的颜色和透明度。 - 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。
这个例子中,我们创建了一个简单的立方体作为示例。实际应用中,可以将肿瘤的三维点数据和多边形数据代入 vtkPoints
和 vtkCellArray
中,以生成更复杂的三维形体。
使用纹理贴图和 vtkPolyData
显示三维物体表面的 C++ 示例代码
以下是一个使用 VTK 库在 C++ 中实现纹理贴图的示例代码。这个示例展示了如何将纹理映射到一个简单的立方体上。
cpp
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkJPEGReader.h>
#include <vtkTexture.h>
#include <vtkTextureMapToCylinder.h>
int main()
{
// 创建点数据
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(0, 0, 0);
points->InsertNextPoint(1, 0, 0);
points->InsertNextPoint(1, 1, 0);
points->InsertNextPoint(0, 1, 0);
points->InsertNextPoint(0, 0, 1);
points->InsertNextPoint(1, 0, 1);
points->InsertNextPoint(1, 1, 1);
points->InsertNextPoint(0, 1, 1);
// 创建多边形数据
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
polys->InsertNextCell(4);
polys->InsertCellPoint(0);
polys->InsertCellPoint(1);
polys->InsertCellPoint(2);
polys->InsertCellPoint(3);
polys->InsertNextCell(4);
polys->InsertCellPoint(4);
polys->InsertCellPoint(5);
polys->InsertCellPoint(6);
polys->InsertCellPoint(7);
polys->InsertNextCell(4);
polys->InsertCellPoint(0);
polys->InsertCellPoint(1);
polys->InsertCellPoint(5);
polys->InsertCellPoint(4);
polys->InsertNextCell(4);
polys->InsertCellPoint(1);
polys->InsertCellPoint(2);
polys->InsertCellPoint(6);
polys->InsertCellPoint(5);
polys->InsertNextCell(4);
polys->InsertCellPoint(2);
polys->InsertCellPoint(3);
polys->InsertCellPoint(7);
polys->InsertCellPoint(6);
polys->InsertNextCell(4);
polys->InsertCellPoint(3);
polys->InsertCellPoint(0);
polys->InsertCellPoint(4);
polys->InsertCellPoint(7);
// 创建 vtkPolyData
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetPolys(polys);
// 读取纹理图像
vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("path/to/your/image.jpg");
reader->Update();
// 创建纹理
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
texture->SetColorModeToDirectScalars();
texture->InterpolateOff();
texture->SetInputConnection(reader->GetOutputPort());
// 创建纹理映射
vtkSmartPointer<vtkTextureMapToCylinder> textureMap = vtkSmartPointer<vtkTextureMapToCylinder>::New();
textureMap->SetInputData(polyData);
textureMap->PreventSeamOn();
textureMap->Update();
// 创建 mapper
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(textureMap->GetOutputPort());
// 创建 actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->SetTexture(texture);
// 创建 renderer
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(1.0, 1.0, 1.0); // 白色背景
// 创建 render window
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(800, 800);
// 创建 render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// 开始渲染
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
说明
- 创建点数据 :使用
vtkPoints
类来存储立方体的顶点坐标。 - 创建多边形数据 :使用
vtkCellArray
类来定义这些顶点如何组成多边形。 - 创建
vtkPolyData
:将点数据和多边形数据组合成一个vtkPolyData
对象。 - 读取纹理图像 :使用
vtkJPEGReader
类读取纹理图像文件。 - 创建纹理 :使用
vtkTexture
类将读取的图像数据设置为纹理。 - 纹理映射 :使用
vtkTextureMapToCylinder
类将纹理映射到几何体上。 - 创建
vtkPolyDataMapper
:将vtkPolyData
映射到图形对象。 - 创建
vtkActor
:定义图形对象并将vtkPolyDataMapper
和纹理关联到vtkActor
。 - 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。
请确保将 "path/to/your/image.jpg"
替换为实际纹理图像文件的路径。这个示例中,我们使用了一个简单的立方体,实际应用中可以替换为任何复杂的三维模型。
我们可以将立方体表面改为环面(即一个圆环表面)。以下是使用 VTK 库在 C++ 中实现纹理贴图并显示环面的示例代码:
cpp
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkJPEGReader.h>
#include <vtkTexture.h>
#include <vtkParametricFunction.h>
#include <vtkParametricTorus.h>
#include <vtkParametricFunctionSource.h>
#include <vtkTextureMapToCylinder.h>
#include <vtkTransformTextureCoords.h>
int main()
{
// 创建环面参数化函数
vtkSmartPointer<vtkParametricTorus> torus = vtkSmartPointer<vtkParametricTorus>::New();
torus->SetRingRadius(1.0); // 环面的外径
torus->SetCrossSectionRadius(0.5); // 环面的内径
// 创建参数化源
vtkSmartPointer<vtkParametricFunctionSource> source = vtkSmartPointer<vtkParametricFunctionSource>::New();
source->SetParametricFunction(torus);
source->SetUResolution(50); // U方向的分辨率
source->SetVResolution(50); // V方向的分辨率
source->Update();
// 读取纹理图像
vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("path/to/your/image.jpg");
reader->Update();
// 创建纹理
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
texture->SetColorModeToDirectScalars();
texture->InterpolateOff();
texture->SetInputConnection(reader->GetOutputPort());
// 创建纹理映射
vtkSmartPointer<vtkTextureMapToCylinder> textureMap = vtkSmartPointer<vtkTextureMapToCylinder>::New();
textureMap->SetInputConnection(source->GetOutputPort());
textureMap->PreventSeamOn();
textureMap->Update();
// 创建纹理坐标变换
vtkSmartPointer<vtkTransformTextureCoords> transformTextureCoords = vtkSmartPointer<vtkTransformTextureCoords>::New();
transformTextureCoords->SetInputConnection(textureMap->GetOutputPort());
transformTextureCoords->SetScale(1.0, 1.0);
transformTextureCoords->SetTranslation(0.0, 0.0);
// 创建 mapper
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(transformTextureCoords->GetOutputPort());
// 创建 actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->SetTexture(texture);
// 创建 renderer
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(1.0, 1.0, 1.0); // 白色背景
// 创建 render window
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(800, 800);
// 创建 render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// 开始渲染
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
说明
- 创建环面参数化函数 :使用
vtkParametricTorus
类创建一个环面参数化函数,并设置环面的外径和内径。 - 创建参数化源 :使用
vtkParametricFunctionSource
类将参数化函数转换为vtkPolyData
,并设置 U 和 V 方向的分辨率。 - 读取纹理图像 :使用
vtkJPEGReader
类读取纹理图像文件。 - 创建纹理 :使用
vtkTexture
类将读取的图像数据设置为纹理。 - 纹理映射 :使用
vtkTextureMapToCylinder
类将纹理映射到几何体上。 - 纹理坐标变换 :使用
vtkTransformTextureCoords
类对纹理坐标进行变换,以便更好地贴合环面。 - 创建
vtkPolyDataMapper
:将vtkPolyData
映射到图形对象。 - 创建
vtkActor
:定义图形对象并将vtkPolyDataMapper
和纹理关联到vtkActor
。 - 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。
请确保将 "path/to/your/image.jpg"
替换为实际纹理图像文件的路径。这个示例中,我们使用了一个环面,实际应用中可以调整参数或使用其他几何体。
总结
通过 vtkPolyData
,可以方便地管理和操作多边形数据,包括顶点坐标、顶点之间的连接关系以及各种属性数据。这些成员和方法为创建和渲染复杂的几何体提供了强大的支持。