vtkStructuredGridでは, 線形座標変換を定義することができます.サンプルのfilter_1です.サンプルでは, vtkMultiBlockDataSetであるbodyに, 構造格子vtkStructuredGridがいくつか入ったものを作成します. こやつを, 線形変換しましょう.
Affine変換
Affine変換を行うことができます. 同次座標表示で
\[ \begin{bmatrix} a_{11}&a_{12}&a_{13}&b_1\\a_{21}&a_{22}&a_{23}&b_2\\a_{31}&a_{32}&a_{33}&b_3\\0&0&0&1 \end{bmatrix} \begin{bmatrix} x_1\\x_2\\x_3\\1\end{bmatrix} \]による変換が可能です.
まずはMatrixを作成:
auto myMatrix=vtkSmartPointer<vtkMatrix4x4>::New(); myMatrix->Zero(); myMatrix->SetElement(0,0,1.0);//a_11 ... myMatrix->Print(std::cout);
これで
vtkMatrix4x4 (0x10340dcf0) Elements: 1 0.1 0 0 0 1 0 0 0 0 1 0 0 0 0 1
が得られる.
Transformを作成
auto myTransform=vtkSmartPointer<vtkTransform>::New(); myTransform->SetMatrix(myMatrix);
これでmyMatrixを変換行列とする線形変換が定義できる. 行列以外に, 回転とかスケールとかで指定する方法もある.
Transformを確認
myTransform->Print(std::cout);
これにより, 変換行列をゲットできます:
vtkTransform (0x1032e2f00) Debug: Off ... Elements: 2 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
まあこんな感じですわ
TransformFilterを作成
Transformを実行するフィルターを作成します.
auto myFilter=vtkSmartPointer<vtkTransformFilter>::New(); auto vtkData=body->GetBlock(idom);//idom番目のvtkStructuredGridを取得 myFilter->SetInputData(vtkData); myFilter->SetTransform(myTransform); myFilter->Update();//パイプラインを走らせます auto res=myFilter->GetOutput(); vtkData->ShallowCopy(res);//オリジナルを書き換えておきます.
これで,こんな感じに菱形の領域ができました:
どうせなら中身も変換
上の方法では, 幾何形状は変換されますが, PointData, CellDataにベクトルやテンソルがあっても, 変換されません.
設定により3Dベクトルまでは同様に変換できるらしいんですが, テンソルは無視するクソ仕様なので,役に立たないかもですね.