首页 > 代码库 > vtkAnimationCue、vtkCommand和vtkAVIWriter

vtkAnimationCue、vtkCommand和vtkAVIWriter

1. 用vtkAnimationCue自定义一个vtkCustomAnimationCue类,用来实现球体逐渐张开的过程;

2.用vtkCommand自定义衍生一个vtkCustomAnimationCue,在类中实现动画视频记录的开始,记录每一帧,最后结束记录

3.在场景中添加监听器,监听vtkCustomAnimationCue对象的开始、每一帧的画面和结束,并分别调用vtkCustomAnimationCue中的回调函数

 

class vtkCustomAnimationCue : public vtkAnimationCue
{
public:
    static vtkCustomAnimationCue* New(){return new vtkCustomAnimationCue;}
    vtkTypeMacro(vtkCustomAnimationCue,vtkAnimationCue)
    vtkTypeRevisionMacro (vtkCustomAnimationCue,vtkAnimationCue);

    vtkRenderWindow *RenWin;
    vtkSphereSource *Sphere;
    vtkRenderer *renderer;
protected:
    vtkCustomAnimationCue()
    {
        this->RenWin = 0;
        this->Sphere = 0;
        theta=0;
    }
    ~vtkCustomAnimationCue(){}
protected:
    double theta;
    // Overridden to adjust the sphere‘sradius depending on the frame we
    // are rendering. In this animation wewant to change the StartTheta
    // of the sphere from 0 to 180 over thelength of the cue.
    virtual void TickInternal(double currenttime, double deltatime, double clocktime)
    {
        double new_st = currenttime * 180;
        // since the cue is in normalizedmode, the currenttime will be in the
        // range[0,1], where 0 is start ofthe cue and 1 is end of the cue.
        this->Sphere->SetStartTheta(new_st);
        this->renderer->ResetCamera();
        this->RenWin->Render();
    }

};

 

class MyCallBackAVI:public vtkCommand
{
public:
    static MyCallBackAVI *New(){ return new MyCallBackAVI; }

    vtkWindowToImageFilter *filter;
    vtkAVIWriter *writer;
//    vtkRenderWindow *renWin;
    virtual void Execute(vtkObject *caller,unsigned long eveventId,void*vtkNotUsed(callData))
    {
        switch (eveventId)
        {
        case vtkCommand::StartAnimationCueEvent:
            cout<<"timer callback!"<<endl;
            writer->Start();
            break;
        case vtkCommand::AnimationCueTickEvent:
            filter->Modified();
            writer->Write();
            break;
        case vtkCommand::EndAnimationCueEvent:
            writer->End();
        default:
            break;
        }

    }

    vtkTypeMacro(MyCallBackAVI,vtkCommand)
    protected:
        MyCallBackAVI()
    {
//        renWin=vtkRenderWindow::New();
        filter=vtkWindowToImageFilter::New();
        writer=vtkAVIWriter::New();
    }
};

 

int main(int, char *[])
{
    // Create the graphics sturctures. Therenderer renders into the
    // render window.
    vtkRenderer *ren1 = vtkRenderer::New();
    vtkRenderWindow *renWin =vtkRenderWindow::New();
    vtkRenderWindowInteractor *iren =vtkRenderWindowInteractor::New();
    vtkInteractorStyleTrackballCamera *style=vtkInteractorStyleTrackballCamera::New();
    iren->SetInteractorStyle(style);
    //    renWin->SetMultiSamples(0);
    renWin->AddRenderer(ren1);
    iren->SetRenderWindow(renWin);
    vtkSphereSource *sphere =vtkSphereSource::New();
    vtkPolyDataMapper *mapper =vtkPolyDataMapper::New();
    mapper->SetInputConnection(sphere->GetOutputPort());
    /**********沿X轴旋转30度*****************/
    vtkTransform *transform;
    vtkTransformPolyDataFilter *transformFilter;
    transform=vtkTransform::New();
    transform->RotateWXYZ(30,1,0,0);
    transformFilter=vtkTransformPolyDataFilter::New();
    transformFilter->SetTransform(transform);
    transformFilter->SetInputConnection(sphere->GetOutputPort());
    transformFilter->Update();
    mapper->SetInputConnection(transformFilter->GetOutputPort());
    /**********沿X轴旋转45度*****************/
    vtkActor *actor = vtkActor::New();
    actor->SetMapper(mapper);
    ren1->AddActor(actor);
    ren1->ResetCamera();
    renWin->Render();

    //Create an Animation Scene
    vtkAnimationScene *scene =vtkAnimationScene::New();
    scene->SetModeToSequence();
    scene->SetFrameRate(5);
    scene->SetStartTime(0);
    scene->SetEndTime(20);

    // Create an Animation Cue to animate thecamera.
    vtkCustomAnimationCue *cue1 =vtkCustomAnimationCue::New();
    cue1->Sphere = sphere;
    cue1->RenWin = renWin;
    cue1->renderer=ren1;

    cue1->SetTimeModeToNormalized();
    cue1->SetStartTime(0);
    cue1->SetEndTime(1.0);
    scene->AddCue(cue1);
    /***********************录制视频******************************/
    vtkSmartPointer<MyCallBackAVI> myCallBackAvi=vtkSmartPointer<MyCallBackAVI>::New();
    vtkSmartPointer<vtkWindowToImageFilter> filter=vtkSmartPointer<vtkWindowToImageFilter>::New();
    vtkSmartPointer<vtkAVIWriter> writer=vtkSmartPointer<vtkAVIWriter>::New();
    filter->SetInput(renWin);
    writer->SetInputConnection(filter->GetOutputPort());
    writer->SetFileName("myVideo.avi");
    writer->SetRate(5);

    myCallBackAvi->filter=filter;
    myCallBackAvi->writer=writer;
///设置场景的监听器,监听动画的开始事件(StartAnimationCueEvent),调用自定义的回调类MyCallBackAVI,启动记录
///               监听动画的结束事件(EndAnimationCueEvent),调用自定义的回调类MyCallBackAVI,结束记录
///               监听动画的Tick事件(AnimationCueTickEvent),调用自定义的回调类MyCallBackAVI,记录一帧视频

    scene->AddObserver(vtkCommand::StartAnimationCueEvent,myCallBackAvi);
    scene->AddObserver(vtkCommand::AnimationCueTickEvent,myCallBackAvi);
    scene->AddObserver(vtkCommand::EndAnimationCueEvent,myCallBackAvi);

    iren->Initialize();
    scene->Play();
    scene->Stop();
    iren->Start();

    ren1->Delete();

    renWin->Delete();
    scene->Delete();
    cue1->Delete();

    return EXIT_SUCCESS;
}

 

vtkAnimationCue、vtkCommand和vtkAVIWriter