三维有限元网格的快速显示
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
收稿日期:2001 10 09
作者简介:梁振光(1967-),男,山东莱州人,副教授,博士,主要研究方向:电机控制、电磁场有限元分析、科学计算可视化.
文章编号:1001-9081(2002)04-0096-02
三维有限元网格的快速显示
梁振光
(山东大学电气工程学院,山东济南250061)
摘 要:应用OpenGL 三维图形库,结合三维有限元网格的特点,提出了一种方便、实用的三维有限元网格的快速消隐显示方法,使得三维图形显示速度大为提高,并对显示中出现的网格线间断、缺线问题提出了相应的解决措施。
关键词:三维有限元网格;OpenGL;消隐中图分类号:TP317.4 文献标识码:A
1 引言
有限元法作为一种非常有效的数值计算方法,在力学、电磁学等领域得到了广泛的应用。然而采用有限元法需要对计算模型进行剖分,通常剖分生成的有限元网格可达几万、十几万个单元,为了检查剖分结果及显示计算结果,需要将模型、剖分网格进行显示,并作消隐处理。对三维有限元网格的显示,关键在于对模型的消隐。目前已提出的消隐算法有数百种,比较常用的有画家算法、Z-buffer 算法、扫描线算法、区域采样算法(Warnock 算法)等,各种消隐算法各具特点,适用于不同的情况[1,2]。但对于动辄达十几万单元的网格的处理,都是一个沉重的负担。本文针对三维有限元剖分网格的特点,提出一种实用的快速网格显示方法。
2 快速网格显示方法
在各种消隐算法中,画家算法方法简单,且当绘制图形的面较少时效率较高,但当绘制的面很多时速度很慢;而Z-buffer 算法虽然对于绘制面较少的图形并没有速度优势,但对图形复杂、绘制面非常多时其速度优势明显[2]。为此,根据有限元网格显示的特点,可以选取Z -buffer 算法进行消隐处理。Z-buffer 算法的基本思想是对于变换到屏幕坐标的图像的每一个象素,除记录每个象素的光强度外,还要存储象素在屏幕坐标空间中的深度值,即Z 坐标。Z-bu ffer 算法计算准备写入缓冲器的象素的深度值或Z 值,并与已存储在Z 缓冲器中的该象素的原深度值比较。若新深度值小于原深度值,则将新象素值写入缓冲器,同时Z 缓冲器用新的Z 值更新,否则不更新。由于剖分网格数巨大,即使采用Z -buffer 算法计算量仍然巨大,直接影响显示速度,为此需要对有限元网格数据进行预处理,减少消隐显示的计算量。本文采取的方法是结合剖分网格特点的数据预处理的Z -buffer 法。由于利用了Z-buffer 法的优点,有效减少了显示计算量,因而显示速度明显提高。
2.1 显示数据的预处理
对显示数据的预处理是将有限元网格分为可见面、可能可见面和不可见面,将大量的不可见面从显示数据中剔除。
尽量减少要绘制的单元多边形面(三角形、四边形)。三维有限元网格图形的绘制,是将剖分后的模型呈现出来,需要将有限元单元的面绘制出来。对于计算模型的各个部件,显示时
所看到的是部件表面或切割面上的多边形,而内部的单元、多边形则看不到,在显示时如果能够采取措施剔除内部的不可见单元、多边形,则可以大大减少图形绘制的工作量,提高显示速度,实现三维有限元网格图的快速消隐。本文针对有限元网格的特点,采取有效的算法将内部不可见面剔除,而将可能可见面与可见面继续保留。这样,既减少了绘制的多边形数,又利用Z-buffer 法消隐处理的高效性。内部不可见面的剔除是利用了这样的特性,即对于每一个面,若该面仅属于一个单元,则该面是模型的外部面;若该面属于两个单元,则该面为模型的内部面。对于模型的内部面,若包含它的两个单元的材料号相同,则该面为某种材料的内部面;若两个单元的材料号不同则该面为两种材料的交界面。模型的外面和不同材料的交界面是可能可见面,显示时保留,同种材料的内部面为不可见面,显示时剔除。
以变压器的三维电磁场有限元为例,其剖分采用逐层延拓的方法生成三棱柱单元。每一个三棱柱单元有三个四边形面和两个三角形面组成,三棱柱侧面为四边形,顶面和底面为三角形,如图1所示。对有限元网格的所有单元面,建立一个面表,记录面的相关单元。面表的建立根据网格特点对四边形面和三角形面分别进行处理进行。
图1 三棱柱剖分单元
对四边形的处理,从第一个单元到最后一个单元进行循环,记录单元的侧面。首先记录第一个单元的三个面及第一个相关单元,对其它单元,与已有的面比较,若面已存在,则将
单元号的负值记录到该面的第二个相关单元(两相邻单元的公共面的有向节点编号顺序相反);若面不存在,则记录该面和第一个相关单元。由于相邻单元的编号比较接近,对于面
第22卷第4期2002年4月
计算机应用Computer Applications Vol.22,No.4Apr.,2002
的比较,可以仅在较小范围内进行。对三角形的处理,首先记录第一层单元的底面及相关单元,然后对所有单元记录其顶面,相关单元为该单元及其上层的对应单元。当面表形成后,可根据面的两相关单元的材料号是否相等判断其是否结构件内部的面,若为内部面则在显示时跳过不做处理,若为表面的面单元,则通过所采用的消隐方法进行显示。
2.2 三维网格的消隐显示
为了提高编程和绘图效率、提高绘图软件的可移植性,本文的三维图形处理调用OpenGL标准图形库函数[3]。OpenGL 提供了高效的三维图形处理基本函数,能够进行消隐处理(Z -buffer法),并且绝大多数的3D图形加速卡都对OpenGL有硬件支持。OpenGL有允许/禁止深度测试函数glEnable(GL DEPTH TEST)、glDisable(GL DEPTH TES T),只要每次画图前,开启深度测试函数,即可实现自动消隐。
对三维有限元网格的网格面的绘制,在OpenGL中设定当前色,并给出多边形的顶点序列,即得到以当前色填充的多边形面或者线框图形。三维有限元网格图的显示是这样实现的:对每个要显示的多边形面,先以填充方式绘制彩色实体,再用对比鲜明的颜色绘制线框轮廓,允许深度测试,并用深度比较设置函数glDepthFunc(GL LEQUAL)将深度比较设为小于等于!,这样得到经过消隐的三维网格图,不同结构件用不同的颜色显示。
图形的绘制过程如下:首先设置图形显示环境,如设置背景颜色、清除颜色缓冲区和深度缓冲区、启动深度测试等,然后根据用户操作进行的场景变换(坐标变换,包括视点变换和投影变换),接着就开始绘制网格单元,可以选择绘制实体图、线框图和线框消隐图。
对模型的平移、旋转、缩放功能,可通过调用glTranslate, glRotate等函数实现。
2.3 网格线断续现象的解决措施
由于OpenGL在绘图时,对多边形面和多边形线段的栅格化方式不同,造成在进行深度缓冲区操作时引起深度值的微小的不同,其结果是线条的某些象素显示,而某些象素不显示,造成网格线出现断续,如图2(a)所示,严重的会是整条线段消失,影响图形显示质量。为此,本文给出两种解决网格断续的措施。
2.3.1 模板缓冲区法
模板缓冲区法是利用模板缓冲区可限制在屏幕的某处绘图的功能。模板检验把存贮在模板缓冲区的象素值与参考值相比,根据检验结果,修改模板缓冲区的值。对每个网格面,先绘制多边形线段,并将绘制的线段设为限制绘图区,然后绘制多边形面(此时绘制的面就不会覆盖网格线段了),最后取消该多边形线段区的绘图限制。具体实现如下:
//初始化
gl Clear Stencil(0);//对模板缓冲区清零gl Enable(G L STENCIL TEST);//启用模板缓冲区//画多边形线,并置屏蔽绘图区
gl StencilFunc(G L ALWAYS,1,1);
//设置模板检验的比较函数、参考值和屏蔽值
gl StencilOp(G L REP LACE,GL REPLACE,GL REPLACE);
//指定进行模板检验后修改模板缓冲区中数据的方法
gl Color3fv(0.0,0.0,0.0);//置绘图色为黑色
glBegin(G L LINE);//画多边形线glVertex3f(x mode[1],y node[1],z node[1]);//多边形的顶点∀∀
glEnd();
//画多边形面
glStencilFunc(GL NO TEQUA L,1,1);
glStencilOp(GL KEEP,G L KEEP,GL KEEP);
glColor3f(1.0,1.0,1.0);//置绘图色为白色glBegin(G L POLYGON);//画多边形面glVertex3f(x mode[1],y node[1],z node[1]);
∀∀
glEnd();
//画多边形线,并清屏蔽绘图区
glStencilFunc(GL A LWAYS,1,1);
glStencilOp(GL ZERO,GL ZERO,GL ZERO);
glColor3fv(0.0,0.0,0.0);//置绘图色为黑色glBegin(G L LINE);//画多边形线glVertex3f(x mode[1],y node[1],z node[1]);
∀∀
glEnd();
2.3.2 多边形偏移法
OpenGL 1.1版本新增了多边形偏移功能函数glPolygonOffset(),该函数的作用是在深度缓冲区中偏移多边形象素,使在同一平面上的点、线和多边形没有交叉,在绘制时可清晰地绘制出多边形轮廓线。用函数glEnable()和glDisable()允许和禁止多边形偏移功能,其参数可取(GL POLYGON OFFSET POINT,GL POLYGON OFFSET LINE, GL POLYGON OFFSE T FILL)。用函数gl PolygonOffset(GLfloat factor,GLfloat units)设置偏移量,偏移量offset=factor*max slope+uni ts*min difference,其中比例因子factor和最小单元数uni ts是传给函数glPolygonOffset的两个参数的值,可正可负,max slope是所画多边形深度斜率绝对值的最大值;min difference是保证两个深度坐标能在窗口坐标系下产生相对不同的最小值,是一个特定的常量。具体实现如下:
//设置多边形偏移功能
glPol ygonOffs et(1.0,2);//设置偏移量的大小(fac tor=1,units=2) glEnable(GL PO LYG ON OFFSET FILL);//允许填充多边形偏移//画带边界的多边形
glColor3fv(0.0,0.0,0.0);//置绘图色为黑色glBegin(G L LINE);//画多边形线glVertex3f(x mode[1],y node[1],z node[1]);
∀∀
glEnd();
glColor3f(1.0,1.0,1.0);//置绘图色为白色glBegin(G L POLYGON);//画多边形面glVertex3f(x mode[1],y node[1],z node[1]);
∀∀
glEnd();
2.3.3 两种实现方法的比较
采用两种方法都可以得到高质量的显示效果。模板缓冲区法因对模板缓冲区进行操作,绘图速度明显变慢,但该法使用较为灵活,尤其适合基于OpenGL1.0的系统(如Microsoft Fortran Powerstation4.0等)。多边形偏移法使用方便、绘图速度快,但需基于OpenGL1.1及以上版本。
97
第4期梁振光:三维有限元网格的快速显示