#はじめに
pyqt5上でOpenFOAMの計算結果をvtkで表示する方法を簡単にまとめます。
ほぼ、私向けの備忘録となってます。
#環境
OS: windows7
OpenFOAM v4.0
python 3.6.4
pyqt5-5.9.2
vtk-8.0.0
numpy
#ファイル構成
case/
├ pyvtk.py (本プログラム)
└ pitzDaily
├ 0 (中身はp,Uなど)
├ constant
├ system
├ 100 (以下フォルダ0と同様)
├ 200
├ 300
├ 400
└ 406
↓github
https://github.com/matsubaraDaisuke/my_qiita/tree/master/pyvtk
#簡単な説明
vtkライブラリには「vtkOpenFOAMReader」クラスが標準で実装されており、簡単にOpenFOAMの結果を読み込むことができる。
VTKの使い方の流れは、以下の様な流れで使用する。
Reader→Filter→Mapper→Actor→Renderer→Window
詳しくはVTK勉強会資料が役につ(↓pdfの表示)
http://www.simulation-studies.org/wp-content/uploads/2014/01/vtk_semi_comp.pdf
##vtkを使ったOpenFOAMの結果の読み込み
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import vtk as vtk
import numpy as np
from vtk.util.numpy_support import vtk_to_numpy
rootDir = "pitzDaily"
fileName = rootDir + "/system/controlDict"
# reader
reader = vtk.vtkOpenFOAMReader()
reader.SetFileName(fileName)
reader.CreateCellToPointOn()
reader.DecomposePolyhedraOn()
reader.EnableAllCellArrays()
reader.Update()
tArray =vtk_to_numpy(reader.GetTimeValues()) #出力ファイルの時間を格納
print(tArray) #output-> [ 0. 100. 200. 300. 400. 406.]
reader.UpdateTimeStep(tArray[-1]) #最新の時間406を出力設定
reader.Update()
filter = vtk.vtkGeometryFilter()
filter.SetInputConnection(reader.GetOutputPort()) #filterにreaderを設定
# mapper
mapper = vtk.vtkCompositePolyDataMapper2()
mapper.SetInputConnection(filter.GetOutputPort()) #mapperにfilterを設定
##スカラー値の設定
mapper.SetScalarModeToUseCellFieldData() #scalarデータ用に設定
mapper.SelectColorArray("p") #圧力を表示する
mapper.SetScalarRange(-10,50) #圧力を[-10,50]の範囲で表示
# actor
actor = vtk.vtkActor()
actor.SetMapper(mapper) #actorにmapperを設定
# renderer
renderer = vtk.vtkRenderer()
renderer.AddActor(actor) #rendererにactorを設定
##背景色の設定
renderer.GradientBackgroundOn() #グラデーション背景を設定
renderer.SetBackground2(0.2,0.4,0.6) #上面の色
renderer.SetBackground(1,1,1) #下面の色
#Window
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer) #Windowにrendererを設定
iren = vtk.vtkRenderWindowInteractor();
iren.SetRenderWindow(renWin);
renWin.SetSize(850, 850)
renWin.Render()
iren.Start();
##pyqt5とvtkを使ったOpenFOAMの結果の読み込み
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import vtk as vtk
import numpy as np
from vtk.util.numpy_support import vtk_to_numpy
from PyQt5 import QtCore, QtGui
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class MainWindow(Qt.QMainWindow):
def __init__(self, parent = None):
Qt.QMainWindow.__init__(self, parent)
#Qtの枠の設定
#########追加
self.setWindowTitle('QtSample')
self.frame = Qt.QFrame()
self.vl = Qt.QVBoxLayout()
self.iren = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.iren)
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
#########window以外は一緒
self.rootDir = "pitzDaily"
self.fileName = self.rootDir + "/system/controlDict"
# reader
self.reader = vtk.vtkOpenFOAMReader()
self.reader.SetFileName(self.fileName)
self.reader.CreateCellToPointOn()
self.reader.DecomposePolyhedraOn()
self.reader.EnableAllCellArrays()
self.reader.Update()
tArray =vtk_to_numpy(self.reader.GetTimeValues()) #出力ファイルの時間を格納
print(tArray) #output-> [ 0. 100. 200. 300. 400. 406.]
self.reader.UpdateTimeStep(tArray[-1]) #最新の時間406を出力設定
self.reader.Update()
self.filter = vtk.vtkGeometryFilter()
self.filter.SetInputConnection(self.reader.GetOutputPort()) #filterにreaderを設定
# mapper
self.mapper = vtk.vtkCompositePolyDataMapper2()
self.mapper.SetInputConnection(self.filter.GetOutputPort()) #mapperにfilterを設定
##スカラー値の設定
self.mapper.SetScalarModeToUseCellFieldData() #scalarデータ用に設定
self.mapper.SelectColorArray("p") #圧力を表示する
self.mapper.SetScalarRange(-10,50) #圧力を[-10,50]の範囲で表示
# actor
self.actor = vtk.vtkActor()
self.actor.SetMapper(self.mapper) #actorにmapperを設定
# renderer
self.renderer = vtk.vtkRenderer()
self.renderer.AddActor(self.actor) #rendererにactorを設定
##背景色の設定
self.renderer.GradientBackgroundOn() #グラデーション背景を設定
self.renderer.SetBackground2(0.2,0.4,0.6) #上面の色
self.renderer.SetBackground(1,1,1) #下面の色
#Window
#########追加
self.iren.GetRenderWindow().AddRenderer(self.renderer)
self.iren.SetSize(850, 850)
self.iren.Initialize()
self.iren.Start();
self.show()
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
##結果
枠のタイトルがPyQtのQtSampleとなっていることがわかる。
##リンク
続編
PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その2(「ファイルを開く」の実装編)
#不具合
macOS High Sierra v10.13.2で動作確認をしたところ以下のような不具合が発生した。枠全体に表示されずに、左下に小さく表示されてしまう。