LoginSignup
17
11

More than 3 years have passed since last update.

VTKファイルの読み込み・書き込み

Last updated at Posted at 2018-04-03

VTKファイルの規格(format)

個人的な備忘録なので、かなり端折ってます。そのうち時間ができたら加筆するかもしれません。
非構造格子をVTKファイルに書き込む例を追記しました。

VTKファイルには大きく分けて

  • Legacy規格
  • XML規格

があります。詳しくは公式ページのVTK file formatsを読んでください。アカデミックの分野ではLegacy規格が今でもよく使われています。ただしLegacy規格は時系列データをサポートしていないため、時系列データを描画したい場合は、XML規格をPVDファイルと共に使う必要があります。

データセットの幾何・トポロジーを決める型として

  • STRUCTURED_POINTS
  • STRUCTURED_GRID
  • UNSTRUCTURED_GRID
  • POLYDATA
  • RECTILINEAR_GRID
  • FIELD

が用意されています。数値計算の結果を可視化する場合、Structured GridとUnstructured Gridを最もよく使うと思います。

VTKファイルの読み込み・書き込み

VTKライブラリに読み込み・書き込みするためのツールが含まれているので、自分でI/O用のツールを作る必要は全くありません。
(ネットを検索すると、なぜか自分でI/Oを書くような解説が結構ヒットしますが、時間の無駄です。)
最新版のビルド方法がわからなければ、私の過去の記事を参考にしてください。

↓の記事を読めば基本的な使い方がすぐ理解できます。
VTKによるファイル読み込みと書き込み

より細かい使い方は

を参照すれば大体でてきます。

非構造格子をVTKファイルに書き込むコードの例

VTKライブラリを使って非構造格子(Unstructured Grid)をLegacy規格のVTKファイルに書き込む例を示します。基本的な手順は下記の通りです。

  1. Point配列を作成する
  2. Cell配列を作成する
  3. Point配列およびCell配列からGridデータを作成する
  4. Point/Cellに付属するデータ配列を作成し、Gridデータへ与える
  5. ファイルへ書き込む

この例では簡単のため4を省略しGridデータのみ書き込んでいます。

C++

VtkUnstructuredGridWriter.hpp
#ifndef VTK_UNSTRUCTURED_GRID_WRITER_H
#define VTK_UNSTRUCTURED_GRID_WRITER_H

#include <array>
#include <vector>
#include <string>

using Point = std::array<double, 3>;
using QuadCell = std::array<int, 4>;

void VtkUnstructuredGridWriter(const std::string& filename,
                               const std::string& header,
                               const std::vector<Point>& points,
                               const std::vector<QuadCell>& cells);

#endif
VtkUnstructuredGridWriter.cpp
#include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h>
#include <vtkUnstructuredGridWriter.h>
#include <vtkQuad.h>
#include <vtkCellArray.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include "VtkUnstructuredGridWriter.hpp"

void VtkUnstructuredGridWriter(const std::string& filename,
                               const std::string& header,
                               const std::vector<Point>& points,
                               const std::vector<QuadCell>& cells) {
// Point配列を作成する
auto vtk_points = vtkSmartPointer<vtkPoints>::New();
for (auto&& point : points) {
    vtk_points->InsertNextPoint(point.data());
}

// Cell配列を作成する
// この例の場合、Cell形式はVTK_QUAD
auto vtk_cells = vtkSmartPointer<vtkCellArray>::New();
for (auto&& cell : cells) {
    auto vtk_cell = vtkSmartPointer<vtkQuad>::New();
    // Cell1個当たりのPointの数が決まっていないCell形式
    //  - VTK_POLY_VERTEX
    //  - VTK_POLY_LINE
    //  - VTK_TRIANGLE_STRIP
    //  - VTK_POLYGON
    // の場合は、下のfor-loopを回す前に
    //   vtk_cell->GetPointIds()->SetNumberOfIds(npoints);
    // としてあらかじめリストサイズを確保するか、
    // SetId(i, id)の代わりにInsertNextId(id)を使う
    for (int i = 0; i < cell.size(); ++i) {
        vtk_cell->GetPointIds()->SetId(i, cell[i]);
    }
    vtk_cells->InsertNextCell(vtk_cell);
}

// Point配列とCell配列からGridを作成する
auto vtk_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
vtk_grid->SetPoints(vtk_points);
vtk_grid->SetCells(VTK_QUAD, vtk_cells);

// GridをVTKファイルに書き込む
auto writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New();
writer->SetFileName(filename.c_str());  // ファイル名をセットする
writer->SetHeader(header.c_str());      // ヘッダーをセットする
writer->SetInputData(vtk_grid);         // Gridをセットする
writer->Write();
}

Python

そのうち書くかも。

CMakeの設定

CMakeを使ってビルドするとき、CMakeLists.txtに次のような設定を加えます。

add_executable(myapp myapp.cpp)

# VTKライブラリを検索
find_package(VTK REQUIRED)
# VTKライブラリをリンク
target_link_libraries(mylib ${VTK_LIBRARIES})
# VTKライブラリのヘッダーファイルをインクルード
target_include_directories(mylib
  SYSTEM PRIVATE ${VTK_INCLUDE_DIRS}
  )

VTKライブラリをローカルディレクトリにインストールしている場合は、cmakeを実行するときにオプションを加えて実行します。

cmake -DVTK_DIR:PATH=/home/usr/local/dir ..
17
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11