LorensenGarbage1
A ine at the top
This example uses vtkAnimationScene and vtkAnimationCue to animate actors. The vtk Scene and Cue classes provide a powerful mechanism for animating vtk classes. However, the setup can be complicated. This example provides an ActorAnimator class that can serve as a prototype for actor animation. It tries to hide some of the complexity of scene and cue animation.
AnimateActors.cxx
<source lang="cpp">
- include "AnimateActors.h"
- include <vtkSmartPointer.h>
- include <vtkAnimationCue.h>
- include <vtkRenderer.h>
- include <vtkSphereSource.h>
- include <vtkConeSource.h>
- include <vtkPolyDataMapper.h>
- include <vtkCommand.h>
- include <vtkAnimationScene.h>
- include <vtkRenderWindow.h>
- include <vtkRenderWindowInteractor.h>
- include <vtkCamera.h>
int main(int argc, char *argv[]) {
// Create the graphics structure. The renderer renders into the // render window. vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New(); vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); renWin->SetMultiSamples(0); iren->SetRenderWindow(renWin); renWin->AddRenderer(ren1); // Generate a sphere vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New(); vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); sphereMapper->SetInputConnection( sphereSource->GetOutputPort()); vtkSmartPointer<vtkActor> sphere = vtkSmartPointer<vtkActor>::New(); sphere->SetMapper(sphereMapper); ren1->AddActor(sphere);
// Generate a cone vtkSmartPointer<vtkConeSource> coneSource = vtkSmartPointer<vtkConeSource>::New(); vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); coneMapper->SetInputConnection( coneSource->GetOutputPort()); vtkSmartPointer<vtkActor> cone = vtkSmartPointer<vtkActor>::New(); cone->SetMapper(coneMapper); ren1->AddActor(cone);
// Create an Animation Scene vtkSmartPointer<vtkAnimationScene> scene = vtkSmartPointer<vtkAnimationScene>::New(); if(argc>=2 && strcmp(argv[1],"-real")==0) { cout << "real-time mode" << endl; scene->SetModeToRealTime(); } else { cout << "sequence mode" << endl; scene->SetModeToSequence(); } scene->SetLoop(0); scene->SetFrameRate(5); scene->SetStartTime(0); scene->SetEndTime(20); vtkSmartPointer<AnimationSceneObserver> sceneObserver = vtkSmartPointer<AnimationSceneObserver>::New(); sceneObserver->SetRenderWindow(renWin); scene->AddObserver(vtkCommand::AnimationCueTickEvent,sceneObserver);
// Create an Animation Cue for each actor vtkSmartPointer<vtkAnimationCue> cue1 = vtkSmartPointer<vtkAnimationCue>::New(); cue1->SetStartTime(5); cue1->SetEndTime(23); scene->AddCue(cue1);
vtkSmartPointer<vtkAnimationCue> cue2 = vtkSmartPointer<vtkAnimationCue>::New(); cue2->SetStartTime(1); cue2->SetEndTime(10); scene->AddCue(cue2); // Create an ActorAnimator for each actor; ActorAnimator animateSphere; animateSphere.SetActor(sphere); animateSphere.AddObserversToCue(cue1);
ActorAnimator animateCone; std::vector<double> endCone(3); endCone[0] = -1; endCone[1] = -1; endCone[2] = -1; animateCone.SetEndPosition(endCone); animateCone.SetActor(cone); animateCone.AddObserversToCue(cue2);
renWin->Render(); ren1->ResetCamera(); ren1->GetActiveCamera()->Dolly(.5); ren1->ResetCameraClippingRange();
// Create Cue observer. scene->Play(); scene->Stop(); iren->Start(); return EXIT_SUCCESS;
} </source>
AnimateActors.h
<source lang="cpp">
- ifndef __AnimateActors_h
- include <vtkActor.h>
- include <vtkAnimationCue.h>
- include <vtkCommand.h>
- include <vtkRenderWindow.h>
- include <vector>
class ActorAnimator { public:
ActorAnimator() { this->Actor=0; this->Observer = AnimationCueObserver::New(); this->Observer->Animator = this; this->StartPosition.resize(3); this->StartPosition.insert(this->StartPosition.begin(), 3, 0.0); this->EndPosition.resize(3); this->EndPosition.insert(this->EndPosition.begin(), 3, .5); } ~ActorAnimator() { if(this->Actor) { this->Actor->UnRegister(0); this->Actor=0; } this->Observer->UnRegister(0); } void SetActor(vtkActor *actor) { if (this->Actor) { this->Actor->UnRegister(0); } this->Actor = actor; this->Actor->Register(0); } void SetStartPosition(std::vector<double> position) { this->StartPosition = position; } void SetEndPosition(std::vector<double> position) { this->EndPosition = position; } void AddObserversToCue(vtkAnimationCue *cue) { cue->AddObserver(vtkCommand::StartAnimationCueEvent,this->Observer); cue->AddObserver(vtkCommand::EndAnimationCueEvent,this->Observer); cue->AddObserver(vtkCommand::AnimationCueTickEvent,this->Observer); } void Start(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info)) { this->Actor->SetPosition(this->StartPosition[0], this->StartPosition[1], this->StartPosition[2]); } void Tick(vtkAnimationCue::AnimationCueInfo *info) { double t = (info->AnimationTime - info->StartTime) / (info->EndTime - info->StartTime); double position[3]; for (int i = 0; i < 3; i++) { position[i] = this->StartPosition[i] + (this->EndPosition[i] - this->StartPosition[i]) * t; } this->Actor->SetPosition(position); } void End(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info)) { this->Actor->SetPosition(this->EndPosition[0], this->EndPosition[1], this->EndPosition[2]); }
protected:
class AnimationCueObserver : public vtkCommand { public: static AnimationCueObserver *New() { return new AnimationCueObserver; } virtual void Execute(vtkObject *vtkNotUsed(caller), unsigned long event, void *calldata) { if(this->Animator != 0) { vtkAnimationCue::AnimationCueInfo *info= static_cast<vtkAnimationCue::AnimationCueInfo *>(calldata); switch(event) { case vtkCommand::StartAnimationCueEvent: this->Animator->Start(info); break; case vtkCommand::EndAnimationCueEvent: this->Animator->End(info); break; case vtkCommand::AnimationCueTickEvent: this->Animator->Tick(info); break; } } } AnimationCueObserver() { this->Animator = 0; } ActorAnimator *Animator; };
vtkActor * Actor; AnimationCueObserver * Observer; std::vector<double> StartPosition; std::vector<double> EndPosition;
};
class AnimationSceneObserver : public vtkCommand { public:
static AnimationSceneObserver *New() { return new AnimationSceneObserver; } void SetRenderWindow( vtkRenderWindow *renWin) { if (this->RenderWindow) { this->RenderWindow->UnRegister(this); } this->RenderWindow = renWin; this->RenderWindow->Register(this);
} virtual void Execute(vtkObject *vtkNotUsed(caller), unsigned long event, void *vtkNotUsed(calldata)) { if(this->RenderWindow != 0) { switch(event) { case vtkCommand::AnimationCueTickEvent: this->RenderWindow->Render(); break; } } }
protected:
AnimationSceneObserver() { this->RenderWindow = 0; } ~AnimationSceneObserver() { if(this->RenderWindow) { this->RenderWindow->UnRegister(this); this->RenderWindow = 0; } } vtkRenderWindow *RenderWindow;
};
- endif
</source>
CMakeLists.txt
<source lang="cmake"> cmake_minimum_required(VERSION 2.6)
PROJECT(AnimateActors)
FIND_PACKAGE(VTK REQUIRED) INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(AnimateActors AnimateActors.cxx) TARGET_LINK_LIBRARIES(AnimateActors vtkHybrid)
</source>