找回密码
 立即注册
首页 业界区 业界 VTK开发笔记(三):熟悉VTK开发流程,编写球体,多半透 ...

VTK开发笔记(三):熟悉VTK开发流程,编写球体,多半透明球体Demo

森萌黠 5 小时前
前言

  开始vtk实战,了解vtk的一些基本框架,通过代码是最好的方式。
  本篇实现一个vtk实现多球体半透明的Demo。
 Demo

  
1.png

  
2.gif

  
3.gif

  下面是osg存在的问题:
  
4.gif

 坐标系

  计算机图形学里常用的坐标系统主要有4中,分别是model坐标系统、world坐标系统、view坐标系统和Display坐标系统。
  
5.png


  • Model坐标系统:定义模型时所采用的坐标系统,笛卡尔坐标系。
  • World坐标系统:actor(渲染模型)的三维控件坐标系,就是世界坐标系。每一个  actor可以通过缩放、旋转、平移等操作讲model坐标系放入world,就是三维相对坐标系变换。World坐标系也是相机和灯光所在的坐标系。
  • View坐标系统:相机能看见的坐标系统,XYZ轴取值都为[-1,1],表示平面上的位置,Z值表示到相机的距离。
  • Display坐标系统:屏幕坐标系,坐标轴取值就是像素。
      
    6.png

 可视化管线渲染流程

  
  数据源->多线段数据映射->【演员->渲染器->渲染窗口】。
  复杂一点的渲染管线:
  
7.png

  
8.png


  • Source:用于创建数据或者读取数据,跟字面意义一样是数据源。Source可作为Filter的输入,进行数据的过滤,生成新的数据。
  • Filter:特定规则进行处理过滤,比如轮廓线、比如剖面,更多的后续再讲究。
  • Mapper:映射器,更多的后续再讲究。
 智能指针

  智能指针会自动管理引用计数的增加或者减少,这个概念在编程语言中有,在ogs中也有,且使用方式基本一致。当指针{}作用域过了,其智能指针实际还存在,只有在其计数为0时,此时没有对象使用它了,则会销毁。
  1. vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
复制代码
  智能指针类型可以作为函数返回值,正确的写法如下:
  1. vtkSmartPointer<vtkImageData> MyFunction()
  2. {
  3.     vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
  4.     return myObject;
  5. }
复制代码
  函数MyFunction()的返回值是通过复制的方式,讲数据赋值给调用的变量,因此该数据的引用计数保持不变,而且函数MyFunction里的myObject也不会删除。
  反过来,要是函数里面定义是智能指针类型,返回类型是指针,其计数会减去1,示例如下:
  1. vtkImageData * MyFunction()
  2. {
  3.     vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
  4. return myObject;
  5. }
  6. vtkImageData *pImageData = MyFunction();
复制代码
  
  (注意:这里有点拗口难理解,为什么返回指针就-1,osg处理这块是无所谓的,混合了代码做过osg的测试,并不会崩溃,但是vtk说是会崩溃)
  Vtk的智能指针,还有一个注意点,就是一个智能指针的对象,在第一次赋值的时候,智能指针会分配对象相关的内存,初始化引用计数,后续不能再把这个指针更换对象,否则会引用计数出错,
  以上这几个点,都要注意,其在osg的智能指针中没这些讲究,比较完善,但是vtk如果使用智能指针,就要遵循这些,会轻微增加代码,主要是函数返回类型和赋值给的变量类型定义这两块为主。
 绘制一个球体

步骤一:创建球体数据源

  
9.png

步骤二:创建多边形映射器

  
10.png

步骤三:创建演员类(类似osg模型结点)

  
11.png

步骤四:创建渲染器

  
12.png

步骤五:设置渲染器到渲染窗口

  
13.png

 源码

