スポンサーリンク

VTKで一つのオブジェクトに頂点色情報を二つ以上与えて切り替えて表示

vtkPolyDataにAddArrayし、表示時にSetNameで指定したスカラー名でSelectColorArrayを呼び出す。かならずModifiedも呼び出す。

#include <iostream>

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


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


#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPointData.h>

#include <vtkRenderWindowInteractor.h>
#include <vtkCommand.h>
#include <vtkInteractorStyleTrackballCamera.h>


#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);



// キーボード入力を処理
class MyCommand : public vtkCommand {
  bool IsRed = true;
public:
  static MyCommand* New() {
    return new MyCommand;
  }

  void SetMapper(vtkSmartPointer<vtkPolyDataMapper> mapper) {
    this->Mapper = mapper;
  }

  void Execute(vtkObject* caller, unsigned long eventId, void*) override {
    if (eventId == vtkCommand::KeyPressEvent) {
      vtkRenderWindowInteractor* interactor = dynamic_cast<vtkRenderWindowInteractor*>(caller);
      std::string key = interactor->GetKeySym();

      // 注意 デフォルト機能で E キーで終了してしまう

      if(IsRed) {
        Mapper->SelectColorArray("ColorsRed");// 頂点色切替
        Mapper->Modified();
      }
      else {
        Mapper->SelectColorArray("ColorsBlue");
        Mapper->Modified();
      }

IsRed = !IsRed; interactor->GetRenderWindow()->Render(); } } private: vtkSmartPointer<vtkPolyDataMapper> Mapper; };
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////

// ランダムな点群を生成
vtkSmartPointer<vtkPolyData> CreateRandomCloud() {
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();

  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
  polyData->SetPoints(points);
  polyData->SetVerts(vertices);

  vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
  vtkIdType pid[1];
  for (int i = 0; i < 10000; i++) {
    double p[3];
    p[0] = vtkMath::Random(-1.0, 1.0);
    p[1] = vtkMath::Random(-1.0, 1.0);
    p[2] = vtkMath::Random(-1.0, 1.0);

    pid[0] = points->InsertNextPoint(p);
    verts->InsertNextCell(1, pid);
  }

  polyData->SetVerts(verts);

  return polyData;
}
      
// データに色情報を追加
// 呼び出すたびにdataに色情報が追加される
void SetColor(vtkSmartPointer<vtkPolyData> data,const char* scalarname,std::array<unsigned char,3> rgb) {
  
  size_t PointNum = data->GetNumberOfPoints();

  vtkSmartPointer<vtkUnsignedCharArray> colorsNew = vtkSmartPointer<vtkUnsignedCharArray>::New();
  colorsNew->SetNumberOfComponents(3);
  colorsNew->SetName(scalarname);
  for (int i = 0; i < PointNum; i++) {
    colorsNew->InsertNextTuple3(rgb[0], rgb[1], rgb[2]);
  }
  data->GetPointData()->AddArray(colorsNew);

}
int main(int /*argc*/, char** /*argv*/)
{
  vtkSmartPointer<vtkPolyData> cloud = CreateRandomCloud();

  SetColor(cloud, "ColorsRed",{255,0,0});
  SetColor(cloud, "ColorsBlue", { 0,0,255 });

  // cloudのactorを作成
  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(cloud);
  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  //////////////////////////////////////
  //////////////////////////////////////
  //////////////////////////////////////
  // 使用する色をAddArrayで指定したスカラー値を使用するように設定
  mapper->SetScalarVisibility(1);                     // スカラー値を使用して色をつける設定
  mapper->SetScalarModeToUsePointFieldData();         // スカラー値はポイントデータに設定されているものを使用
  mapper->SetColorModeToDefault();                    // カラーモードをデフォルトに設定

  // 実際にどのスカラー値を使用するかを設定
  // 切り替え時にはかならずModified()を呼ぶ
  mapper->SelectColorArray("ColorsRed");
  mapper->Modified();// マッパーを更新
  //////////////////////////////////////
  //////////////////////////////////////
  //////////////////////////////////////

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



  //////////////////////////////////////
  auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  //////////////////////////////////////
  // キー入力で色を切り替えるコマンドを設定
  vtkSmartPointer<MyCommand> colorToggleCommand = vtkSmartPointer<MyCommand>::New();
  colorToggleCommand->SetMapper(mapper);
  interactor->AddObserver(vtkCommand::KeyPressEvent, colorToggleCommand);

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

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

  return 0;
}

コメントを残す

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

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


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