スポンサーリンク

VTKでタイマー(クラスインスタンスver)、複数タイマー,タイマー停止

前にやったときはコールバック関数を直接呼び出していたが今度はクラスのインスタンスを作成してExecuteメンバを呼び出す。

VTKのタイマーは一つのコールバック用のクラスインスタンスのExecuteを各タイミングで呼び出す。

タイマーの停止はDestroyTimerで行う。

#include <iostream>

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


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

//円筒とその表示に必要
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.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 MyTimerCallback : public vtkCommand
{
public:
    static MyTimerCallback* New()
    {
        return new MyTimerCallback;
    }

    int counter100 = 0;
    int counter500 = 0;


    void Execute(vtkObject* caller, unsigned long eventId, void* callData) override
    {
        if (eventId == vtkCommand::TimerEvent)
        {
            int timerId = *(int*)(callData);

            if (timerId == this->TimerId100)
            {
                // TimerId100の処理
                counter100++;
                std::cout << "Timer100 triggered!" << counter100 <<std::endl;

                // タイマーを停止
                if(counter100 >= 10)
                {
                    std::cout << "Stopping Timer100" << std::endl;
                    Interactor->DestroyTimer(timerId);
                }
            }
            else if (timerId == this->TimerId500)
            {
                // TimerId500の処理
                counter500++;
                std::cout << "Timer500 triggered!" << counter500 << std::endl;
            }
        }
    }

    vtkSmartPointer<vtkRenderWindowInteractor> Interactor;
    int TimerId100 = -1; // タイマーの識別子
    int TimerId500 = -1;
};



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

    //////////////////////////////////////
    // Create a vtkCylinderSource
    vtkSmartPointer<vtkCylinderSource> cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
    cylinderSource->SetCenter(0.0, 0.0, 0.0);
    cylinderSource->SetRadius(5.0);
    cylinderSource->SetHeight(7.0);
    cylinderSource->SetResolution(100);

    //////////////////////////////////////
    // Create a mapper and actor
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(cylinderSource->GetOutputPort());
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    //////////////////////////////////////
    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();
    //////////////////////////////////////

    // タイマーコールバックの設定
    vtkSmartPointer<MyTimerCallback> timerCallback =
        vtkSmartPointer<MyTimerCallback>::New();

    // タイマーを作成。戻り値は識別子
    timerCallback->TimerId100 = interactor->CreateRepeatingTimer(100);
    timerCallback->TimerId500 = interactor->CreateRepeatingTimer(500);

    // DestroyTimerのためにinteractorを保持
    timerCallback->Interactor = interactor;

    interactor->AddObserver(vtkCommand::TimerEvent, timerCallback);
    interactor->SetRenderWindow(renderer->GetRenderWindow());
    interactor->Initialize();
    //////////////////////////////////////


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

    return 0;
}

コメントを残す

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

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


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