VTKManager.cpp
  1. vtkSmartPointer<vtkSphereSource> VTKManager::createSphereSource(double x, double y, double z, double r, int vNum, int hNum)
  2. {
  3.     /*
  4.      * 继承关系:
  5.      * vktObject ---> vtkAlhorithm ---> vtkPolyDataAlgorithm ---> vtkSphereSource
  6.      * 渲染关系:
  7.      * vtkSphereSource ---> vtkPolyDataMapper ---> vtkActor
  8.      */
  9.     // 步骤一:智能指针定义
  10.     vtkSmartPointer<vtkSphereSource> pSphereSource;
  11.     // 步骤二:智能指针实例化
  12.     pSphereSource = vtkSmartPointer<vtkSphereSource>::New();
  13.     // 步骤三:设置球心坐标
  14.     pSphereSource->SetCenter(x, y, z);
  15.     // 步骤三:设置球体的半径
  16.     pSphereSource->SetRadius(r);
  17.     // 步骤四:设置球体的纬度分辨率,即球体纵向的切片数量(垂直/纵向精细度)
  18.     pSphereSource->SetPhiResolution(vNum);
  19.     // 步骤五:设置球体的经度分辨率,即球体横向的切片数量(横向/水平精细度)
  20.     pSphereSource->SetThetaResolution(hNum);
  21.     return pSphereSource;
  22. }
  23. vtkSmartPointer<vtkPolyDataMapper> VTKManager::createPolyDataMapper(vtkSphereSource * pSphereSource)
  24. {
  25.     // 步骤一:智能指针定义
  26.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper;
  27.     // 步骤二:智能指针实例化
  28.     pPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  29.     // 步骤三:设置
  30.     pPolyDataMapper->SetInputConnection(pSphereSource->GetOutputPort());
  31.     return pPolyDataMapper;
  32. }
  33. vtkSmartPointer<vtkActor> VTKManager::createActor(vtkPolyDataMapper *pPolyDataMapper, double r, double g, double b)
  34. {
  35.     // 步骤一:智能指针定义
  36.     vtkSmartPointer<vtkActor> pActor;
  37.     // 步骤二:智能指针实例化
  38.     pActor = vtkSmartPointer<vtkActor>::New();
  39.     // 步骤三:设置映射器
  40.     pActor->SetMapper(pPolyDataMapper);
  41.     // 步骤四:设置颜色
  42.     pActor->GetProperty()->SetColor(r, g, b);
  43.     return pActor;
  44. }
  45. vtkSmartPointer<vtkActor> VTKManager::createActor(vtkPolyDataMapper *pPolyDataMapper, double r, double g, double b, double a)
  46. {
  47.     // 步骤一:智能指针定义
  48.     vtkSmartPointer<vtkActor> pActor;
  49.     // 步骤二:智能指针实例化
  50.     pActor = vtkSmartPointer<vtkActor>::New();
  51.     // 步骤三:设置映射器
  52.     pActor->SetMapper(pPolyDataMapper);
  53.     // 步骤四:设置颜色
  54.     pActor->GetProperty()->SetColor(r, g, b);
  55.     // 步骤五:设置透明度
  56.     pActor->GetProperty()->SetOpacity(a);
  57.     return pActor;
  58. }
  59. vtkSmartPointer<vtkRenderer> VTKManager::createRenderer(vtkActor *pActor)
  60. {
  61.     // 步骤一:智能指针定义
  62.     vtkSmartPointer<vtkRenderer> pRenderer;
  63.     // 步骤二:智能指针实例化
  64.     pRenderer = vtkSmartPointer<vtkRenderer>::New();
  65.     // 步骤三:设置映射器
  66.     pRenderer->AddActor(pActor);
  67.     return pRenderer;
  68. }
  69. vtkSmartPointer<vtkRenderer> VTKManager::createRenderer(std::vector<vtkActor *> listPActor)
  70. {
  71.     // 步骤一:智能指针定义
  72.     vtkSmartPointer<vtkRenderer> pRenderer;
  73.     // 步骤二:智能指针实例化
  74.     pRenderer = vtkSmartPointer<vtkRenderer>::New();
  75.     // 步骤三:设置映射器
  76.     for(int index = 0; index < listPActor.size(); index++)
  77.     {
  78.         pRenderer->AddActor(listPActor.at(index));
  79.     }
  80.     return pRenderer;
  81. }
