VTK_python入门

tk基本介绍

  1. VTK 库的框架结构

vtkObject -> vtkSource -> vtkFilter -> vtkMapper -> vtkActor -> vtkRenderer

对象 介绍
vtkObject vtk库的基类
vtkSource vtkFilter父类,为为整个可视化流程的开始定义具体的行为和接口,比如读取数据
vtkFilter 对原始数据进行滤波器处理,转化成可以直接应用算法模块的形式
vtkMapper 它将 vtkFilter 处理后的应用数据映射为几何数据,相当于为原始数据和图像数据之间定义了接口
vtkActor 表示渲染场景下一个特定物体(几何结构和属性)
vtkRenderer 为渲染器提供一种抽象规范,最终 vtkActor 通过 vtkRenderer 类将结果在窗口中显示出来

VTK_python入门_第1张图片

  1. vtk基本对象

    基本对象 介绍
    渲染控制器 定义与设备无关的坐标计算方法,创建渲染窗口
    渲染窗口 渲染窗口管理显示设备上的窗口,绘制方法可在渲染窗口上创建一个场景;渲染窗口是用户图形界面,其中包括了设置渲染窗口的大小,产生立体显示效果等方法
    渲染器 渲染器(Renderer)是管理光源照相机和绘制对象等的位置、属性等,提供了世界坐标系,观察坐标系及显示坐标系之间的转换
    灯光 灯光可在场景中照亮绘制对象
    摄像机 摄像机是定义观察者的位置
    角色 角色代表渲染场景中的绘制对象实体,通过参数调节可以设置角色的位置、方向、渲染特性、引用、纹理映射等属性,并可对角色进行缩放。
    特性 特性是说明几何物体的一些特性,实现三维图形真实感
    映射 映射制定了渲染数据和图形库中基本图元之间的联系
    变换 变换是一个放置 4x4 变换矩阵的堆栈,可以进行各种操作

    在vtk中绘制或者渲染一个场景,需要以下基本对象

  • vtkRenderWindow

  • vtkRenderer

  • vtkLight

  • vtkCamera

  • vtkActor

  • vtkProperty

  • vtkMapper
    VTK_python入门_第2张图片
    VTK_python入门_第3张图片

# 案例
import vtk
def Create():
    arrow_source = vtk.vtkArrowSource() # 数据源 箭头
    mapper = vtk.vtkPolyDataMapper() # 创建映射器
    mapper.SetInputConnection(arrow_source.GetOutputPort()) #映射器添加箭头的数据源
    actor = vtk.vtkActor() # 创建演员
    actor.SetMapper(mapper) # 给演员添加映射器
    ren = vtk.vtkRenderer() #创建绘制器
    ren.AddActor(actor) #绘制器加演员
    renWin = vtk.vtkRenderWindow() #创建显示窗口
    renWin.AddRenderer(ren) #向窗口中加入绘制器
    renWin.Render() #窗口读取绘制器,并生成图形

    iren = vtk.vtkRenderWindowInteractor() #窗口交互器
    iren.SetRenderWindow(renWin) #交互器中加入窗口
    iren.Initialize()
    iren.Start()
Vtk柱体
cylinder = vtk.vtkCylinderSource()
    cylinder.SetHeight(3.0)
    cylinder.SetRadius(1.0)
    cylinder.SetResolution(360)
    print("高:{0};半径:{1};角度:{2}".format(cylinder.GetHeight(),cylinder.GetRadius(),cylinder.GetResolution()))
    
	# 映射,将输入的数据转换为几何图元(点、线、多边形)进行渲染
    mapper =vtk.vtkPolyDataMapper()
    # 设置 VTK 可视化管线的输入数据接口,对应的可视化管线输出数据的接口为 GetOutputPort()
    mapper.SetInputConnection(cylinder.GetOutputPort())

    actor = vtk.vtkActor()

    prop = vtk.vtkProperty()
    prop.SetColor(0.6,0.96,1)
    bmpReader = vtk.vtkBMPReader()
    bmpReader.SetFileName("sky.bmp")
    texture = vtk.vtkTexture()
    texture.SetInputConnection(bmpReader.GetOutputPort())
    texture.InterpolateOn()
    actor.SetProperty(prop)
    actor.SetTexture(texture)
    
    actor.SetMapper(mapper)

    renderer = vtk.vtkRenderer()
    renderer.AddActor(actor)
    renderer.SetBackground(0.1,0.2,0.4)

    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(renderer)
    renWin.SetSize(1200,1200)
    renWin.Render() # 绘制窗口内所有绘制器同步渲染绘制

    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)
    iren.Initialize() #必须
    iren.Start() #开始进入事件响应循环

