




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
慧都控件网HOOPS 3D可视化入门教程三:基本概念和数据结构上篇文章介绍了 HOOPS 的主要模块,这篇文章将要向大家介绍HOOPS的数据结构以及穿插其中的一些基本概念。这些内容主要包含在3dGS模块内。一、保留模式HOOPS采用保留绘图模式(retainedmode)。所谓保留模式是相对于传统的非保留模式而言的。做过OpenGL编程的人都知 道,OpenGL的绘制都是通过调用一系列绘图命令来实现的,通常是在一个叫updateGL的函数里。除非你自己把相关绘图信息保存起来,否则出了这个 函数OpenGL就不认帐了,也就是说你无法从OpenGL里面再获取你曾经绘制的一些图元信息。而保留模式则不这样,它把绘制过的命令和图形会保存起 来,放在特定的数据结构中,从而使得我们可以事后随时读取这些数据。相比于非保留模式,保留模式能够提供更高的效率(因为数据都在内部,下次绘制时不需要 再读取),更快的交互(通过特定的基于数据结构的算法,可以加速选取、高亮等等交互操作),还有更方便的编程接口。当然凡事都有两面性,保留模式也有它的 缺点,其中之一就是它增加了程序的内存消耗(用于存储那个数据结构)。但我们认为这样的代价是完全值得的。二、基于段的数据结构HOOPS的 数据结构简单讲是基于段(segment)的树状结构。最上层是根段,为“/”。该数据结构和Linux文件系统有着一曲同工之妙,有Linux使用经验 的同学将会很容易理解。Linux的根目录的符号也是“/”,所有文件系统中的文件或者文件夹的路径都以该符号开头。文件夹有名字,段也有名字。如同文件 夹内可以有文件和子文件夹,segment下可以有subsegment。这样的层次结构可以很好地构建我们想要的图形。打开一个段的HOOPS函数是HC_Open_Segment,它有一个参数,就是这个段的名字。我们可以传一个空字符串给它,从而创建一个匿名 段。如果已经存在这个名字的段,则该函数会打开这个段,否则就自动创建一个新段。打开后,我们就可以在该段内做任何我们想要做的操作。操作结束,记得用HC_Close_Segment来关闭这个段。HOOPS采用和OpenGL一样的上下文机制,那就是“状态机(StateMachine)”。所谓状态机,形象地讲就是一旦改变了状态,则接 下去不论程序运行到哪里,该状态将一直保存,直到下次改变状态。在HOOPS中,打开一个段实际上就意味着进入了一个状态机,直到你关闭这个段,你所有的 操作都将在这样一个上下文中进行。具体来讲就是,打开一个段,然后你可以跳转到任意的程序位置完成具体的绘制任务,然后关闭段,这一系列操作没有必要在一 个函数中完成。这无疑大大增加了我们编程的灵活性。举个例子,我们想要绘制一所房子,房子有房顶、窗户还有门,我们可以用如下代码:HC_Open_Segment(“/”);HC_Open_Segment(“house”);HC_Open_Segment(“roof”);HC_Close_Segment();HC_Open_Segment(“door”);HC_Open_Segment(“windows”);HC_Open_Segment(“window1”);HC_Close_Segment();HC_Open_Segment(“window2”);HC_Close_Segment();HC_Open_Segment(“window3”);HC_Close_Segment();HC_Close_Segment();HC_Close_Segment();HC_Close_Segment();实际上我们创建了如下的树状结构:创建了段之后,我们需要有相应的方法能够找到这个段,这时就会用到段的路径。和Linux上的文件路径类似,段的路径也分为两种:相对路径和绝对路 径。我们打开一个段,进入该段的状态机,如果要打开它下面的子段,就可以用相对路径。HOOPS会自动地在该段下面找给出的段名,如果找不到,则会报错。 绝对路径则是从根段名“/”开始,逐步地把段名添加上去,直到我们想要找的段为止,完整的路径就是绝对路径。例如我们要找第三扇窗户,相对于house的 相对路径是:”windows/window3”,而绝对路径是:”/house/windows/window3。我们可以用“.”和“.”来分别指代当前目录和父目录,这又跟Linux上的路径使用习惯是一致的。这种简称只能用于相对路径中。为了能够更方便地提供段的路径,HOOPS中还有一套特有的符号,叫做“wildcards”,可以同时指代多个不同的路径,有以下几种:1.逗号wildcard。这个是最简单的一种。有时候我们需要同时对多个可枚举的段进行统一处理,例如我们想用同一种颜色来装饰roof和door(虽然这种做法很少见),我们就可以用这样的一个路径来同时指代这两个段:/house/(door,roof)。2.通配符。可以用“*”来匹配0个或多个字符,“%”来匹配单个字符,这个跟我们用Windows系统搜索功能是一样的,也和正则表达式相一致。3.递归wildcards。其实上面两个并不是HOOPS所独有的,在其他也有见到。但是HOOPS还有一个它特有的符号,那就是“”,该符 号可以指代一个段名或者一串路径上的段名。例如我们可以用/house/window1来指代第一扇窗户,而不用去管当中到底隔了多少个段。该种方法 非常长适合于我们不清楚house到window1之间到底存在着怎样的父子结构。虽然方面,但是如果我们确切地知道window1的完整路径,那就不要 这么写了,因为HOOPS是通过自顶向下的方式搜索得到window1,所以需要消耗一定的计算量。另外,该符号还可以递归地表示一个段的所有子段以及子 段的子段。如果我们要对一个段内的所有子段进行某项修改,那么这个wildcards真是再合适不过了。三、几何信息(Geometry)segment像文件夹一样,它本身并没有实质的东西,而只是一个容器。真正绘制出车的形状,还需要具体的几何信息。因此,段内部除了可以存储子段 外,还可以存储Geometry。HOOPS中的Geometry丰富多样,囊括了点、边、面、壳(shell)、网络(mesh)等等基本上大家能够想 到的图元。这些基本几何通过相互组合,可以组成更加复杂的图像信息,这是一个自底向上的组建过程。例如我们可以通过下面的方式插入一个点和一条直线:HC_Open_Segment(“myseg”);HC_Insert_Marker(0,1,1);HC_Insert_Line(-1,-1,-1,2,2,2);HC_Close_Segment();HC_Insert_Marker需要传入三个浮点参数,也就是一个点的三维坐标。HC_Insert_Line需要传入六个参数,为一个线段的起始点和终止点的三维坐标。我们可以用下面的代码插入一个多边形的面:HC_POINTpts4=HC_POINT(0,0,0),HC_POINT(1,0,0),HC_POINT(1,1,0),HC_POINT(0,1,0);HC_Open_Segment(“mypolygon”);HC_Insert_Polygon(4,pts);HC_Close_Segment();HC_Insert_Polygon需要传入两个参数,分别是多边形顶点个数以及存放顶点三维坐标的数组。该函数代表了HOOPS中一类参数,就是 对一群点进行操作。需要注意的是,这类函数在内部会对传入的三维坐标数组进行拷贝,所以如果你传入的坐标数组是动态申请出来的,在调用完该类函数之后,必 须手动地将其释放掉。除了基本的点、线、多边形等,HOOPS还提供了两个相对高级的图元,分别是Shell和Mesh。在进行大型场景构建时,这两个图元是非常常用 的,例如我们用三角网格构建一个人的模型,那么这个三角模型就是一个shell。shell有三个层次的图元组成,分别是node(点)、edge(边) 和face(面),这三部分相互连接形成一个整体。mesh和shell非常类似,同样由点边面三部分组成,唯一的区别是mesh它不能形成一个封闭的类 似于人这样的模型,它只能是一张面,而且只能是一张四边形面,例如一张四边形纸。这样的区别使得在处理特定的模型时,如果mesh能够满足应用需要,那么 mesh将会比shell表现得高效得多。下面举例创建一个立方体,并在它的一个面上接一个金字塔体:HC_POINTpts=HC_POINT(0,0,1),HC_POINT(1,0,1),HC_POINT(1,1,1),HC_POINT(0,1,1),HC_POINT(0,0,2),HC_POINT(1,0,2),HC_POINT(1,1,2),HC_POINT(0,1,2),HC_POINT(0.5,0.5,2.5);intflist=4,0,3,2,1,4,0,1,5,4,4,1,2,6,5,4,2,3,7,6,4,3,0,4,7,3,4,5,8,3,5,6,8,3,6,7,8,3,7,4,8;HC_Open_Segment(mymodel);HC_Insert_Shell(9,pts,41,flist);HC_Close_Segment();HC_Insert_Shell需要四个参数,分别是shell的顶点个数,顶点数组,面列表数组的长度,面列表数组指针。顶点个数和数组很好理 解,就是具体的各个顶点的三维坐标。面列表是这样的格式:面顶点个数n,第一个顶点序号,第二个顶点序号,第n个顶点序号。例如flist第一 行,4表示该面由四个顶点构成,也就是一个四边形。然后,0,3,2,1表示由pts这个数组中的第0、3、2、1号点构成这个面。需要注意的是 HC_Insert_Shell的第三个参数实质flist这个数组本身的长度,而不是将要构建的shell上面的个数。例如这个例子中面的个数为9,但 flist的长度为41。效果如下图所示:四、段的属性上文中,我们在HOOPS中创建了一个房子,假设我们现在已经用几何图元将房子给绘制出来了,但是光有结构还不行,至少我们还需要给它上色,或许我 们还会通过贴上不同的纹理来表示不同的材料。HOOPS的段结构中除了可以存放Geometry,还可以存放属性Attribute。我们常用的属性包 括:可见性(Visibility),颜色(Color),可选择性(Selectability),点、边、字体的大小,光照(light),渲染属性 (rendition)等等。甚至可以添加我们自定义的属性(Userdefinedattribution)。可以说,HOOPS的属性功能是非常 全面而强大的。和插入几何一样,要修改一个segment的属性,我们需要进入该segment的状态机,亦即要首先打开这个段。下面以house模型为例:HC_Open_Segment(“house”);HC_Open_Segment(“roof”);/addroofgeometryhere.HC_Set_Color(“geometry=red”);HC_Close_Segment();HC_Open_Segment(“door”);/adddoorgeometryhere.HC_Set_Color(“geometry=grey”);HC_Close_Segment();HC_Close_Segment();这样,我们将屋顶和门分别设置成了红色和灰色。又比如刚才我们自创的那个集合模型,这回,我们要让它不再空白一片了,我们给它点颜色看看(J):HC_Open_Segment(mymodel);HC_Set_Color(faces=grey,edges=green);HC_Set_Visibility(edges=on);HC_Insert_Shell(9,pts,41,flist);HC_Close_Segment();我们设置了mymodel这个段的两个属性,颜色和可见性。在设置颜色中,我们设置面为灰色,而设置边为绿色;在设置可见性上,我们设置边为可见。 为什么不设置面为可见呢?因为在HOOPS中,有些是默认可见的,而有些是默认不可兼得;而shell的面是默认可见的,edges则恰好是默认不可见 的。下面是新的效果图,怎么样,和之前不一样了吧?记住这个模型,往后的教程中我们还会多次用到,比如给它贴上漂亮的纹理、光照等等,还有动画。上面在设置颜色时,我们用一个字符串命令同时设置了面和边的颜色。这种格式化的字符串在HOOPS中被大量应用,几乎接受字符串作为参数的 HOOPS函数中都有这样的格式化命令。faces和edges对于HC_Set_Color函数来说,是可以设置颜色的对象,而等号后面是具体的值,中 间用逗号分隔。如果没有显式地说明设置对象,那么就是everything,也就是所有对象。该格式化字符串有很多相关使用技巧,具体可以参看HOOPS 的帮助文档,下面仅举几个例子来说明格式化字符串的基本用法:1.“red,faces=green”,设置所有几何图元为红色,只有面为绿色;2.“markers=edges=black”,点和边为黑色;3.“!edges=(r=0.5g=0.5b=0.5)”,非边的图元颜色都设置为灰色。至于设置对象是复数还是单数是无所谓的,即edges和edge的作用效果完全一样。五、属性的继承属性(Attribute)是可以被继承的,就像面向对象的编程语言里面类的继承一样。对于绝大多数属性来说,继承的方向是子段从父段中继承属性。 这种特性有时候对我们来说可以提供极大的方便。回想我们之前创建的house,它有三扇窗户,一般来说,一座房子的窗户颜色都是一样的,如果没有属性的继 承,那么我们大概就需要针对每一个窗户段设置它的颜色属性。对于我们这座小房子来说,这还可以接受,可是某天你发达了,让你构建一桩拥有成千上万扇窗户的 摩天大楼,那恐怕就是场灾难了。有了属性的继承,世界还是美好的。我们可以在windows这个段设置颜色,那么所有该段下面的子段都自动继承了该颜色属 性,再不用我们单独去设置了。然而,问题也随之出现。整幢大楼里毕竟有些窗户所在的房间住着不寻常的人,而这些窗户我们希望显示出不一样的颜色,以彰显这些人的显赫身份。那如何 避免这些窗户继承父段的颜色呢?我们可以单独设置这些窗户的颜色,HOOPS在绘制这些窗时,会优先使用单独设置在这些段上的颜色;如果没有单独设置(如 同绝大多数窗户),那么HOOPS才会自动地去读取父段的该属性,直到最上层的根节点“/”。如果根节点也没有设置该属性,HOOPS就会报错。对于绝大 多数的属性来说,HOOPS正是遵循这种“追根溯源”的方式来确定一个属性的值的。虽然这种直接覆盖的属性占大多数,但是有些属性不是直接覆盖得到的,例如旋转矩阵。要计算一个图元最终在世界坐标上的位置,我们需要从根节点开始,逐步地累加旋转矩阵,一直到该段,这样计算所得的旋转矩阵才是最后真正的旋转矩阵。虽然我们能够控制一个特定的段的属性,但是有时候我们还是想要强制整个段表现为同一种属性,而不管底下各个子段是否单独设置了该属性。有些属性就提 供了这样的功能,其中之一就是颜色属性。当我们用鼠标选中了某一个segment之后,我们希望整个段都显示一种高亮色,而不管该段内部子段的单独颜色。 这时,我们需要用到颜色的属性锁。可以通过调用下面的代码来对颜色加锁:HC_Open_Segment(“myseg”);HC_Set_Color(red);HC_Set_Rendering_Options(attributelock=color);HC_Close_Segment();这样,myseg这个段的颜色就被锁定为红色。如果后续操作中我们不再需要对颜色进行锁定,则可以使用HC_UnSet_Rendering_Option(“attributelock”)。六、特殊的段包含段和样式段上面介绍的段都是HOOPS中的普通类型的段。此外,HOOPS还有包含段(includedsegment)和样式段(stylesegment)。这些段的功能实际上都可以用普通段来实现,但是正因为引入了这些特殊类型的段,我们可以将HOOPS的数据结构设计得更为精巧和高效,我们的程序结构性也更好。再回顾我们之前给的house模型。我们在房子上添加了三扇窗户。一般来说,一幢房子上的窗户长得都是差不多的,因此我们想到是否可以只设计窗户一 次,而三次重复使用呢?可以的,HOOPS里面使用的就是包含段(includedsegment)。包含段实际上就是一次定义,多次重复使用,它提高 了代码的使用率,也提高了内存使用率。实际上包含段和C/C+语言中的头文件是很像的,我们编写一次头文件,然后在需要用到的地方通过#include 就可以将其包含进来,而不需要另外再写。包含机制除了提高效率之外,还能够方便后续的维护,例如当我们想要更新窗户的样式时,只需要在定义处修改一次,由 于三处窗户都是包含该窗户的,所以这三处就自动加载了新的样式。我们不再需要一个个地分别去修改,既提高了效率,又减少了出错的可能。包含段通常是针对含有几何信息的段(当然,由于包含段本质上还是普通的段,因此它可以包含属性),而样式段则仅包含属性。有些时候,我们需要重用的 可能仅仅是一套样式,例如颜色、大小、光照等,对于具体的几何图元我们却兴趣不大,这个时候就可以用到HOOPS的样式段。下面的代码演示了如何使用 Stylesegment:HC_Open_Segment(“mystyle”);HC_Set_Color(“edges=red,faces=(diffuse=(r=0.5g=0.2b=0.3)”);HC_Close_Segment();HC_Open_Segment(“myseg1”);HC_Style_Segment(“mystyle”);/Insertmygeometry.HC_Close_Segment();HC_Open_Segment(“myseg2”);HC_Style_Segment(“mystyle”);/Insertmyanothergeometry.HC_Close_Segment();这段创建了一个样式段,两个普通段,这两个普通段插入了不同的几何图元,但是使用了同样的样式段,所以它们显示出来后都是红色的边,紫色的面。七、键值键值(通常是HC_KEY类型)是HOOPS中一个非常重要的概念。HC_KEY本质上是一个32位带符号的整型。前文中我们说,可以通过段的名字 以及路径(相对路径或者绝对路径)来索引一个段,于此同时我们也可以用键值来索引段。HC_Open_Segment会返回一个long型的整数,就是打 开的这个段的键值。注意,新版本的HOOPS取消了在API谓词前的K变形,而所以之前这些K变形函数都返回
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 铁路局机务考试题及答案
- 2025年广西壮族自治区纪委监委公开遴选公务员笔试试题及答案解析
- 山西联合体考试题及答案
- 农业科研技术合作开发合同书
- 技士证考试题库及答案
- 鞍山中考模拟考试题及答案
- 岳阳二中考试题目及答案
- 信阳九中分班考试试卷及答案
- 日本驾考笔试题库及答案
- 人事管理人员笔试试题及答案
- 辐射安全防护技术革新方案
- 2025年大学生人文知识竞赛题库及参考答案
- 高考集合考试题及答案
- 中秋团圆主题班会课件
- 潍坊市辅警考试题库2025
- 飞行服务站2025年无人机培训基地建设与发展报告
- 2025年福建农业行政执法资格考试(专业法律知识)历年参考题库含答案详解
- 新质生产力六大科创中心
- 医疗数据孤岛问题与跨平台安全共享策略-洞察及研究
- 2025年有机食品消费者购买行为与偏好研究报告
- 2025年迎中秋节庆国庆节主题班会课件
评论
0/150
提交评论