vtk动态显示多边形网格数据

本文介绍了一个使用VTK库创建动态行走效果的例子。通过逐步调整3D模型顶点的位置来实现动态效果,并解决了颜色刷新问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期老板要求做一个人的动态行走,先转一个vtk动态显示的例子,转自http://tzc.is-programmer.com

#include <iostream>
#include <stdio.h>
#include <malloc.h>

#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkProperty.h"
#include "vtkCubeSource.h"

void read_point_file ( float p [ ] [ 3 ]const  char *name1 )
{
        FILE *fp= NULL;
         if ( (fp=fopen (name1, "r" ) )== NULL )
         {
                cout<< "open file name1 error"<<endl;
                 return;
         }
         float arr [ 3 ];
         int nn= 0;
        fscanf (fp,  "%d", &nn );
         int n= 0;
         while (!feof (fp ) )
         {
                 int ret=fscanf (fp, "%f %f %f",&arr [ 0 ],&arr [ 1 ],&arr [ 2 ] );
                 if (ret!= 3 )
                         break;
                p [n ] [ 0 ]=arr [ 0 ];
                p [n ] [ 1 ]=arr [ 1 ];
                p [n ] [ 2 ]=arr [ 2 ];
                n++;
         }
        fclose (fp );
}

void read_tri_file (vtkIdType tri [ ] [ 3 ]const  char *name2 )
{
        FILE *fp= NULL;
         if ( (fp=fopen (name2, "r" ) )== NULL )
         {
                cout<< "open file name2 error"<<endl;
                 return;
         }
         int nn= 0;
        fscanf (fp,  "%d", &nn );
         int n= 0;
         int num;
         int int_arr [ 3 ];
         while (!feof (fp ) )
         {
                 int ret=fscanf (fp, "%d %d %d %d",&num, &int_arr [ 0 ],&int_arr [ 1 ],&int_arr [ 2 ] );
                 if (ret!= 4 )
                         break;
                tri [n ] [ 0 ]=int_arr [ 0 ];
                tri [n ] [ 1 ]=int_arr [ 1 ];
                tri [n ] [ 2 ]=int_arr [ 2 ];
                n++;
         }
        fclose (fp );
}

int main ( int argc,  char *argv [ ] )
{
         char *file1= NULL, *file2= NULL;
         if  (argc <  3 ) {
                file1 =  ( char* ) malloc ( 20* sizeof ( char ) );
                file2 =  ( char* )malloc ( 20* sizeof ( char ) );
                file1 =  ( char * ) ( "a.asc" );
                file2 =  ( char * ) ( "aa.asc" );
         } else {
                file1 = argv [ 1 ];
                file2 = argv [ 2 ];
         }
        FILE *fp =  NULL;
         int p_num =  0;
         if ( (fp=fopen (file1, "r" ) )== NULL )
         {
                cout<< "open file "<<argv [ 1 ]<< " error"<<endl;
                 return  1;
         }
        fscanf  (fp,  "%d", &p_num );
        fclose (fp );
         printf ( "point number is : %d\n", p_num );
         float  (*points_arr ) [ 3 ] =  ( float  ( (* ) [ 3 ] ) )malloc ( 3*p_num* sizeof ( float ) );

         int tri_num =  0;
         if ( (fp=fopen (file2, "r" ) )== NULL )
         {
                cout<< "open file "<<argv [ 2 ]<< " error"<<endl;
                 return  1;
         }
        fscanf  (fp,  "%d", &tri_num );
        fclose (fp );
        vtkIdType  (*triangle_arr ) [ 3 ] =  (vtkIdType  ( (* ) [ 3 ] ) )malloc ( 3*tri_num* sizeof (vtkIdType ) );
         printf ( "triangle number is : %d \n", tri_num );

        read_point_file (points_arr, file1 );
        read_tri_file  (triangle_arr, file2 );

         int i;
        vtkPolyData *polydata = vtkPolyData:: New ( );
        vtkPoints *points = vtkPoints:: New ( );
        vtkCellArray *polys = vtkCellArray:: New ( );

        vtkPolyDataMapper *polydataMapper = vtkPolyDataMapper:: New ( );
        polydataMapper->SetInput (polydata );
        vtkActor *polydataActor = vtkActor:: New ( );
        polydataActor->SetMapper (polydataMapper );
        polydataActor->GetProperty ( )->SetColor ( 0.0, 0.0, 1.0 );

        vtkRenderer *renderer = vtkRenderer:: New ( );
        vtkRenderWindow *renWin = vtkRenderWindow:: New ( );
        renWin->AddRenderer (renderer );

        vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor:: New ( );
        iren->SetRenderWindow (renWin );

        renderer->AddActor (polydataActor );
        renderer->SetBackground ( 1, 1, 1 );
        renWin->SetSize ( 400, 400 );

         for  (i= 0; i<p_num; i++ ) points->InsertPoint (i,points_arr [i ] );
         for  (i= 0; i<tri_num; i++ ) {
                polys->InsertNextCell ( 3,triangle_arr [i ] )
         }
        polydata->SetPoints (points );
        polydata->SetPolys (polys );
        renWin->Render ( );
        iren->Start ( );

         for  (i= 0; i<p_num; i++ ) {
                 double *pp=polydata->GetPoint (i );
                points = polydata->GetPoints ( );
                points->SetPoint (i, pp [ 0 ] +10.0, pp [ 1 ], pp [ 2 ] );
                polydata->SetPoints (points );
                polydataActor->GetProperty ( )->SetColor ( 0.00.0(i* 1.0 )/ (i* 1.0 +0.000001 ) );

                renWin->Render ( );
         }

        renWin->Render ( );
        iren->Start ( );

        polydata->Delete ( );
        polydataMapper->Delete ( );
        polydataActor->Delete ( );
        renderer->Delete ( );
        renWin->Delete ( );
        iren->Delete ( );

         return  0;
}
编译命令为:

                                
        gcc -o main polydata0. cxx -I /usr/include/vtk -5.0  /usr/lib/libvtkRendering. so -Wno-deprecated

