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; }