2017-06-28 31 views
0

メッシュを読み込んで視覚化するためのビューアが簡単になりました。VTK APIを使用したメッシュのレンダリング

VTKは私には新しく、私は最初に、ビューアのメッシュデータを設定するための最善の方法を見つけようとしています。私はVTKとC++の例がたくさんありますが、多くはvtk形式やレンダリングプリミティブに変換することです。

私は私かVTKポリデータがを設定し、それをレンダリングVTK非構造格子に私のメッシュデータを設定するだけで何、VTKフォーマットに変換するのに興味がありません。

私は少しテストをしました。このコードは正しくレンダリングされますが、これがデータセットを設定する最も効率的な方法ですか?私がN_SQUARESを1 000 000に設定すると、それは機能しますが、三角ループは非常に遅いようです。

vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); 


    //TEST MESH 
    int N_SQUARES = 100; 

    //This creates node coordinates for N_SQUARES amount of squares. (Nodal data would be read from a file later on) 
    vtkSmartPointer<vtkPoints> nodes = vtkSmartPointer<vtkPoints>::New(); 

    for (int i = 0; i < N_SQUARES; i++){ 
     nodes->InsertNextPoint(0.0, 0.0, 0.0 + 0.2f*float(i)); 
     nodes->InsertNextPoint(1.0, 0.0, 0.0 + 0.2f*float(i)); 
     nodes->InsertNextPoint(1.0, 1.0, 0.0 + 0.2f*float(i)); 
     nodes->InsertNextPoint(0.0, 1.0, 0.2 + 0.2f*float(i)); 
    } 

    //Here two triangles are created for each square. (these indices would later on be read from FEM element data) 
    vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New(); 

    for (int j = 0; j < N_SQUARES; j++){ 
     vtkSmartPointer<vtkTriangle> triangle1 = vtkSmartPointer<vtkTriangle>::New(); 
     triangle1->GetPointIds()->SetId(0, 0 + j); 
     triangle1->GetPointIds()->SetId(1, 1 + j); 
     triangle1->GetPointIds()->SetId(2, 2 + j); 

     vtkSmartPointer<vtkTriangle> triangle2 = vtkSmartPointer<vtkTriangle>::New(); 
     triangle2->GetPointIds()->SetId(0, 2 + j); 
     triangle2->GetPointIds()->SetId(1, 3 + j); 
     triangle2->GetPointIds()->SetId(2, 0 + j); 


     triangles->InsertNextCell(triangle1); 
     triangles->InsertNextCell(triangle2); 
    } 

    vtkSmartPointer<vtkPolyData> meshData = vtkSmartPointer<vtkPolyData>::New(); 
    meshData->SetPoints(nodes); 
    meshData->SetPolys(triangles); 

    vtkSmartPointer<vtkPolyDataMapper> meshMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 
    meshMapper->SetInputData(meshData); 

    vtkSmartPointer<vtkActor> meshActor = vtkSmartPointer<vtkActor>::New(); 
    meshActor->SetMapper(meshMapper); 

    renderer->AddActor(meshActor); 


    ui.qvtkWidget->GetRenderWindow()->AddRenderer(renderer); 

答えて

1

あなたの例のコードは、あなたがあなたのj -loop内の2つのvtkTriangleインスタンスを構築し、破壊している

  • 、いくつかの理由のいずれか遅いかもしれません。これは高価で、恐らく遅くなる最大の原因です。
  • polydataをビルドしたので、vtkTriangleをまったく使用しないことをお勧めします。前もってのことを行っているかの配列(点座標または接続)の大きな代わりに、

    for (int j = 0; j < N_SQUARES; ++j) 
    { 
        vtkIdType triangle1[3] = {j, j+1, j+2}; 
        vtkIdType triangle2[3] = {j+2, j+3, j}; 
        triangles->InsertNextCell(3, triangle1); 
        triangles->InsertNextCell(3, triangle2); 
        // ... or better yet, create a single quad: 
        vtkIdType quad[4] = {j, j+1, j+2, j+3}; 
        triangles->InsertNextCell(4, quad); 
    } 
    
  • ような何かをあなたはVTKを教えていません。これは、VTKがサイズを増やすとアレイを再割り当てしてコピーする必要があることを意味します。最初のループの前にnodes->GetData()->Allocate(4 * N_SQUARES);を追加してみてください(i以上)。同様に、vtkCellArrayに、あらかじめ適切な量のメモリを割り当てるように指示することができます(これは、nptsPerPoly0 ptId0Poly0 ptId1Poly0 ... ptIdNPoly0 nPtsPerPoly1 ...のようにフォーマットされた整数の配列です)。三角形の場合は、triangles->Allocate((1 + 3) * 2 * N_SQUARES);とします。前の例のようにクワッドの場合は、triangles->Allocate((1 + 4) * N_SQUARES);になります。

  • あなたの例では、複数の四角で共有されるポイントは再利用されません。つまり、nodestrianglesは、必要以上に多くのメモリを消費します。
  • 中規模のメッシュ(1台のコンピュータのメモリに収まるサイズ)の場合、スレッドを使用してnodestrianglesアレイを準備することができます。大規模なメッシュの場合、VTKは複数のコンピュータで動作するように構築されており、それぞれがメッシュの一部(分散メモリ並列処理)を保持します。
  • すでにメッシュをメモリに入れている場合は、VTKの最近のバージョンでは、コピーを必要とせずにメッシュをVTKに公開する特別なクラスを書くことができますが、これはこの質問の範囲を超えています。ただし、メッシュが消費するメモリ量は半分になるため、メッシュやコンピュータのメモリによっては重要になる可能性があります。
  • N_SQUARESのサイズに応じて、コンピュータにスワップファイルまたはパーティションを使用させる可能性があります。その場合は、メッシュのサイズを小さくするか、分散メモリの並列処理を使用する必要があります。
+0

ありがとうございました!これは私が必要としている答えの一種です。コードを修正してテストします。私は、OpenGLとバッファの使用など、レンダリングの経験があります。私は "ボンネットの下で" VTKがこれを使用していると信じています。 VTKがさまざまなOpenGLメソッドを呼び出す方法の概要はありますか? – remi000

+0

@ remi000 VTKのすべてのOpenGL呼び出しは、VTK/Rendering/OpenGLまたはVTK/Rendering/OpenGL2ディレクトリのクラスに限定されています(古いOpenGLまたは新しいOpenGLバックエンドを使用するかどうかによって異なります)。 'vtkOpenGLPolyDataMapper.cxx'は' vtkOpenGLVertexBufferObject'インスタンスにデータを取り込み、バッファオブジェクトをバインド/アップロードするコールは 'vtkOpenGLBufferObject'(' vtkOpenGLVertexBufferObject'のスーパークラス)にあります。 – Drone2537

関連する問題