首页 > 其他分享 >VTK随笔三:坐标系统、空间变换、VTK管线、VTK智能指针

VTK随笔三:坐标系统、空间变换、VTK管线、VTK智能指针

时间:2024-08-24 09:24:27浏览次数:9  
标签:include 对象 VTK 指针 坐标 随笔 管线 vtkNew

一、坐标系统 

  • Model坐标系统:定义模型时所采用的坐标系统,通常是局部的笛卡尔坐标系。
  • World坐标系统:是放置Actor的三维空间坐标系,Actor(vtkActor类)其中的一个功能就是负责将模型从Model坐标系统变换到World坐标系统。每一个模型可以定义自己的Model坐标系统,但World坐标系只有一个,每一个Actor必须通过放缩、旋转、平移等操作将Model坐标系变换到World坐标系。World坐标系同时也是相机和灯光所在的坐标系统。
  • View坐标系统:表示的是相机所看见的坐标系统。X、Y、Z轴取值为[-1, 1],X、Y值表示像平面上的位置,Z值表示到相机的距离。相机负责将World坐标系变换到View坐标系。
  • Display坐标系统:与View坐标系统类似,但是各坐标轴的取值不是[-1, 1],而是使用屏幕的像素值。屏幕上显示的不同窗口的大小会影响View坐标系的坐标值[-1, 1]到Display坐标系的映射。可以把不同的渲染场景放在同一个窗口进行显示,例如,在一个窗口里,分为左右两个渲染场景,这左右的渲染场景(vtkRenderer)就是不同的视口(Viewport)。

示例Viewport实现将一个窗口分为4个视口:

#include <QApplication>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkActor.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkCylinderSource.h>
#include <vtkSphereSource.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建四个不同形状的源对象
    vtkNew<vtkConeSource> cone;
    vtkNew<vtkCubeSource> cube;
    vtkNew<vtkCylinderSource> cylinder;
    vtkNew<vtkSphereSource> sphere;

    // 创建四个Mapper对象,将源对象连接到Mapper上
    vtkNew<vtkPolyDataMapper> coneMapper;
    coneMapper->SetInputConnection(cone->GetOutputPort());
    vtkNew<vtkPolyDataMapper> cubeMapper;
    cubeMapper->SetInputConnection(cube->GetOutputPort());
    vtkNew<vtkPolyDataMapper> cylinderMapper;
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphere->GetOutputPort());

    // 创建四个Actor对象,并将Mapper连接到Actor上
    vtkNew<vtkActor> coneActor;
    coneActor->SetMapper(coneMapper);
    vtkNew<vtkActor> cubeActor;
    cubeActor->SetMapper(cubeMapper);
    vtkNew<vtkActor> cylinderActor;
    cylinderActor->SetMapper(cylinderMapper);
    vtkNew<vtkActor> sphereActor;
    sphereActor->SetMapper(sphereMapper);

    // 创建四个Renderer对象,并设置每个Renderer的背景颜色和视口
    vtkNew<vtkRenderer> renderer1;
    renderer1->AddActor(coneActor);
    renderer1->SetBackground(1.0,0.0,0.0);
    renderer1->SetViewport(0.0,0.0,0.5,0.5);
    vtkNew<vtkRenderer> renderer2;
    renderer2->AddActor(cubeActor);
    renderer2->SetBackground(0.0,1.0,0.0);
    renderer2->SetViewport(0.5,0.0,1.0,0.5);
    vtkNew<vtkRenderer> renderer3;
    renderer3->AddActor(cylinderActor);
    renderer3->SetBackground(0.0,0.0,1.0);
    renderer3->SetViewport(0.0,0.5,0.5,1.0);
    vtkNew<vtkRenderer> renderer4;
    renderer4->AddActor(sphereActor);
    renderer4->SetBackground(1.0,1.0,0.0);
    renderer4->SetViewport(0.5,0.5,1.0,1.0);

    // 创建RenderWindow对象,并将四个Renderer添加到RenderWindow中
    vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer1);
    renderWindow->AddRenderer(renderer2);
    renderWindow->AddRenderer(renderer3);
    renderWindow->AddRenderer(renderer4);
    QVTKOpenGLNativeWidget w;
    w.setRenderWindow(renderWindow);

    w.show();
    return a.exec();
}

效果如下:

vtkCoordinate可以用来表示坐标系统,其内部提供了函数接口来定义坐标系统: 

SetCoordinateSystemToDisplay()
SetCoordinateSystemToNormalizedDisplay()
SetCoordinateSystemToViewport()
SetCoordinateSystemToNormalizedViewport()
SetCoordinateSystemToView()
SetCoordinateSystemToWorld()

