paraviewにファイルを読み込ませる際に、VTKファイルがよく使用されます。VTKファイルとは、paraviewのもととなっているライブラリに読み込ませるためのファイル形式です。
ちなみに、VTK以外の拡張子もあります。例えば、.vtuや.vtiなどがあります。.vtuは非構造格子を表し、.vtiは構造格子を表します。
ここでは、構造を理解して読み書きできるようになるために、VTKのファイルの中身を解説します。以前、レガシーフォーマットについて解説したので、今回はXMLフォーマットについて解説します。
VTKファイルの種類
VTKファイルには2種類あります。レガシーフォーマットとXMLフォーマットです。
レガシーフォーマット
レガシーフォーマットとは、その名の通り古いフォーマットです。直感的に書ける一方で、拡張性が低いという問題があります。例えば、必ずシリアル形式になる、つまり並列化ができない等です。それを対処したのがXMLフォーマットになります。
XMLフォーマット
XML形式は、HTMLに似た構造をとったファイル形式です。XML自体が拡張可能なマーク付け言語と呼ばれており、VTKに限らず様々なファイルのデータ形式として使用されます。
XMLフォーマットは複雑ですが、非常に多機能です。例えば、並列化に対応していたり、データ圧縮に対応していたりします。
そのような細かい話は置いといて、実は一番大事なのは他の人が使っているかどうかだったりします。レガシーフォーマットに比べてXMLフォーマットのほうが使用されているので、難しくてもこちらを使用することをおすすめします。
ということで、今回はXMLフォーマットについてデータ構造を理解しましょう。
VTKファイルの構造
まずはファイル構造の大枠を見ていきます。
<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid">
<UnstructuredGrid>
<Piece NumberOfPoints="3" NumberOfCells="1">
<Points>
<DataArray type="Float32" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
1 1 0
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="offsets" format="ascii">
3
</DataArray>
<DataArray type="Int32" Name="connectivity" format="ascii">
0 1 2
</DataArray>
<DataArray type="Int32" Name="types" format="ascii">
5
</DataArray>
</Cells>
<PointData>
<DataArray type="Float32" Name="point_scalars" format="ascii">
0.0
1.0
2.0
</DataArray>
</PointData>
<CellData>
<DataArray type="Float32" Name="cell_scalars" format="ascii">
1.0
</DataArray>
</CellData>
</Piece>
</UnstructuredGrid>
</VTKFile>
出力結果は下記の三角形になります。
先に言っておくと、XMLは理解が難しいです。もし挫折しそうであれば、レガシーフォーマットから学んでいくことをおすすめします。
それでは早速解説に移りましょう。XML形式のVTKファイルは、大きく分けて4つの要素で構成されています。
1.ファイルバージョンと格子構造
<?xml version=”1.0″?>
<VTKFile type=”UnstructuredGrid”>
<UnstructuredGrid>
・・・
</UnstructuredGrid>
</VTKFile>
まずは、ファイルバージョンを指定します。基本的には、ここは手を付けなくても大丈夫です。1行目では、XMLのバージョンを指定します。若干の仕様の違いにより、一般的に1.0と0.1のバージョンが使用されているようですが、1.0のままで大丈夫です。
2行目では格子を指定します。今回は非構造格子なのでUnstructuredGridを使用します。構造格子の場合はRectlinearGridやStructuredGridを使用します。
3行目では、設定した格子構造に対するオプションを設定します。今回の非構造格子だと必要がないので、UnstructuredGridとだけ書いてあります。
下2行を見ると分かるように、XMLファイルでは範囲を明確にするために</・・・>の形で閉じる記述があります。一見コードが長く見えるのはこのせいです。ただ便利な点もあり、適切に字下げをすることで一つの記述がどこまで続いているのかがすぐに分かります。
2.Piece
<Piece NumberOfPoints=”3″ NumberOfCells=”1″>
・・・
</Piece>
ここでは、NumberOfPointsに節点の数、NumberOfCellsにセルの数を記入します。今回は三角形なので、節点数は3でセル数は1です。構造格子だとここで節点位置の範囲を指定します。
3.節点位置とセル情報
<Points>
<DataArray type=”Float32″ NumberOfComponents=”3″ format=”ascii”>
0 0 0
1 0 0
1 1 0
</DataArray>
</Points>
<Cells>
<DataArray type=”Int32″ Name=”offsets” format=”ascii”>
3
</DataArray>
<DataArray type=”Int32″ Name=”connectivity” format=”ascii”>
0 1 2
</DataArray>
<DataArray type=”Int32″ Name=”types” format=”ascii”>
5
</DataArray>
</Cells>
前半の<Point>~</Point>の部分で、節点の位置を指定しています。その下で、DataArrayというものが入れ子構造になっています。このように統一のフォーマットを使用することで、データが管理しやすくなっています。
2行目では、節点の情報を示します。DataArray typeで型を浮動小数点型に設定し、NumberOfComponentsに節点の数を入れます。今回は三角形なので接点数は3です。解説のために今回はformatにてフォーマット形式としてASCIIを指定しています。ここでバイナリ形式を指定することもできます。
3行目以降で、各行において節点のxyz座標を記入します。
後半の<Cell>~</Cell>の部分で、セルの情報を記入します。セルは節点をつなげて作るので、節点とは必要な情報が大きく異なります。今回は非構造格子を扱うので、offset、connnectivity、typesの3つを指定する必要があります。
offset、connnectivity、typesの3つはそれぞれDataArrayというデータ配列の形で管理されます。
まずはoffsetについて指定します。<DataArray type=”Int32″ Name=”offsets” format=”ascii”> ~ </DataArray>の部分でオフセットを指定します。オフセットとは、データを読み込む際に1つのセル情報の長さを伝える部分です。言い換えると、一つのセルが使用する節点の数を記入します。今回は三角形セルなので、3を記入します。
次にconnectivityについて指定します。<DataArray type=”Int32″ Name=”connectivity” format=”ascii”> ~ </DataArray>の部分で、節点の連結情報を記入します。今回は0番目の節点と1番目の節点と2番目の節点が繋がっているので、012と記入します。
最後にtypesについて指定します。これはセル形状を表します。よく使うセル形状は下記のとおりです。今回は三角形なので、5を入れます。
- 点:1
- 三角:5
- 四角:9
- 四面体:10
- 六面体:12
4.データ部分
<PointData>
<DataArray type=”Float32″ Name=”point_scalars” format=”ascii”>
0.0
1.0
2.0
</DataArray>
</PointData>
<CellData>
<DataArray type=”Float32″ Name=”cell_scalars” format=”ascii”>
1.0
</DataArray>
</CellData>
データ情報を記入します。今回は、節点データとセルデータを入力します。
<PointData>というのが、節点データについて書かれている部分です。ここでも先程説明したDataArrayという統一のフォーマットで記述されています。
まずは節点データを指定します。DataArray typeで型として浮動小数点を指定しており、Nameで好き名前をつけます。例えば、pressureやvelocityなどです。最後にデータフォーマットとしてアスキーを指定します。
各データは節点の番号順に与えられます。0番目の節点には0.0、1番目の節点には1.0、2番目の節点には2.0が入ります。
セルデータに関しても同様です。今回は0番目のセルに1.0という値を与えています。
paraviewで値を確認すると、各節点に指定した値が入っていることがわかります。
おわりに
今回はXMLフォーマットを例にVTKのファイル構造について解説しました。レガシーフォーマットに関しては既に解説しているので、そちらを御覧ください。
youtubeもやってます。どうぞ。
参考:
https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf
http://penguinitis.g1.xrea.com/study/ParaView/VTK/VTK.html