*カスタム・リーダー(ParaView) [#k0eb16de]

[[ParaView:http://www.paraview.org/]]に自分で作成したリーダーを組み込む方法を説明します。

本家の[[Writing_ParaView_Readers:http://www.paraview.org/Wiki/Writing_ParaView_Readers]]を参考にしています。(ほとんど日本語約です)
本家の[[Writing_ParaView_Readers:http://www.paraview.org/Wiki/Writing_ParaView_Readers]]を参考にしています。(ほとんど日本語訳です)

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

**VTKへの組み込み [#p2b7d067]

***ProcessRequest [#b7dd2673]

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

***RequestInformation [#y49b00b5]

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

#code(c){{
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を返します。



***RequestData [#a3cf3d32]

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

#code(c){{
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 [#h897e844]

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

***SetFileName [#h087c5fb]

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

#code(c){{

vtkSetStringMacro(FileName);

}}

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

**マルチグループ (Multi-Block, AMR)リーダー [#m9fe174f]

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


**並列用リーダー [#yc6c5e14]

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

***構造格子 [#f6699cd2]

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

#code(c){{
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;
}

}}

***非構造格子 [#n1543edb]

非構造格子(vtkPolyData、vtkUnstructuredGrid)の場合は、RequestInformationメソッドで、MAXIMUM_NUMBER_OF_PIECESキーをoutput informationオブジェクトに設定する必要があります。これは、ファイルから生成される最大のピース数を指定します。リーダーがデータ全体を読み込むだけの場合は、最大ピース数を1に設定する必要があります。入力ファイルを可能なピース数(つまり、1プロセスに1つ)に読み込む場合は、最大ピース数を-1に設定します。
#code(c){{
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)を返します。リーダーは、現プロセスがデータのどの部分を読むかを決定する際に、この情報を使用します。以下に、コードの例を示します。

#code(c){{
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の作成 [#ma8fc35d]

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

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

#code(xml){{
<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