Open Inventor

作者:Robert Hartley

Open Inventor 是一个强大的 3-D 图形库,使用户能够快速轻松地创建交互式 3-D 应用程序。它将面向对象编程添加到 OpenGL,这是最广泛使用的标准 3-D API。这种面向对象抽象层并没有以失去对应用程序的控制为代价——直接使用 OpenGL 编程的所有强大功能仍然可用。

衡量完成工作需要多少细节的一个标准是标准参考书的大小。我个人图形编程的五本必备书籍列在“资源”部分。要精通 Inventor 编程,最重要的一本是 Josie Wernecke 的《Inventor Mentor》

它包含什么?

Inventor 将其数据组织成场景图,这是一个结构化的图形对象集合,存储为节点。这些节点可以代表许多事物,从几何图元、引擎、灯光和材质属性到可以包含缩放、旋转和平移属性的变换节点。

Inventor 有效地处理许多图形操作,否则这些操作必须由用户编码。它具有场景图管理、拾取、查看和用户交互的功能。标准查看器有五种基本类型:飞行、步行、平面、检查器和渲染区域。

材质、定向光、变换和其他节点属性的编辑器可以附加到场景图中,并且可以在任何标准编辑器查看器中交互式地渲染更改。这些编辑器以源代码形式提供,因此可以自定义以满足用户的特定需求。

它来自哪里?

Open Inventor 由 Silicon Graphics (SGI) 开发,这是一家构建图形工作站的公司。它是 Iris Inventor 的第二个版本,它封装了 IrisGL,OpenGL 就是从中衍生出来的。Inventor/GL API 功能丰富,并且已经成熟了大约十年。它已被证明值得花费时间和精力去学习。虽然有很多东西要学习,但即使是新手也很容易完成很多事情,稍后将对此进行演示。

Template Graphics Software (TGS) 拥有 Open Inventor 和 OpenGL 的源代码许可。TGS 负责将 Inventor 移植和分发到 Linux 和其他 UNIX 平台以及 Windows NT/95,并在移植过程中对其进行增强和丰富。1997 年 9 月,第一个 Linux 版 Inventor 出现在 TGS 互联网站点上(请参阅“资源”部分)。

VRML 连接是什么?

Inventor 文件格式被选为 VRML 1.0 文件格式的基础,通常以 .WRL 扩展名区分。许多 Inventor 节点直接用于 VRML,并且经常被称为“剥离了所有好东西的 Inventor”。随着 VRML 2.0 的新定义,最近发布的 Inventor 版本,包括最新的 Linux 版本,已经更新为能够读取、写入和处理 VRML 文件。实际上,我发现标准 Inventor 查看器比一些适用于 Windows 和 UNIX/Linux 的查看器更适合作为 VRML 模型查看器。它们提供更好的性能和更好的渲染外观。

我可以用它做什么?

Inventor 是创建动画、模拟、数据可视化、VR 作品和 CAD 的理想环境。

在 Pratt & Whitney,我们在高端 UNIX 工作站上使用 Catia,用于飞机、工业和船舶应用燃气涡轮发动机开发的设计/制造过程。Catia 是一个非常强大的 3-D CAD/CAM 系统,并且有自己的 API 用于查询绘图模型以检索几何图形和其他信息。

使用此 API,编写了一个 Open Inventor 程序 xmtriag,用于将 Catia 实体模型转换为立体光刻 (STL) 格式,以便输入到 STL 机器进行快速原型制作。除了 STL 格式外,该程序还生成一个 Inventor 文件,供我们直观地验证零件是否已正确转换。

我的公司在我们的设计过程中使用此程序作为实用程序,以获取发动机零件的 3-D 快照,将其转换为 STL 格式,并通过 FTP 发送给供应商,然后供应商向我们发回报价,最终发回零件。这些零件可用于设计评审或用于铸造目的以制作精密模具。这种方法节省了设计/评审/制造周期中的资金和时间,并提高了质量。事实上,这个过程非常成功,我们正在安装我们自己的内部快速原型制作设施。

除了工程领域的人员外,许多其他人也对查看和查询我们的绘图数据库感兴趣。为了避免占用 Catia 许可证,开发了一个查看器,用于从模型数据库中提取 3-D 几何图形并将其转换为 Inventor 格式。这些新的 Inventor 模型可以作为零件的轻量级版本保存,而不是将它们存储在 Catia 中。使用 SQL 数据库,我们可以从分层绘图树中选择零件,而无需考虑正在使用的平台,并查看所选零件的相关工程数据和其他数据。除了 Catia 之外,此转换器/查看器还将处理 Unigraphics 和其他 CAD 绘图格式。