三维空间中渲染对象最常用的是vtkProp子类是vtkActor(几何数据)和vtkVolume(体数据)

vtkProp子类负责确定渲染场景中对象的位置、大小和方向信息。
Prop依赖于两个对象(Prop一词来源于戏剧里的“道具”,在VTK里表示的是渲染场景中可以看得到的对象。)一个是Mapper(vtkMapper)对象,负责存放数据和渲染信息,另一个是属性(vtkProperty)对象,负责控制颜色、不透明度等参数。

VTK数据结构

import vtk

# *******三个点 加拓扑*******
# 创建点数据
points = vtk.vtkPoints()
# 创建顶点类型 points是坐标不是顶点
vertices = vtk.vtkCellArray()

# 创建点的坐标
points_list = [[1,0,0],[0,0,1],[0,0,0]]

for point in points_list:
    # 每个点坐标加入到 vtkPoints 中,返回加入点的索引号
    id = points.InsertNextPoint(point)
    # 在每个坐标点上分别创建一个顶点,顶点是单元 Cell 里的一种类型
    vertices.InsertNextCell(1)
    vertices.InsertCellPoint(id)

line0 = vtk.vtkLine()
# 线有两个端点,连接两个point
line0.GetPointIds().SetId(0,0) 
line0.GetPointIds().SetId(1,1)

line1 = vtk.vtkLine()
line1.GetPointIds().SetId(0,1)
line1.GetPointIds().SetId(1,2)

line2 = vtk.vtkLine()
line2.GetPointIds().SetId(0,2)
line2.GetPointIds().SetId(1,0)

lines = vtk.vtkCellArray()
lines.InsertNextCell(line0)
lines.InsertNextCell(line1)
lines.InsertNextCell(line2)

# 创建 vtkPolyData 对象
polydata = vtk.vtkPolyData()
# 指定数据集的几何结构(由 points 指定)
polydata.SetPoints(points)
# 指定数据集的拓扑结构(由 vertices 指定)
polydata.SetVerts(vertices)

polydata.SetLines(lines)


mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polydata)
actor = vtk.vtkActor()
actor.SetMapper(mapper)

actor.GetProperty().SetPointSize(10)
actor.GetProperty().SetLineWidth(10)

render = vtk.vtkRenderer()
render.SetBackground(0, 0, 0)

# Renderer Window
window = vtk.vtkRenderWindow()
window.AddRenderer(render)
window.SetSize(600, 600)

# System Event
win_render = vtk.vtkRenderWindowInteractor()
win_render.SetRenderWindow(window)

# Style
win_render.SetInteractorStyle(vtk.vtkInteractorStyleMultiTouchCamera())

# Insert Actor
render.AddActor(actor)

win_render.Initialize()
win_render.Start()

可视化基础

单元 Cell 是可视化的基础,单元是一系列有序的点按指定类型连接所定义的结构。这些点的连接顺序通常被称为顶点列表(Connectivity List);所指定的类型定义了单元的拓扑结构;点的坐标定义了单元的几何结构。

单元就是有序点集

单元是由单元类型单元顶点列表 两部分构成

单元类型:决定点集的顺序,也就是拓扑

单元顶点列表由点的索引号表示,通过索引号可以找到坐标值

线性单元和非线性单元

VTK 单元类型分为线性和非线性和其他类型。单元类型的线性和非线性划分主要是以插值函数为依据。

线性单元

线性单元采用的是线性或者常量插值函数。单元里的任意一条辨都是由两个点连接定义的。常见的有:

单元
Vertex 顶点,由一个点定义,是零维的基本类型
Polyvertex 多顶点,多个顶点组合而成,是零维的组合单元,其定义不受顶点顺序的限制
Line 直线,一维的基本类型,由两个点定义,方向是从第一个点指向第二个点
Polyline 折线,由一条或多条直线组合而成,属于一维的类型。由n+1个有序的点连接定义的,n表示折线的线段条数,每两个点(i, i+1)定义一条线段
Triangle 三角形,二维的基本类型,由三个点按逆时针的方向连接定义的,点的连接方向和表面法向量符合右手法则
非线性单元

数值分析领域里为了更准确、精确地表达数据,采用非线性单元作为数据的基本表达结构。线性单元可以很容易转换成线图元被图形库处理,非线性单元不被图形库直接支持,因此非线性单元必须先转换成线性单元后才能被图形库支持。

VTK除了提供一套复杂的非线性单元接口框架,另一种做法就是在非线性单元的每一条曲线增加一个关键点,或者增加一个曲面来近似模拟非线性单元。

属性数据

属性数据主要用于描述数据集的属性特征,对数据集的可视化实质上是对属性数据的可视化,例如根据温度显示不同的颜色。

vtk也有矢量数据,VTK的矢量数据也是指既有大小也有方向的量,三维方向上用三元组(Triple)表示为(u, v, w),如速度、应力、位移等。

import vtk

points = vtk.vtkPoints()
points.InsertNextPoint(0,0,0)
points.InsertNextPoint(1,0,0)

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)

weights = vtk.vtkDoubleArray()
weights.SetNumberOfValues(2)
weights.SetValue(0,1)
weights.SetValue(1,2)

polydata.GetPointData().SetScalars(weights)

weight = polydata.GetPointData().GetScalars().GetValue(0)

print(weight)
数据集

数据集由组织结构(拓扑和几何)以及属性数据组成。

  • vtkImageData

VTK_python入门_第4张图片

vtkImageData 类型的数据是按规则排列在矩形方格中的点和单元的集合,如果数据集的点和单元排列在平面(二维)上,称此数据集为像素映射(Pixmap)、位图或图像,由 vtkPixel 单元组成;如果排列在层叠面(三维)上,则称为体 (Volume),由 vtkVoxel 单元组成。数据维数用一个三元组 (nx, ny, nz) 来表示,分别表示在 X、Y 和 Z 方向上点的个数。

  • vtkPolyData

VTK_python入门_第5张图片

多边形数据集 vtkPolyData 由顶点 (Vertex)、多顶点 (Polyvertex)、线 (Line)、折线 (Polyline) 和三角条带 (Triangle Strip) 等单元构成,多边形数据是不规则结构的,并且多边形数据集的单元在拓扑维度上有多种类型,多边形数据是数据、算法和高速计算机图像学的桥梁。

  • vtkRectilinearGrid

VTK_python入门_第6张图片

vtkRectilinearGrid 类型(线性网格)的数据是排列在矩形方格中的点和单元的集合,线性网格的拓扑结构是规则的,但其几何结构只是部分规则,也就是说,它的点是沿着坐标轴排列的,但是两点间的间隔可能不同,与 vtkImageData 类型的数据相似,线性网格是由像素或体素等单元组成的,它的拓扑结构通过指定网格的维数来隐式表达,几何结构则通过一系列的 x, y, z 坐标来表达。

  • vtkStructuredGrid

VTK_python入门_第7张图片

vtkStructuredGrid 是结构化网格数据,具有规则的拓扑结构和不规则的几何结构,但是单元之间没有重叠或交叉,如图(c)所示。结构化网格的单元是由四边形或六面体组成,结构化网格通常用于有限差分分析。典型的应用包括流体流动、热量传输和燃烧学等。

  • vtkUnstructuredGrid

VTK_python入门_第8张图片

vtkUnstructuredGrid,非结构化网格是最常见的数据集类型,它的拓扑结构和几何结构都是不规则的,在此数据集中所有单元类型都可以组成任意组合,所以单元的拓扑结构从零维延伸至三维,如图(f)所示。

VTK中任一类型的数据集都可用非结构化网格来表达,vtkUnstructuredGrid 类型数据的存储需要大量的空间以及计算时需要消耗大量的资源,除非迫不得已,一般较少使用此种类型的数据集。非结构化网格主要用于有限元分析、计算几何和几何建模等领域。

  • vtkUnstructuredPoints

VTK_python入门_第9张图片