复制代码
VTKWidget.cpp
  1. void VTKWidget::test_demo2_1_createSphere()
  2. {
  3.     // 步骤一:创建球体数据源
  4.     vtkSmartPointer<vtkSphereSource> pSphereSource1 =
  5.             VTKManager::createSphereSource(0, 0, 0, 10, 100, 100);
  6.     vtkSmartPointer<vtkSphereSource> pSphereSource2 =
  7.             VTKManager::createSphereSource(-20, 0, 0, 10, 100, 100);
  8.     vtkSmartPointer<vtkSphereSource> pSphereSource3 =
  9.             VTKManager::createSphereSource(20, 0, 0, 10, 100, 100);
  10.     vtkSmartPointer<vtkSphereSource> pSphereSource4 =
  11.             VTKManager::createSphereSource(0, 20, 0, 10, 100, 100);
  12.     vtkSmartPointer<vtkSphereSource> pSphereSource5 =
  13.             VTKManager::createSphereSource(0, -20, 0, 10, 100, 100);
  14.     vtkSmartPointer<vtkSphereSource> pSphereSource6 =
  15.             VTKManager::createSphereSource(0, 0, 20, 10, 100, 100);
  16.     vtkSmartPointer<vtkSphereSource> pSphereSource7 =
  17.             VTKManager::createSphereSource(0, 0, -20, 10, 100, 100);
  18.     // 步骤二:创建多边形映射器
  19.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper1 =
  20.             VTKManager::createPolyDataMapper(pSphereSource1);
  21.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper2 =
  22.             VTKManager::createPolyDataMapper(pSphereSource2);
  23.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper3 =
  24.             VTKManager::createPolyDataMapper(pSphereSource3);
  25.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper4 =
  26.             VTKManager::createPolyDataMapper(pSphereSource4);
  27.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper5 =
  28.             VTKManager::createPolyDataMapper(pSphereSource5);
  29.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper6 =
  30.             VTKManager::createPolyDataMapper(pSphereSource6);
  31.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper7 =
  32.             VTKManager::createPolyDataMapper(pSphereSource7);
  33.     // 步骤三:创建演员
  34.     vtkSmartPointer<vtkActor> pActor1 =
  35.             VTKManager::createActor(pPolyDataMapper1, 1.0, 0.0, 0.0, 0.25);
  36.     vtkSmartPointer<vtkActor> pActor2 =
  37.             VTKManager::createActor(pPolyDataMapper2, 0.0, 1.0, 0.0, 0.25);
  38.     vtkSmartPointer<vtkActor> pActor3 =
  39.             VTKManager::createActor(pPolyDataMapper3, 0.0, 0.0, 1.0, 0.25);
  40.     vtkSmartPointer<vtkActor> pActor4 =
  41.             VTKManager::createActor(pPolyDataMapper4, 1.0, 1.0, 0.0, 0.25);
  42.     vtkSmartPointer<vtkActor> pActor5 =
  43.             VTKManager::createActor(pPolyDataMapper5, 0.0, 1.0, 1.0, 0.25);
  44.     vtkSmartPointer<vtkActor> pActor6 =
  45.             VTKManager::createActor(pPolyDataMapper6, 1.0, 0.0, 1.0, 0.25);
  46.     vtkSmartPointer<vtkActor> pActor7 =
  47.             VTKManager::createActor(pPolyDataMapper7, 1.0, 1.0, 1.0, 0.25);
  48.     // 步骤四:创建渲染器
  49.     std::vector<vtkActor *> listActor;
  50.     listActor.push_back(pActor1);
  51.     listActor.push_back(pActor2);
  52.     listActor.push_back(pActor3);
  53.     listActor.push_back(pActor4);
  54.     listActor.push_back(pActor5);
  55.     listActor.push_back(pActor6);
  56.     listActor.push_back(pActor7);
  57.     vtkSmartPointer<vtkRenderer> pRenderer =
  58.             VTKManager::createRenderer(listActor);
  59.     // 步骤五:渲染器添加到QVTKWidget渲染
  60.     _pQVTKWidget->GetRenderWindow()->AddRenderer(pRenderer);
  61. }
  62. void VTKWidget::test_demo2_2_createSphere()
  63. {
  64.     // 步骤一:创建球体数据源
  65.     vtkSmartPointer<vtkSphereSource> pSphereSource1 =
  66.             VTKManager::createSphereSource(0, 0, 0, 10, 100, 100);
  67.     vtkSmartPointer<vtkSphereSource> pSphereSource2 =
  68.             VTKManager::createSphereSource(-20, 0, 0, 10, 100, 100);
  69.     vtkSmartPointer<vtkSphereSource> pSphereSource3 =
  70.             VTKManager::createSphereSource(20, 0, 0, 10, 100, 100);
  71.     vtkSmartPointer<vtkSphereSource> pSphereSource4 =
  72.             VTKManager::createSphereSource(0, 20, 0, 10, 100, 100);
  73.     vtkSmartPointer<vtkSphereSource> pSphereSource5 =
  74.             VTKManager::createSphereSource(0, -20, 0, 10, 100, 100);
  75.     vtkSmartPointer<vtkSphereSource> pSphereSource6 =
  76.             VTKManager::createSphereSource(0, 0, 20, 10, 100, 100);
  77.     vtkSmartPointer<vtkSphereSource> pSphereSource7 =
  78.             VTKManager::createSphereSource(0, 0, -20, 10, 100, 100);
  79.     // 步骤二:创建多边形映射器
  80.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper1 =
  81.             VTKManager::createPolyDataMapper(pSphereSource1);
  82.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper2 =
  83.             VTKManager::createPolyDataMapper(pSphereSource2);
  84.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper3 =
  85.             VTKManager::createPolyDataMapper(pSphereSource3);
  86.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper4 =
  87.             VTKManager::createPolyDataMapper(pSphereSource4);
  88.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper5 =
  89.             VTKManager::createPolyDataMapper(pSphereSource5);
  90.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper6 =
  91.             VTKManager::createPolyDataMapper(pSphereSource6);
  92.     vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper7 =
  93.             VTKManager::createPolyDataMapper(pSphereSource7);
  94.     // 步骤三:创建演员
  95.     vtkSmartPointer<vtkActor> pActor1 =
  96.             VTKManager::createActor(pPolyDataMapper1, 1.0, 1.0, 1.0, 0.25);
  97.     vtkSmartPointer<vtkActor> pActor2 =
  98.             VTKManager::createActor(pPolyDataMapper2, 1.0, 1.0, 1.0, 0.25);
  99.     vtkSmartPointer<vtkActor> pActor3 =
  100.             VTKManager::createActor(pPolyDataMapper3, 1.0, 1.0, 1.0, 0.25);
  101.     vtkSmartPointer<vtkActor> pActor4 =
  102.             VTKManager::createActor(pPolyDataMapper4, 1.0, 1.0, 1.0, 0.25);
  103.     vtkSmartPointer<vtkActor> pActor5 =
  104.             VTKManager::createActor(pPolyDataMapper5, 1.0, 1.0, 1.0, 0.25);
  105.     vtkSmartPointer<vtkActor> pActor6 =
  106.             VTKManager::createActor(pPolyDataMapper6, 1.0, 1.0, 1.0, 0.25);
  107.     vtkSmartPointer<vtkActor> pActor7 =
  108.             VTKManager::createActor(pPolyDataMapper7, 1.0, 1.0, 1.0, 0.25);
  109.     // 步骤四:创建渲染器
  110.     std::vector<vtkActor *> listActor;
  111.     listActor.push_back(pActor1);
  112.     listActor.push_back(pActor2);
  113.     listActor.push_back(pActor3);
  114.     listActor.push_back(pActor4);
  115.     listActor.push_back(pActor5);
  116.     listActor.push_back(pActor6);
  117.     listActor.push_back(pActor7);
  118.     vtkSmartPointer<vtkRenderer> pRenderer =
  119.             VTKManager::createRenderer(listActor);
  120.     // 步骤五:渲染器添加到QVTKWidget渲染
  121.     _pQVTKWidget->GetRenderWindow()->AddRenderer(pRenderer);
  122. }
复制代码
 工程模板v1.1.0

  
14.png


来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除
您需要登录后才可以回帖 登录 | 立即注册