スポンサーリンク

VTKのオブジェクトをスレッドで生成・追加

actorなどの生成まではスレッドでできるが、Render()関数などの呼び出しはメインスレッドで行わなければいけない。

VTKのメッセージループを使う限りはシグナルを送ったりということが簡単にできないので、OnTimerで定期的にRender()をする。

 

#include <iostream>
#include <thread>

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


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

#include <vtkPolyDataMapper.h>
#include <vtkSphereSource.h>
#include <vtkCallbackCommand.h>
#include <vtkCamera.h>

#include <vtkActor.h>

// #include "createpoly.hpp"

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

// 定期的に Render する
void OnTimer(vtkObject* /*caller*/, unsigned long /*eventId*/, void* clientData, void* /*callData*/) {
    auto renderWindow = static_cast<vtkRenderWindow*>(clientData);
    if (renderWindow) {
        renderWindow->Render();
    }
}

// 停止フラグ
std::atomic<bool> g_stop{ false };
 
// スレッド
void work(vtkSmartPointer<vtkRenderer> renderer) {


    for (size_t i = 0; i < 100; i++) {

        // 乱数
        double x = (std::rand() % 100) / 10.0 - 5.0;
        double y = (std::rand() % 100) / 10.0 - 5.0;
        double z = (std::rand() % 100) / 10.0 - 5.0;
        // 球体


        vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
        sphereSource->SetCenter(x,y,z);
        sphereSource->SetRadius(5.0);
        sphereSource->Update();

        vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputConnection(sphereSource->GetOutputPort());
        actor->SetMapper(mapper);
        renderer->AddActor(actor);


        std::this_thread::sleep_for(std::chrono::seconds(1));

        if(g_stop) 
            break;
    }

}

int main(int /*argc*/, char** /*argv*/)
{

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

    renderer->ResetCamera();
    renderer->GetActiveCamera()->SetPosition(0, 0, 100);

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

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

    auto cb = vtkSmartPointer<vtkCallbackCommand>::New();
    cb->SetClientData(renderWindow);
    cb->SetCallback(OnTimer);
    interactor->AddObserver(vtkCommand::TimerEvent, cb);

    interactor->Initialize();
    interactor->CreateRepeatingTimer(10);


    std::thread t1(work, renderer);

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

    g_stop = true;
    t1.join();

    return 0;
}

コメントを残す

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

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


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