运行:
./生成的可执行文件名  点表文件  面表文件                            
                       

此处动画显示的处理方式为将所有顶点坐标按顺序将z坐标都加10.0,处理方式如下:

				
	for (i=0; i<p_num; i++){
		double *pp=polydata->GetPoint(i);
		points = polydata->GetPoints();
		points->SetPoint(i, pp[0]+10.0, pp[1], pp[2]);
		polydata->SetPoints(points);
		polydataActor->GetProperty()->SetColor(0.0, 0.0, (i*1.0)/(i*1.0+0.000001));

		renWin->Render();
	}
				
			

对 代码的解释,首先是一个循环以遍历所有点,定义了临时指针变量pp(随便取的),令pp指向当前顶点,采用代码 polydata->GetPoints()获取点表,points->SetPoint(i, pp[0]+10.0, pp[1], pp[2])用于设定点表中第i个点的坐标,重新设定polydata的点表polydata->SetPoints(points),然后就是重 新渲染显示renWin->Render()。可能细心的您已经发现了,这里有一行代码没解释 polydataActor->GetProperty()->SetColor(0.0, 0.0, (i*1.0)/(i*1.0+0.000001)),没错,的确没解释,也不需要解释,但是必须有,此代码用于设定对象的颜色,在VTK中不知为什么, 如果采用固定的常量颜色,无法实现动态刷新渲染,这里采用了变量(i*1.0)/(i*1.0+0.000001),没做实质性修改,但是正是有了此句代 码才能刷新渲染效果。