结果,我们不必购买新的 Catia 许可证或其他昂贵的第三方查看器。图形开发的大部分工作由一个人完成,数据库方面的人员在六个月内提供了一些辅助帮助。不包括 Inventor 许可证的价格(在 SGI 工作站上是免费的),第三方查看器许可证的价格与此人的工资之比超过 100 比 1。

它是如何工作的?

Inventor 主要包含 3-D 对象及其相关属性:几何形状、颜色、灯光和 3-D 对象操纵器。这些使用 OpenGL 或类似的 API(例如 Brian Paul 的 Mesa(请参阅“资源”部分))进行渲染。

Inventor Xt 组件和实用程序库为事件处理、渲染、查看器和可以直接操作场景图的编辑器提供小部件和实用程序。这些事件包括节点的选择、拾取和突出显示、键盘和鼠标处理以及处理 Xt 和 Motif 回调函数。

我还需要什么?

对于标准 GUI 设计,我们可以求助于 Motif(Windows NT/95 下的 MFC),或者任何我们喜欢的 2-D GUI API。预定义的查看器类等标准组件已设置为利用 UNIX/Linux 下的 Motif 和 Xt,使用 SoXt 类。这些类已在 Windows 下模拟,因此我们可以更轻松地在平台之间移植代码。

我发现 Motif 编程有点麻烦,所以我一直在使用 Viewkit(可从 http://www.ics.com/ 获取),并结合在 Irix 上运行的 RapidApp 来构建 GUI 并生成 C++ 代码存根。Viewkit 可免费用于 SGI 和 Linux 工作站,RapidApp 代码可以在 Linux 下干净地编译。GUI 可以手动完全在 Linux 下构建,但它有助于设计过程能够交互式地工作。此外,在两个平台上构建可能有助于确保可移植性问题在设计过程的早期出现。

Motif 不是 UNIX 下的绝对先决条件。SGI 前员工 Mark J. Kilgard 在他的著作《X Window 系统的 Open GL 编程》(请参阅“资源”部分)中说明了如何在没有 Motif 的情况下使用 Open Inventor。

“Hello Cone”,一个 Inventor 示例

让我们看一下一个快速示例,说明设置场景图和查看器有多么容易。《Inventor Mentor》的示例 2-4 使用标准场景查看器呈现了“Hello Cone”。(见图 1。)该图显示了 SceneViewer 的三个主要区域:三个拇指轮、八个侧面按钮和一个渲染区域。

图 1. 带有“Hello Cone”的场景查看器

这八个按钮处理对象选择/拾取、视点操作、帮助、返回主视点、设置新的主视点、执行 viewAll 以查看整个场景、寻找点以及在正交和透视之间切换相机类型。

三个拇指轮通过围绕 X 轴和 Y 轴旋转相机角度以及沿 Z 轴平移以获得缩放效果来处理场景视点的操作。

渲染区域是最有趣的。鼠标可以用来获得与拇指轮相同的效果。鼠标按钮 1 将允许用户选择对象,如果鼠标在释放时正在移动,则对象将继续沿鼠标光标移动的方向旋转。鼠标按钮 2 将允许用户向上/向下和向左/向右平移,如果按下 control 键,则放大和缩小。鼠标按钮 3 会弹出一个弹出菜单,允许用户设置各种属性(例如“原样”渲染、隐藏线、线框、仅点和边界框)、首选项以及拇指轮和侧面按钮的显示(称为装饰)。

列表 1 显示了创建此程序有多么简单。前七行是最小的头文件。Inventor 有 553 个不同的包含文件。这看起来可能很多;但是,每个文件都非常专业,并且仅选择需要的那些文件将加快编译时间。如果我愿意,我可以简单地包含 Inventor/So.h,并让编译器处理所有以“So”为前缀的文件。

main 之后的头两行执行行创建主窗口小部件并调用 SoXt::init。这是程序的重要组成部分,因为在这里,Inventor 被绑定到 Xt 事件处理,以便其传感器能够正常工作。SoXT::init 也是调用许可代码的地方。未能调用 init 将导致核心转储。

要可见,每个场景图都必须有一个节点附加到查看器。在列表中,我正在使用一个 SoSeparator,它在进入之前保存遍历状态,并在之后恢复它。这用于防止其子节点的属性影响后续场景图的其他部分。分隔符可以包括灯光、相机、坐标、法线、绑定和所有其他属性。分隔符还基于边界框计算在拾取和渲染期间提供其子项的缓存和剔除。

一旦您创建一个节点并将其传递给场景图,Inventor 就会接管。Inventor 节点始终使用 C++ new 命令动态创建——永远不在堆栈上。每个节点都有一个引用计数,创建时从零开始,并在节点作为子节点添加到其他父节点时递增和递减。当此引用计数从 1 降至 0 时,Inventor 会自动删除该节点。

在遍历期间,节点被引用,然后在场景图被遍历时被取消引用。如果我们没有执行 ref,那么当我们第一次遍历场景图时,它的引用计数会在进入时递增,将其引用计数移动到 1,然后在离开时将其递减回 0,从而自动删除该节点以及任何引用计数也降至 0 的子节点。我们会想知道我们的节点去了哪里。

接下来,我们将材质属性作为子节点添加到根节点。它具有漫反射颜色或 (1.0,0.0,0.0),对应于全红色,红色、绿色和蓝色 (RGB) 量表示为介于 0.0 和 1.0 之间的浮点值。

现在将一个圆锥添加到根节点。它的默认值是底座为一单位,长度为一单位。它位于原点 0,0,0,并且在未旋转时,沿 Y 轴从底座向上指向一单位。由于圆锥在指定上述颜色的材质属性之后出现,因此圆锥继承其属性并且也是红色的。

Inventor 通过从根节点开始并向下和向右移动来遍历其场景图。由于 OpenGL 是一个状态机,因此一旦我们设置了一个属性,它将保留该值直到更改。

现在我们创建 SceneViewer,传递父窗口的小部件,将我们的场景图连接到它并设置窗口标题。

showhide 方法在将子小部件传递给它时调用 XtManageChildXtUnmanageChild。如果小部件是 shell 小部件,则 show 将调用 RealizeWidgetXMapWindow,如果它被图标化,它将提升并取消图标化它。hide 方法将调用 XUnmapWindow

Inventor 操纵器

通过添加操纵器,可以增强此程序,使其不仅仅允许更改视点。使用 SoTrackballManip 提供了在三个轴中的任何一个轴上围绕其自身中心交互式旋转对象的能力,如图 2 所示。

图 2. 旋转圆锥

只需在源代码中添加两行代码。在上面程序的包含部分末尾,添加行

#include <Inventor/manips/SoTrackballManip.h>

并在 root->ref 调用之后立即添加行

root->addChild(new SoTrackballManip);
为了确保我正在旋转圆锥,我使用鼠标按钮 2 将其移到一侧,并使用鼠标按钮 3 的弹出菜单打开原点的三个轴显示。

单击主窗口右侧的顶部按钮会将鼠标更改为选择模式。将光标移动到双环的任何交点并使用鼠标按钮 1 选择它会导致它以黄色突出显示,从而允许我们围绕其轴旋转圆锥。如果鼠标在释放时仍在移动,它将继续旋转。单击手形图标将恢复为视点操作模式,以便圆锥及其操纵器都可以围绕视点轴旋转。圆锥现在在其自身的轴上旋转并围绕场景中心轨道运行。

其他操纵器将执行旋转、缩放和平移(移动)任务以及这些功能的任何组合。

编辑节点

Inventor 附带了许多用于修改场景的标准节点编辑器。图 3 是 SceneViewer 中的典型模型(没有任何更改),SceneViewer 是 Inventor 发行版附带的演示程序。有关该图的更多信息,请参阅侧边栏 “关于图 3 的一点信息”

图 3. Deep Flight One 的模型,这艘单人潜艇由加利福尼亚州圣拉斐尔的 Hawkes Ocean Technologies 设计和制造

从主菜单中选择“编辑器”,我们可以选择“材质编辑器”并获得如图 4 所示的对话框。

图 4. 材质编辑器对话框

可以在工艺前端选择蓝色圆顶并使其半透明;可以添加一些灯光并关闭查看器的内置头灯。Inventor 有三种类型的灯光可以添加到场景中

  • SoPointLight 的作用类似于灯泡,向所有方向均匀地辐射光线。

  • SoDirectionalLight 沿单个方向发射光线,就好像它几乎位于无限远处一样,就像太阳一样。

  • SoSpotLight 在圆锥中发射光线,使其可以被指向和聚焦。

图 5 是绿色 SoDirectionalLight 以及红色和白色 SoSpotLights 的示例。它们的相应图标已保留,以便操纵器可见——它们通常会在渲染期间关闭。使用鼠标,我可以选择和移动它们以及更改其方向。SoSpotLights 添加了圆锥,可以通过更改投影半径来聚焦光线。

图 5. 交叉彩色聚光灯的结果

在图 5 中,我们看到了当光池相交时光的行为方式。在更改圆顶的材质属性后,我们看到了绿光如何显示为反射。如果添加雾、其他大气效果和纹理映射,我们将拥有一个高度逼真的场景,可以进行富有想象力的动画。

这个潜艇模型是我正在开发的模拟器的一部分。它包括一个数字高程地图查看器,可以读取和渲染地形数据以显示驾驶地形。我使用了一些 John Beale 关于利用政府数据渲染景观图像的想法。在他的网站 http://www.best.com/~beale/ 上,他提供了一些有用的转换器,这些转换器是从其他人那里改编而来的,可以将一分钟高程地图转换为 PGM 文件像素图。

图 6. 地形显示

该程序的 terrain-handling 部分如图 6 所示。它允许控制地形分辨率和颜色。右侧的查看器是标准的,因此可以根据需要缩放、平移和旋转图像。根据机器速度和地形复杂性,渲染或多或少是交互式的。就我个人而言,我发现 24 是一个理想的地形复杂性值。

高程数据保存在一个 1204 x 1204 的整数数组中,表示地图中测量的高度。这对于在 PC 上尝试交互式操作来说有点多,因此地形复杂性拇指轮允许我们选择我们想要的减少量。使用了一个非常简单的算法。图 6 中拇指轮的值 2 用作正方形的长度,我们从中获取最大高度,然后作为坐标点添加到 Inventor SoQuadMesh,基本上是由四边形组成的网格。值为 2 时,最大高度为四个高程点。值为 10 时,最大高度为 100 个点,消除了 99% 的地图用于渲染目的。由于这是交互式工作的,因此可以更改该值,直到找到将所需细节量与所需渲染速度相结合的平衡点。在此范围内,可以找到感兴趣的区域,并且仅渲染所需的细节。

图 6 中的每个 SoQuadMesh 节点都由一组四个顶点定义,每个顶点与其相邻邻居共享。这些顶点具有相关的颜色分量,该分量在 SoQuadMesh 的区域上平滑化。为了给出高度的一些视觉指示并总体上使事物更有趣,我已将每个高程设置为具有不同的颜色,该颜色基于用户指定的简单公式。

六个垂直轮处理每个颜色分量的最大深度和最小深度的分配,因此蓝色和红色的重叠会导致紫色的重叠区域。颜色量计算如下:从最大和最小范围找到中点,并且从颜色边界到该中点的距离百分比是要使用的该颜色的百分比。因此,中点处的顶点对于该颜色分量的值为 1.0,而四分之三到边缘的顶点对于该颜色的值将为 0.75。

读入的文件格式基本上是一个 ASCII PGM 文件,其中包含三个值,表示最大 X、Y 和 Z 值,后跟所有高程。这很方便,因为可以使用 xv 命令读取该文件,并以任何其他需要的图形文件格式保存。

最初,图 6 中表示的地形是图 7 中所示的像素图,较亮的区域具有较高的高度。

图 7. 原始像素图地形图像

连接新硬件

操纵杆驱动程序可用于 Linux。关于如何扩展 Inventor 的 Inventor Toolmaker 书籍的背面有一节关于添加新硬件设备的内容。进行了冗长的讨论,需要了解窗口系统的详细信息。我发现我可以通过使用 Inventor SoTimerSensor 节点绕过它,该节点设置为在几乎任何时间间隔使用附加的节点指针调用回调函数。它的设置如下

SoTimerSensor *JS_Sensor =
 new SoTimerSensor(JS_SensorCallback, craft_xf);
JS_Sensor->setInterval(0.005); //scheduled 200/sec ...
JS_Sensor->schedule();

名为 JS_SensorCallback 的函数检查操纵杆驱动程序以查看它移动了多少。这也是更新飞行状态模型以更改速度和航向的地方。我们可以根据当前的 XYZ 坐标检查诸如剩余空气量和功率量以及我们有多深之类的信息。

要添加的内容

我希望添加到此模拟器的一些内容是

  • 通过互联网联网以将两个用户连接在一起

  • 动画对象,例如鱼

  • 直接从互联网读取地形数据

  • 更多经验参数,以确保飞行器在模拟器中的响应方式与在现实生活中的响应方式相同

  • 潮汐和水流效应

  • 光衰减随深度增加

总结

除了易于使用和原始功率的可用性之外,我喜欢 Open Inventor,因为我开发的任何东西都可以在我的家用 Linux 机器和我在办公室的 SGI 工作站之间完全移植。使用 Viewkit、Motif 和 Mesa,我在选择软件开发地点和方式方面具有极大的灵活性。

Inventor 和 Viewkit 提供了 SGI 工作站的软件功能,并且随着图形硬件的最新进展,Linux PC 明天将更接近 SGI 工作站今天的水平。明天已经计划好了——没有人需要问我们今天想去哪里。

特别感谢 Alexandre Naaman 指明方向,保持耐心并在事情变得混乱时简化事情。

Inventor 的免费替代品

硬件和软件

资源

Open Inventor
Robert Hartley 是一位澳大利亚公民,目前居住在加拿大蒙特利尔。他最早接触 UNIX 是在八十年代中期的 Minix 操作系统上。他的职业生涯始于为魁北克省和安大略省的各个市政当局编写公共安全软件。他现在是 Pratt & Whitney Canada 的图形系统分析师。可以通过电子邮件 robert.hartley@pwc.ca 与他联系。
加载 Disqus 评论