另外,该类还实现这些坐标系统之间的转换,例如下述代码实现了归一化窗口坐标与窗口坐标之间的转换: 

vtkNew<vtkCoordinate> coordinate;
coordinate->SetCoordinateSystemToNormalizedDisplay();
coordinate->SetValue(.5, .5, 0);	// 屏幕中心

int* val = coordinate->GetComputedDisplayValue(renderer);	// 窗口坐标转换

二、空间变换 

        在三维空间里定义的三维模型,最后显示时都是投影到二维平面,比如在屏幕上显示三维到二维的投影包括透视投影(PerspectiveProjection)和正交投影(Orthogonal Projection)。正交投影也叫平行投影。

        VTK里与空间变换有关的类有vtkTransform2D,vtkTransform,vtkPerspectiveTransform,vtkGeneralTransform,vtkTransformFilter,vtkMatrix4×4等。例如下面代码实现了vtkActor对象的空间变换: 

vtkNew<vtkTransform> transform;
transform->PostMultiply();	// 设置右乘计算变换矩阵。
transform->RotateZ(40);	//旋转
transform->Translate(10, 0, 0);	// 平移
cylinderActor->SetUserTransform(transform);

 三、VTK管线

        vtkProp、vtkAbstractMapper、vtkProperty、vtkCamera、vtkLight、vtkRenderer、vtkRendererWindow、vtkRenderWindowInteractor、vtkTransform、vtkLookupTable等等类都是与数据显示或渲染相关的,它们构成了VTK的渲染引擎(Rendering Engine)。渲染引擎主要负责数据的可视化表达,是VTK里的两个重要概念之一,而另一个重要概念就是可视化管线(Visualization Pipeline)

        可视化管线是指用于获取或创建数据、处理数据以及把数据写入文件或者把数据传递给渲染引擎进行显示,这样的一种结构在VTK里就称为可视化管线。数据对象(Data Object)、处理对象(Process Object)和数据流方向(Direction of Data Flow)是可视化管线的三个要素。每个VTK程序都会有可视化管线存在。

 

        Source是指用于创建数据(如vtkCylinderSource)或者读取数据(如vtkBMPReader、vtkStructuredPointsReader等)类的统称,即VTK的数据源。Source输出的数据作为Filter的输入,经Filter处理以后(可以经过多个Filter处理),生成新的数据。Filter的输出可以直接写入文件,或者经Mapper变换后传入渲染引擎进行渲染、显示,结束可视化管线。上图的箭头方向即为VTK里数据流流动的方向。

        可视化管线的三要素分别为数据对象、处理对象和数据流方向,Source、Filter和Mapper一起构成了处理对象,它们的区别是基于数据流的初始化、维持和终止。根据数据的生成方式,Source可以分为程序源对象(Procedural,如vtkCylinderSource,通过程序代码生成相关的数据)和读取源对象(Reader,如vtkBMPReader,从外部文件中导入数据)。

四、智能指针

   智能指针会自动管理引用计数的增加与减少。

c++中智能指针:

1:unique_ptr :这是一种独占式的智能指针;确保在其使用的生命周期内只有一个指针可以指向被

分配的对象;当其被销毁的时候,其管理的对象也被销毁。

2:share_ptr : 允许多个智能指针共享对同一资源的所有权。它使用引用计数来跟踪资源的引用次数,当最后一个std::shared_ptr离开作用域时,资源会被释放

3:weak_ptr : 允许多个智能指针共享对同一资源的所有权。它使用引用计数来跟踪资源的引用次数,当最后一个std::shared_ptr离开作用域时,资源会被释放。

        VTK中智能指针类为vtkSmartPointer。VTKSmartPointer是一个模板类,继承自VTKSmartPointerBase类。VTKSmartPointerBase中定义了一个vtkObjectBase类型的指针对象Object,用于存储智能指针中实际生成的对象。智能指针定义为:

vtkSmartPointer<vtkCamera> camera =  vtkSmartPointer<vtkCamera>::New();   //引用计数为1

        VTKSmartPointer中定义了静态函数New()来生成一个智能指针对象。该函数的核心在于:会根据模板参数类型来生成一个对象,并将其保存在基类VTKSmartPointerBase的成员变量Object中。

        VTKSmartPointer中重载了“->”操作符,返回实际模板参数类型的对象,因此可以方便地访问对象的成员函数,如camera->setFocusPosition(0,0,0)。

        VTKSmartPointer重载了“=”操作符,可以在VTKSmartPointer对象之间进行赋值。在赋值过程中,VTKSmartPointer会自动控制其内部对象指针Object的引用计数加1。

例如:

