[vtkusers] Aminate actor
沈庄明
zhuangming.shen at sphic.org.cn
Wed Feb 17 01:31:57 EST 2016
Hi all,
I would like to display 5 different vtkActors in a loop. That means, display the 1st vtkActor in the 1st second, display the 2nd vtkActor in the 2nd second, ... , display the 1st vtkActor in the 6th second, ... . All the vtkActors are kept in the vector<vtkActor*> actorList. I wrote my code (see below) with reference to the two existing VTK examples (http://www.vtk.org/Wiki/VTK/Examples/Cxx/Animation/AnimateActors and http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/AnimationScene).<http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/AnimationScene> Currently, I can animate those vtkActors when I set "scene->SetLoop(0)". However, when I change the setting to "scene->SetLoop(1)" to endlessly play the animation, those vtkActors can only be animated in the first loop but kept still from the second loop. Therefore, I'm so confused whether I have missed something important in my code. Anyone can help me? Thanks in advance.
Regards,
Zhuangming Shen
----------------------------------------------------- Part of My Code ----------------------------------------------------------------
const int frameNum = 5;
const int frameRate = 1;
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;
};
class ActorAnimator
{
public:
ActorAnimator()
{
this->Actor = 0;
this->Ren = 0;
this->Observer = AnimationCueObserver::New();
this->Observer->Animator = this;
}
~ActorAnimator()
{
if (this->Actor)
{
this->Actor->UnRegister(0);
this->Actor = 0;
}
if (this->Ren)
{
this->Ren->UnRegister(0);
this->Ren = 0;
}
this->Observer->UnRegister(0);
}
void SetActor(vtkActor *actor)
{
if (this->Actor)
{
this->Actor->UnRegister(0);
}
this->Actor = actor;
this->Actor->Register(0);
}
void SetRenderer(vtkRenderer *ren)
{
if (this->Ren)
{
this->Ren->UnRegister(0);
}
this->Ren = ren;
this->Ren->Register(0);
}
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->SetActor(actorList[0]);
this->Ren->AddActor(this->Actor);
this->Ren->Modified();
}
void Tick(vtkAnimationCue::AnimationCueInfo *info)
{
this->SetActor(actorList[int(info->AnimationTime)]); // choose which vtkActor from actorList will be displayed according to the AnimationTime
this->Ren->AddActor(this->Actor);
this->Ren->Modified();
}
void End(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info))
{
this->SetActor(actorList[0]);
this->Ren->AddActor(this->Actor);
this->Ren->Modified();
}
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;
};
AnimationCueObserver *Observer;
vtkActor *Actor;
vtkRenderer *Ren;
};
int main()
{
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkRenderer *ren1 = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
iren->SetRenderWindow(renWin);
renWin->SetMultiSamples(0);
renWin->AddRenderer(ren1);
// All the vtkActors have been kept in actorList
ren1->AddActor(actorList[0]);
// create Animation Scene
vtkAnimationScene *scene = vtkAnimationScene::New();
scene->SetModeToSequence();
scene->SetLoop(1);
scene->SetFrameRate(frameRate);
scene->SetStartTime(0);
scene->SetEndTime(frameNum - 1);
AnimationSceneObserver *sceneObserver = AnimationSceneObserver::New();
sceneObserver->SetRenderWindow(renWin);
scene->AddObserver(vtkCommand::AnimationCueTickEvent, sceneObserver);
// create an Animation Cue
vtkAnimationCue *cue1 = vtkAnimationCue::New();
cue1->SetStartTime(0);
cue1->SetEndTime(frameNum - 1);
scene->AddCue(cue1);
ActorAnimator animateOrgan;
animateOrgan.SetActor(actorList[0]);
animateOrgan.SetRenderer(ren1);
animateOrgan.AddObserversToCue(cue1);
vtkCamera *camera = vtkCamera::New();
camera->SetViewUp(0.0, 0.0, -1.0);
camera->SetPosition(0.0, 1.0, 0.0);
camera->SetFocalPoint(0.0, 0.0, 0.0);
camera->ComputeViewPlaneNormal();
camera->Dolly(1.5);
ren1->ResetCameraClippingRange();
ren1->SetActiveCamera(camera);
renWin->Render();
ren1->ResetCamera();
scene->Play();
scene->Stop();
iren->Start();
return EXIT_SUCCESS;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160217/4ffd6728/attachment.html>
More information about the vtkusers
mailing list