python VTK(一)绘制简单几何体模型、循环生成六面体单元 、设定模型坐标位置

利用vtk生成模型并做一些交互处理时一种比较流行的操作方式,也是很多商业软件开发模型的依赖,本文主要是对vtk建模的思路进行流水线式解析,并且阐述建模的固定模板。笔者也是初学,如果有一些见解不对,还请您留言指正。

关于代码部分首先有几点说明:本文的建立网格化代码是参考vtk官方文档生成,关于给定一些自定义的的一系列散点然后生成六面体单元将在后续的文章中给出。

import vtk
import numpy as np
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkPoints
from vtkmodules.vtkCommonDataModel import vtkCellArray, vtkExplicitStructuredGrid
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleRubberBandPick
from vtkmodules.vtkRenderingCore import vtkActor, vtkRenderWindowInteractor
//这里有一些必要导入的库。其中根据vtk的版本不同可能导入的描述不同,在此使用的版本是vtk9
//下面这个函数为引用vtk官方文档,建立了一个点的数据和依赖该数据集生成的六面体单元的数据集
def create_explicit_structured_grid(dimensions, spacing=(1, 1, 1)):
    ni, nj, nk = dimensions//输入的要生成的长方体的长宽高
    si, sj, sk = spacing//xyz轴的分度值
//生成点的数据集,分别从z,y,x轴进行循环添加
    points = vtkPoints()
    for z in range(0, nk * sk, sk):
        for y in range(0, nj * sj, sj):
            for x in range(0, ni * si, si):
                points.InsertNextPoint((x, y, z))
//生成六面体单元的数据集,其中pts=...这行代码是文档给出的,不用这个代码也可以,只要给定8个点,前四个点一个面,后四个点为与前面不重复的点组成的面即可
    cells = vtkCellArray()
    for k in range(0, nk - 1):
        for j in range(0, nj - 1):
            for i in range(0, ni - 1):
                multi_index = ([i, i + 1, i + 1, i, i, i + 1, i + 1, i],
                               [j, j, j + 1, j + 1, j, j, j + 1, j + 1],
                               [k, k, k, k, k + 1, k + 1, k + 1, k + 1])
                pts = np.ravel_multi_index(multi_index, dimensions, order='F')
                cells.InsertNextCell(8, pts)

    grid = vtkExplicitStructuredGrid()
    grid.SetDimensions(ni, nj, nk)
    grid.SetPoints(points)
    grid.SetCells(cells)
    return grid
# 创建一个渲染器
renderer = vtk.vtkRenderer()
renderer.SetBackground(1, 1, 1)
# 创建一个渲染窗口
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
render_window.SetWindowName('CreateESGrid')
render_window.SetSize(1024, 768)
# 创建一个交互式渲染窗口交互器

# 创建一个结构化网格
grid = create_explicit_structured_grid((201, 51, 6), (1, 1, 1))
# 在这里添加你的结构化网格数据到structured_grid对象中
# ...

# 创建一个结构化网格的映射器
mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(grid)

# 创建一个结构化网格的演员
colors = vtkNamedColors()
actor = vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().EdgeVisibilityOn()
actor.GetProperty().LightingOff()
actor.GetProperty().SetColor(colors.GetColor3d('Seashell'))
actor.SetPosition(0, 0, 0)
actor2 = vtkActor()
actor2.SetMapper(mapper)
actor2.GetProperty().EdgeVisibilityOn()
actor2.GetProperty().SetColor(1, 0.5, 0)
actor2.GetProperty().LightingOff()
actor2.SetPosition(0, 0, -5)

# 将演员添加到渲染器中
renderer.AddActor(actor)
renderer.AddActor(actor2)

# 创建一个圆柱体
cylinder = vtk.vtkCylinderSource()
cylinder.SetHeight(50.0)
cylinder.SetRadius(30.0)
cylinder.SetResolution(12000)

# 创建一个圆柱体的映射器
cylinder_mapper = vtk.vtkPolyDataMapper()
cylinder_mapper.SetInputConnection(cylinder.GetOutputPort())

