vtkPolyData 示例代码

 

本文主要介绍使用使用一系列的点生成各种 PolyData 的过程。

我们首先生成螺旋曲线, 这个比较简单。 使用一些简单的数据知识就可以办到:

 1 /********************************************
 2  * 描述:
 3  *    构建形成线条的所有点集。
 4  * 参数列表:
 5  *  count - 线条所在坐标三个维度的分辨率。
 6  * 返回值:
 7  *    线条的点集。
 8  *******************************************/
 9 std::vector < vtkPoint >  BuildPoints ( int count )
10 {
11     std::vector < vtkPoint > points;
12 
13     for ( int y = 0; y < count; y++ )
14     {        
15         vtkPoint point;
16         point.x = radians * cos ( y / vtkMath::Pi() );
17         point.y = y;
18         point.z = radians * sin ( y / vtkMath::Pi() );
19         point.radians = 3; 
20         points.push_back ( point );        
21     }
22 
23     return points;
24 }

 

有了点之后,我们把这些点连接成线。

 1 /********************************************
 2  * 描述:将点连成线
 3  * 参数列表:
 4  *    points - 点集.
 5  * 返回值:
 6  *    用 vtkPolyData 表示的线条。
 7  *******************************************/
 8 vtkPolyData * BuildLines ( std::vector < vtkPoint > & points )
 9 {
10     vtkNew <vtkPoints> polydataPoints;
11     vtkNew < vtkCellArray > cells;
12 
13     int count = points.size();
14     for ( int i=0; i<count; i++ )
15     {
16         polydataPoints->InsertNextPoint ( points[i].x, points[i].y, points[i].z );
17     }
18 
19     for ( int i=0; i<count-1; i++ )
20     {
21         vtkIdType pts[2] = { i, i+1 };
22         cells->InsertNextCell ( 2, pts );
23     }
24 
25     vtkPolyData * polyData = vtkPolyData::New ();
26     polyData->SetPoints ( polydataPoints );
27     polyData->SetLines ( cells );
28 
29     return polyData;
30 }

然后我们就可以把这个线显示出来:如图

 

 

 之后我们继续以每个点为圆心作圆。

 1 vtkPolyData * BuildCircles ( std::vector < vtkPoint > & points, int resolution )
 2 {
 3     std::vector < vtkPoint > circlePoints = BuildCirclePoints ( points, resolution );
 4     
 5     vtkNew < vtkAppendPolyData > append;
 6     int count = circlePoints.size();
 7     
 8     for ( int i=0; i<count; i+=resolution )
 9     {
10         vtkNew < vtkPoints > vPoints;
11         vtkNew < vtkCellArray > cells;
12         
13         for ( int j=0; j<resolution; j++ )
14         {
15             int idx = i+j;
16             vPoints->InsertNextPoint ( circlePoints[idx].x, circlePoints[idx].y, circlePoints[idx].z );
17         }
18 
19         for ( int j=0; j<resolution; j++ )
20         {
21             int n = j+1;
22             if ( n >= resolution )
23                 n = 0;
24 
25             vtkIdType pts[2] = {j, n};
26             cells->InsertNextCell ( 2, pts );
27         }
28 
29         vtkNew < vtkPolyData > polyData;
30         polyData->SetPoints ( vPoints );
31         polyData->SetLines ( cells );
32         append->AddInputData ( polyData );
33     }
34 
35     //
36     append->Update ();
37     vtkPolyData * retPolyData = append->GetOutput ();
38     retPolyData->Register ( NULL );
39 
40     //
41     return retPolyData;
42 }

将它返回的 retPolyData 显示出来就是下面的样子。

 

 

 

 最后,我们只需连接上下两个圆的点,形成面片,就可以生成三维表面了。

 1 /********************************************
 2 * 描述: 构建表面。
 3 *    参数列表:
 4 *        points - 点集,每一个点都是一个圆的圆心。
 5 *        resolution - 圆是由一系列的线段构成, resolution 指定线段数量。
 6 * 返回值:
 7 *    返回所有圆构成的表面.
 8 *******************************************/
 9 vtkPolyData * BuildSurface ( std::vector < vtkPoint > & points, int resolution )
10 {
11     std::vector < vtkPoint > circlePoints = BuildCirclePoints ( points, resolution );
12 
13     vtkNew < vtkAppendPolyData > append;
14     int count = circlePoints.size() - resolution;
15 
16     for ( int i=0; i<count; i+=resolution )
17     {
18         for ( int j=0; j<resolution; j++ )
19         {
20             vtkNew < vtkPoints > vPoints;
21             vtkNew < vtkCellArray > cells;
22 
23             bool bflag = j == ( resolution-1 );
24 
25             int idx = j+i;
26             int lt = idx;
27             int rt = idx + 1;
28             int rd = rt + resolution;
29             int ld = lt + resolution;
30 
31             if ( bflag ) 
32             {
33                 rt = i;
34                 rd = i + resolution;
35             }
36 
37 
38             vPoints->InsertNextPoint ( circlePoints[lt].x, circlePoints[lt].y, circlePoints[lt].z );
39             vPoints->InsertNextPoint ( circlePoints[rt].x, circlePoints[rt].y, circlePoints[rt].z );
40             vPoints->InsertNextPoint ( circlePoints[rd].x, circlePoints[rd].y, circlePoints[rd].z);
41             vPoints->InsertNextPoint ( circlePoints[ld].x, circlePoints[ld].y, circlePoints[ld].z);
42 
43             //
44             vtkNew < vtkQuad > quad;
45             for ( int c=0; c<4; c++ )
46             {
47                 quad->GetPointIds()->SetId ( c, c );            
48             }
49             cells->InsertNextCell ( quad );
50 
51             //
52             vtkNew < vtkPolyData > polyData;
53             polyData->SetPoints ( vPoints );
54             polyData->SetPolys ( cells );
55             append->AddInputData ( polyData );
56         }        
57     }
58 
59     //
60     append->Update ();
61     vtkPolyData * retPolyData = append->GetOutput ();
62     retPolyData->Register ( NULL );
63 
64     //
65     return retPolyData;
66 }

把这里返回的 PolyData 显示出来就是下面的样子:

 

posted @ 2021-04-03 14:38  河东游子  阅读(766)  评论(0编辑  收藏  举报