李庚武
(重庆市消防救援总队,重庆 400000)
当前,全国消防救援队伍陆续引进计算机模拟训练和进行实战辅助的相关软件,但实际应用效果并未达到预期,其用于参观演示的意义大于实战意义。针对当前存在的问题,对建筑自动三维建模功能的研究实现,可以极大弥补现有系统使用的局限性,突破使用场景单一、建模工作量反复的桎梏。通过利用重点单位的建筑图纸文件,在虚拟场景中快速完成建筑场景模型的建立并完成对建筑信息向FDS 计算场景文件的转换,体现了自动的特点,减少使用者的工作量。
自Autodesk 公司1982 年推出第一款基于类似DOS 操作方式的自动计算机辅助设计软件AutoCAD V1.0 以来,其经过三十余年的版本更新和发展,凭借在辅助设计中丰富的功能,已广泛应用于建筑图纸绘制、工业制图、服装设计等众多领域。
OSG 三维渲染引擎是一个基于工业标准OpenGL 的API 接口,作为一个开源和跨平台的渲染引擎,随着逐步的发展,它的整个体系结构经历了一个由简单向复杂的过程。OSG 的主要部分由核心库、NodeKits、插件、用于互操作的类库以及不断发展和扩充的函数构成。核心库是整个渲染引擎中最重要的部分,它负责整个程序三维场景生成和渲染的基本功能,它又由三个类库组成:OSG 库包括在构建场景图中需要用到的节点类和控制场景渲染状态的类等;Util 库,顾名思义是指和工具相关的类库,提供了在三维场景中用于实现使用者和程序进行交互的交运算类和对场景中的内容进行控制和优化的工具;DB 库用来在程序中读取和调用一些已经建立好的二维或三维模型。
一个完整的DWG 格式建筑图纸内部包括HEADER、ENTITY、TABLE、BLOCK ENTITY 和CONTINGENCY HEADER 五部分,采用了五种标准的数据类型来记录所有信息,分别是char、byte、double int、long int 和double float。第一部分HEADER 是DWG 文件中基础信息部分,包含文件的版本、用户基本信息和各种信息内存的索引地址、系统变量等。
位于中间的ENTITY、BLOCK ENTITY、TABLE 这三个部分属于记录DWG 文件信息中的图形数据区域。
本文采用开源的AutoCAD 二次开发技术DWGDirect 来完成建筑关键信息读取工作。DWGDirect 的类库和数据库结构是与DWG 文件格式中建筑图纸信息的存储方式紧密联系的。Auto-CAD 软件在读取DWG 文件格式时是将所有信息以数据库的形式进行调用,整个数据库在内存中分为十个部分,包括一个用来存储一般对象的对象词典和九个符号表,用户在添加图纸文件中的信息时,AutoCAD 软件在相应类型的符号表中添加记录。每个类型的表记录中有包括相应的模型空间和图纸空间,而模型空间中包含了图纸文件中的实体信息[1]。因此DWGDirect 类库也采取类似的功能接口,分别读取DWG 文件的每一类信息。
一个完整的建筑工程DWG 格式文件包含了大量信息,因此在实际读取DWG 格式文件信息进行处理的过程中,主要需要解决以下几点问题:①如何提取有效信息除去冗余信息;②将建筑图纸读入信息之后如后将不同类型的构件进行准确识别;③如何兼顾计算机的效率,使计算性能用在信息读入上的开销不至于过大。
所有与建筑三维自动建模生成相关的功能均由建筑建模模块实现。这个模块包括了图纸信息的读取,数据处理与存储以及调用三维渲染引擎进行展示的所有功能。由于要实现信息的读取功能,首先需要定义用于储存信息的容器,以用于读取DWG文件中的建筑构件信息。
通过分类整理,将图纸中所涉及的建筑构件实体信息类型分为五类,包括点、线、圆、弧、多段线五种基本实体结构,其中线可以实现墙、柱、门、窗、洞的信息存储,圆可以实现感温探测器、烟感探测器和喷淋系统的识别存储。
在建筑建模模块类中,首先有针对性地定义这三个接口的指针对象:①代表整个应用程序的指针对象,通过这个指针对象能以面向对象方式来处理应用程序,再利用其应用程序属性来操作主应用程序;②负责控制整个应用程序的各个属性和应用程序层面的指针对象,通过这个指针对象用于完成应用程序层面的一些工作以及与操作系统等外界环境的交互;③代表当前图纸的指针对象,并在构造函数中对三个指针的值初始化为NULL。
其次在模块中定义三个函数分别用于对类进行相关的初始化、载入DWG 文件以及完成DWG 文件读取的操作。初始化函数对系统的内存进行释放,完成环境的初始化;载入DWG 文件的函数以参数的形式将文件的路径和名字以参数的形式传入系统中,使系统能够准确地找到文件,并通过句柄对象指针内部函数获取当前图纸;文件读取函数通过其内部的获取数据库函数从而完成文件信息的获取,并定义一个长整型变量用于记录图纸文件中块的个数。通过以上程序流程就可以对文件信息进行循环读取,循环次数为记录块个数的值,完成后释放数据库并关闭文件。
再次,定义六个临时接口对象向量指针用于临时存储不同实体信息地址,包括点、直线、弧形、圆、多段线和属性。获得信息后根据类型的不同,调用四个不同的实体读取函数将实体信息读取后存入相应结构体的向量容器中。四个函数分别用于读取DWG 文件中的直线参数、圆参数、弧参数以及多线段参数。
最后,在信息读取完成后,需要采取的步骤是将所读取的信息分门别类的放入相应的存储容器中,由不同的向量容器来记录不同类型建筑构件的线条。
为保持各部分的独立性,系统采用了面向对象的设计方式,把各部分的实现函数按功能区分封装成独立的类。首先根据类型的不同,将所有建筑构件分为墙、楼梯、楼板、门、窗、感温探测器、感烟探测器和水喷淋八种,并根据每种构件的特点确定所需要的输入参数。然后针对这八种类型分别定义DrawWall、DrawStairs、DrawLayer、DrawDoor、DrawWindow、DrawTem、DrawSmo、DrawSpr八个函数。其次再将每种构件的生成分解为最基本的点线面图形,建立三个基本图形函数用于绘制三维场景中的基本图形,通过八个建筑构件生成函数将参数传入基本图形函数中,由基本图形完成每个构件的生成。
首先在工程文件中加入OpenSceneGraph 的链接库,然后建立OSG.cpp 文件和OSG.h 头文件,步骤如下:
(1)在可视化引擎:渲染引擎类中增加以下成员变量:
窗口句柄:用于引用所操作展示的窗口。
场景根节点:用于实现整个场景所有对象的加载和控制。
(2)定义用于选择操作模式的整形变量,包括三个状态:
trackball 操作器、flight 操作器、第一人视角漫游器。
(3)定义用于选择显示模式的整形变量,包括两个状态:
普通显示和立体显示。
(4)在可视化引擎:渲染引擎类中增加成员函数分别完成OpenSceneGraph 三维渲染引擎的初始化操作,完成操作器、场景、相机配置、灯光等的初始化,然后编写建立窗口和相机的函数,最后建立三个函数分别负责绘制前后的处理工作和渲染工作。
对建筑构件的生成实质上是将构件分解成不同的基础图形,调用DrawBox 函数将每一个独立的三维图形通过子节点的形式加入整个建筑三位场景中。同样在OSG 渲染引擎中,每一个建筑构件也是通过成为子节点的形式加入到整个场景树中的。三维场景的体系构架、数据组织结构是采用包围体层次来实现对场景图形的管理,采用树状结构来保存信息[2]。系统在场景交互类中定义OSG 渲染引擎指针对象,通过组节点管理叶节点。组节点类一般是作为父节点或者根节点出现,可以使用加入子节点函数将下一级的场景加入其中,就像树的分叉一样。组节点类是继承至Referenced 类。
OSG 渲染引擎中采取了智能指针的计数方式,当用户使用该模版类管理一个对象时,内存计数器便在本身的基础上加1,即树的分叉下,每增加一个枝节,分叉点的计数增加1,当分叉下的枝节每减少一个,分叉点的计数减1,当分叉下的所有枝节都取消时,分叉点的计数为0,整个分叉从场景树中销毁并释放内存。
建筑自动三维建模功能的研究实现,可以极大弥补现有系统使用的局限性,突破使用场景单一、建模工作量反复的约束。通过利用重点单位的建筑图纸文件,在虚拟场景中快速完成建筑场景模型的建立并完成对建筑信息向FDS 计算场景文件的转换,体现了自动的特点,减少使用者的工作量。下一步,通过烟气模拟、训练设计等环节的研究,即可完成一个简单已用,可扩展性强的系统平台。