【VTK+有限元后处理】实时剖切视图

目的

实现后处理结果云图的平面剖切视图。

方法

通过使用vtkPlaneWidget控件交互,得到剖切平面,通过vtkClipDataSet完成对vtkUnstructuredGrid有限元结果数据的剖切操作。渲染管线如下图所示$^{[1]}$。

image-20221119155430445

代码实现

首先,我们先写一个创建vtkPlaneWidget控件的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def clipFEModel_planeWidget(self, ugrid):
# 三维切割平面控件构建
self.planeWidget = vtk.vtkPlaneWidget()
self.planeWidget.SetInteractor(self.interactor) # 与交互器关联
self.planeWidget.SetInputData(ugrid) # 设置数据集,用于初始化平面,可以不设置
self.planeWidget.SetResolution(1) # 即:设置网格数
self.planeWidget.GetPlaneProperty().SetColor(.2, .8, 0.1) # 设置颜色
self.planeWidget.GetPlaneProperty().SetOpacity(1) # 设置透明度
self.planeWidget.GetPlaneProperty().SetLineWidth(4)
self.planeWidget.GetHandleProperty().SetColor(0, .4, .7) # 设置平面顶点颜色
self.planeWidget.GetHandleProperty().SetPointSize(1)
self.planeWidget.GetHandleProperty().SetLineWidth(1) # 设置平面线宽
self.planeWidget.NormalToZAxisOn() # 初始法线方向平行于Z轴
self.planeWidget.SetRepresentationToWireframe() # 平面显示为网格属性 SetRepresentationToSurface()
self.planeWidget.SetCenter(ugrid.GetCenter()) # 设置平面坐标
self.planeWidget.SetPlaceFactor(1.0)
self.planeWidget.PlaceWidget() # 放置平面
self.planeWidget.On() # 显示平面

# 设置vtkPlaneCallback
self.planeWidget.AddObserver(vtk.vtkCommand.InteractionEvent, vtkPlaneCall(self, ugrid))

上面代码中,通过self.planeWidget.AddObserver(vtk.vtkCommand.InteractionEvent, vtkPlaneCall(self, ugrid)),设置了平面控件的回调函数,传入ugrid参数,即我们的vtkUnstructuredGrid有限元剖切对象。回调类vtkPlaneCall定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class vtkPlaneCall:
def __init__(self, sceneManager, ugrid):
self.sceneManager = sceneManager
self.ugrid = ugrid
self.clippingPlane = vtk.vtkPlane() # 剖切平面

def __call__(self, caller, ev):
caller.GetPlane(self.clippingPlane) # 得到当前planeWidget的平面,作为剖切平面

clipper = vtk.vtkClipDataSet()
clipper.SetClipFunction(self.clippingPlane) # 设置剖切方法为平面剖切
clipper.SetInputData(self.ugrid) # 设置剖切对象
# clipper.SetValue(0.0)
clipper.GenerateClippedOutputOn()
clipper.Update()

insideMapper = vtk.vtkDataSetMapper()
insideMapper.SetInputData(clipper.GetOutput())
insideMapper.ScalarVisibilityOn()

self.sceneManager.drawOutline(self.ugrid)

# clippedMapper = vtk.vtkDataSetMapper()
# clippedMapper.SetInputData(clipper.GetClippedOutput())
# clippedMapper.ScalarVisibilityOn()

scalarRange = clipper.GetOutput().GetPointData().GetScalars().GetRange()
title = clipper.GetOutput().GetPointData().GetScalars().GetName()
self.sceneManager.drawScalarField(insideMapper, scalarRange, title)
self.sceneManager.display()

这里的sceneManager参数为显示管理类,主要用于可视化渲染。drawScalarField函数为云图绘制函数,具体实现细节参加:【VTK+有限元后处理】可视化结果云图

结果

![GIF 2022-11-19 16-18-47](D:\OneDrive\桌面\GIF 2022-11-19 16-18-47.gif)

参考

[1] 陈航. 基于Qt和VTK的铸造有限元后处理可视化系统研发[D]. 湖北:华中科技大学,2018. DOI:10.7666/d.D01542051.