vktSmartPointer<vtkCamera> camera1 =vtkSmartPointer<vtkCamera>::New();
vtkSmartPointer<vtkCamera> camera2 = camera1;

        需要注意的是,此时camera1和camera2的引用计数都等于2。
        过程为:首先camera1的vtkCamera对象Object调用Register()函数,自动将引用计数加1,然后将camera2的Object指向camera1的Object对象。
        当一个智能指针对象的生命周期结束时,会自动调用其析构函数释放内存。在析构函数中会调用其内部对象Object的UnRegister()函数修改引用计数。如果此时的引用计数为0,Object对象会自动释放内存。

 

标签:include,对象,VTK,指针,坐标,随笔,管线,vtkNew
From: https://blog.csdn.net/u012959478/article/details/141463096

相关文章

  • 2024.8.23随笔
    前言先说明我前两天没有写随笔的原因。第一天(8.21)是因为我当时写完一篇题解后没有来得及写总结,然后我妈就说要带我去九眼桥那片去转转,最后我们十点半才回到家。昨天是因为我想复习一下当日内容,先去写了主席树,然后做了一道题单里的dp加贪心题,然后特判的时候没有return0交上去......
  • VTK随笔二:三维场景的基本要素
    一、灯光        剧场里有各式各样的灯光,三维渲染场景中也一样,可以有多个灯光存在。灯光和相机是三维渲染场景必备的要素,如果没有指定,vtkRenderer会自动创建默认的灯光和相机。VTK里用类vtkLight来表示渲染场景中的灯光。与现实中的灯光类似,VTK中的vtkLight示例也可以......
  • 随笔-firefox-配置
    内存泄漏https://support.mozilla.org/zh-CN/kb/内存消耗严重#w_zhong-xin-qi-dong-firefoxfirefox浏览器设置书签打开新网址时,想要打开一个新的标签(tab),而不是覆盖掉原来网页,可以这样设置:-地址栏中输入about:config-搜索browser.tabs.loadBookmarksInTabs,会发现值为fa......
  • 2024.8.20随笔
    树分治这部分知识是我的弱项,之前学习时也没有听懂。此前碰到这类题也会想尽办法用数据结构代替,但发现非常不可做,代码复杂程度极高。而且感觉之前我连普通的区间分治都不太熟练,没有学好的信心。现在学习过后好了很多,理解了分治的核心(也许),就是每次到分治的关键点就去统计包含关键点......
  • 银河麒麟V10入门学习随笔(一)
    操作系统:银河麒麟高级服务器操作系统V10  1.前置学习资料1.1.基本的linux的命令~cd:https://blog.csdn.net/2302_76410765/article/details/1297665921.2.防火墙配置指令:https://blog.csdn.net/weixin_43829023/article/details/132623979 2.Todesk远程工具安装2.1.......
  • VTK—vtkImplicitFunction 隐函数
    通过这个例子可以直观理解隐函数是什么、在空间中怎么分布、怎么布尔运算。1.完整代码#include<vtkBox.h>#include<vtkNew.h>#include<vtkActor.h>#include<vtkSphere.h>#include<vtkAutoInit.h>#include<vtkProperty.h>#include<vtkRenderer.h>#include<vtkIm......
  • 2024.8.19随笔
    关于迟到这么多天就迟到一次就被抓了个正着/jk今天刚好错过地铁,后来在地铁上碰见了int08,本来他和我都坐的上一班结果今天都迟到了,然后在路上就一直讨论李老和hfu抓住我们的概率。本来我想今天迟到就算了,毕竟刚好错过地铁下一班要等好一会没办法,但int08认为他有很大概率被抓......
  • python随笔day4
    python实战面试题目1、列出你知道的http协议的状态码,说出表示什么意思?1xx临时响应2xx成功3xx重定向4xx请求错误5xx服务器错误我经常遇到的:200成功、404未找到网页文件、403服务器拒绝请求(禁止)、304未修改(自从上次请求后该网页就未修改过)、500服务器内部错误、503服务器......
  • vtk范围映射 -1 ~ +1 映射到 0 ~ 255
    来源:https://www.ilikebigbits.com/2015_02_05_remap.html inlinefloatremap(floatx,floatin_min,floatin_max,floatout_min,floatout_max){floatt=(x-in_min)/(in_max-in_min);returnlerp(out_min,out_max,t);}......
  • 真随笔
    要想成为优秀的人可真困难啊比如现在我一点都不想看雅思了但是还是要继续看为什么呢因为我想尽量一次考过然后拿到游戏机唉真的很想要游戏机我一点都不想看雅思了但是要要再学一会可能如果不学雅思我也不知道我应该干什么吧总之学习总不会出错的那些个大学霸可真是厉害......