邱龙辉, 叶 琳
(青岛科技大学机电工程学院,山东 青岛 266061)
工程图学虚拟实验采用Web+Java+VRML平台,在网络中构建图学学习实践的空间,优化学生的课内和课后实验和实践训练环境。实验系统要求能够实现:① 三维立体的实时变形处理,如截交线实验中的立体切割;② 立体之间的位置变化处理,如立体相贯实验和组合体实验中立体的定位;③ 实验参数调整灵活:可以直接控制模型调整和通过 Web页面的界面调整[1]。但VRML的基本节点本身并不具备实现这些目标的能力,要实现上述目标,必须能够通过程序方便的控制虚拟实验系统中虚拟模型,如获得模型的状态数据、读取模型的几何结构数据、程序动态生成模型等,本文研究了使用Java平台实现实验系统的几个关键技术。
Java程序控制VRML可以通过两种方式,即通过 SAI (Script Authoring Interface)或 EAI(External Authoring Interface)[2]。SAI方式是通过VRML中的Script接口节点控制场景,充分利用了VRML原有的事件机制,但其Java程序类必须是Script类的子类[2-3],也就是说所编写的Java类都必须继承自Script类。EAI方式是使用一套针对VRML浏览器的Java类,实现了Java Applet与 VRML场景的通信。通过 EAI,Java Applet可以访问当前运行的 VRML场景,在外部直接操作、控制和修改 VRML内部的场景。SAI和EAI相当于Java对VRML场景的内部控制和外部控制方法,可以满足不同实验的需要。
在系统中欲实现对 VRML场景的控制,应首先在 VRML程序对其开放的被控制节点使用DEF命名,建立该节点被检索的标识,然后在Java程序中通过该名称获得对应节点的Node类实例。在SAI和EAI中获得节点实例的方法不同,SAI必须在Script节点中定义域,并使用USE关键词引用对应的节点,在 Java程序中使用getField()方法通过读取Script节点中的域值获得该实例。而EAI则相对灵活,只需使用getNode()方法即可直接获得。
在虚拟实验操作过程中,诸如截交线实验的截平面、组合体实验中构件都需要获得其空间位置,测绘实验中需要获得坐标点数据,此时获得场景中模型当前的状态数据和几何结构数据成为关键环节之一,正确读取相关数据才能进行其他的相关操作。场景中模型的结构数据和当前的状态是由节点的出事件和外露域的参数表现的,所以获得模型的结构数据和当前的状态就是获得相应节点的出事件和外露域参数。
使用VRML API时,获得节点的出事件和外露域参数有两个途径:① 使用VRML的ROUTE语句,通过Script节点的eventIn获得相关节点的状态数据,需要在 VRML文件中添加许多ROUTE语句,但只适用于SAI模式开发;② 直接读取 VRML节点的出事件和外露域,SAI和EAI均可以实现。
如图1所示,直接读取VRML节点出事件和外露域需要如下几个步骤:
图1 读取出事件
(1)获得Browser实例
本步骤需要定义一个 VRML API特有的Browser类,然后使用该类的 getBrowser()方法建立当前的Browser类实例。Browser类实际上是对VRML场景的一个Java封装,其中包含了获取当前浏览环境信息的各种方法。
(2)获得节点(Node)实例
使用 SAI或 EAI开发时,获得节点实例的方法不同:SAI必须在关联的Script节点中定义域,并使用 USE关键词引用对应的节点,然后在 Java程序中使用 getField()方法通过读取Script节点中的域值获得该实例;而EAI则相对灵活,只需使用getNode()方法即可直接获得。
(3)获得节点出事件(eventOut)或外露域(exposedField)实例
模型的结构数据和当前的状态数据是通过该节点的eventOut或exposedField反映的。所以应先获得该事件的实例。该实例的获得通过Node类的getEventOut()方法实现。这一步骤需要将getEventOut得到的实例强制类型转化为EventOut的相应子类(如 EventOutMFVec3f),以实现读取eventOut事件目的。
(4)读取模型的状态数据
通过eventOut实例的getValue()方法实现模型的状态数据的读取。
按照前述步骤,在虚拟截交线实验中,采用了 EAI的方式实时获得了切割平面位置。其中须定义变量如下:
在实验过程中,经常需要根据实验需求动态的建立模型;当针对实验模型进行诸如切割、拉伸等操作后,也需要重新生成虚拟模型。因此,使用 Java程序动态地生成虚拟模型成为了虚拟实验的关键过程。
向VRML场景添加节点,需要以下5个步骤。
(1)获得浏览器的管理。
(2)获得父节点的控制
场景中一般使用Transform节点作为容纳模型形体的父节点,在 VRML文件需要对相应的Transform节点使用DEF定义名称,同时在Java中使用Browser类的getNode()方法获得该节点的Node类实例。
(3)获得父节点的eventIn实例
向Transform节点中添加模型节点是通过该节点的eventIn事件addChildren实现的。所以必须先获得该事件的实例。该实例的获得通过Node类的 getEventIn()方法实现。此处同样需要注意的是将getEventIn得到的addChildren实例强制转化为EventIn的子类EventInMFNode。
(4)建立新模型节点数据
模型节点数据生成步骤如下:
1)计算获得模型立体的点表和面表数据;
2)按VRML格式建立坐标(coordString)和坐标索引(coordindexString)字符串,1)中计算获得的点表数据是双精度型,而 VRML模型中数据精度不必太高,这里使用Java中Math类的 round()方法保留两位小数,然后将坐标值转换为字符串向坐标字符串赋值。同时注意各坐标之间需要加入空格,每组坐标后要加入逗号分隔,以符合VRML格式要求。
3)建立Node类数组
创建 Node类型的实例数组使用 API中Browser类的createVrmlFromString()方法,该方法的参数是符合 VRML格式的字符串。这里将坐标、坐标索引字符串与Transform的其他相关字符串组合。此处的字符串应按照 VRML编程时的格式,分行列出,这样可以极大地减少程序在运行过程中的出错率。
下面以棱柱截交线实验为例,说明各种方法的应用。截交线实验进行中,截平面位置的获得使用了VRML模型数据的获取技术,如图2所示;而截切后截断体的生成使用了 Java程序生成虚拟模型技术,如图3所示。
图2 截平面位置的获得
图3 Java程序生成截断体
本文针对工程图学虚拟实验系统在控制虚拟模型方面的需求,研究实现了 Java程序控制VRML,获取VRML模型数据,生成虚拟模型等几个实现模型控制中的关键技术。解决了虚拟实验系统开发中的几个难点问题,也为其他VRML虚拟系统提供了开发基础。
[1]邱龙辉, 叶 琳. 基于VRML-Java平台的工程图学网络实验系统研究与实现[J]. 工程图学学报, 2005,26(5): 155-159.
[2]Rikk Carey, Gavin Bell, Chris Marrin. ISO/IEC 14772-1:1997, Virtual Reality Modeling Language [S].
[3]The Java Tutorial [EB/OL]. http://java.sun.com/docs/books/tutorial