<think>嗯,用户现在想了解VTK在后处理中支持哪些数据结构。从之前的对话历史来看,用户之前询问过开源多物理场耦合框架,现在转向了可视化工具VTK数据结构问题,说明用户可能在完成某个多物理场项目的后处理需求。用户提供的引用材料非常专业,涵盖了VTK的核心数据结构文档。我需要重点参考这些引用内容来组织回答。引用[1]和[3]明确指出VTK的五种主要数据集类型,引用[2]和[4]则补充了图像数据和拓扑结构的细节,引用[5]解释了底层数据组织方式。用户特别强调"后处理"这个应用场景,这意味着需要突出这些数据结构在实际可视化中的用途。比如vtkImageData对应科学图像,vtkPolyData适合曲面渲染,vtkUnstructuredGrid能处理复杂网格等。用户可能是工程师或科研人员,正在为仿真结果选择合适的数据表达形式。 注意到用户引用的示例中出现了ParaView的案例,可以推测用户可能实际在使用这个基于VTK的平台。因此回答中应该强调这些数据结构在ParaView中的对应关系,比如如何用vtkPolyData显示流线等。在整理回答时,我会把五种数据集分成三类:规则网格、不规则网格和特殊结构。每类都要说明其几何+拓扑特性(引用[4]提到的关键概念),并给出典型后处理案例(如引用[2]中的图像处理)。最后补充场数据(引用[5])这个重要概念,因为后处理中经常需要映射标量/矢量场。用户没有明确说明领域,但结合之前的多物理场框架讨论,补充案例应该偏向CFD或结构分析。比如用vtkStructuredGrid展示翼型流场,用vtkUnstructuredGrid显示应力云图等。 需要特别注意系统指令要求:所有数学公式必须用$...$格式,如$f(x,y,z)$表示标量场。但当前问题不涉及复杂公式,重点在于数据结构描述。回答末尾要按示例格式生成相关问题,帮助用户深入理解特定数据结构的应用。</think>VTK在后处理中支持的核心数据结构均派生自`vtkDataSet`,这些结构专门为科学可视化设计,尤其适合处理多物理场仿真结果。主要支持以下五类数据结构: --- ### **1. 规则网格数据** - **`vtkImageData`**(规则网格) 三维像素/体素阵列,坐标轴对齐且间距恒定。 **后处理应用**: - 处理CT/MRI扫描数据(引用[2]) - 标量场可视化(如温度云图) - 矢量场切片(如流速场切片) $$ \text{坐标映射:} \quad (i,j,k) \rightarrow (x_0 + i \cdot \Delta x, y_0 + j \cdot \Delta y, z_0 + k \cdot \Delta z) $$ --- ### **2. 曲线网格数据** - **`vtkRectilinearGrid`**(矩形网格网格线平行坐标轴但间距非均匀。 **后处理应用**: - 非均匀采样数据(如气象网格) - 复杂边界层流动分析 - **`vtkStructuredGrid`**(结构化网格) 拓扑规则但几何变形(如弯曲网格)。 **后处理应用**: - 流体绕流模拟(如翼型流场) - 映射物理场到变形几何体 --- ### **3. 非结构化网格数据** - **`vtkUnstructuredGrid`** 任意单元类型(四面体、六面体等)的自由组合。 **后处理应用**: - 复杂几何体应力分析(引用[3]) - 多材料域耦合场可视化 - 自适应网格细化结果 **单元支持**: ```plaintext 四面体(Tetra) | 六面体(Hexahedron) | 金字塔(Pyramid) | 楔形(Wedge) | 多边形(Polygon) ``` - **`vtkPolyData`**(多边形数据集) 由点、线、多边形组成的表面网格。 **后处理应用**(引用[4]): - 流线/迹线生成 - 等值面提取(如Marching Cubes结果) - 表面应力分布渲染 > 需同时定义**几何结构**(点坐标)和**拓扑结构**(点连接关系)才能正确显示(引用[4])。 --- ### **4. 通用数据组织方式** 所有数据结构均通过**场数据(`vtkFieldData`)** 管理物理量: - **标量场**(如压力 $p$) - **矢量场**(如速度 $\vec{v}$) - **张量场**(如应力 $\sigma_{ij}$) 数据以`vtkDataArray`数组存储,支持动态绑定到网格点或单元(引用[5])。 --- ### **典型后处理流程示例** ```mermaid graph LR A[仿真结果] --> B(vtkUnstructuredGrid) B --> C{场数据映射} C --> D[标量场] --> E[云图着色] C --> F[矢量场] --> G[流线生成] B --> H[等值面提取] --> I(vtkPolyData) I --> J[表面渲染] ``` --- ### **数据结构选择建议** | 数据类型 | 适用场景 | 后处理优势 | |-----------------------|-----------------------------------|--------------------------| | `vtkImageData` | 均匀采样数据(CT/MRI) | 快速体绘制 | | `vtkStructuredGrid` | 变形网格(流体边界层) | 保留拓扑关系 | | `vtkUnstructuredGrid` | 复杂几何体(机械零件应力) | 任意单元支持 | | `vtkPolyData` | 表面流线/等值面 | GPU加速渲染效率高 | > 可通过ParaView等工具直接操作这些数据结构(引用[4])。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值