• VTK 图形进阶_vtkPolyData属性数据


    1.从图形着色说起

    前一个实验显示结果中的图像是白色的,而图形颜色与vtkPolyData属性数据息息相关。由于并未指定任何颜色和属性数据,因此在显示时默认以白色显示。
    属性数据包括点属性和单元属性。可以为vtkPolyData的点数据和单元数据分别指定属性数据。
    属性数据可以是标量,如点的曲率;可以是向量,如点或者单元的法向量;也可以是张量,主要在流场中较为常见。
    颜色可以直接作为一种标量属性数据,设置到相应的点或者单元数据中,这也是最直接的一种图形着色方式。
    下面的实例代码仅是对上例图形进行着色:
      1 #include <vtkAutoInit.h>
      2 VTK_MODULE_INIT(vtkRenderingOpenGL);
      3  
      4 #include <vtkSmartPointer.h>
      5 #include <vtkPoints.h>
      6 #include <vtkPolygon.h>
      7 #include <vtkTriangle.h> 
      8 #include <vtkCellArray.h>
      9 #include <vtkPolyData.h>
     10 #include <vtkUnsignedCharArray.h> //Attribution
     11 #include <vtkPointData.h>
     12 #include <vtkCellData.h>
     13 ///
     14 #include <vtkPolyDataMapper.h>
     15 #include <vtkActor.h>
     16 #include <vtkRenderer.h>
     17 #include <vtkRenderWindow.h>
     18 #include <vtkRenderWindowInteractor.h>
     19  
     20 int main()
     21 {
     22     //几何结构数据:点集
     23     vtkSmartPointer<vtkPoints> pts =
     24         vtkSmartPointer<vtkPoints>::New();
     25     pts->InsertNextPoint(0.0, 0.0, 0.0);
     26     pts->InsertNextPoint(1.0, 0.0, 0.0);
     27     pts->InsertNextPoint(1.0, 1.0, 0.0);
     28     pts->InsertNextPoint(0.0, 1.0, 0.0);
     29     pts->InsertNextPoint(2.0, 0.0, 0.0);
     30     //拓扑结构数据:正四边形
     31     vtkSmartPointer<vtkPolygon> polygon =
     32         vtkSmartPointer<vtkPolygon>::New();
     33     polygon->GetPointIds()->SetNumberOfIds(4);
     34     polygon->GetPointIds()->SetId(0, 0);
     35     polygon->GetPointIds()->SetId(1, 1);
     36     polygon->GetPointIds()->SetId(2, 2);
     37     polygon->GetPointIds()->SetId(3, 3);
     38     //拓扑结构数据:三角形
     39     vtkSmartPointer<vtkTriangle> triangle =
     40         vtkSmartPointer<vtkTriangle>::New();
     41     triangle->GetPointIds()->SetId(0, 1);
     42     triangle->GetPointIds()->SetId(1, 2);
     43     triangle->GetPointIds()->SetId(2, 4);
     44     //构成拓扑结构集合
     45     vtkSmartPointer<vtkCellArray> cells =
     46         vtkSmartPointer<vtkCellArray>::New();
     47     cells->InsertNextCell(polygon);
     48     cells->InsertNextCell(triangle);
     49     //合成几何拓扑结构用于显示
     50     vtkSmartPointer<vtkPolyData> polygonPolyData =
     51         vtkSmartPointer<vtkPolyData>::New();
     52     polygonPolyData->SetPoints(pts);
     53     polygonPolyData->SetPolys(cells);
     54  
     55     //添加属性结构
     56     unsigned char red[3] = { 255, 0, 0 };
     57     unsigned char green[3] = { 0, 255, 0 };
     58     unsigned char blue[3] = { 0, 0, 255 };
     59     vtkSmartPointer<vtkUnsignedCharArray> ptColor =
     60         vtkSmartPointer<vtkUnsignedCharArray>::New();
     61     ptColor->SetNumberOfComponents(3);
     62     ptColor->InsertNextTupleValue(red);
     63     ptColor->InsertNextTupleValue(green);
     64     ptColor->InsertNextTupleValue(blue);
     65     ptColor->InsertNextTupleValue(red);
     66     ptColor->InsertNextTupleValue(green);
     67     polygonPolyData->GetPointData()->SetScalars(ptColor);
     68  
     69     vtkSmartPointer<vtkUnsignedCharArray> cellColor =
     70         vtkSmartPointer<vtkUnsignedCharArray>::New();
     71     cellColor->SetNumberOfComponents(3);
     72     cellColor->InsertNextTupleValue(blue);
     73     cellColor->InsertNextTupleValue(red);
     74     polygonPolyData->GetCellData()->SetScalars(cellColor);
     75     
     76     vtkSmartPointer<vtkPolyDataMapper> mapper =
     77         vtkSmartPointer<vtkPolyDataMapper>::New();
     78     mapper->SetInputData(polygonPolyData);
     79  
     80     vtkSmartPointer<vtkActor> actor =
     81         vtkSmartPointer<vtkActor>::New();
     82     actor->SetMapper(mapper);
     83  
     84     vtkSmartPointer<vtkRenderer> render =
     85         vtkSmartPointer<vtkRenderer>::New();
     86     render->AddActor(actor);
     87     render->SetBackground(0.0, 0.0, 0.0);
     88  
     89     vtkSmartPointer<vtkRenderWindow> rw =
     90         vtkSmartPointer<vtkRenderWindow>::New();
     91     rw->AddRenderer(render);
     92     rw->SetSize(320, 240);
     93     rw->SetWindowName("Creating PolyData Structure");
     94  
     95     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
     96         vtkSmartPointer<vtkRenderWindowInteractor>::New();
     97     rwi->SetRenderWindow(rw);
     98     rwi->Render();
     99     rwi->Start();
    100  
    101     return 0;
    102 }
    该示例代码继承了上一节中的vtkPolyData数据。定义了两个vtkUnsignedCharArray对象ptColor和cellColor,分别为点和单元设置颜色数据。vtkUnsignedCharArray对象实际上为一个Unsigned char类型的数组。SetNumberOfComponents()函数指定了该数组中每个元组的大小。由于每个颜色是由RGB三个颜色分量组成。因此设置元组大小为3。InsertNextTupleValue()函数可以顺序插入元组数据。
    由于要为点集设置颜色,因此颜色数目要与点数保持一致。对于单元的颜色数据设置同样需要注意,有多少个单元,就要设置多少个颜色。
    设置点的颜色时,需要通过GetPointData()函数获取vtkPointData类型的点数据指针,然后通过SetScalar()函数设置颜色数据。
    显示结果如下所示,从图中可以看出,在进行颜色渲染时,使用的是点的颜色,而不是单元的颜色!
    根据之前的内容,我们知道:点数据和单元的属性数据是分别存储在VTKPointData和VTKCellData中的。
    在这里,我们还是要着重区分一下标量属性数据和向量属性数据的区别:
    向量数据具有方向和模;而标量数据不具有。如果一个数据(可以是单组分、也可以是多组分)经过一个几何变换后保持不变,那么该数据是一个标量,例如我们说的颜色属性。然而,对于法向量,该数据同样有三个组分,却是一个矢量属性,因为法向量经过几何变换后(如图像旋转)会发生改变。因此不能简单滴通过组分的个数来区分标量数据或者矢量数据。在对属性数据进行赋值时,也要分清标量数据还是矢量数据,不能将两者混淆,例如将颜色数据设置为矢量数据,那么在对图像数据进行几何变换后,颜色数据会发生改变。

    2. 单元的标量属性和矢量属性数据设置

    默认情况下,vtkPolyDataMapper会使用一个unsigned char类型的三元数组作为颜色值进行渲染。但是在很多情况下,模型颜色是通过属性数据获取的,比如根据标量数据在颜色查找表中获取相应的颜色。
     1 #include <vtkAutoInit.h>
     2 VTK_MODULE_INIT(vtkRenderingOpenGL);
     3  
     4 #include <vtkSmartPointer.h>
     5 #include <vtkPlaneSource.h>
     6 #include <vtkPolyData.h>
     7 #include <vtkFloatArray.h>
     8 #include <vtkCellData.h>
     9 #include <vtkLookupTable.h>
    10 #include <vtkPolyDataMapper.h>
    11 #include <vtkActor.h>
    12 #include <vtkRenderer.h>
    13 #include <vtkRenderWindow.h>
    14 #include <vtkRenderWindowInteractor.h>
    15  
    16 int main()
    17 {
    18     vtkSmartPointer<vtkPlaneSource> gridSource =
    19         vtkSmartPointer<vtkPlaneSource>::New();
    20     gridSource->SetXResolution(3);
    21     gridSource->SetYResolution(3);
    22     gridSource->Update();
    23  
    24     vtkSmartPointer<vtkPolyData> grid = gridSource->GetOutput();
    25     //标量属性
    26     vtkSmartPointer<vtkFloatArray> cellScalars =
    27         vtkSmartPointer<vtkFloatArray>::New();
    28     //矢量属性
    29     vtkSmartPointer<vtkFloatArray> cellVector =
    30         vtkSmartPointer<vtkFloatArray>::New();
    31     cellVector->SetNumberOfComponents(3);
    32     //设置属性
    33     for (int i = 0; i < 9; i++)
    34     {
    35         cellScalars->InsertNextValue(i + 1); //九个索引
    36         cellVector->InsertNextTuple3(0.0, 0.0, 1.0);
    37     }
    38  
    39     grid->GetCellData()->SetScalars(cellScalars);
    40     grid->GetCellData()->SetVectors(cellVector);
    41  
    42     vtkSmartPointer<vtkLookupTable> lut =
    43         vtkSmartPointer<vtkLookupTable>::New();
    44     lut->SetNumberOfTableValues(10);
    45     lut->Build();
    46     lut->SetTableValue(0, 0, 0, 0, 1);
    47     lut->SetTableValue(1, 0.8900, 0.8100, 0.3400, 1);
    48     lut->SetTableValue(2, 1.0000, 0.3882, 0.2784, 1);
    49     lut->SetTableValue(3, 0.9608, 0.8706, 0.7020, 1);
    50     lut->SetTableValue(4, 0.9020, 0.9020, 0.9804, 1);
    51     lut->SetTableValue(5, 1.0000, 0.4900, 0.2500, 1);
    52     lut->SetTableValue(6, 0.5300, 0.1500, 0.3400, 1);
    53     lut->SetTableValue(7, 0.9804, 0.5020, 0.4471, 1);
    54     lut->SetTableValue(8, 0.7400, 0.9900, 0.7900, 1);
    55     lut->SetTableValue(9, 0.2000, 0.6300, 0.7900, 1);
    56     //
    57     vtkSmartPointer<vtkPolyDataMapper> mapper =
    58         vtkSmartPointer<vtkPolyDataMapper>::New();
    59     mapper->SetInputData(grid);
    60     mapper->SetScalarRange(0, 9);
    61     mapper->SetLookupTable(lut);
    62     //
    63     vtkSmartPointer<vtkActor> actor =
    64         vtkSmartPointer<vtkActor>::New();
    65     actor->SetMapper(mapper);
    66  
    67     vtkSmartPointer<vtkRenderer> render =
    68         vtkSmartPointer<vtkRenderer>::New();
    69     render->AddActor(actor);
    70     render->SetBackground(0.0, 0.0, 0.0);
    71  
    72     vtkSmartPointer<vtkRenderWindow> rw =
    73         vtkSmartPointer<vtkRenderWindow>::New();
    74     rw->AddRenderer(render);
    75     rw->SetSize(320, 320);
    76     rw->SetWindowName("Setting Attribution of Vectors and Scalars");
    77  
    78     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
    79         vtkSmartPointer<vtkRenderWindowInteractor>::New();
    80     rwi->SetRenderWindow(rw);
    81     rwi->Start();
    82  
    83     return 0;
    84 }
    这个实例主要演示了怎样添加单元的标量属性数据和向量属性数据。
    VTKPlaneSource定义了一个3*3的网格数据。cellScalars定义了vtkFloatArray类型的标量属性数据,默认情况下其元组大小为1,因此不需要显示指定其大小;cellVectors则定义了vtkFloatArray类型的矢量属性数组,通过SetNumberOfComponents()指定向量维数为3,并通过InsertNextTuple3()可以方便地插入向量数据。
    定义完毕后,vtkPolyData的单元数据(VTKCellData)通过调用函数SetScalars()和SetVectors()设置相应的属性数据和标量数据。
    为了进一步演示利用标量数据进行颜色映射,定义了一个具有10个颜色的颜色映射表。利用vtkPolyDataMapper类的SetLookupTable()函数设置定义的颜色映射表。另外,需要注意的是,SetScalarRange()指定了颜色映射范围的最小值和最大值,当标量值大于最大值时,按定义最大值获取颜色;当小鱼最小值时,按照指定的最小值获取颜色。这样做的一个好处是,可以在一个小的标量范围内显示更多的颜色!!!
    该例的输出结果为:
  • 相关阅读:
    j.u.c系列(01) ---初探ThreadPoolExecutor线程池
    mySql---or和in的效率问题(和<=、>=、between之间的关系)
    spring---aop(10)---Spring AOP中AspectJ
    spring---aop(9)---Spring AOP中引入增强
    设计模式系列---适配器模式
    spring---aop(8)---Spring AOP中optimize
    spring---aop(7)---Spring AOP中expose-proxy介绍
    spring---aop(6)---Spring AOP中ProxyFactoryBean介绍
    spring---aop(5)---Spring AOP的配置的背后的配置
    spring---aop(4)---Spring AOP的CGLIB动态代理
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14241672.html
Copyright © 2020-2023  润新知