VTK AnimateActors

简介

        简单介绍下这个系列的初衷吧,这个专题下的例子都是搬运于https://kitware.github.io/vtk-examples 这个网站,首先本人英语不太好,可能翻译的有些误差hhhhh。这个系列在csdn上也有付费版不过听说质量不是很好,我这边会翻译后把坑踩一遍然后将每个example的工程上传到GitHub上。vtk在国内比较小众,用的人也不多,前一阵有个同学也是找到了我问了些问题,我觉得做这个事情还是有些意义的,希望自己能坚持下来...

工程环境

visual studio 2019

项目模板

Cmake项目

Example

         程序功能圆锥与球体的动画

代码

AnimateActors.h

#pragma once
#include <vtkActor.h>
#include <vtkAnimationCue.h>
#include <vtkCommand.h>
#include <vtkSmartPointer.h>
#include <vtkVector.h>
#include <vtkVectorOperators.h>

class ActorAnimator
{
public:
    ActorAnimator()
        : Actor(nullptr)
        , StartPosition(0, 0, 0)
        , EndPosition(0.5, 0.5, 0.5)
    {
    }

    ~ActorAnimator() = default;

    void SetActor(vtkActor* actor) { this->Actor = actor; }

    void SetStartPosition(const vtkVector3d& position)
    {
        this->StartPosition = position;
    }
    void SetEndPosition(const vtkVector3d& position)
    {
        this->EndPosition = position;
    }

    void AddObserversToCue(vtkAnimationCue* cue)
    {
        cue->AddObserver(vtkCommand::StartAnimationCueEvent, this, &ActorAnimator::Start);
        cue->AddObserver(vtkCommand::EndAnimationCueEvent, this, &ActorAnimator::End);
        cue->AddObserver(vtkCommand::AnimationCueTickEvent, this, &ActorAnimator::Tick);
    }

private:
    //@{
    /**
     * These are callbacks that called when corresponding events are fired by the
     * cue (see AddObserversToCue)
     */
    void Start()
    {
        this->Actor->SetPosition(this->StartPosition.GetData());
    }

    void Tick(vtkObject* vtkNotUsed(caller), unsigned long vtkNotUsed(event), void* calldata)
    {
        vtkAnimationCue::AnimationCueInfo* info =
            reinterpret_cast<vtkAnimationCue::AnimationCueInfo*>(calldata);
        const double t = (info->AnimationTime - info->StartTime) /
            (info->EndTime - info->StartTime);
        vtkVector3d position = this->StartPosition + (this->EndPosition - this->StartPosition) * t;
        this->Actor->SetPosition(position.GetData());
    }

    void End()
    {
        this->Actor->SetPosition(this->EndPosition.GetData());
    }
    //@}

    vtkSmartPointer<vtkActor> Actor;
    vtkVector3d StartPosition;
    vtkVector3d EndPosition;
};

AnimateActors.cpp

#include "AnimateActors.h"

#include <vtkAnimationCue.h>
#include <vtkAnimationScene.h>
#include <vtkCamera.h>
#include <vtkColor.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

