第01章 数据模型02 vtkPolyData类介绍

vtkPolyData 类的特点和用途

vtkPolyData 是 VTK (Visualization Toolkit) 库中的一个核心数据结构,用于表示和处理三维几何数据。它主要由以下几部分组成:

  1. Points (点):存储几何对象的顶点坐标。
  2. Vertices (顶点):表示独立的点。
  3. Lines (线):表示连接两个或多个点的线段。
  4. Polygons (多边形):表示由三个或更多点组成的多边形。
  5. TriangleStrips (三角带):一种高效存储三角形的方法,通过共享边来减少数据冗余。
  6. CellData (单元数据):存储与几何对象相关的属性数据,如颜色、纹理坐标等。
  7. 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. vtkPointDatavtkCellData - 属性数据容器

  • 作用:分别存储与顶点和单元相关的属性数据。
  • 类型vtkPointDatavtkCellData 对象。
  • 成员函数
    • 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()
点击并拖拽以移动

说明

  1. 创建点数据 :使用 vtkPoints 类来存储肿瘤表面的顶点坐标。
  2. 创建多边形数据 :使用 vtkCellArray 类来定义这些顶点如何组成多边形。
  3. 创建 vtkPolyData :将点数据和多边形数据组合成一个 vtkPolyData 对象。
  4. 创建 vtkPolyDataMapper :将 vtkPolyData 映射到图形对象。
  5. 创建 vtkActor :定义图形对象并将 vtkPolyDataMapper 关联到 vtkActor
  6. 设置颜色和透明度 :使用 vtkProperty 类设置 vtkActor 的颜色和透明度。
  7. 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。

这个例子中,我们创建了一个简单的立方体作为示例。实际应用中,可以将肿瘤的三维点数据和多边形数据代入 vtkPointsvtkCellArray 中,以生成更复杂的三维形体。

使用纹理贴图和 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;
}

说明

  1. 创建点数据 :使用 vtkPoints 类来存储立方体的顶点坐标。
  2. 创建多边形数据 :使用 vtkCellArray 类来定义这些顶点如何组成多边形。
  3. 创建 vtkPolyData :将点数据和多边形数据组合成一个 vtkPolyData 对象。
  4. 读取纹理图像 :使用 vtkJPEGReader 类读取纹理图像文件。
  5. 创建纹理 :使用 vtkTexture 类将读取的图像数据设置为纹理。
  6. 纹理映射 :使用 vtkTextureMapToCylinder 类将纹理映射到几何体上。
  7. 创建 vtkPolyDataMapper :将 vtkPolyData 映射到图形对象。
  8. 创建 vtkActor :定义图形对象并将 vtkPolyDataMapper 和纹理关联到 vtkActor
  9. 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。

请确保将 "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;
}

说明

  1. 创建环面参数化函数 :使用 vtkParametricTorus 类创建一个环面参数化函数,并设置环面的外径和内径。
  2. 创建参数化源 :使用 vtkParametricFunctionSource 类将参数化函数转换为 vtkPolyData,并设置 U 和 V 方向的分辨率。
  3. 读取纹理图像 :使用 vtkJPEGReader 类读取纹理图像文件。
  4. 创建纹理 :使用 vtkTexture 类将读取的图像数据设置为纹理。
  5. 纹理映射 :使用 vtkTextureMapToCylinder 类将纹理映射到几何体上。
  6. 纹理坐标变换 :使用 vtkTransformTextureCoords 类对纹理坐标进行变换,以便更好地贴合环面。
  7. 创建 vtkPolyDataMapper :将 vtkPolyData 映射到图形对象。
  8. 创建 vtkActor :定义图形对象并将 vtkPolyDataMapper 和纹理关联到 vtkActor
  9. 创建渲染器和渲染窗口:设置渲染器和渲染窗口,并启动交互器以显示三维形体。

请确保将 "path/to/your/image.jpg" 替换为实际纹理图像文件的路径。这个示例中,我们使用了一个环面,实际应用中可以调整参数或使用其他几何体。

总结

通过 vtkPolyData,可以方便地管理和操作多边形数据,包括顶点坐标、顶点之间的连接关系以及各种属性数据。这些成员和方法为创建和渲染复杂的几何体提供了强大的支持。

相关推荐
毒丐30 分钟前
GCC使用说明
linux·c语言·c++
强大的RGG38 分钟前
从源码编译Qt5
开发语言·c++·qt
(❁´◡`❁)Jimmy(❁´◡`❁)1 小时前
3103: 【基础】既生瑜,何生亮!
c++
s.feng1 小时前
00_basic_gemm
c++
oulaqiao3 小时前
以C++为基础快速了解C#
开发语言·c++·c#
Vec[95]3 小时前
如何将光源视角的深度贴图应用于摄像机视角的渲染
c++·算法·3d·贴图
AI+程序员在路上4 小时前
OpenCV轮廓相关操作API (C++)
c++·人工智能·opencv
ZPC82104 小时前
MoveItConfigsBuilder 配置机器人的完整示例
c++·人工智能·机器人
m0_725958995 小时前
day36 C++对C的扩充
c++
一丝晨光5 小时前
如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?
java·c++·python·visual studio·unicode·ansi·utf8