vtkUnstructuredPoints,非结构化点集,是指不规则地分布在空间的点集。非结构化点集具有不规则的几何结构,不具有拓扑结构,非结构化点集用离散点来表达。

通常,这类数据没有固定的结构,由一些可视化程序识别和创建的,非结构化点集适合表现非结构化数据,为了实现数据的可视化,可将这种数据形式转换成其它一些结构化的数据形式

VTK_python入门_第10张图片

数据集的存储
  • vtkDataArray 数据集的访问基于索引,从零开始

  • Tuple(元组)的概念

许多可视化数据是由多个数据分量组成的,如RGB颜色数据由红、绿、蓝三个分量组成,为了在连续数组中表达这一类数据,VTK引入了元组(Tuple)的概念。元组是数据数组的子数组,用于存储数据类型相同的分量数据,元组的大小在给定后不会改变。

vtkDataArray 存储的是数值数据,如属性数据 (Attribute Data) 和点数据 (Point) 等。有些属性数据,如点、矢量、法向量和张量等,在定义时就需要指定元组的大小。例如,点、矢量和法向量等属性数据,元组的大小是3,而张量属性数据的元组大小是9 (即3×3的矩阵),标量属性数据对于元组的大小则没有任何要求,对于处理标量属性数据的算法,通常都是只处理标量每一个元组数据的第一个分量。VTK提供了将多分量的数据数组分离成单一分量的数据数组,以及将单一分量的数据数组合并成多分量的数据数组的类,即 vtkSplitField 和 vtkMergeFields。

import numpy
import vtk
from vtk.util.numpy_support import numpy_to_vtk

if __name__ == '__main__':
    # 读取 txt 文档
    source_data = numpy.loadtxt("bun000.txt")

    # 新建 vtkPoints 实例
    points = vtk.vtkPoints()
    # 导入点数据
    points.SetData(numpy_to_vtk(source_data))
    # 新建 vtkPolyData 实例
    polydata = vtk.vtkPolyData()
    # 设置点坐标
    polydata.SetPoints(points)

    # 顶点相关的 filter
    vertex = vtk.vtkVertexGlyphFilter()
    vertex.SetInputData(polydata)

    # mapper 实例
    mapper = vtk.vtkPolyDataMapper()
    # 关联 filter 输出
    mapper.SetInputConnection(vertex.GetOutputPort())

    # actor 实例
    actor = vtk.vtkActor()
    # 关联 mapper
    actor.SetMapper(mapper)

    # render
    render = vtk.vtkRenderer()
    render.SetBackground(0, 0, 0)

    # Renderer Window
    window = vtk.vtkRenderWindow()
    window.AddRenderer(render)
    window.SetSize(1200, 1200)

    # System Event
    win_render = vtk.vtkRenderWindowInteractor()
    win_render.SetRenderWindow(window)

    # Style
    win_render.SetInteractorStyle(vtk.vtkInteractorStyleMultiTouchCamera())

    # Insert Actor
    render.AddActor(actor)
    win_render.Initialize()
    win_render.Start()
def data_actor_transform(source_data):


    points = vtk.vtkPoints()
    points.SetData(numpy_to_vtk(source_data))

    polydata = vtk.vtkPolyData()
    polydata.SetPoints(points)

    vertex = vtk.vtkVertexGlyphFilter()
    vertex.SetInputData(polydata)
   # 设置变换过程
    transform = vtk.vtkTransform()
    transform.Translate(0,0,0)
    transform.RotateY(180)
   # 新建变换的 filter
    transformFilter = vtk.vtkTransformPolyDataFilter()
     # 将变换 filter 输入设置为点数据模型 
  transformFilter.SetInputConnection(vertex.GetOutputPort())
    # 设置变换过程
    transformFilter.SetTransform(transform)
    transformFilter.Update()

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(transformFilter.GetOutputPort())

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    return  actor

vtk.vtkTransformPolyDataFilter()
# 将变换 filter 输入设置为点数据模型
transformFilter.SetInputConnection(vertex.GetOutputPort())
# 设置变换过程
transformFilter.SetTransform(transform)
transformFilter.Update()

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(transformFilter.GetOutputPort())

actor = vtk.vtkActor()
actor.SetMapper(mapper)

return  actor

你可能感兴趣的:(VTK,qt)