int main(int argc, char* argv[])
{
    // Colors
    vtkNew<vtkNamedColors> colors;
    vtkColor3d coneColor = colors->GetColor3d("Tomato");
    vtkColor3d sphereColor = colors->GetColor3d("Banana");
    vtkColor3d backgroundColor = colors->GetColor3d("Peacock");

    // Create the graphics structure. The renderer renders into the
    // render window.
    vtkNew<vtkRenderWindowInteractor> iren;
    vtkNew<vtkRenderer> ren1;
    ren1->SetBackground(backgroundColor.GetData());

    vtkNew<vtkRenderWindow> renWin;
    iren->SetRenderWindow(renWin);
    renWin->AddRenderer(ren1);

    // Generate a sphere
    vtkNew<vtkSphereSource> sphereSource;
    sphereSource->SetPhiResolution(31);
    sphereSource->SetThetaResolution(31);

    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
    vtkNew<vtkActor> sphere;
    sphere->SetMapper(sphereMapper);
    sphere->GetProperty()->SetDiffuseColor(sphereColor.GetData());
    sphere->GetProperty()->SetDiffuse(.7);
    sphere->GetProperty()->SetSpecular(.3);
    sphere->GetProperty()->SetSpecularPower(30.0);

    ren1->AddActor(sphere);

    // Generate a cone
    auto coneSource = vtkSmartPointer<vtkConeSource>::New();
    coneSource->SetResolution(31);

    auto coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    coneMapper->SetInputConnection(coneSource->GetOutputPort());
    auto cone = vtkSmartPointer<vtkActor>::New();
    cone->SetMapper(coneMapper);
    cone->GetProperty()->SetDiffuseColor(coneColor.GetData());

    ren1->AddActor(cone);

    // Create an Animation Scene
    auto scene = vtkSmartPointer<vtkAnimationScene>::New();
    //scene->SetModeToRealTime();
    scene->SetModeToSequence();
    scene->SetLoop(0);
    scene->SetFrameRate(30);
    scene->SetStartTime(0);
    scene->SetEndTime(20);
    scene->AddObserver(vtkCommand::AnimationCueTickEvent, renWin.GetPointer(), &vtkWindow::Render);

    // Create an Animation Cue for each actor
    auto cue1 = vtkSmartPointer<vtkAnimationCue>::New();
    cue1->SetStartTime(5);
    cue1->SetEndTime(23);
    scene->AddCue(cue1);

    auto 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;
    animateCone.SetEndPosition(vtkVector3d(-1, -1, -1));
    animateCone.SetActor(cone);
    animateCone.AddObserversToCue(cue2);

    renWin->SetWindowName("AnimateActors");

    renWin->Render();
    ren1->ResetCamera();
    ren1->GetActiveCamera()->Dolly(.5);
    ren1->ResetCameraClippingRange();

    // Create Cue observer.
    scene->Play();
    scene->Stop();

    iren->Start();
    return EXIT_SUCCESS;
}

说明

1、使用vtkNamedColors设置球体、圆锥、背景的颜色。

        GetColor3d是获取对应颜色名称的rgb值,还有GetColor4d等函数可以获取对应颜色名称的rgba值等(vtkNamedColors (htmlpreview.github.io))对照表已添加到工程里。

 

2、使用vtkSphereSource创建球体

        常用接口:

SetThetaResolution (int)
 
设置经度方向上的点数(从StartTheta到EndTheta)
SetPhiResolution (int)设置纬度方向上的点数(范围从StartPhi到EndPhi)
SetRadius (double)

设置球体半径。默认值为0.5 

SetCenter (double, double, double)设置球体的中心。默认值为0,0,0

 3、使用vtkConeSource创建锥体

        SetResolution设置圆锥的棱边数

4、使用vtkPolyDataMapper设置对应多边形的mapper

5、使用vtkActor创建渲染场景

        常用接口:

SetShade打开或者关闭阴影测试
SetAmbient设置环境光
SetDiffuse设置漫反射光
SetSpecular设置镜面反射光
SetSpecularPower设置镜面反射亮点的大小(0-128)

6、使用vtkAnimationScene创建一个动画场景

                        

SetModeToRealTime设置实时播放模式
SetModeToSequence设置顺序播放模式
SetLoop设置循环播放模式
SetFrameRate设置帧率,单位时间内渲染的帧数
SetStartTime动画开始时间
SetEndTime动画结束时间

        AddObserver对AnimationCueTickEvent这个事件添加回调函数将动画运行显示绑定到渲染窗口进行显示。

        cue有三种状态:未初始化、激活和未激活。未初始化表示在cue开始时间之前的一个时间点。激活表示在cue开始时间和结束时间之间的某个时间点。但是,在结束时间之后,它处于未激活状态。当提示进入激活状态时,StartAnimationCueEvent被触发,此事件可以初始化动画的实体。当提示离开激活状态时,EndAnimationCueEvent被触发,此事件处理动画运行结束后的需要进行的操作。在激活过程中会触发AnimationCueTickEvent 事件,此事件用来处理实际动画的运行效果。

        头文件中也是利用AddObserversToCue这个函数来对这三个事件进行绑定。start函数设置Actor的起始位置,Tick函数计算每次Actor移动到的位置,End函数设置Actor的结束位置。

7、使用vtkAnimationCue创建两个个随时间变化/动态的实体加入到动画场景中

8、使用scene->Play()、scene->Stop()进行动画的开始和停止。

GitHub地址

VTKExamples/Animation/AnimateActors at main · 18810186103/VTKExamples (github.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

混元太极马保国

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值