# 创建一个圆柱体的actor
cylinder_actor = vtk.vtkActor()
cylinder_actor.SetMapper(cylinder_mapper)
cylinder_actor.SetPosition(100, 25, 35)
cylinder_actor.GetProperty().SetColor(1, 0.5, 0)
cylinder_actor2 = vtk.vtkActor()
cylinder_actor2.SetMapper(cylinder_mapper)
cylinder_actor2.SetPosition(100, 25, -35)
cylinder_actor2.GetProperty().SetColor(1, 0.5, 0)
# 将圆柱体演员添加到渲染器中
renderer.AddActor(cylinder_actor)
renderer.AddActor(cylinder_actor2)
# 开始交互渲染
camera = renderer.GetActiveCamera()

interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)
interactor.SetInteractorStyle(vtkInteractorStyleRubberBandPick())
render_window.Render()
interactor.Start()

其中关于官方文档给出的六面体单元的代码在上述中笔者已有注释,下面分开阐述生成vtk模型的必要操作步骤。

1.创建点集或者单元集合/利用vtk的模型库直接创建长方体或者圆柱体等其他模型

下面为创建一个圆柱体的代码半径为30高度为50的圆柱体,其中setresolution为设定生成时圆的边数,那为什么会有变,是因为计算机生成模型是利用的是一种无限微分的原理,这种微分取决于你给定的边数,边数越大越看上去趋于圆形,如果给了一个4,那就是正方形。

cylinder = vtk.vtkCylinderSource()
cylinder.SetHeight(50.0)
cylinder.SetRadius(30.0)
cylinder.SetResolution(12000)

2.创建mapper映射器

cylinder_mapper = vtk.vtkPolyDataMapper()
cylinder_mapper.SetInputConnection(cylinder.GetOutputPort())

就好比创建了模型的参数后,要给出能够反映出他的投影仪,因此一个模型必须对应一个映射器,几个模型就写几个映射器的代码。在此需要说明的时点集或者单元集各自都是对应一个映射器。

3.创建actor

cylinder_actor.SetMapper(cylinder_mapper)
cylinder_actor.SetPosition(100, 25, 35)
cylinder_actor.GetProperty().SetColor(1, 0.5, 0)
cylinder_actor2 = vtk.vtkActor()
cylinder_actor2.SetMapper(cylinder_mapper)
cylinder_actor2.SetPosition(100, 25, -35)
cylinder_actor2.GetProperty().SetColor(1, 0.5, 0)

我们知道mapper都绑定对应一个模型,只需理解为在vtk里actor需要添加的是mapper(模型的代言人)而不是模型本身的参数就可以了。因此在此简单理解为,有了投影仪mapper后,还需要一些“演员”表演出这个模型。上述代码中我们设定了两个actor,但是都是表演同一个mapper,不同之处就是actor的位置不同,关于位置的确定可以自行设置,这个可能就需要一些自己预先在纸上画一下位置大小,自由发挥即可。如果没有设定,默认在中心位置,如果actor多了,就会重叠在一起不太好看。

4.renderer

首先是创建一个渲染器,设定背景颜色

# 创建一个渲染器
renderer = vtk.vtkRenderer()
renderer.SetBackground(1, 1, 1)

渲染器是给演员actor化妆,因此需要将actor添加到渲染器中,像下面这样:

# 将圆柱体演员添加到渲染器中
renderer.AddActor(cylinder_actor)
renderer.AddActor(cylinder_actor2)

5.创建渲染窗口

render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
render_window.SetWindowName('CreateESGrid')
render_window.SetSize(1024, 768)

窗口就是舞台,所有的准备都完成了,选择就是需要搭建舞台给化好妆的演员们(actor)表演,需要对大小、名称设定,但是也是可有可无的,也会给出默认。注意吧渲染器加进去哦!不然舞台就是空的

6.开始交互渲染

# 开始交互渲染
camera = renderer.GetActiveCamera()

interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)
interactor.SetInteractorStyle(vtkInteractorStyleRubberBandPick())
render_window.Render()
interactor.Start()

后面的这个代码就是比较“死”的,除了添加的渲染从窗口的代码名称不一样外。

可以注意到我们还给了一个相机camera,当然你也可以设定他的位置,主要是为了鼠标操作时方便一些,怎么调整看自己咯。

以上六步就是建立一个vtk模型的步骤。下面是效果图:

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值