カスタム・リーダー(ParaView)

ParaViewに自分で作成したリーダーを組み込む方法を説明します。

本家のWriting_ParaView_Readersを参考にしています。(ほとんど日本語訳です)

ParaViewでサポートされていないデータファイルをParaViewに読み込むには、ParaViewに読み込めるファイル形式に書き換えるコンバーターを作成するか、自作のリーダーを作成する必要があります。リーダーは、VTKの標準のパイプライン内で動作させる必要があります。ここでは、新規のリーダーをVTKに組み込む方法を説明し、正しくリーダーを動作させるのに実装しなければならないC++メソッドの概略も説明します。

VTKへの組み込み

ProcessRequest

このメソッドは、パイプラインが生成するリクエストを介して、vtkAlgorithmへの入り口になります。リーダーは、このメソッドをオーバーライドして、すべてのリクエストに対する返しを実装できます。このメソッドは、リーダークラスのpublicにおく必要があります。正常終了は1を、異常終了は0を返します。ほとんどのリーダーはoutput-type-specificクラスを継承して、下記にあるrequest-specificメソッドを実装するようにします。

RequestInformation

このメソッドは、REQUEST_INFORMATIONリクエストを受け取った際に、親クラスのProcessRequestの実装から起動されます。このメソッドで出力ポートに、入力ファイルのデータ情報を保存する必要があります。例えば、リーダーが構造格子データを生成する場合は、whole extentをここで設定します(以下参照)。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 
 
-
|
|
|
|
|
|
|
|
|
|
-
!
|
!
 
int vtkExampleReader::RequestData(
  vtkInformation*, vtkInformationVector**,
  vtkInformationVector* outVec)
{
  vtkInformation* outInfo = outVec->GetInformationObject(0);
  vtkImageData* outData = vtkImageData::SafeDownCast
    (outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
  int extent[6] = {0,-1,0,-1,0,-1};
  outInfo->Get
    (vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent);
 
  outData->SetExtent(extent);
 
  // ... read data for this extent from the file ...
 
  return 1;
}

このメソッドは並列で実行するリーダーを作成するときに必要となります。(下の章で説明します。)このメソッドは、protectedに記述します。正常終了で1を、異常終了で0を返します。

RequestData

このメソッドは、REQUEST_DATAリクエストを受け取った際に、親クラスのProcessRequestの実装から起動されます。このメソッドは、出力ポートの対応するデータオブジェクトに、ファイルから読み込んだデータを保存する必要があります。出力するデータオブジェクトは、このリクエストが生成される前に、パイプラインによってあらかじめ生成されます。このデータは、出力ポート情報から特定のキーを指定することで読みだすことができます。例えば、リーダーがvtkImageDataを生成する場合は、このメソッドは以下のようになります。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 
 
-
|
|
|
-
!
-
!
|
|
-
!
|
!
 
int vtkExampleReader::RequestInformation(
  vtkInformation*, vtkInformationVector**,
  vtkInformationVector* outVec)
{
  vtkInformation* outInfo = outVec->GetInformationObject(0);
  int extent[6];
 
  // ... read file to find available extent ...
 
  //store that in the pipeline
  outInfo->Set
    (vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
 
  // ... store other information ...
 
  return 1;
}

このメソッドは、protectedに記述します。正常終了で1を、異常終了で0を返します。

CanReadFile

このメソッドは、指定したデータファイルが読み込めるかどうかを決定します。入力パラメータは、const char*でデータファイル名を指定します。このメソッドは、実際にデータを読み込まずに、リーダーが読むフォーマットに整合するかを判定します。このメソッドは整数値を返します:1は指定したファイルが正しいタイプであることを意味します;0は正しくないことを意味します。このメソッドの実装は必ずしも必要ではありませんが、ParaViewは実装が存在する場合は、これを使用します。

SetFileName

このメソッドはリーダーによってロードするデータファイル名を指定するのに使用します。このメソッドは、SetFileNameという名前である必要はありませんが、名前を指定する機能は実装しなければなりません。SetFileNameを実装する最も簡単な方法は、このクラスのヘッダ―ファイル内で、vtkSetStringMacroを用いる方法です。(GetFileNameを実装するvtkGetStringMacroも同様に用意されています。)このメソッドは、このファイル名を格納する配列のメモリを取得し、ファイル名が変更された際には、リーダーがパイプラインをアップデートするように通知します。

Everything is expanded.Everything is shortened.
  1
  2
 
 
vtkSetStringMacro(FileName);

このマクロを使用する際は、このクラスのprotectedに、char*のFileNameインスタンスを追加しなければなりません。また、SetFileNameを使用する前に、コンストラクタであらかじめ、FileNameをNULLで初期化する必要があります。デストラクタでは、SetFileName(0)を呼び出すことで、ファイル名のメモリを解放します。

マルチグループ (Multi-Block, AMR)リーダー

VTK5.0, ParaView2.4以降、multi-blockとAMRのデータセットがサポートされています。マルチグループのリーダーを作成する場合も、前節に書いたのと同じガイドラインにしたがいます。multi-blockリーダーを作成する場合は、vtkMultiBlockDataSetAlgorithmからサブクラスを作成すると便利です。また、AMRリーダーを作成する場合は、vtkHierarchicalDataSetAlgorithmのサブクラスを作成するとよいでしょう。これらからサブクラスを作成しない場合は、CreateDefaultExecutive()、FillInputPortInformation()のメソッドを間違いなく、実装する必要があります。(vtkMultiBlockDataSetAlgorithmは出発点として利用できます。)vtkMultiBlockPLOT3DReader とvtkXMLHierarchicalDataReaderはマルチグループデータセットリーダーの良い例となっています。

並列用リーダー

特に指定しない場合、ParaViewで使われるVTKリーダーは、データ全体を最初のプロセスに読み込みます。それから、ParaViewはデータを他のプロセスに割り振ります。より望ましいのは、ParaViewに並列に読み込ませることで、データを各プロセスに正しく分割させることです。ParaViewに並列処理をさせるには、2つのメソッドを変更する必要があります:RequestInformationとRequestDataです。正確には、読み込むデータタイプが、構造格子か非構造格子かによって、どのように変更するかが異なります。

構造格子

構造格子データ(vtkStructuredGrid、vtkRectilinearGrid、vtkImageData)用リーダーのRequestInformationで、output informationオブジェクトにWHOLE_EXTENTキーを設定して、下流にあるフィルターにデータ全体の次元を引き渡す必要があります。WHOLE_EXTENTは6つのパラメータを使用して定めます:3つの座標軸に沿ったそれぞれの最小・最大インデックス(imin, imax, jmin, jmax, kmin, kmax)、または長さが6の整数配列。以下に、C++コードの例を示します。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 
 
 
-
|
|
|
|
|
-
!
|
|
|
|
|
!
 
int vtkDEMReader::RequestInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector ** vtkNotUsed( inputVector ),
  vtkInformationVector *outputVector)
{
  vtkInformation* outInfo =
 
  outputVector->GetInformationObject(0);
  int extent[6];
 
  //Read entire extent from file.
  ...
 
  outInfo->Set
    (vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent,6);
 
  return 1;
}

非構造格子

非構造格子(vtkPolyData、vtkUnstructuredGrid)の場合は、RequestInformationメソッドで、MAXIMUM_NUMBER_OF_PIECESキーをoutput informationオブジェクトに設定する必要があります。これは、ファイルから生成される最大のピース数を指定します。リーダーがデータ全体を読み込むだけの場合は、最大ピース数を1に設定する必要があります。入力ファイルを可能なピース数(つまり、1プロセスに1つ)に読み込む場合は、最大ピース数を-1に設定します。

Everything is expanded.Everything is shortened.
  1
 
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);

