スポンサーリンク

VTKでVTKが管理していない頂点データを指定して可視化

vtkDoubleArrayでSetArrayをすると、他ライブラリで管理している頂点データやカラーデータをVTKにコピーせずに使用できる(かもしれない)。

データ構造がXYZの配列のようにVTKの管理形式と同じである必要がある。

ただ、vtkCellArray(可視化する際に必要な頂点IDの配列)はいずれにせよ作成しなければいけないので、メモリ効率が劇的によくなるかというとそうでもない。

#include <iostream>

//VTK_MODULE_INITに必要
#include <vtkAutoInit.h>


#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

//円筒とその表示に必要
#include <vtkPolyDataMapper.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkActor.h>


#include <vtkeigen/eigen/Dense>

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"psapi.lib")
#pragma comment(lib,"dbghelp.lib")
#pragma comment(lib,"ws2_32.lib")


//必須
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);


void create(std::vector<Eigen::Vector3d>& position, std::vector<Eigen::Vector3d>& color) {
  for (size_t i = 0; i < 100000; i++) {
    double x = (double)rand() / (double)RAND_MAX;
    double y = (double)rand() / (double)RAND_MAX;
    double z = (double)rand() / (double)RAND_MAX;

    position.push_back(Eigen::Vector3d(x, y, z));
    color.push_back(Eigen::Vector3d(x, y, z)); // 色も同じ値にする
  }
}

vtkSmartPointer<vtkActor> createActor(double* const position,double* const color,size_t count) {

  ///////////////////////////////////////////////////
  // 頂点データをVTKでラップ
  auto vtk_array_points = vtkSmartPointer<vtkDoubleArray>::New();
  vtk_array_points->SetNumberOfComponents(3);
  vtk_array_points->SetArray(position, count * 3, 1); // save=1の時、double_ptrの管理を移譲しない

  ///////////////////////////////////////////////////
  // カラーデータをVTKでラップ
  auto vtk_array_color = vtkSmartPointer<vtkDoubleArray>::New();
  vtk_array_color->SetNumberOfComponents(3);
  vtk_array_color->SetName("Colors");
  vtk_array_color->SetArray(color, count * 3, 1); // save=1の時、double_ptrの管理を移譲しない
  ///////////////////////////////////////////////////
  // 頂点インデクスの配列
  auto vertices = vtkSmartPointer<vtkCellArray>::New();
  for (vtkIdType i = 0; i < count; ++i) {
    vertices->InsertNextCell(1, &i);
  }

  ///////////////////////////////////////////////////
  auto vtk_points = vtkSmartPointer<vtkPoints>::New();
  vtk_points->SetData(vtk_array_points);

  // --- vtkPolyData作成 ---
  auto polydata = vtkSmartPointer<vtkPolyData>::New();
  polydata->SetPoints(vtk_points);
  polydata->SetVerts(vertices);
  polydata->GetPointData()->SetScalars(vtk_array_color);

  // --- actor作成 ---
  auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(polydata);

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);



  return actor;

}

int main(int /*argc*/, char** /*argv*/)
{
  std::vector<Eigen::Vector3d> position;
  std::vector<Eigen::Vector3d> color;
  create(position, color);

  auto actor = createActor(
    reinterpret_cast<double*>(position.data()),
    reinterpret_cast<double*>(color.data()),
    position.size()
  );

  auto renderer = vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);
  renderer->ResetCamera();

  //////////////////////////////////////
  auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();

  //////////////////////////////////////
  auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  renderWindow->SetInteractor(interactor);
  renderWindow->Render();

  interactor->Start(); //イベントループへ入る

  return 0;
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: