当前位置:   article > 正文

GaussianSplat_gaussian-splatting源码

gaussian-splatting源码

GaussianSplat

The code

首先,新建一个GaussianSplat.cpp文件并将以下代码复制进去:

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkContourFilter.h>
#include <vtkGaussianSplatter.h>
#include <vtkSphereSource.h>

#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

int main(int, char *[])
{
    // Create points on a sphere
    vtkSmartPointer<vtkSphereSource> sphereSource =
        vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->Update();

    vtkSmartPointer<vtkPolyData> polydata =
        vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(sphereSource->GetOutput()->GetPoints());

    vtkSmartPointer<vtkGaussianSplatter> splatter =
        vtkSmartPointer<vtkGaussianSplatter>::New();
#if VTK_MAJOR_VERSION <= 5
    splatter->SetInput(polydata);
#else
    splatter->SetInputData(polydata);
#endif
    splatter->SetSampleDimensions(50, 50, 50);
    splatter->SetRadius(0.5);
    splatter->ScalarWarpingOff();

    vtkSmartPointer<vtkContourFilter> surface =
        vtkSmartPointer<vtkContourFilter>::New();
    surface->SetInputConnection(splatter->GetOutputPort());
    surface->SetValue(0, 0.01);

    // Create a mapper and actor
    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(surface->GetOutputPort());

    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    // Visualize
    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderer->AddActor(actor);
    renderer->SetBackground(1, 1, 1); // Background color white

    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

The explanation

  现在,让我们来一步一步地分析代码。

    vtkSmartPointer<vtkSphereSource> sphereSource =
        vtkSmartPointer<vtkSphereSource>::New();
  • 1
  • 2
vtkSmartPointer
  • 定义:

  智能指针会自动管理引用计数(引用计数是个简单的垃圾回收体系,它允许多个有相同值的对象共享这个值,因此不需要构造和析构这个值的副本,从而达到节省内存的目的)的增加与减少,若检测到某对象的引用计数值减少为0,则会自动释放该对象的资源,从而达到自动管理内存的目的。

  • 用法:

  vtkSmartPointer是一个模板类,所需要的模板参数就是待创建的对象的类名,如:

vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
  • 1

  不能把对象的原始指针赋值给智能指针,下面代码编译时可以通过,但程序退出时会有内存泄漏,因为智能指针无法自动释放该对象的内存:

vtkSmartPointer<vtkImageData> image = vtkImageData::New();
  • 1
vtkSphereSource

  该类派生于vtkPolyDataAlgorithm,生成的数据类型就是vtkPolyData,它主要是生成一个中心在渲染场景原点的球体,球体的半径、面数(resolution)都可以任意指定。

    vtkSphereSource::SetRadius() // 默认为0.5
    vtkSphereSource::SetResolution() // 默认为8
  • 1
  • 2

    vtkSmartPointer<vtkPolyData> polydata =
        vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(sphereSource->GetOutput()->GetPoints());
  • 1
  • 2
  • 3
vtkPolyData
  • 定义:

  多边形数据集主要由几何结构数据、拓扑结构数据和属性数据组成,由顶点(Vertex)、多顶点(Polyvertex)、线(Line)、折线(Polyline)和三角形条带(Triange Strip)等单元构成的VTK中常用的数据结构之一,可以表示小到一个点、一条线,大到一个模型、一个场景等。

  • 用法:

  用户可以显示地定义vtkPolyData,首先需要定义一个点集合(vtkPoints)和一个单元(vtkCellArray)集合,点集合定义了vtkPolyData的几何结构,而单元集合则定义了点的拓扑结构。点集合由坐标来定义(InsertNextPoint()),单元集合则由点的索引而非坐标来定义(GetPointIds()->SetId()),这样能够减少数据的存储空间。点数据和单元数据都定义完毕,通过void SetPoints(vtkPoints*)void SetPolys(vtkCellArray*)将其添加至vtkPolyData中。


    // Create a mapper and actor
    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(surface->GetOutputPort());

    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
vtkPolyDataMapper

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

  vtkPolyDataMapper::SetInputConnection():VTK可视化管线的输入数据接口,对应的可视化管线的输出数据接口为GetOutputPort();VTK 5.0之前的版本使用SetInput()GetOutput()作为输入输出接口,VTK 5.X版本保留了对这两个接口的支持。

vtkActor

  该类派生自vtkProp类,渲染场景中数据的可视化表达(包括对象的位置、大小和方向等信息)通过vtkProp的子类负责。比如本例中要渲染一个球体,球体的数据类型是vtkPolyData,数据要在场景中渲染时,不是直接把数据加入渲染场景,而是以vtkProp的形式存在于渲染场景中。三维空间中渲染对象最常用的vtkProp子类有vtkActor(表达场景中的几何数据)和vtkVolume(表达场景中的体数据);二维空间中的数据则是用vtkActor2D表达。

  Prop依赖于两个对象:一个是Mapper(vtkMapper)对象,负责存放数据和渲染信息;另一个是属性(vtkProperty)对象,负责控制颜色、不透明度等参数。

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


    // Visualize
    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();

    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderer->AddActor(actor);
    renderer->SetBackground(1, 1, 1); // Background color white

    renderWindow->Render();
    renderWindowInteractor->Start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
vtkRenderWindow

  将操作系统与VTK渲染引擎连接到一起。vtkRenderWindow中包含了vtkRenderer集合、渲染参数等。

  vtkRenderWindow->AddRenderer():用于加入vtkRenderer对象。

  vtkRenderWindow->SetSize():用于设置窗口的大小,以像素为单位。

vtkRenderer

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

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

  vtkRenderer::SetBackground():用于设置渲染场景的背景颜色,用RGB的格式设置,三个分量的取值为0.0~1.0。(0.0,0.0,0.0)为黑色,(1.0,1.0,1.0)为白色。

vtkRenderWindowInteractor

  提供平台独立的响应鼠标、键盘和时钟事件的交互机制,通过VTK的观察者/命令模式将监听到的特定平台的鼠标、键盘和时钟事件交由vtkInteractorObserve或其子类(如vtkInteractorStyle)进行处理。vtkInteractorStyle等监听这些消息并进行处理以完成旋转、拉伸和缩放等运动控制。

  vtkRenderWindowInteractor::SetRenderWindow():用于设置渲染窗口,消息是通过渲染窗口捕获到的,所以必须给交互器对象设置渲染窗口。

  vtkRenderWindowInteractor::SetInteractorStyle():用于定义交互器样式,默认为vtkInteractorStyleSwitch。

  vtkRenderWindowInteractor::Initialize():为处理窗口事件做准备,交互器工作之前必须先调用这个方法进行初始化,但是官网上的例子代码(本例)并没有做这一步

  vtkRenderWindowInteractor::Start():开始进入事件响应循环,交互器处于等待状态,等待用户交互事件的发生。


可以将以上示例看作一个舞台剧演出。整个剧院就好比VTK程序的渲染窗口(vtkRenderWindow);舞台就相当于渲染场景(vtkRenderer);而演员就是程序中的Actor,台上演员与台下观众的互动可以看作与应用程序的交互(vtkRenderWindowInteractor);演员与观众的互动方式有很多种,就好比程序中的交互器样式(vtkInteractorStyle);对于舞台上的演员,观众可以通过他们的容貌打扮辨认,就相当于程序中vtkActor的不同属性(vtkProperty);每一个vtkActor的数据和渲染信息存储在一个vtkMapper对象中,负责将原始数据转换为渲染所需的图元数据。

Compiling and running the program

  复制如下语句到你的 CMakeLists.txt 文件中:

cmake_minimum_required(VERSION 2.6)

PROJECT(GaussianSplat)

FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})

ADD_EXECUTABLE(GaussianSplat GaussianSplat.cxx)
TARGET_LINK_LIBRARIES(GaussianSplat ${VTK_LIBRARIES})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  完成后即可用CMake进行编译,生成相应的可执行文件后就可以运行了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/612223
推荐阅读
相关标签
  

闽ICP备14008679号