Qt&Vtk-004-AmbientSpheres

举报
DreamLife 发表于 2021/07/30 12:49:40 2021/07/30
【摘要】 欢迎来到我的博客,希望这篇文章对你有所帮助,如果觉得不错,请点赞搜藏哈。 Qt&Vtk-AmbientSpheres 1 效果展示 2源码 2.1 ambientspheres.h 2.2 ambientspheres.cpp 3 涉及主要知识点 3.1 vtkCamera 3.2 vtkLight 3.3 vtkPolyDataMapper 3.4 vtkActor 3.5 vtkRend...

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

在这里插入图片描述


博客签名2021

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。