RequestDataメソッドでは、最初にUPDATE_NUMBER_OF_PIECESとUPDATE_PIECE_NUMBERをoutput informationオブジェクトから取得する必要があります。UPDATE_NUMBER_OF_PIECIESから戻る値は、出力データが分割されるピースの数です。UPDATE_PIECE_NUMBERは、現プロセスが保有するピース番号(0または、UPDATE_NUMBER_OF_PIECES-1)を返します。リーダーは、現プロセスがデータのどの部分を読むかを決定する際に、この情報を使用します。以下に、コードの例を示します。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 
 
 
-
|
|
|
|
|
|
|
|
|
-
!
|
|
!
 
int vtkUnstructuredGridReader::RequestData(
  vtkInformation *,
  vtkInformationVector **,
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  int piece, numPieces;
 
  piece = outInfo->Get
    (vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
 
  numPieces = outInfo->Get
    (vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
 
  //skip to proper offset in the file and read piece
  ...
 
  return 1;
}

XMLの作成

ParaViewで自作のリーダーを使用するためには、XMLファイルを作成する必要があります。

ParaViewにあるリーダーもXMLファイルで制御されています。Servers/ServerManager/Resources/readers.xmlが該当しています。

  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
 31
<SourceProxy name="XMLPolyDataReader"
                          class="vtkXMLPolyDataReader"
                          label="XML Polydata reader">
  <StringVectorProperty name="FileName" 
      command="SetFileName"
      animateable="0"
      number_of_elements="1">
      <FileListDomain name="files"/>
  </StringVectorProperty>
 
  <StringVectorProperty name="CellArrayInfo"
      information_only="1">
     <ArraySelectionInformationHelper attribute_name="Cell"/>
  </StringVectorProperty>
 
  <StringVectorProperty name="CellArrayStatus"
      command="SetCellArrayStatus"
      number_of_elements="0" 
      repeat_command="1" number_of_elements_per_command="2"
      element_types="2 0"
      information_property="CellArrayInfo"
      label="Cell Arrays">
      <ArraySelectionDomain name="array_list">
          <RequiredProperties>
              <Property name="CellArrayInfo" 
              function="ArrayList"/>
          </RequiredProperties>
      </ArraySelectionDomain>
  </StringVectorProperty>
 
</SourceProxy>

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-12-25 (木) 17:14:24 (1245d)