zoukankan      html  css  js  c++  java
  • Qt&Vtk-004-AmbientSpheres

    titlle bar

    欢迎来到我的博客,希望这篇文章对你有所帮助,如果觉得不错,请点赞搜藏哈。

    Qt&Vtk-AmbientSpheres

    从本章开始,将开始搬运官方实例代码,顺便开始学习,能理解多少算多少。

    1 效果展示

    今天搬运第一个Vtk官方示例AmbientSpheres,如下图

    image-20210622203824970

    image-20210622203946412

    2源码

    下面看下源代码,这次分别写在了头文件中和源文件中。

    2.1 ambientspheres.h

    #ifndef AMBIENTSPHERES_H
    #define AMBIENTSPHERES_H

    #include <QWidget>
    #include "QVTKOpenGLWidget.h"               //新版本,旧版QVTKWidget
    #include "vtkAutoInit.h"
    #include "vtkSmartPointer.h"
    #include "vtkSphereSource.h"
    #include "vtkPolyDataMapper.h"
    #include "vtkActor.h"
    #include "vtkRenderer.h"
    #include "vtkRenderWindow.h"
    #include "vtkProperty.h"
    #include "vtkCamera.h"
    #include "vtkLight.h"

    namespace Ui {
    class AmbientSpheres;
    }

    class AmbientSpheres : public QWidget
    {
       Q_OBJECT

    public:
       explicit AmbientSpheres(QWidget *parent = 0);
       ~AmbientSpheres();

    private:
       Ui::AmbientSpheres *ui;
       vtkSmartPointer<vtkSphereSource> sphere = nullptr;
       vtkSmartPointer<vtkPolyDataMapper> sphereMapper = nullptr;
       vtkSmartPointer<vtkActor>   sphere1 = nullptr,
                                   sphere2 = nullptr,
                                   sphere3 = nullptr,
                                   sphere4 = nullptr,
                                   sphere5 = nullptr,
                                   sphere6 = nullptr,
                                   sphere7 = nullptr,
                                   sphere8 = nullptr;
       vtkSmartPointer<vtkRenderer> renderer = nullptr;
       vtkSmartPointer<vtkLight> light = nullptr;
    };

    #endif // AMBIENTSPHERES_H

    2.2 ambientspheres.cpp

    #include "ambientspheres.h"
    #include "ui_ambientspheres.h"
    #include <QDebug>
    /**
    * @brief AmbientSpheres::AmbientSpheres
    * @param parent
    * 照搬官方实例,有道翻译官方文件中内容如下
    * This examples demonstrates the effect of specular lighting.
    * 这个例子演示了镜面照明的效果。
    * 专业名词后面慢慢学习,代码先撸起来
    */
    AmbientSpheres::AmbientSpheres(QWidget *parent) :QWidget(parent),ui(new Ui::AmbientSpheres)
    {
       ui->setupUi(this);
       //创建一个球体
       sphere = vtkSmartPointer<vtkSphereSource>::New();
       sphere->SetThetaResolution(100);
       sphere->SetPhiResolution(50);
       //创建一个映射器
       sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
       sphereMapper->SetInputConnection(sphere->GetOutputPort());
       //创建8个小球
       sphere1 = vtkSmartPointer<vtkActor>::New();
       sphere2 = vtkSmartPointer<vtkActor>::New();
       sphere3 = vtkSmartPointer<vtkActor>::New();
       sphere4 = vtkSmartPointer<vtkActor>::New();
       sphere5 = vtkSmartPointer<vtkActor>::New();
       sphere6 = vtkSmartPointer<vtkActor>::New();
       sphere7 = vtkSmartPointer<vtkActor>::New();
       sphere8 = vtkSmartPointer<vtkActor>::New();

       sphere1->SetMapper(sphereMapper);
       sphere1->GetProperty()->SetColor(1,0,0);            //颜色
       sphere1->GetProperty()->SetAmbient(0.125);          //环境光系数
       sphere1->GetProperty()->SetDiffuse(0.0);            //漫反射光系数
       sphere1->GetProperty()->SetSpecular(0.0);           //镜面反射系数
                                                           //镜面系数SetSpecularPower()


       sphere2->SetMapper(sphereMapper);
       sphere2->GetProperty()->SetColor(1,0,1);
       sphere2->GetProperty()->SetAmbient(0.25);
       sphere2->GetProperty()->SetDiffuse(0.0);
       sphere2->GetProperty()->SetSpecular(0.0);
       sphere2->AddPosition(1.25,0,0);


       sphere3->SetMapper(sphereMapper);
       sphere3->GetProperty()->SetColor(1,0.1,0);
       sphere3->GetProperty()->SetAmbient(0.375);
       sphere3->GetProperty()->SetDiffuse(0.0);
       sphere3->GetProperty()->SetSpecular(0.0);
       sphere3->AddPosition(2.5,0,0);

       sphere4->SetMapper(sphereMapper);
       sphere4->GetProperty()->SetColor(1,0,0);
       sphere4->GetProperty()->SetAmbient(0.5);
       sphere4->GetProperty()->SetDiffuse(0.0);
       sphere4->GetProperty()->SetSpecular(0.0);
       sphere4->AddPosition(3.75,0,0);


       sphere5->SetMapper(sphereMapper);
       sphere5->GetProperty()->SetColor(1,0,0);
       sphere5->GetProperty()->SetAmbient(0.625);
       sphere5->GetProperty()->SetDiffuse(0.0);
       sphere5->GetProperty()->SetSpecular(0.0);
       sphere5->AddPosition(0.0,1.25,0);


       sphere6->SetMapper(sphereMapper);
       sphere6->GetProperty()->SetColor(1,0,0);
       sphere6->GetProperty()->SetAmbient(0.75);
       sphere6->GetProperty()->SetDiffuse(0.0);
       sphere6->GetProperty()->SetSpecular(0.0);
       sphere6->AddPosition(1.25,1.25,0);

       sphere7->SetMapper(sphereMapper);
       sphere7->GetProperty()->SetColor(1,0,0);
       sphere7->GetProperty()->SetAmbient(0.875);
       sphere7->GetProperty()->SetDiffuse(0.0);
       sphere7->GetProperty()->SetSpecular(0.0);
       sphere7->AddPosition(2.5,1.25,0);

       sphere8->SetMapper(sphereMapper);
       sphere8->GetProperty()->SetColor(1,0,0);
       sphere8->GetProperty()->SetAmbient(1.0);
       sphere8->GetProperty()->SetDiffuse(0.0);
       sphere8->GetProperty()->SetSpecular(0.0);
       sphere8->AddPosition(3.75,1.25,0);


       renderer = vtkSmartPointer<vtkRenderer>::New();         //窗口渲染器
       renderer->AddActor(sphere1);
       renderer->AddActor(sphere2);
       renderer->AddActor(sphere3);
       renderer->AddActor(sphere4);
       renderer->AddActor(sphere5);
       renderer->AddActor(sphere6);
       renderer->AddActor(sphere7);
       renderer->AddActor(sphere8);
       renderer->SetBackground(0.1,0.2,0.4);               //设置背景颜色
       ui->widget->GetRenderWindow()->AddRenderer(renderer);   //

       light = vtkSmartPointer<vtkLight>::New();               //创建光照
       light->SetFocalPoint(1.875,0.6125,0);                   //设置灯光焦点
       light->SetPosition(0.875,1.6125,1);                     //设置灯光位置
                                                               //设置灯光强度SetIntensity()
                                                               //设置灯光锥角SetConeAngle()
                                                               //选择设置平行光或者聚光PositionalOff/On()
       renderer->AddLight(light);
       
       renderer->GetActiveCamera()->SetFocalPoint(0,0,0);      //设置相机焦点
       renderer->GetActiveCamera()->SetPosition(0,0,1);        //设置相机位置
       renderer->GetActiveCamera()->SetViewUp(0,1,0);          //设置图像正方向
       renderer->GetActiveCamera()->ParallelProjectionOn();    //平行投影/透视投影
       renderer->ResetCamera();
       renderer->GetActiveCamera()->SetParallelScale(4.0);

    }

    AmbientSpheres::~AmbientSpheres()
    {
       delete ui;
    }

     

    3 涉及主要知识点

    3.1 vtkCamera

    参考链接: https://vtk.org/doc/release/5.2/html/a00154.html

    https://blog.csdn.net/wzheng92/article/details/79935059

    https://blog.csdn.net/colddie/article/details/16948231

    image-20210622214423840

    vtkCamera在这里其实没有涉及太多,仅仅有SetFocalPointSetPositionSetViewUpParallelProjectionOnSetParallelScale

    摘自 :VTK图形图像开发进阶

    相机负责把三维场景投影到二维平面,如屏幕,相机投影是一体如下图所示。

    image-20210624182939495

    1. 相机位置,相机所处的位置,使用vtkCamera::SetPosition()方法设置

    2. 相机焦点,用vtkCamera::SetFocusPoint()方法设置,默认的焦点位置在世界坐标系的原点

    3. 朝上方向,朝上方向即那个方向为相机的朝上方向;就好比直立看东西,方向为头朝上,看到东西也是直立的,如果是倒立看某个东西,这是方向为头朝下,看到的东西就是倒立的,相机位置、相机焦点和朝上方向三个因素确定了相机的实际方向,即确定相机的视图。

    4. 投影方向,相机位置到相机焦点的向量方向即为投影方向。

    5. 投影方法,该要素用于确定Actor是如何映射到平面的,vtkCanmera定义了两种投影方法:一种是正交投影(Orthographic Projection),也叫平行投影(Parallel Projection),即进入相机的光线与投影方向是平行的;另一种是透视投影(Perspective Projection),即所有光线相交于一点。该投影方法最符合人类眼镜对于景物所产生的近大远小的视觉习惯。

    6. 视角,透视投影时需要指定相机的视角(View Angle),默认视角大小为30°,可以使用vtkCamera::SetViewAngle()方法设置

    7. 前后裁剪平面,裁剪平面与投影方向相交,一般与投影方向也是垂直的。裁剪平面主要用于评估Actor与相机距离的远近,只有在前后裁剪平面之间的Actor才是可见的,裁剪平面的位置可以用vtkCamera::SetClippongRange()方法设置

    vtkCamera除了提供设置与相机投影因素相关的方法之外,还提供了大量的控制相机运动的方法,如Dolly()、Azimuth()、Yaw()、Elevation()、Pitch()和Zoom()。相机运动方向示意图如下

    image-20210624185617647

     

    3.2 vtkLight

    参考链接:https://blog.csdn.net/zy2317878/article/details/78663264

    https://blog.csdn.net/zz187260382/article/details/81478351

    https://www.cnblogs.com/ybqjymy/p/13985559.html

     

    image-20210622222330854

    摘自:VTK图形图像开发进阶

    vtkLight可以分为位置灯光(Positional Light也叫聚光灯)和方向灯光(Direction Light)。位置灯光是光源位置在渲染场景中的某个位置,可以指定灯光的衰减值、锥角等;方向灯光及光源位置在无穷远,可以认为光线是平行的,比如自然界中的太阳。光源的位置和焦点的连线定义光线的方向,默认的vtkLight为方向灯光。

    vtkLight的常用方法如下:

    SetColor():设置灯光的颜色,以RGB的形式指定颜色。

    SetPosition():设置灯光位置。

    SetFocalPoint():设置灯光焦点。

    SetIntensity():设置灯光的强度。

    SetSwitch()/SwitchOn()/SwitchOff():打开或关闭对应的灯光。

     

    3.3 vtkPolyDataMapper

    参考链接:https://vtk.org/doc/nightly/html/classvtkPolyDataMapper.html

    https://blog.csdn.net/shenziheng1/article/details/54809989

    https://blog.csdn.net/kateyabc/article/details/84430985

    image-20210623092730133

    摘自:VTK图形图像开发进阶

    该类用于渲染多边形集合数据(vtkPolyData),派生自类vtkMapper,将输入的数据转换为几何图元(点、线、多边形)进行渲染。

    vtkPolyDataMapper::SetInputConnection(): VTK可视化管线的输入数据接口,对应的可视化管线的输出数据接口为GetOutputPort();在VTK5.0之前的版本使用SetInput()和GetOutput()作为输入输出接口。

    结合官方实例中的代码,

    sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection(sphere->GetOutputPort());          //把球体的输出接口链接到映射器的输入接口
     
     
    vtkSphereSource
    vtkPolyDataMapper
     

    3.4 vtkActor

    参考链接:https://vtk.org/doc/nightly/html/classvtkActor.html

    image-20210623183542476

    摘自VTK图形图像开发进阶

    该类派生自(vtkProp3D)vtkProp类,渲染场景中数据的可视化表达通过vtkProp的子类负责,比如实例中的Cbue,Cube的数据类型是vtkPolyData,数据要在场景中渲染时,不是直接把数据加入到渲染场景,而是以vtkProp的形式存在于渲染场景中。三维空间中渲染对象最常用的vtkProp子类有vtkActor(表达场景中的几何数据)和vtkVolume(表达场景中的体数据);二维空间中的数据则是用vtkActor2D表达,vtkProp子类扶着确定渲染场景中对象的位置、大小和方向信息;Prop依赖两个对象,一个是Mapper(vtkMapper)对象,负责存放数据和渲染信息;另一个是属性(vtkProperty)对象,负责控制颜色、不透明度等参数。另外vtkActor中还可以设置纹理(vtkTexrure)对象,用于纹理贴图。

    VTK定义了大量的Prop,如vtkImageActor(负责图像显示)和vtkPieChartActor(用来创建数组数据的饼图可视化表示形式)。其中有些Prop内部直接包含了控制显示的参数和待渲染数据的索引,因此并不需要额外的Property和Mapper对象,例如vtkAxisActor。vtkActor的子类vtkFollower可以自动更新方向信息,使其始终面向一个特定的相机,这样无论怎样旋转该对象都是可见的,例如三维场景中广告版或者文本。vtkActor的子类vtkLODActor可以自动改变自身的几何表达式来实现所需的交互帧率。vtkAssemble建立了各个Actor的层次结构以便在整个结构平移、旋转或缩放等变换是能够更合理的进行控制。

    vtkActor::SetMapper():该方法用于设置生成几何图元的Mapper,即链接一个Actor到可视化管线的末端(Mapper是可视化管线的末端)

    3.5 vtkRenderWindow

    参考链接:https://vtk.org/doc/nightly/html/classvtkRenderWindow.html

    https://blog.csdn.net/qq_38446366/article/details/82787847

    image-20210623183641345

    摘自VTK图形图像开发进阶

    vtkRenderWindow将操作系统与VTK渲染引擎链接到一起。不同平台下的vtkRenderWindow子类负责管理本地计算机系统中窗口创建和渲染过程。当使用VTK开发应用程序是,只需要使用与平台无关的vtkRenderWindow类,程序运行时,系统会自动替换为平台相关的vtkRenderWindow子类。比如Windows下运行程序时,实际创建的是vtkWin32OpenGLRenderWindow对象。

    vtkRenderWindow中包含了vtkRenderer集合、渲染参数,如立体显示(Strero)、反走样、运动模糊(Motion Blur)和焦点深度(Focal Depth)等。

    vtkRenderWindow::AddRenderer():该方法用于加入vtkRenderer对象。

    vtkRenderWindow::SetSize():该方法从vtkRenderWindow的父类vtkWindow继承而来,用于设置窗口的大小,以像素为单位。

    3.6 vtkRenderer

    参考链接:https://vtk.org/doc/nightly/html/classvtkRenderer.html

    https://www.cnblogs.com/AprilBlank/p/12900773.html

    image-20210623183756309

    摘自VTK图形图像开发进阶

    vtkRenderer负责管理场景的渲染过程。组织场景的对象包括Prop、相机(vtkCammera)和光照(vtkLight)都被整合到一个vtkRenderer对象中。一个vtkRenderWindow中可以有多个vtkRenderer对象,而这些vtkRenderer可以选在在窗口不同的矩形区域(即视口)或者覆盖整个窗口区域。

    vtkRenderer::AddActor():该方法用于将vtkProp类型的对象添加到渲染场景中。

    vtkRenderer::SetBackground():该方法是从vtkRenderer的父类vtkViewport继承的,用于设置渲染场景的背景颜色,用RGB格式设置,取值范围0.0~1.0.

    vtkViewport::SetBackgroung2()用于设置简便的另外一种颜色,但是要是背景颜色渐变生效或者关闭,必须调用以下方法

    vtkViewport::SetGradientBackground(bool):参数为0是关闭,反之为开

    vtkViewport::GradientBackgroundOn():该方法用于打开背景渐变效果,

    vtkViewport::GradientBackgroundOff():该方法用户关闭背景渐变效果。

    ★ 源码 ★

    在这里插入图片描述

     

    这里就要有人问了呀,这么优秀的代码,能不能分享下呀,当然可以呀,我不生产代码,我只是代码的搬运工,链接如下:

     

    自取:https://github.com/DreamLife-Jianwei/Qt-Vtk

     

    在这里插入图片描述

     


     

  • 相关阅读:
    Ui设计哪里有好的素材
    android重写view和viewgroup的区别
    笔记本电脑连接wifi有时候会自动断网提示有限的访问权限解决办法
    ADT 怎么删除logcat过滤规则
    Android开发在使用第三方推送的时候出现INSTALL_FAILED_VERSION_DOWNGRADE
    评论的延迟加载(转载)
    让Entity Framework支持MySql数据库(转载)
    Net4.0---AspNet中URL重写的改进(转载)
    Entity Framework 使用
    深入浅出JSONP--解决ajax跨域问题
  • 原文地址:https://www.cnblogs.com/DreamDog/p/15078887.html
Copyright © 2011-2022 走看看